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) {
......
......@@ -39,147 +39,149 @@ class CodeStubAssembler;
V(Make##C##CodeYoungAgainEvenMarking, BUILTIN, kNoExtraICState)
// Define list of builtins implemented in C++.
#define BUILTIN_LIST_C(V) \
V(Illegal, BUILTIN_EXIT) \
\
V(EmptyFunction, BUILTIN_EXIT) \
\
V(ArrayConcat, BUILTIN_EXIT) \
V(ArrayPop, BUILTIN_EXIT) \
V(ArrayPush, BUILTIN_EXIT) \
V(ArrayShift, BUILTIN_EXIT) \
V(ArraySlice, BUILTIN_EXIT) \
V(ArraySplice, BUILTIN_EXIT) \
V(ArrayUnshift, BUILTIN_EXIT) \
\
V(ArrayBufferConstructor, BUILTIN_EXIT) \
V(ArrayBufferConstructor_ConstructStub, BUILTIN_EXIT) \
V(ArrayBufferPrototypeGetByteLength, BUILTIN_EXIT) \
V(ArrayBufferIsView, BUILTIN_EXIT) \
\
V(BooleanConstructor, BUILTIN_EXIT) \
V(BooleanConstructor_ConstructStub, BUILTIN_EXIT) \
\
V(DataViewConstructor, BUILTIN_EXIT) \
V(DataViewConstructor_ConstructStub, BUILTIN_EXIT) \
V(DataViewPrototypeGetBuffer, BUILTIN_EXIT) \
V(DataViewPrototypeGetByteLength, BUILTIN_EXIT) \
V(DataViewPrototypeGetByteOffset, BUILTIN_EXIT) \
\
V(DateConstructor, BUILTIN_EXIT) \
V(DateConstructor_ConstructStub, BUILTIN_EXIT) \
V(DateNow, BUILTIN_EXIT) \
V(DateParse, BUILTIN_EXIT) \
V(DateUTC, BUILTIN_EXIT) \
V(DatePrototypeSetDate, BUILTIN_EXIT) \
V(DatePrototypeSetFullYear, BUILTIN_EXIT) \
V(DatePrototypeSetHours, BUILTIN_EXIT) \
V(DatePrototypeSetMilliseconds, BUILTIN_EXIT) \
V(DatePrototypeSetMinutes, BUILTIN_EXIT) \
V(DatePrototypeSetMonth, BUILTIN_EXIT) \
V(DatePrototypeSetSeconds, BUILTIN_EXIT) \
V(DatePrototypeSetTime, BUILTIN_EXIT) \
V(DatePrototypeSetUTCDate, BUILTIN_EXIT) \
V(DatePrototypeSetUTCFullYear, BUILTIN_EXIT) \
V(DatePrototypeSetUTCHours, BUILTIN_EXIT) \
V(DatePrototypeSetUTCMilliseconds, BUILTIN_EXIT) \
V(DatePrototypeSetUTCMinutes, BUILTIN_EXIT) \
V(DatePrototypeSetUTCMonth, BUILTIN_EXIT) \
V(DatePrototypeSetUTCSeconds, BUILTIN_EXIT) \
V(DatePrototypeToDateString, BUILTIN_EXIT) \
V(DatePrototypeToISOString, BUILTIN_EXIT) \
V(DatePrototypeToPrimitive, BUILTIN_EXIT) \
V(DatePrototypeToUTCString, BUILTIN_EXIT) \
V(DatePrototypeToString, BUILTIN_EXIT) \
V(DatePrototypeToTimeString, BUILTIN_EXIT) \
V(DatePrototypeValueOf, BUILTIN_EXIT) \
V(DatePrototypeGetYear, BUILTIN_EXIT) \
V(DatePrototypeSetYear, BUILTIN_EXIT) \
V(DatePrototypeToJson, BUILTIN_EXIT) \
\
V(FunctionConstructor, BUILTIN_EXIT) \
V(FunctionPrototypeBind, BUILTIN_EXIT) \
V(FunctionPrototypeToString, BUILTIN_EXIT) \
\
V(GeneratorFunctionConstructor, BUILTIN_EXIT) \
V(AsyncFunctionConstructor, BUILTIN_EXIT) \
\
V(GlobalDecodeURI, BUILTIN_EXIT) \
V(GlobalDecodeURIComponent, BUILTIN_EXIT) \
V(GlobalEncodeURI, BUILTIN_EXIT) \
V(GlobalEncodeURIComponent, BUILTIN_EXIT) \
V(GlobalEscape, BUILTIN_EXIT) \
V(GlobalUnescape, BUILTIN_EXIT) \
\
V(GlobalEval, BUILTIN_EXIT) \
\
V(JsonParse, BUILTIN_EXIT) \
V(JsonStringify, BUILTIN_EXIT) \
\
V(MathHypot, BUILTIN_EXIT) \
\
V(NumberPrototypeToExponential, BUILTIN_EXIT) \
V(NumberPrototypeToFixed, BUILTIN_EXIT) \
V(NumberPrototypeToLocaleString, BUILTIN_EXIT) \
V(NumberPrototypeToPrecision, BUILTIN_EXIT) \
V(NumberPrototypeToString, BUILTIN_EXIT) \
\
V(ObjectAssign, BUILTIN_EXIT) \
V(ObjectCreate, BUILTIN_EXIT) \
V(ObjectDefineGetter, BUILTIN_EXIT) \
V(ObjectDefineProperties, BUILTIN_EXIT) \
V(ObjectDefineProperty, BUILTIN_EXIT) \
V(ObjectDefineSetter, BUILTIN_EXIT) \
V(ObjectEntries, BUILTIN_EXIT) \
V(ObjectFreeze, BUILTIN_EXIT) \
V(ObjectGetOwnPropertyDescriptor, BUILTIN_EXIT) \
V(ObjectGetOwnPropertyDescriptors, BUILTIN_EXIT) \
V(ObjectGetOwnPropertyNames, BUILTIN_EXIT) \
V(ObjectGetOwnPropertySymbols, BUILTIN_EXIT) \
V(ObjectGetPrototypeOf, BUILTIN_EXIT) \
V(ObjectIs, BUILTIN_EXIT) \
V(ObjectIsExtensible, BUILTIN_EXIT) \
V(ObjectIsFrozen, BUILTIN_EXIT) \
V(ObjectIsSealed, BUILTIN_EXIT) \
V(ObjectKeys, BUILTIN_EXIT) \
V(ObjectLookupGetter, BUILTIN_EXIT) \
V(ObjectLookupSetter, BUILTIN_EXIT) \
V(ObjectPreventExtensions, BUILTIN_EXIT) \
V(ObjectProtoToString, BUILTIN_EXIT) \
V(ObjectSeal, BUILTIN_EXIT) \
V(ObjectValues, BUILTIN_EXIT) \
\
V(ProxyConstructor, BUILTIN_EXIT) \
V(ProxyConstructor_ConstructStub, BUILTIN_EXIT) \
\
V(ReflectDefineProperty, BUILTIN_EXIT) \
V(ReflectDeleteProperty, BUILTIN_EXIT) \
V(ReflectGet, BUILTIN_EXIT) \
V(ReflectGetOwnPropertyDescriptor, BUILTIN_EXIT) \
V(ReflectGetPrototypeOf, BUILTIN_EXIT) \
V(ReflectHas, BUILTIN_EXIT) \
V(ReflectIsExtensible, BUILTIN_EXIT) \
V(ReflectOwnKeys, BUILTIN_EXIT) \
V(ReflectPreventExtensions, BUILTIN_EXIT) \
V(ReflectSet, BUILTIN_EXIT) \
V(ReflectSetPrototypeOf, BUILTIN_EXIT) \
\
V(StringFromCodePoint, BUILTIN_EXIT) \
\
V(StringPrototypeTrim, BUILTIN_EXIT) \
V(StringPrototypeTrimLeft, BUILTIN_EXIT) \
V(StringPrototypeTrimRight, BUILTIN_EXIT) \
\
V(SymbolConstructor, BUILTIN_EXIT) \
V(SymbolConstructor_ConstructStub, BUILTIN_EXIT) \
\
V(TypedArrayPrototypeBuffer, BUILTIN_EXIT) \
\
V(HandleApiCall, EXIT) \
V(HandleApiCallAsFunction, EXIT) \
V(HandleApiCallAsConstructor, EXIT) \
\
V(RestrictedFunctionPropertiesThrower, BUILTIN_EXIT) \
#define BUILTIN_LIST_C(V) \
V(Illegal, BUILTIN_EXIT) \
\
V(EmptyFunction, BUILTIN_EXIT) \
\
V(ArrayConcat, BUILTIN_EXIT) \
V(ArrayPop, BUILTIN_EXIT) \
V(ArrayPush, BUILTIN_EXIT) \
V(ArrayShift, BUILTIN_EXIT) \
V(ArraySlice, BUILTIN_EXIT) \
V(ArraySplice, BUILTIN_EXIT) \
V(ArrayUnshift, BUILTIN_EXIT) \
\
V(ArrayBufferConstructor, BUILTIN_EXIT) \
V(ArrayBufferConstructor_ConstructStub, BUILTIN_EXIT) \
V(ArrayBufferPrototypeGetByteLength, BUILTIN_EXIT) \
V(ArrayBufferIsView, BUILTIN_EXIT) \
\
V(BooleanConstructor, BUILTIN_EXIT) \
V(BooleanConstructor_ConstructStub, BUILTIN_EXIT) \
\
V(DataViewConstructor, BUILTIN_EXIT) \
V(DataViewConstructor_ConstructStub, BUILTIN_EXIT) \
V(DataViewPrototypeGetBuffer, BUILTIN_EXIT) \
V(DataViewPrototypeGetByteLength, BUILTIN_EXIT) \
V(DataViewPrototypeGetByteOffset, BUILTIN_EXIT) \
\
V(DateConstructor, BUILTIN_EXIT) \
V(DateConstructor_ConstructStub, BUILTIN_EXIT) \
V(DateNow, BUILTIN_EXIT) \
V(DateParse, BUILTIN_EXIT) \
V(DateUTC, BUILTIN_EXIT) \
V(DatePrototypeSetDate, BUILTIN_EXIT) \
V(DatePrototypeSetFullYear, BUILTIN_EXIT) \
V(DatePrototypeSetHours, BUILTIN_EXIT) \
V(DatePrototypeSetMilliseconds, BUILTIN_EXIT) \
V(DatePrototypeSetMinutes, BUILTIN_EXIT) \
V(DatePrototypeSetMonth, BUILTIN_EXIT) \
V(DatePrototypeSetSeconds, BUILTIN_EXIT) \
V(DatePrototypeSetTime, BUILTIN_EXIT) \
V(DatePrototypeSetUTCDate, BUILTIN_EXIT) \
V(DatePrototypeSetUTCFullYear, BUILTIN_EXIT) \
V(DatePrototypeSetUTCHours, BUILTIN_EXIT) \
V(DatePrototypeSetUTCMilliseconds, BUILTIN_EXIT) \
V(DatePrototypeSetUTCMinutes, BUILTIN_EXIT) \
V(DatePrototypeSetUTCMonth, BUILTIN_EXIT) \
V(DatePrototypeSetUTCSeconds, BUILTIN_EXIT) \
V(DatePrototypeToDateString, BUILTIN_EXIT) \
V(DatePrototypeToISOString, BUILTIN_EXIT) \
V(DatePrototypeToPrimitive, BUILTIN_EXIT) \
V(DatePrototypeToUTCString, BUILTIN_EXIT) \
V(DatePrototypeToString, BUILTIN_EXIT) \
V(DatePrototypeToTimeString, BUILTIN_EXIT) \
V(DatePrototypeValueOf, BUILTIN_EXIT) \
V(DatePrototypeGetYear, BUILTIN_EXIT) \
V(DatePrototypeSetYear, BUILTIN_EXIT) \
V(DatePrototypeToJson, BUILTIN_EXIT) \
\
V(FunctionConstructor, BUILTIN_EXIT) \
V(FunctionPrototypeBind, BUILTIN_EXIT) \
V(FunctionPrototypeToString, BUILTIN_EXIT) \
\
V(GeneratorFunctionConstructor, BUILTIN_EXIT) \
V(AsyncFunctionConstructor, BUILTIN_EXIT) \
\
V(GlobalDecodeURI, BUILTIN_EXIT) \
V(GlobalDecodeURIComponent, BUILTIN_EXIT) \
V(GlobalEncodeURI, BUILTIN_EXIT) \
V(GlobalEncodeURIComponent, BUILTIN_EXIT) \
V(GlobalEscape, BUILTIN_EXIT) \
V(GlobalUnescape, BUILTIN_EXIT) \
\
V(GlobalEval, BUILTIN_EXIT) \
\
V(JsonParse, BUILTIN_EXIT) \
V(JsonStringify, BUILTIN_EXIT) \
\
V(MathHypot, BUILTIN_EXIT) \
\
V(NumberPrototypeToExponential, BUILTIN_EXIT) \
V(NumberPrototypeToFixed, BUILTIN_EXIT) \
V(NumberPrototypeToLocaleString, BUILTIN_EXIT) \
V(NumberPrototypeToPrecision, BUILTIN_EXIT) \
V(NumberPrototypeToString, BUILTIN_EXIT) \
\
V(ObjectAssign, BUILTIN_EXIT) \
V(ObjectCreate, BUILTIN_EXIT) \
V(ObjectDefineGetter, BUILTIN_EXIT) \
V(ObjectDefineProperties, BUILTIN_EXIT) \
V(ObjectDefineProperty, BUILTIN_EXIT) \
V(ObjectDefineSetter, BUILTIN_EXIT) \
V(ObjectEntries, BUILTIN_EXIT) \
V(ObjectFreeze, BUILTIN_EXIT) \
V(ObjectGetOwnPropertyDescriptor, BUILTIN_EXIT) \
V(ObjectGetOwnPropertyDescriptors, BUILTIN_EXIT) \
V(ObjectGetOwnPropertyNames, BUILTIN_EXIT) \
V(ObjectGetOwnPropertySymbols, BUILTIN_EXIT) \
V(ObjectGetPrototypeOf, BUILTIN_EXIT) \
V(ObjectIs, BUILTIN_EXIT) \
V(ObjectIsExtensible, BUILTIN_EXIT) \
V(ObjectIsFrozen, BUILTIN_EXIT) \
V(ObjectIsSealed, BUILTIN_EXIT) \
V(ObjectKeys, BUILTIN_EXIT) \
V(ObjectLookupGetter, BUILTIN_EXIT) \
V(ObjectLookupSetter, BUILTIN_EXIT) \
V(ObjectPreventExtensions, BUILTIN_EXIT) \
V(ObjectProtoToString, BUILTIN_EXIT) \
V(ObjectSeal, BUILTIN_EXIT) \
V(ObjectValues, BUILTIN_EXIT) \
\
V(ProxyConstructor, BUILTIN_EXIT) \
V(ProxyConstructor_ConstructStub, BUILTIN_EXIT) \
\
V(ReflectDefineProperty, BUILTIN_EXIT) \
V(ReflectDeleteProperty, BUILTIN_EXIT) \
V(ReflectGet, BUILTIN_EXIT) \
V(ReflectGetOwnPropertyDescriptor, BUILTIN_EXIT) \
V(ReflectGetPrototypeOf, BUILTIN_EXIT) \
V(ReflectHas, BUILTIN_EXIT) \
V(ReflectIsExtensible, BUILTIN_EXIT) \
V(ReflectOwnKeys, BUILTIN_EXIT) \
V(ReflectPreventExtensions, BUILTIN_EXIT) \
V(ReflectSet, BUILTIN_EXIT) \
V(ReflectSetPrototypeOf, BUILTIN_EXIT) \
\
V(SharedArrayBufferPrototypeGetByteLength, BUILTIN_EXIT) \
\
V(StringFromCodePoint, BUILTIN_EXIT) \
\
V(StringPrototypeTrim, BUILTIN_EXIT) \
V(StringPrototypeTrimLeft, BUILTIN_EXIT) \
V(StringPrototypeTrimRight, BUILTIN_EXIT) \
\
V(SymbolConstructor, BUILTIN_EXIT) \
V(SymbolConstructor_ConstructStub, BUILTIN_EXIT) \
\
V(TypedArrayPrototypeBuffer, BUILTIN_EXIT) \
\
V(HandleApiCall, EXIT) \
V(HandleApiCallAsFunction, EXIT) \
V(HandleApiCallAsConstructor, EXIT) \
\
V(RestrictedFunctionPropertiesThrower, BUILTIN_EXIT) \
V(RestrictedStrictArgumentsPropertiesThrower, BUILTIN_EXIT)
// Define list of builtins implemented in assembly.
......
// 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