Chromium Code Reviews| Index: src/runtime.cc |
| diff --git a/src/runtime.cc b/src/runtime.cc |
| index 97751470426cc62109970a2f17477e364c9e5ba4..612cf9f838804bf95c3446599ff9a7cc3263eaed 100644 |
| --- a/src/runtime.cc |
| +++ b/src/runtime.cc |
| @@ -747,11 +747,34 @@ bool Runtime::SetupArrayBufferAllocatingData( |
| } |
| +static Failure* ThrowTypeError(Isolate* isolate, |
| + const char* message_id, |
| + const char* arg) { |
| + HandleScope scope(isolate); |
| + Handle<Object> name_obj = |
| + isolate->factory()->NewStringFromAscii(CStrVector(arg)); |
| + Handle<Object> args[1] = { name_obj }; |
| + return isolate->Throw( |
| + *isolate->factory()->NewTypeError( |
| + message_id, HandleVector(args, 1))); |
| +} |
| + |
| + |
| RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferInitialize) { |
| HandleScope scope(isolate); |
| ASSERT(args.length() == 2); |
| - CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0); |
| + CONVERT_ARG_HANDLE_CHECKED(Object, this_obj, 0); |
| CONVERT_ARG_HANDLE_CHECKED(Object, byteLength, 1); |
| + |
| + if (!this_obj->IsJSArrayBuffer()) { |
| + return ThrowTypeError(isolate, "constructor_not_function", "ArrayBuffer"); |
| + } |
| + Handle<JSArrayBuffer> holder(JSArrayBuffer::cast(*this_obj)); |
| + if (!holder->byte_length()->IsUndefined()) { |
| + return ThrowTypeError( |
| + isolate, "object_already_initialized", "ArrayBuffer"); |
| + } |
| + |
| size_t allocated_length; |
| if (byteLength->IsSmi()) { |
| allocated_length = Smi::cast(*byteLength)->value(); |
| @@ -822,43 +845,53 @@ enum TypedArrayId { |
| }; |
| static void ArrayIdToTypeAndSize( |
| - int arrayId, ExternalArrayType* array_type, size_t* element_size) { |
| + int arrayId, |
| + ExternalArrayType* array_type, size_t* element_size, const char** name) { |
| switch (arrayId) { |
| case ARRAY_ID_UINT8: |
| *array_type = kExternalUnsignedByteArray; |
| *element_size = 1; |
| + *name = "Uint8Array"; |
| break; |
| case ARRAY_ID_INT8: |
| *array_type = kExternalByteArray; |
| *element_size = 1; |
| + *name = "Int8Array"; |
| break; |
| case ARRAY_ID_UINT16: |
| *array_type = kExternalUnsignedShortArray; |
| *element_size = 2; |
| + *name = "Uint16Array"; |
| break; |
| case ARRAY_ID_INT16: |
| *array_type = kExternalShortArray; |
| *element_size = 2; |
| + *name = "Int16Array"; |
| break; |
| case ARRAY_ID_UINT32: |
| *array_type = kExternalUnsignedIntArray; |
| *element_size = 4; |
| + *name = "Uint32Array"; |
| break; |
| case ARRAY_ID_INT32: |
| *array_type = kExternalIntArray; |
| *element_size = 4; |
| + *name = "Int32Array"; |
| break; |
| case ARRAY_ID_FLOAT32: |
| *array_type = kExternalFloatArray; |
| *element_size = 4; |
| + *name = "Float32Array"; |
| break; |
| case ARRAY_ID_FLOAT64: |
| *array_type = kExternalDoubleArray; |
| *element_size = 8; |
| + *name = "Float64Array"; |
| break; |
| case ARRAY_ID_UINT8C: |
| *array_type = kExternalPixelArray; |
| *element_size = 1; |
| + *name = "Uint8ClampedArray"; |
| break; |
| default: |
| UNREACHABLE(); |
| @@ -869,22 +902,32 @@ static void ArrayIdToTypeAndSize( |
| RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitialize) { |
| HandleScope scope(isolate); |
| ASSERT(args.length() == 5); |
| - CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0); |
| + CONVERT_ARG_HANDLE_CHECKED(Object, this_obj, 0); |
| CONVERT_SMI_ARG_CHECKED(arrayId, 1); |
| CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 2); |
| CONVERT_ARG_HANDLE_CHECKED(Object, byte_offset_object, 3); |
| CONVERT_ARG_HANDLE_CHECKED(Object, byte_length_object, 4); |
| + ExternalArrayType array_type = kExternalByteArray; // Bogus initialization. |
| + size_t element_size = 1; // Bogus initialization. |
| + const char* name = NULL; // Bogus initialization. |
| + ArrayIdToTypeAndSize(arrayId, &array_type, &element_size, &name); |
|
arv (Not doing code reviews)
2013/08/04 16:44:28
Can you move this code into the error cases? The c
Dmitry Lomov (no reviews)
2013/08/05 10:15:22
Done. Do you think it's cleaner that way? (Perf im
arv (Not doing code reviews)
2013/08/05 13:34:33
Sorry, I think my comment was bad advice. I didn't
|
| + |
| + if (!this_obj->IsJSTypedArray()) { |
| + return ThrowTypeError(isolate, "constructor_not_function", name); |
| + } |
| + Handle<JSTypedArray> holder(JSTypedArray::cast(*this_obj)); |
| + if (!holder->buffer()->IsUndefined()) { |
| + return ThrowTypeError( |
| + isolate, "object_already_initialized", name); |
| + } |
| + |
| ASSERT(holder->GetInternalFieldCount() == |
| v8::ArrayBufferView::kInternalFieldCount); |
| for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { |
| holder->SetInternalField(i, Smi::FromInt(0)); |
| } |
| - ExternalArrayType array_type = kExternalByteArray; // Bogus initialization. |
| - size_t element_size = 1; // Bogus initialization. |
| - ArrayIdToTypeAndSize(arrayId, &array_type, &element_size); |
| - |
| holder->set_buffer(*buffer); |
| holder->set_byte_offset(*byte_offset_object); |
| holder->set_byte_length(*byte_length_object); |
| @@ -916,21 +959,31 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitialize) { |
| RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitializeFromArrayLike) { |
| HandleScope scope(isolate); |
| ASSERT(args.length() == 4); |
| - CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0); |
| + CONVERT_ARG_HANDLE_CHECKED(Object, this_obj, 0); |
| CONVERT_SMI_ARG_CHECKED(arrayId, 1); |
| CONVERT_ARG_HANDLE_CHECKED(Object, source, 2); |
| CONVERT_ARG_HANDLE_CHECKED(Object, length_obj, 3); |
| + ExternalArrayType array_type = kExternalByteArray; // Bogus initialization. |
| + size_t element_size = 1; // Bogus initialization. |
| + const char* name = NULL; // Bogus initialization. |
| + ArrayIdToTypeAndSize(arrayId, &array_type, &element_size, &name); |
|
arv (Not doing code reviews)
2013/08/04 16:44:28
Ditto
Dmitry Lomov (no reviews)
2013/08/05 10:15:22
Ditto :)
|
| + |
| + if (!this_obj->IsJSTypedArray()) { |
| + return ThrowTypeError(isolate, "constructor_not_function", name); |
| + } |
| + Handle<JSTypedArray> holder(JSTypedArray::cast(*this_obj)); |
| + if (!holder->buffer()->IsUndefined()) { |
| + return ThrowTypeError( |
| + isolate, "object_already_initialized", name); |
| + } |
| + |
| ASSERT(holder->GetInternalFieldCount() == |
| v8::ArrayBufferView::kInternalFieldCount); |
| for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { |
| holder->SetInternalField(i, Smi::FromInt(0)); |
| } |
| - ExternalArrayType array_type = kExternalByteArray; // Bogus initialization. |
| - size_t element_size = 1; // Bogus initialization. |
| - ArrayIdToTypeAndSize(arrayId, &array_type, &element_size); |
| - |
| Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); |
| size_t length = NumberToSize(isolate, *length_obj); |
| size_t byte_length = length * element_size; |
| @@ -1089,11 +1142,20 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArraySetFastCases) { |
| RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewInitialize) { |
| HandleScope scope(isolate); |
| ASSERT(args.length() == 4); |
| - CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); |
| + CONVERT_ARG_HANDLE_CHECKED(Object, this_obj, 0); |
| CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 1); |
| CONVERT_ARG_HANDLE_CHECKED(Object, byte_offset, 2); |
| CONVERT_ARG_HANDLE_CHECKED(Object, byte_length, 3); |
| + if (!this_obj->IsJSDataView()) { |
| + return ThrowTypeError(isolate, "constructor_not_function", "DataView"); |
| + } |
| + Handle<JSDataView> holder(JSDataView::cast(*this_obj)); |
| + if (!holder->buffer()->IsUndefined()) { |
| + return ThrowTypeError( |
| + isolate, "object_already_initialized", "DataView"); |
| + } |
| + |
| ASSERT(holder->GetInternalFieldCount() == |
| v8::ArrayBufferView::kInternalFieldCount); |
| for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { |
| @@ -1361,10 +1423,28 @@ DATA_VIEW_SETTER(Float64, double) |
| #undef DATA_VIEW_SETTER |
| - |
| RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInitialize) { |
| HandleScope scope(isolate); |
| ASSERT(args.length() == 1); |
| + CONVERT_ARG_HANDLE_CHECKED(Object, holder, 0); |
| + if (!holder->IsJSSet()) { |
| + return ThrowTypeError(isolate, "constructor_not_function", "Set"); |
| + } |
| + Handle<JSSet> set(JSSet::cast(*holder)); |
| + |
| + if (!set->table()->IsUndefined()) { |
| + return ThrowTypeError(isolate, "object_already_initialized", "Set"); |
| + } |
| + |
| + Handle<ObjectHashSet> table = isolate->factory()->NewObjectHashSet(0); |
| + set->set_table(*table); |
| + return *holder; |
| +} |
| + |
| + |
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_SetClear) { |
| + HandleScope scope(isolate); |
| + ASSERT(args.length() == 1); |
| CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); |
| Handle<ObjectHashSet> table = isolate->factory()->NewObjectHashSet(0); |
| holder->set_table(*table); |
| @@ -1418,8 +1498,27 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetGetSize) { |
| RUNTIME_FUNCTION(MaybeObject*, Runtime_MapInitialize) { |
| HandleScope scope(isolate); |
| ASSERT(args.length() == 1); |
| - CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0); |
| + CONVERT_ARG_HANDLE_CHECKED(Object, holder, 0); |
| + if (!holder->IsJSMap()) { |
| + return ThrowTypeError(isolate, "constructor_not_function", "Map"); |
| + } |
| + Handle<JSMap> map(JSMap::cast(*holder)); |
| + |
| + if (!map->table()->IsUndefined()) { |
| + return ThrowTypeError(isolate, "object_already_initialized", "Map"); |
| + } |
| + |
| Handle<ObjectHashTable> table = isolate->factory()->NewObjectHashTable(0); |
| + map->set_table(*table); |
| + return *holder; |
| +} |
| + |
| + |
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_MapClear) { |
| + HandleScope scope(isolate); |
| + ASSERT(args.length() == 1); |
| + CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0); |
| + Handle<ObjectHashSet> table = isolate->factory()->NewObjectHashSet(0); |
| holder->set_table(*table); |
| return *holder; |
| } |
| @@ -1493,7 +1592,37 @@ static JSWeakCollection* WeakCollectionInitialize(Isolate* isolate, |
| } |
| -RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionInitialize) { |
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapInitialize) { |
| + HandleScope scope(isolate); |
| + ASSERT(args.length() == 1); |
| + CONVERT_ARG_HANDLE_CHECKED(Object, holder, 0); |
| + if (!holder->IsJSWeakMap()) { |
| + return ThrowTypeError(isolate, "constructor_not_function", "WeakMap"); |
| + } |
| + Handle<JSWeakMap> map(JSWeakMap::cast(*holder)); |
| + if (!map->table()->IsUndefined()) { |
| + return ThrowTypeError(isolate, "object_already_initialized", "WeakMap"); |
| + } |
| + return WeakCollectionInitialize(isolate, map); |
| +} |
| + |
| + |
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakSetInitialize) { |
| + HandleScope scope(isolate); |
| + ASSERT(args.length() == 1); |
| + CONVERT_ARG_HANDLE_CHECKED(Object, holder, 0); |
| + if (!holder->IsJSWeakSet()) { |
| + return ThrowTypeError(isolate, "constructor_not_function", "WeakSet"); |
| + } |
| + Handle<JSWeakSet> set(JSWeakSet::cast(*holder)); |
| + if (!set->table()->IsUndefined()) { |
| + return ThrowTypeError(isolate, "object_already_initialized", "WeakSet"); |
| + } |
| + return WeakCollectionInitialize(isolate, set); |
| +} |
| + |
| + |
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionClear) { |
| HandleScope scope(isolate); |
| ASSERT(args.length() == 1); |
| CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0); |