Commit 2f36ee71 authored by franzih's avatar franzih Committed by Commit bot

[builtins] Migrate SharedArrayBuffer.byteLength to C++.

Drive-by-fix: hydrogen code does not blindly return the
byteLength offset, instead it executes what is defined
in the byteLength getter.

BUG=

Review-Url: https://codereview.chromium.org/2123263002
Cr-Commit-Position: refs/heads/master@{#37595}
parent 0058f82e
......@@ -400,7 +400,6 @@ action("js2c_experimental") {
"src/messages.h",
"src/js/harmony-async-await.js",
"src/js/harmony-atomics.js",
"src/js/harmony-sharedarraybuffer.js",
"src/js/harmony-simd.js",
"src/js/harmony-string-padding.js",
"src/js/promise-extra.js",
......
......@@ -72,9 +72,6 @@ bool Accessors::IsJSObjectFieldAccessor(Handle<Map> map, Handle<Name> name,
return
CheckForName(name, isolate->factory()->length_string(),
JSArray::kLengthOffset, object_offset);
case JS_ARRAY_BUFFER_TYPE:
return CheckForName(name, isolate->factory()->byte_length_string(),
JSArrayBuffer::kByteLengthOffset, object_offset);
default:
if (map->instance_type() < FIRST_NONSTRING_TYPE) {
return CheckForName(name, isolate->factory()->length_string(),
......
......@@ -214,7 +214,8 @@ class Genesis BASE_EMBEDDED {
#undef DECLARE_FEATURE_INITIALIZATION
Handle<JSFunction> InstallArrayBuffer(Handle<JSObject> target,
const char* name);
const char* name, Builtins::Name call,
BuiltinFunctionId id);
Handle<JSFunction> InstallInternalArray(Handle<JSObject> target,
const char* name,
ElementsKind elements_kind);
......@@ -1815,8 +1816,9 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
}
{ // -- A r r a y B u f f e r
Handle<JSFunction> array_buffer_fun =
InstallArrayBuffer(global, "ArrayBuffer");
Handle<JSFunction> array_buffer_fun = InstallArrayBuffer(
global, "ArrayBuffer", Builtins::kArrayBufferPrototypeGetByteLength,
BuiltinFunctionId::kArrayBufferByteLength);
InstallWithIntrinsicDefaultProto(isolate, array_buffer_fun,
Context::ARRAY_BUFFER_FUN_INDEX);
}
......@@ -2799,7 +2801,9 @@ void Genesis::InitializeGlobal_harmony_sharedarraybuffer() {
Factory* factory = isolate->factory();
Handle<JSFunction> shared_array_buffer_fun =
InstallArrayBuffer(global, "SharedArrayBuffer");
InstallArrayBuffer(global, "SharedArrayBuffer",
Builtins::kSharedArrayBufferPrototypeGetByteLength,
BuiltinFunctionId::kSharedArrayBufferByteLength);
native_context()->set_shared_array_buffer_fun(*shared_array_buffer_fun);
Handle<String> name = factory->InternalizeUtf8String("Atomics");
......@@ -2900,7 +2904,9 @@ void Genesis::InitializeGlobal_harmony_array_prototype_values() {
}
Handle<JSFunction> Genesis::InstallArrayBuffer(Handle<JSObject> target,
const char* name) {
const char* name,
Builtins::Name call,
BuiltinFunctionId id) {
// Create the %ArrayBufferPrototype%
// Setup the {prototype} with the given {name} for @@toStringTag.
Handle<JSObject> prototype =
......@@ -2927,9 +2933,8 @@ Handle<JSFunction> Genesis::InstallArrayBuffer(Handle<JSObject> target,
Builtins::kArrayBufferIsView, 1, true);
// Install the "byteLength" getter on the {prototype}.
SimpleInstallGetter(prototype, factory()->byte_length_string(),
Builtins::kArrayBufferPrototypeGetByteLength, false,
kArrayBufferByteLength);
SimpleInstallGetter(prototype, factory()->byte_length_string(), call, false,
id);
return array_buffer_fun;
}
......@@ -3333,7 +3338,7 @@ bool Genesis::InstallExperimentalNatives() {
static const char* harmony_explicit_tailcalls_natives[] = {nullptr};
static const char* harmony_tailcalls_natives[] = {nullptr};
static const char* harmony_sharedarraybuffer_natives[] = {
"native harmony-sharedarraybuffer.js", "native harmony-atomics.js", NULL};
"native harmony-atomics.js", NULL};
static const char* harmony_simd_natives[] = {"native harmony-simd.js",
nullptr};
static const char* harmony_do_expressions_natives[] = {nullptr};
......
......@@ -5627,6 +5627,14 @@ BUILTIN(ArrayBufferPrototypeGetByteLength) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSArrayBuffer, array_buffer,
"get ArrayBuffer.prototype.byteLength");
if (array_buffer->is_shared()) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
isolate->factory()->NewStringFromAsciiChecked(
"get ArrayBuffer.prototype.byteLength"),
args.receiver()));
}
// TODO(franzih): According to the ES6 spec, we should throw a TypeError
// here if the JSArrayBuffer is detached.
return array_buffer->byte_length();
......@@ -5640,6 +5648,20 @@ BUILTIN(ArrayBufferIsView) {
return isolate->heap()->ToBoolean(arg->IsJSArrayBufferView());
}
// ES7 sharedmem 6.3.4.1 get SharedArrayBuffer.prototype.byteLength
BUILTIN(SharedArrayBufferPrototypeGetByteLength) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSArrayBuffer, array_buffer,
"get SharedArrayBuffer.prototype.byteLength");
if (!array_buffer->is_shared()) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
isolate->factory()->NewStringFromAsciiChecked(
"get SharedArrayBuffer.prototype.byteLength"),
args.receiver()));
}
return array_buffer->byte_length();
}
// ES6 section 26.2.1.1 Proxy ( target, handler ) for the [[Call]] case.
BUILTIN(ProxyConstructor) {
......
......@@ -164,6 +164,8 @@ class CodeStubAssembler;
V(ReflectSet, BUILTIN_EXIT) \
V(ReflectSetPrototypeOf, BUILTIN_EXIT) \
\
V(SharedArrayBufferPrototypeGetByteLength, BUILTIN_EXIT) \
\
V(StringFromCodePoint, BUILTIN_EXIT) \
\
V(StringPrototypeTrim, BUILTIN_EXIT) \
......
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
(function(global, utils) {
"use strict";
%CheckIsBootstrapping();
var GlobalSharedArrayBuffer = global.SharedArrayBuffer;
var MakeTypeError;
utils.Import(function(from) {
MakeTypeError = from.MakeTypeError;
})
// -------------------------------------------------------------------
function SharedArrayBufferGetByteLen() {
if (!IS_SHAREDARRAYBUFFER(this)) {
throw MakeTypeError(kIncompatibleMethodReceiver,
'SharedArrayBuffer.prototype.byteLength', this);
}
return %_ArrayBufferGetByteLength(this);
}
utils.InstallGetter(GlobalSharedArrayBuffer.prototype, "byteLength",
SharedArrayBufferGetByteLen);
})
......@@ -6770,6 +6770,7 @@ enum BuiltinFunctionId {
kTypedArrayByteLength,
kTypedArrayByteOffset,
kTypedArrayLength,
kSharedArrayBufferByteLength,
};
......
......@@ -2092,7 +2092,6 @@
'js/macros.py',
'messages.h',
'js/harmony-atomics.js',
'js/harmony-sharedarraybuffer.js',
'js/harmony-simd.js',
'js/harmony-string-padding.js',
'js/promise-extra.js',
......
......@@ -572,3 +572,21 @@ for(i = 0; i < typedArrayConstructors.length; i++) {
assertThrows(function(i) { typedArrayConstructors[i](); }.bind(this, i),
TypeError);
}
// byteLength from prototype can be overwritten
var s = new SharedArrayBuffer(10);
assertEquals(10, s.byteLength);
Object.defineProperty(s, 'byteLength', {value: 42});
assertEquals(42, s.byteLength);
// byteLength on incompatible type (shared vs. regular ArrayBuffer)
var desc = Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, 'byteLength');
s = new SharedArrayBuffer(10);
Object.defineProperty(s, 'byteLength', desc);
assertThrows(function() {s.byteLength}, TypeError);
desc = Object.getOwnPropertyDescriptor(SharedArrayBuffer.prototype,
'byteLength');
var a = new ArrayBuffer(10);
Object.defineProperty(a, 'byteLength', desc);
assertThrows(function() {a.byteLength}, TypeError);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment