Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(922)

Unified Diff: src/d8.cc

Issue 10392130: Some clean-up of typed array support in d8. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/d8.cc
diff --git a/src/d8.cc b/src/d8.cc
index ddd4100fa8209cb9d6075c466229a05eaa869ecd..148518a2f0d692cf3d29402eba0d7d7306005235 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -334,132 +334,109 @@ Handle<Value> Shell::CreateExternalArray(const Arguments& args,
element_size == 8);
if (args.Length() == 0) {
return ThrowException(
- String::New("Array constructor must have at least one "
- "parameter."));
+ String::New("Array constructor must have at least one parameter."));
}
bool first_arg_is_array_buffer =
args[0]->IsObject() &&
args[0]->ToObject()->Get(
String::New(kArrayBufferMarkerPropName))->IsTrue();
// Currently, only the following constructors are supported:
+ // ArrayBuffer(unsigned long length)
// TypedArray(unsigned long length)
// TypedArray(ArrayBuffer buffer,
// optional unsigned long byteOffset,
// optional unsigned long length)
- if (args.Length() > 3) {
- return ThrowException(
- String::New("Array constructor from ArrayBuffer must "
- "have 1-3 parameters."));
- }
-
- Local<Value> length_value = (args.Length() < 3)
- ? (first_arg_is_array_buffer
- ? args[0]->ToObject()->Get(String::New("byteLength"))
- : args[0])
- : args[2];
- size_t byteLength = convertToUint(length_value, &try_catch);
- size_t length = byteLength;
- if (try_catch.HasCaught()) return try_catch.Exception();
-
+ size_t length;
+ size_t byteLength;
+ size_t byteOffset;
void* data = NULL;
- size_t offset = 0;
-
Handle<Object> array = Object::New();
- if (first_arg_is_array_buffer) {
- Handle<Object> derived_from = args[0]->ToObject();
- data = derived_from->GetIndexedPropertiesExternalArrayData();
-
- size_t array_buffer_length = convertToUint(
- derived_from->Get(String::New("byteLength")),
- &try_catch);
+ if (is_array_buffer_construct) {
+ byteLength = convertToUint(args[0], &try_catch);
if (try_catch.HasCaught()) return try_catch.Exception();
+ byteOffset = 0;
+ length = byteLength;
- if (data == NULL && array_buffer_length != 0) {
- return ThrowException(
- String::New("ArrayBuffer doesn't have data"));
+ array->Set(String::New(kArrayBufferMarkerPropName), True(), ReadOnly);
Yang 2012/05/18 12:10:40 Is the property _is_array_buffer_ something that i
rossberg 2012/05/30 13:37:16 Done. _array_buffer_ref_ actually is redundant. Cl
+ } else if (first_arg_is_array_buffer) {
+ Handle<Object> buffer = args[0]->ToObject();
+ data = buffer->GetIndexedPropertiesExternalArrayData();
+ byteLength =
+ convertToUint(buffer->Get(String::New("byteLength")), &try_catch);
+ if (try_catch.HasCaught()) return try_catch.Exception();
+ if (data == NULL && byteLength != 0) {
+ return ThrowException(String::New("ArrayBuffer does not have data"));
}
- if (args.Length() > 1) {
- offset = convertToUint(args[1], &try_catch);
+ if (args.Length() < 2 || args[1]->IsUndefined()) {
+ byteOffset = 0;
+ } else {
+ byteOffset = convertToUint(args[1], &try_catch);
if (try_catch.HasCaught()) return try_catch.Exception();
-
- // The given byteOffset must be a multiple of the element size of the
- // specific type, otherwise an exception is raised.
- if (offset % element_size != 0) {
+ if (byteOffset % element_size != 0) {
return ThrowException(
- String::New("offset must be multiple of element_size"));
+ String::New("byteOffset must be multiple of element_size"));
}
}
- if (offset > array_buffer_length) {
- return ThrowException(
- String::New("byteOffset must be less than ArrayBuffer length."));
- }
-
- if (args.Length() == 2) {
- // If length is not explicitly specified, the length of the ArrayBuffer
- // minus the byteOffset must be a multiple of the element size of the
- // specific type, or an exception is raised.
- length = array_buffer_length - offset;
- }
-
- if (args.Length() != 3) {
- if (length % element_size != 0) {
+ if (args.Length() < 3 || args[2]->IsUndefined()) {
+ if (byteLength % element_size != 0) {
return ThrowException(
- String::New("ArrayBuffer length minus the byteOffset must be a "
- "multiple of the element size"));
+ String::New("buffer size must be multiple of element_size"));
}
- length /= element_size;
+ length = (byteLength - byteOffset) / element_size;
+ } else {
+ length = convertToUint(args[2], &try_catch);
+ if (try_catch.HasCaught()) return try_catch.Exception();
}
- // If a given byteOffset and length references an area beyond the end of
- // the ArrayBuffer an exception is raised.
- if (offset + (length * element_size) > array_buffer_length) {
+ if (byteOffset + length * element_size > byteLength) {
return ThrowException(
- String::New("length references an area beyond the end of the "
- "ArrayBuffer"));
+ String::New("byteOffset or length out of bounds"));
}
+ byteLength = byteOffset + length * element_size;
// Hold a reference to the ArrayBuffer so its buffer doesn't get collected.
array->Set(String::New(kArrayBufferReferencePropName), args[0], ReadOnly);
- }
-
- if (is_array_buffer_construct) {
- array->Set(String::New(kArrayBufferMarkerPropName), True(), ReadOnly);
+ } else {
+ length = convertToUint(args[0], &try_catch);
+ byteLength = length * element_size;
+ byteOffset = 0;
}
Persistent<Object> persistent_array = Persistent<Object>::New(array);
- if (data == NULL && length != 0) {
- // Make sure the total size fits into a (signed) int.
+ if (data == NULL && byteLength != 0) {
+ ASSERT(byteOffset == 0);
+ // Prepend the size of the allocated chunk to the data itself.
+ int total_size =
+ byteLength + kExternalArrayAllocationHeaderSize * sizeof(size_t);
static const int kMaxSize = 0x7fffffff;
- if (length > (kMaxSize - sizeof(size_t)) / element_size) {
+ // Make sure the total size fits into a (signed) int.
+ if (total_size > kMaxSize) {
return ThrowException(String::New("Array exceeds maximum size (2G)"));
}
- // Prepend the size of the allocated chunk to the data itself.
- int total_size = length * element_size +
- kExternalArrayAllocationHeaderSize * sizeof(size_t);
data = malloc(total_size);
if (data == NULL) {
return ThrowException(String::New("Memory allocation failed."));
}
*reinterpret_cast<size_t*>(data) = total_size;
data = reinterpret_cast<size_t*>(data) + kExternalArrayAllocationHeaderSize;
- memset(data, 0, length * element_size);
+ memset(data, 0, byteLength);
V8::AdjustAmountOfExternalAllocatedMemory(total_size);
}
persistent_array.MakeWeak(data, ExternalArrayWeakCallback);
persistent_array.MarkIndependent();
array->SetIndexedPropertiesToExternalArrayData(
- reinterpret_cast<uint8_t*>(data) + offset, type,
+ reinterpret_cast<uint8_t*>(data) + byteOffset, type,
static_cast<int>(length));
array->Set(String::New("byteLength"),
Int32::New(static_cast<int32_t>(byteLength)), ReadOnly);
if (!is_array_buffer_construct) {
+ array->Set(String::New("byteOffset"),
+ Int32::New(static_cast<int32_t>(byteOffset)), ReadOnly);
array->Set(String::New("length"),
Int32::New(static_cast<int32_t>(length)), ReadOnly);
- array->Set(String::New("byteOffset"),
- Int32::New(static_cast<int32_t>(offset)), ReadOnly);
array->Set(String::New("BYTES_PER_ELEMENT"),
Int32::New(static_cast<int32_t>(element_size)));
// We currently support 'buffer' property only if constructed from a buffer.
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698