| Index: src/runtime.cc
|
| diff --git a/src/runtime.cc b/src/runtime.cc
|
| index cfa427cbee30d16056b97d856775c840619ac536..b7fcb2d6041d388fad35156b5bfc27b46057b8fc 100644
|
| --- a/src/runtime.cc
|
| +++ b/src/runtime.cc
|
| @@ -926,11 +926,17 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferNeuter) {
|
|
|
|
|
| void Runtime::ArrayIdToTypeAndSize(
|
| - int arrayId, ExternalArrayType* array_type, size_t* element_size) {
|
| + int arrayId,
|
| + ExternalArrayType* array_type,
|
| + ElementsKind* external_elements_kind,
|
| + ElementsKind* fixed_elements_kind,
|
| + size_t* element_size) {
|
| switch (arrayId) {
|
| #define ARRAY_ID_CASE(Type, type, TYPE, ctype, size) \
|
| case ARRAY_ID_##TYPE: \
|
| *array_type = kExternal##Type##Array; \
|
| + *external_elements_kind = EXTERNAL_##TYPE##_ELEMENTS; \
|
| + *fixed_elements_kind = TYPE##_ELEMENTS; \
|
| *element_size = size; \
|
| break;
|
|
|
| @@ -948,7 +954,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitialize) {
|
| ASSERT(args.length() == 5);
|
| CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
|
| CONVERT_SMI_ARG_CHECKED(arrayId, 1);
|
| - CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 2);
|
| + CONVERT_ARG_HANDLE_CHECKED(Object, maybe_buffer, 2);
|
| CONVERT_ARG_HANDLE_CHECKED(Object, byte_offset_object, 3);
|
| CONVERT_ARG_HANDLE_CHECKED(Object, byte_length_object, 4);
|
|
|
| @@ -960,18 +966,19 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitialize) {
|
|
|
| ExternalArrayType array_type = kExternalInt8Array; // Bogus initialization.
|
| size_t element_size = 1; // Bogus initialization.
|
| - Runtime::ArrayIdToTypeAndSize(arrayId, &array_type, &element_size);
|
| + ElementsKind external_elements_kind = EXTERNAL_INT8_ELEMENTS;
|
| + ElementsKind fixed_elements_kind = INT8_ELEMENTS;
|
| + Runtime::ArrayIdToTypeAndSize(arrayId,
|
| + &array_type,
|
| + &external_elements_kind,
|
| + &fixed_elements_kind,
|
| + &element_size);
|
|
|
| - holder->set_buffer(*buffer);
|
| holder->set_byte_offset(*byte_offset_object);
|
| holder->set_byte_length(*byte_length_object);
|
|
|
| size_t byte_offset = NumberToSize(isolate, *byte_offset_object);
|
| size_t byte_length = NumberToSize(isolate, *byte_length_object);
|
| - size_t array_buffer_byte_length =
|
| - NumberToSize(isolate, buffer->byte_length());
|
| - CHECK(byte_offset <= array_buffer_byte_length);
|
| - CHECK(array_buffer_byte_length - byte_offset >= byte_length);
|
|
|
| CHECK_EQ(0, static_cast<int>(byte_length % element_size));
|
| size_t length = byte_length / element_size;
|
| @@ -984,14 +991,34 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitialize) {
|
|
|
| Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length);
|
| holder->set_length(*length_obj);
|
| - holder->set_weak_next(buffer->weak_first_view());
|
| - buffer->set_weak_first_view(*holder);
|
| -
|
| - Handle<ExternalArray> elements =
|
| - isolate->factory()->NewExternalArray(
|
| - static_cast<int>(length), array_type,
|
| - static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
|
| - holder->set_elements(*elements);
|
| + if (!maybe_buffer->IsNull()) {
|
| + Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(*maybe_buffer));
|
| +
|
| + size_t array_buffer_byte_length =
|
| + NumberToSize(isolate, buffer->byte_length());
|
| + CHECK(byte_offset <= array_buffer_byte_length);
|
| + CHECK(array_buffer_byte_length - byte_offset >= byte_length);
|
| +
|
| + holder->set_buffer(*buffer);
|
| + holder->set_weak_next(buffer->weak_first_view());
|
| + buffer->set_weak_first_view(*holder);
|
| +
|
| + Handle<ExternalArray> elements =
|
| + isolate->factory()->NewExternalArray(
|
| + static_cast<int>(length), array_type,
|
| + static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
|
| + Handle<Map> map =
|
| + JSObject::GetElementsTransitionMap(holder, external_elements_kind);
|
| + holder->set_map_and_elements(*map, *elements);
|
| + ASSERT(IsExternalArrayElementsKind(holder->map()->elements_kind()));
|
| + } else {
|
| + holder->set_buffer(Smi::FromInt(0));
|
| + holder->set_weak_next(isolate->heap()->undefined_value());
|
| + Handle<FixedTypedArrayBase> elements =
|
| + isolate->factory()->NewFixedTypedArray(
|
| + static_cast<int>(length), array_type);
|
| + holder->set_elements(*elements);
|
| + }
|
| return isolate->heap()->undefined_value();
|
| }
|
|
|
| @@ -1017,7 +1044,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitializeFromArrayLike) {
|
|
|
| ExternalArrayType array_type = kExternalInt8Array; // Bogus initialization.
|
| size_t element_size = 1; // Bogus initialization.
|
| - Runtime::ArrayIdToTypeAndSize(arrayId, &array_type, &element_size);
|
| + ElementsKind external_elements_kind;
|
| + ElementsKind fixed_elements_kind;
|
| + Runtime::ArrayIdToTypeAndSize(arrayId,
|
| + &array_type,
|
| + &external_elements_kind,
|
| + &fixed_elements_kind,
|
| + &element_size);
|
|
|
| Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
|
| if (source->IsJSTypedArray() &&
|
| @@ -1070,7 +1103,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitializeFromArrayLike) {
|
| isolate->factory()->NewExternalArray(
|
| static_cast<int>(length), array_type,
|
| static_cast<uint8_t*>(buffer->backing_store()));
|
| - holder->set_elements(*elements);
|
| + Handle<Map> map = JSObject::GetElementsTransitionMap(
|
| + holder, external_elements_kind);
|
| + holder->set_map_and_elements(*map, *elements);
|
|
|
| if (source->IsJSTypedArray()) {
|
| Handle<JSTypedArray> typed_array(JSTypedArray::cast(*source));
|
| @@ -1078,7 +1113,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitializeFromArrayLike) {
|
| if (typed_array->type() == holder->type()) {
|
| uint8_t* backing_store =
|
| static_cast<uint8_t*>(
|
| - JSArrayBuffer::cast(typed_array->buffer())->backing_store());
|
| + typed_array->GetBuffer()->backing_store());
|
| size_t source_byte_offset =
|
| NumberToSize(isolate, typed_array->byte_offset());
|
| memcpy(
|
| @@ -1107,13 +1142,24 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitializeFromArrayLike) {
|
| return typed_array->accessor(); \
|
| }
|
|
|
| -TYPED_ARRAY_GETTER(Buffer, buffer)
|
| TYPED_ARRAY_GETTER(ByteLength, byte_length)
|
| TYPED_ARRAY_GETTER(ByteOffset, byte_offset)
|
| TYPED_ARRAY_GETTER(Length, length)
|
|
|
| #undef TYPED_ARRAY_GETTER
|
|
|
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayGetBuffer) {
|
| + HandleScope scope(isolate);
|
| + ASSERT(args.length() == 1);
|
| + CONVERT_ARG_HANDLE_CHECKED(Object, holder, 0);
|
| + if (!holder->IsJSTypedArray())
|
| + return isolate->Throw(*isolate->factory()->NewTypeError(
|
| + "not_typed_array", HandleVector<Object>(NULL, 0)));
|
| + Handle<JSTypedArray> typed_array(JSTypedArray::cast(*holder));
|
| + return *typed_array->GetBuffer();
|
| +}
|
| +
|
| +
|
| // Return codes for Runtime_TypedArraySetFastCases.
|
| // Should be synchronized with typedarray.js natives.
|
| enum TypedArraySetResultCodes {
|
| @@ -1159,10 +1205,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArraySetFastCases) {
|
| size_t source_offset = NumberToSize(isolate, source->byte_offset());
|
| uint8_t* target_base =
|
| static_cast<uint8_t*>(
|
| - JSArrayBuffer::cast(target->buffer())->backing_store()) + target_offset;
|
| + target->GetBuffer()->backing_store()) + target_offset;
|
| uint8_t* source_base =
|
| static_cast<uint8_t*>(
|
| - JSArrayBuffer::cast(source->buffer())->backing_store()) + source_offset;
|
| + source->GetBuffer()->backing_store()) + source_offset;
|
|
|
| // Typed arrays of the same type: use memmove.
|
| if (target->type() == source->type()) {
|
| @@ -1178,8 +1224,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArraySetFastCases) {
|
| target_base + target_byte_length > source_base)) {
|
| // We do not support overlapping ArrayBuffers
|
| ASSERT(
|
| - JSArrayBuffer::cast(target->buffer())->backing_store() ==
|
| - JSArrayBuffer::cast(source->buffer())->backing_store());
|
| + target->GetBuffer()->backing_store() ==
|
| + source->GetBuffer()->backing_store());
|
| return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING);
|
| } else { // Non-overlapping typed arrays
|
| return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING);
|
| @@ -1187,6 +1233,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArraySetFastCases) {
|
| }
|
|
|
|
|
| +RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayMaxSizeInHeap) {
|
| + ASSERT_OBJECT_SIZE(FLAG_typed_array_max_size_in_heap);
|
| + return Smi::FromInt(FLAG_typed_array_max_size_in_heap);
|
| +}
|
| +
|
| +
|
| RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewInitialize) {
|
| HandleScope scope(isolate);
|
| ASSERT(args.length() == 4);
|
| @@ -14739,6 +14791,17 @@ TYPED_ARRAYS(TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
|
| #undef TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
|
|
|
|
|
| +#define FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, s) \
|
| + RUNTIME_FUNCTION(MaybeObject*, Runtime_HasFixed##Type##Elements) { \
|
| + CONVERT_ARG_CHECKED(JSObject, obj, 0); \
|
| + return isolate->heap()->ToBoolean(obj->HasFixed##Type##Elements()); \
|
| + }
|
| +
|
| +TYPED_ARRAYS(FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
|
| +
|
| +#undef FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
|
| +
|
| +
|
| RUNTIME_FUNCTION(MaybeObject*, Runtime_HaveSameMap) {
|
| SealHandleScope shs(isolate);
|
| ASSERT(args.length() == 2);
|
|
|