Revert of Array length reduction should throw in strict mode if it can't delete an element. (patchset #7 id:220001 of https://codereview.chromium.org/1587073003/ )

Reason for revert:
[Sheriff] Breaks layout tests. Please fix upstream.
https://build.chromium.org/p/client.v8.fyi/builders/V8-Blink%20Linux%2064/builds/4077

Original issue's description:
> Array length reduction should throw in strict mode if it can't delete an element.
>
> When accessor getter callback is called the v8::PropertyCallbackInfo::ShouldThrowOnError() is always false, since according to ES6 there's no difference between strict and non-strict property loads. For the setter case the v8::PropertyCallbackInfo::ShouldThrowOnError() returns true if the property is set in strict context.
>
> Interceptors follow same idea: for getter, enumerator and query callbacks the v8::PropertyCallbackInfo::ShouldThrowOnError() is always false, and for setter and deleter callback the v8::PropertyCallbackInfo::ShouldThrowOnError() returns true in strict context.
>
> This CL also cleans up the CallApiGetterStub and removes bogus asserts from [arm] Push(reg1, reg2, ..., regN) that prevented from pushing a set of registers containing duplicates.
>
> BUG=v8:4267
> LOG=Y
>
> Committed: https://crrev.com/1d3e837fcbbd9d9fd5e72dfe85dfd47c025f3c9f
> Cr-Commit-Position: refs/heads/master@{#33438}

TBR=verwaest@chromium.org,ishell@chromium.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:4267

Review URL: https://codereview.chromium.org/1611313003

Cr-Commit-Position: refs/heads/master@{#33444}
This commit is contained in:
machenbach 2016-01-21 10:54:05 -08:00 committed by Commit bot
parent 6e0573c6ff
commit 575e90c1d0
29 changed files with 309 additions and 648 deletions

View File

@ -3191,21 +3191,19 @@ class PropertyCallbackInfo {
V8_INLINE Local<Object> This() const;
V8_INLINE Local<Object> Holder() const;
V8_INLINE ReturnValue<T> GetReturnValue() const;
V8_INLINE bool ShouldThrowOnError() const;
// This shouldn't be public, but the arm compiler needs it.
static const int kArgsLength = 7;
static const int kArgsLength = 6;
protected:
friend class MacroAssembler;
friend class internal::PropertyCallbackArguments;
friend class internal::CustomArguments<PropertyCallbackInfo>;
static const int kShouldThrowOnErrorIndex = 0;
static const int kHolderIndex = 1;
static const int kIsolateIndex = 2;
static const int kReturnValueDefaultValueIndex = 3;
static const int kReturnValueIndex = 4;
static const int kDataIndex = 5;
static const int kThisIndex = 6;
static const int kHolderIndex = 0;
static const int kIsolateIndex = 1;
static const int kReturnValueDefaultValueIndex = 2;
static const int kReturnValueIndex = 3;
static const int kDataIndex = 4;
static const int kThisIndex = 5;
V8_INLINE PropertyCallbackInfo(internal::Object** args) : args_(args) {}
internal::Object** args_;
@ -8264,12 +8262,6 @@ ReturnValue<T> PropertyCallbackInfo<T>::GetReturnValue() const {
return ReturnValue<T>(&args_[kReturnValueIndex]);
}
template <typename T>
bool PropertyCallbackInfo<T>::ShouldThrowOnError() const {
typedef internal::Internals I;
return args_[kShouldThrowOnErrorIndex] != I::IntToSmi(0);
}
Local<Primitive> Undefined(Isolate* isolate) {
typedef internal::Object* S;

View File

@ -204,19 +204,6 @@ void Accessors::ArrayLengthSetter(
if (JSArray::ObservableSetLength(array, length).is_null()) {
isolate->OptionalRescheduleException(false);
}
if (info.ShouldThrowOnError()) {
uint32_t actual_new_len = 0;
CHECK(array->length()->ToArrayLength(&actual_new_len));
// Throw TypeError if there were non-deletable elements.
if (actual_new_len != length) {
Factory* factory = isolate->factory();
isolate->Throw(*factory->NewTypeError(
MessageTemplate::kStrictDeleteProperty,
factory->NewNumberFromUint(actual_new_len - 1), array));
isolate->OptionalRescheduleException(false);
}
}
}
@ -1417,7 +1404,6 @@ static void ModuleGetExport(v8::Local<v8::Name> property,
static void ModuleSetExport(v8::Local<v8::Name> property,
v8::Local<v8::Value> value,
const v8::PropertyCallbackInfo<void>& info) {
if (!info.ShouldThrowOnError()) return;
Handle<Name> name = v8::Utils::OpenHandle(*property);
Isolate* isolate = name->GetIsolate();
Handle<Object> exception =

View File

@ -70,14 +70,16 @@ v8::Local<v8::Value> FunctionCallbackArguments::Call(FunctionCallback f) {
}
#define WRITE_CALL_2_VOID(Function, ReturnValue, Arg1, Arg2) \
void PropertyCallbackArguments::Call(Function f, Arg1 arg1, Arg2 arg2) { \
Isolate* isolate = this->isolate(); \
VMState<EXTERNAL> state(isolate); \
ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f)); \
PropertyCallbackInfo<ReturnValue> info(begin()); \
f(arg1, arg2, info); \
}
#define WRITE_CALL_2_VOID(Function, ReturnValue, Arg1, Arg2) \
void PropertyCallbackArguments::Call(Function f, \
Arg1 arg1, \
Arg2 arg2) { \
Isolate* isolate = this->isolate(); \
VMState<EXTERNAL> state(isolate); \
ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f)); \
PropertyCallbackInfo<ReturnValue> info(begin()); \
f(arg1, arg2, info); \
}
FOR_EACH_CALLBACK_TABLE_MAPPING_0(WRITE_CALL_0)

View File

@ -152,19 +152,17 @@ class PropertyCallbackArguments
static const int kReturnValueDefaultValueIndex =
T::kReturnValueDefaultValueIndex;
static const int kIsolateIndex = T::kIsolateIndex;
static const int kShouldThrowOnErrorIndex = T::kShouldThrowOnErrorIndex;
PropertyCallbackArguments(Isolate* isolate, Object* data, Object* self,
JSObject* holder, Object::ShouldThrow should_throw)
PropertyCallbackArguments(Isolate* isolate,
Object* data,
Object* self,
JSObject* holder)
: Super(isolate) {
Object** values = this->begin();
values[T::kThisIndex] = self;
values[T::kHolderIndex] = holder;
values[T::kDataIndex] = data;
values[T::kIsolateIndex] = reinterpret_cast<Object*>(isolate);
values[T::kShouldThrowOnErrorIndex] =
Smi::FromInt(should_throw == Object::THROW_ON_ERROR ? 1 : 0);
// Here the hole is set as default value.
// It cannot escape into js as it's remove in Call below.
values[T::kReturnValueDefaultValueIndex] =

View File

@ -5377,39 +5377,34 @@ void CallApiAccessorStub::Generate(MacroAssembler* masm) {
void CallApiGetterStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- sp[0] : name
// -- sp[4 .. (4 + kArgsLength*4)] : v8::PropertyCallbackInfo::args_
// -- sp[0] : name
// -- sp[4 - kArgsLength*4] : PropertyCallbackArguments object
// -- ...
// -- r2 : api_function_address
// -- r2 : api_function_address
// -----------------------------------
Register api_function_address = ApiGetterDescriptor::function_address();
DCHECK(api_function_address.is(r2));
// v8::PropertyCallbackInfo::args_ array and name handle.
const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
// Load address of v8::PropertyAccessorInfo::args_ array and name handle.
__ mov(r0, sp); // r0 = Handle<Name>
__ add(r1, r0, Operand(1 * kPointerSize)); // r1 = v8::PCI::args_
__ mov(r0, sp); // r0 = Handle<Name>
__ add(r1, r0, Operand(1 * kPointerSize)); // r1 = PCA
const int kApiStackSpace = 1;
FrameScope frame_scope(masm, StackFrame::MANUAL);
__ EnterExitFrame(false, kApiStackSpace);
// Create v8::PropertyCallbackInfo object on the stack and initialize
// it's args_ field.
// Create PropertyAccessorInfo instance on the stack above the exit frame with
// r1 (internal::Object** args_) as the data.
__ str(r1, MemOperand(sp, 1 * kPointerSize));
__ add(r1, sp, Operand(1 * kPointerSize)); // r1 = v8::PropertyCallbackInfo&
__ add(r1, sp, Operand(1 * kPointerSize)); // r1 = AccessorInfo&
const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
ExternalReference thunk_ref =
ExternalReference::invoke_accessor_getter_callback(isolate());
// +3 is to skip prolog, return address and name handle.
MemOperand return_value_operand(
fp, (PropertyCallbackArguments::kReturnValueOffset + 3) * kPointerSize);
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
kStackUnwindSpace, NULL, return_value_operand, NULL);
kStackUnwindSpace, NULL,
MemOperand(fp, 6 * kPointerSize), NULL);
}

View File

@ -316,6 +316,7 @@ class MacroAssembler: public Assembler {
// Push two registers. Pushes leftmost register first (to highest address).
void Push(Register src1, Register src2, Condition cond = al) {
DCHECK(!src1.is(src2));
if (src1.code() > src2.code()) {
stm(db_w, sp, src1.bit() | src2.bit(), cond);
} else {
@ -326,6 +327,7 @@ class MacroAssembler: public Assembler {
// Push three registers. Pushes leftmost register first (to highest address).
void Push(Register src1, Register src2, Register src3, Condition cond = al) {
DCHECK(!AreAliased(src1, src2, src3));
if (src1.code() > src2.code()) {
if (src2.code() > src3.code()) {
stm(db_w, sp, src1.bit() | src2.bit() | src3.bit(), cond);
@ -345,6 +347,7 @@ class MacroAssembler: public Assembler {
Register src3,
Register src4,
Condition cond = al) {
DCHECK(!AreAliased(src1, src2, src3, src4));
if (src1.code() > src2.code()) {
if (src2.code() > src3.code()) {
if (src3.code() > src4.code()) {
@ -369,6 +372,7 @@ class MacroAssembler: public Assembler {
// Push five registers. Pushes leftmost register first (to highest address).
void Push(Register src1, Register src2, Register src3, Register src4,
Register src5, Condition cond = al) {
DCHECK(!AreAliased(src1, src2, src3, src4, src5));
if (src1.code() > src2.code()) {
if (src2.code() > src3.code()) {
if (src3.code() > src4.code()) {

View File

@ -5817,21 +5817,17 @@ void CallApiAccessorStub::Generate(MacroAssembler* masm) {
void CallApiGetterStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- sp[0] : name
// -- sp[8 .. (8 + kArgsLength*8)] : v8::PropertyCallbackInfo::args_
// -- sp[0] : name
// -- sp[8 - kArgsLength*8] : PropertyCallbackArguments object
// -- ...
// -- x2 : api_function_address
// -- x2 : api_function_address
// -----------------------------------
Register api_function_address = ApiGetterDescriptor::function_address();
DCHECK(api_function_address.is(x2));
// v8::PropertyCallbackInfo::args_ array and name handle.
const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
// Load address of v8::PropertyAccessorInfo::args_ array and name handle.
__ Mov(x0, masm->StackPointer()); // x0 = Handle<Name>
__ Add(x1, x0, 1 * kPointerSize); // x1 = v8::PCI::args_
__ Add(x1, x0, 1 * kPointerSize); // x1 = PCA
const int kApiStackSpace = 1;
@ -5842,22 +5838,20 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) {
FrameScope frame_scope(masm, StackFrame::MANUAL);
__ EnterExitFrame(false, x10, kApiStackSpace + kCallApiFunctionSpillSpace);
// Create v8::PropertyCallbackInfo object on the stack and initialize
// it's args_ field.
// Create PropertyAccessorInfo instance on the stack above the exit frame with
// x1 (internal::Object** args_) as the data.
__ Poke(x1, 1 * kPointerSize);
__ Add(x1, masm->StackPointer(), 1 * kPointerSize);
// x1 = v8::PropertyCallbackInfo&
__ Add(x1, masm->StackPointer(), 1 * kPointerSize); // x1 = AccessorInfo&
const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
ExternalReference thunk_ref =
ExternalReference::invoke_accessor_getter_callback(isolate());
const int spill_offset = 1 + kApiStackSpace;
// +3 is to skip prolog, return address and name handle.
MemOperand return_value_operand(
fp, (PropertyCallbackArguments::kReturnValueOffset + 3) * kPointerSize);
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
kStackUnwindSpace, NULL, spill_offset,
return_value_operand, NULL);
MemOperand(fp, 6 * kPointerSize), NULL);
}

View File

@ -5664,50 +5664,38 @@ void CallApiAccessorStub::Generate(MacroAssembler* masm) {
void CallApiGetterStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- esp[0] : return address
// -- esp[4] : name
// -- esp[8 .. (8 + kArgsLength*4)] : v8::PropertyCallbackInfo::args_
// -- esp[0] : return address
// -- esp[4] : name
// -- esp[8 - kArgsLength*4] : PropertyCallbackArguments object
// -- ...
// -- edx : api_function_address
// -- edx : api_function_address
// -----------------------------------
DCHECK(edx.is(ApiGetterDescriptor::function_address()));
// v8::PropertyCallbackInfo::args_ array and name handle.
const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
// Allocate v8::PropertyCallbackInfo object, arguments for callback and
// space for optional callback address parameter (in case CPU profiler is
// active) in non-GCed stack space.
const int kApiArgc = 3 + 1;
// array for v8::Arguments::values_, handler for name and pointer
// to the values (it considered as smi in GC).
const int kStackSpace = PropertyCallbackArguments::kArgsLength + 2;
// Allocate space for opional callback address parameter in case
// CPU profiler is active.
const int kApiArgc = 2 + 1;
Register api_function_address = edx;
Register scratch = ebx;
// Load address of v8::PropertyAccessorInfo::args_ array.
__ lea(scratch, Operand(esp, 2 * kPointerSize));
// load address of name
__ lea(scratch, Operand(esp, 1 * kPointerSize));
PrepareCallApiFunction(masm, kApiArgc);
// Create v8::PropertyCallbackInfo object on the stack and initialize
// it's args_ field.
Operand info_object = ApiParameterOperand(3);
__ mov(info_object, scratch);
__ sub(scratch, Immediate(kPointerSize));
__ mov(ApiParameterOperand(0), scratch); // name.
__ lea(scratch, info_object);
__ add(scratch, Immediate(kPointerSize));
__ mov(ApiParameterOperand(1), scratch); // arguments pointer.
// Reserve space for optional callback address parameter.
Operand thunk_last_arg = ApiParameterOperand(2);
ExternalReference thunk_ref =
ExternalReference::invoke_accessor_getter_callback(isolate());
// +3 is to skip prolog, return address and name handle.
Operand return_value_operand(
ebp, (PropertyCallbackArguments::kReturnValueOffset + 3) * kPointerSize);
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
thunk_last_arg, kStackUnwindSpace, nullptr,
return_value_operand, NULL);
ApiParameterOperand(2), kStackSpace, nullptr,
Operand(ebp, 7 * kPointerSize), NULL);
}

View File

@ -595,38 +595,37 @@ void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
void NamedLoadHandlerCompiler::GenerateLoadCallback(
Register reg, Handle<AccessorInfo> callback) {
DCHECK(!AreAliased(scratch2(), scratch3(), scratch4(), receiver()));
DCHECK(!AreAliased(scratch2(), scratch3(), scratch4(), reg));
// Build v8::PropertyCallbackInfo::args_ array on the stack and push property
// name below the exit frame to make GC aware of them.
STATIC_ASSERT(PropertyCallbackArguments::kShouldThrowOnErrorIndex == 0);
STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 1);
STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 2);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 3);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 4);
STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 5);
STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 6);
STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 7);
// Build AccessorInfo::args_ list on the stack and push property name below
// the exit frame to make GC aware of them and store pointers to them.
STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
DCHECK(!scratch2().is(reg));
DCHECK(!scratch3().is(reg));
DCHECK(!scratch4().is(reg));
__ push(receiver());
// Push data from AccessorInfo.
Handle<Object> data(callback->data(), isolate());
if (data->IsUndefined() || data->IsSmi()) {
__ Move(scratch2(), data);
__ Move(scratch3(), data);
} else {
Handle<WeakCell> cell =
isolate()->factory()->NewWeakCell(Handle<HeapObject>::cast(data));
// The callback is alive if this instruction is executed,
// so the weak cell is not cleared and points to data.
__ GetWeakValue(scratch2(), cell);
__ GetWeakValue(scratch3(), cell);
}
__ push(scratch2());
__ LoadRoot(scratch2(), Heap::kUndefinedValueRootIndex);
__ Push(scratch2(), scratch2());
__ mov(scratch2(), Operand(ExternalReference::isolate_address(isolate())));
__ Push(scratch2(), reg);
__ Push(Smi::FromInt(0)); // should_throw_on_error -> false
__ push(scratch3());
__ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex);
__ mov(scratch4(), scratch3());
__ Push(scratch3(), scratch4());
__ mov(scratch4(), Operand(ExternalReference::isolate_address(isolate())));
__ Push(scratch4(), reg);
__ mov(scratch2(), sp); // scratch2 = PropertyAccessorInfo::args_
__ push(name());
// Abi for CallApiGetter
@ -715,8 +714,7 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback,
LanguageMode language_mode) {
Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback) {
Register holder_reg = Frontend(name);
__ push(receiver()); // receiver
@ -733,7 +731,6 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
__ push(ip);
__ mov(ip, Operand(name));
__ Push(ip, value());
__ Push(Smi::FromInt(language_mode));
// Do tail-call to the runtime system.
__ TailCallRuntime(Runtime::kStoreCallbackProperty);

View File

@ -646,19 +646,18 @@ void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
void NamedLoadHandlerCompiler::GenerateLoadCallback(
Register reg, Handle<AccessorInfo> callback) {
DCHECK(!AreAliased(scratch2(), scratch3(), scratch4(), receiver()));
DCHECK(!AreAliased(scratch2(), scratch3(), scratch4(), reg));
// Build v8::PropertyCallbackInfo::args_ array on the stack and push property
// name below the exit frame to make GC aware of them.
STATIC_ASSERT(PropertyCallbackArguments::kShouldThrowOnErrorIndex == 0);
STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 1);
STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 2);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 3);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 4);
STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 5);
STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 6);
STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 7);
// Build AccessorInfo::args_ list on the stack and push property
// name below the exit frame to make GC aware of them and store pointers to
// them.
STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
__ Push(receiver());
@ -674,9 +673,18 @@ void NamedLoadHandlerCompiler::GenerateLoadCallback(
}
__ LoadRoot(scratch4(), Heap::kUndefinedValueRootIndex);
__ Mov(scratch2(), Operand(ExternalReference::isolate_address(isolate())));
__ Push(scratch3(), scratch4(), scratch4(), scratch2(), reg);
__ Push(Smi::FromInt(0)); // should_throw_on_error -> false
__ Push(name());
__ Push(scratch3(), scratch4(), scratch4(), scratch2(), reg, name());
Register args_addr = scratch2();
__ Add(args_addr, __ StackPointer(), kPointerSize);
// Stack at this point:
// sp[40] callback data
// sp[32] undefined
// sp[24] undefined
// sp[16] isolate
// args_addr -> sp[8] reg
// sp[0] name
// Abi for CallApiGetter.
Register getter_address_reg = x2;
@ -766,8 +774,7 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback,
LanguageMode language_mode) {
Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback) {
ASM_LOCATION("NamedStoreHandlerCompiler::CompileStoreCallback");
Register holder_reg = Frontend(name);
@ -787,7 +794,6 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
}
__ Mov(scratch2(), Operand(name));
__ Push(receiver(), holder_reg, scratch1(), scratch2(), value());
__ Push(Smi::FromInt(language_mode));
// Do tail-call to the runtime system.
__ TailCallRuntime(Runtime::kStoreCallbackProperty);

View File

@ -223,8 +223,7 @@ class NamedStoreHandlerCompiler : public PropertyHandlerCompiler {
Handle<Name> name);
Handle<Code> CompileStoreField(LookupIterator* it);
Handle<Code> CompileStoreCallback(Handle<JSObject> object, Handle<Name> name,
Handle<AccessorInfo> callback,
LanguageMode language_mode);
Handle<AccessorInfo> callback);
Handle<Code> CompileStoreCallback(Handle<JSObject> object, Handle<Name> name,
const CallOptimization& call_optimization,
int accessor_index);

View File

@ -594,29 +594,23 @@ void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
void NamedLoadHandlerCompiler::GenerateLoadCallback(
Register reg, Handle<AccessorInfo> callback) {
DCHECK(!AreAliased(scratch2(), scratch3(), receiver()));
DCHECK(!AreAliased(scratch2(), scratch3(), reg));
// Insert additional parameters into the stack frame above return address.
DCHECK(!scratch3().is(reg));
__ pop(scratch3()); // Get return address to place it below.
// Build v8::PropertyCallbackInfo::args_ array on the stack and push property
// name below the exit frame to make GC aware of them.
STATIC_ASSERT(PropertyCallbackArguments::kShouldThrowOnErrorIndex == 0);
STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 1);
STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 2);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 3);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 4);
STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 5);
STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 6);
STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 7);
STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
__ push(receiver()); // receiver
// Push data from AccessorInfo.
Handle<Object> data(callback->data(), isolate());
if (data->IsUndefined() || data->IsSmi()) {
__ push(Immediate(data));
} else {
DCHECK(!scratch2().is(reg));
Handle<WeakCell> cell =
isolate()->factory()->NewWeakCell(Handle<HeapObject>::cast(data));
// The callback is alive if this instruction is executed,
@ -629,9 +623,13 @@ void NamedLoadHandlerCompiler::GenerateLoadCallback(
__ push(Immediate(isolate()->factory()->undefined_value()));
__ push(Immediate(reinterpret_cast<int>(isolate())));
__ push(reg); // holder
__ push(Immediate(Smi::FromInt(0))); // should_throw_on_error -> false
// Save a pointer to where we pushed the arguments. This will be
// passed as the const PropertyAccessorInfo& to the C++ callback.
__ push(esp);
__ push(name()); // name
__ push(scratch3()); // Restore return address.
// Abi for CallApiGetter
@ -733,8 +731,7 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback,
LanguageMode language_mode) {
Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback) {
Register holder_reg = Frontend(name);
__ pop(scratch1()); // remove the return address
@ -750,7 +747,6 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
}
__ Push(name);
__ push(value());
__ push(Immediate(Smi::FromInt(language_mode)));
__ push(scratch1()); // restore return address
// Do tail-call to the runtime system.

View File

@ -21,7 +21,6 @@
#include "src/macro-assembler.h"
#include "src/prototype.h"
#include "src/runtime/runtime.h"
#include "src/runtime/runtime-utils.h"
namespace v8 {
namespace internal {
@ -1748,8 +1747,7 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup,
break;
}
NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder);
return compiler.CompileStoreCallback(receiver, lookup->name(), info,
language_mode());
return compiler.CompileStoreCallback(receiver, lookup->name(), info);
} else if (accessors->IsAccessorPair()) {
Handle<Object> setter(Handle<AccessorPair>::cast(accessors)->setter(),
isolate());
@ -2815,7 +2813,6 @@ RUNTIME_FUNCTION(Runtime_StoreCallbackProperty) {
Handle<HeapObject> callback_or_cell = args.at<HeapObject>(2);
Handle<Name> name = args.at<Name>(3);
Handle<Object> value = args.at<Object>(4);
CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 5);
HandleScope scope(isolate);
Handle<AccessorInfo> callback(
@ -2831,10 +2828,8 @@ RUNTIME_FUNCTION(Runtime_StoreCallbackProperty) {
DCHECK(fun != NULL);
LOG(isolate, ApiNamedPropertyAccess("store", *receiver, *name));
Object::ShouldThrow should_throw =
is_sloppy(language_mode) ? Object::DONT_THROW : Object::THROW_ON_ERROR;
PropertyCallbackArguments custom_args(isolate, callback->data(), *receiver,
*holder, should_throw);
*holder);
custom_args.Call(fun, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value));
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return *value;

View File

@ -585,50 +585,41 @@ void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
void NamedLoadHandlerCompiler::GenerateLoadCallback(
Register reg, Handle<AccessorInfo> callback) {
DCHECK(!AreAliased(scratch2(), scratch3(), scratch4(), receiver()));
DCHECK(!AreAliased(scratch2(), scratch3(), scratch4(), reg));
// Build v8::PropertyCallbackInfo::args_ array on the stack and push property
// name below the exit frame to make GC aware of them.
STATIC_ASSERT(PropertyCallbackArguments::kShouldThrowOnErrorIndex == 0);
STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 1);
STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 2);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 3);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 4);
STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 5);
STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 6);
STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 7);
// Here and below +1 is for name() pushed after the args_ array.
typedef PropertyCallbackArguments PCA;
__ Subu(sp, sp, (PCA::kArgsLength + 1) * kPointerSize);
__ sw(receiver(), MemOperand(sp, (PCA::kThisIndex + 1) * kPointerSize));
// Build AccessorInfo::args_ list on the stack and push property name below
// the exit frame to make GC aware of them and store pointers to them.
STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
DCHECK(!scratch2().is(reg));
DCHECK(!scratch3().is(reg));
DCHECK(!scratch4().is(reg));
__ push(receiver());
Handle<Object> data(callback->data(), isolate());
if (data->IsUndefined() || data->IsSmi()) {
__ li(scratch2(), data);
__ li(scratch3(), data);
} else {
Handle<WeakCell> cell =
isolate()->factory()->NewWeakCell(Handle<HeapObject>::cast(data));
// The callback is alive if this instruction is executed,
// so the weak cell is not cleared and points to data.
__ GetWeakValue(scratch2(), cell);
__ GetWeakValue(scratch3(), cell);
}
__ sw(scratch2(), MemOperand(sp, (PCA::kDataIndex + 1) * kPointerSize));
__ LoadRoot(scratch2(), Heap::kUndefinedValueRootIndex);
__ sw(scratch2(),
MemOperand(sp, (PCA::kReturnValueOffset + 1) * kPointerSize));
__ sw(scratch2(), MemOperand(sp, (PCA::kReturnValueDefaultValueIndex + 1) *
kPointerSize));
__ li(scratch2(), Operand(ExternalReference::isolate_address(isolate())));
__ sw(scratch2(), MemOperand(sp, (PCA::kIsolateIndex + 1) * kPointerSize));
__ sw(reg, MemOperand(sp, (PCA::kHolderIndex + 1) * kPointerSize));
// should_throw_on_error -> false
DCHECK(Smi::FromInt(0) == nullptr);
__ sw(zero_reg,
MemOperand(sp, (PCA::kShouldThrowOnErrorIndex + 1) * kPointerSize));
__ Subu(sp, sp, 6 * kPointerSize);
__ sw(scratch3(), MemOperand(sp, 5 * kPointerSize));
__ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex);
__ sw(scratch3(), MemOperand(sp, 4 * kPointerSize));
__ sw(scratch3(), MemOperand(sp, 3 * kPointerSize));
__ li(scratch4(), Operand(ExternalReference::isolate_address(isolate())));
__ sw(scratch4(), MemOperand(sp, 2 * kPointerSize));
__ sw(reg, MemOperand(sp, 1 * kPointerSize));
__ sw(name(), MemOperand(sp, 0 * kPointerSize));
__ Addu(scratch2(), sp, 1 * kPointerSize);
__ mov(a2, scratch2()); // Saved in case scratch2 == a1.
// Abi for CallApiGetter.
Register getter_address_reg = ApiGetterDescriptor::function_address();
@ -714,8 +705,7 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback,
LanguageMode language_mode) {
Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback) {
Register holder_reg = Frontend(name);
__ Push(receiver(), holder_reg); // Receiver.
@ -730,7 +720,6 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
__ push(at);
__ li(at, Operand(name));
__ Push(at, value());
__ Push(Smi::FromInt(language_mode));
// Do tail-call to the runtime system.
__ TailCallRuntime(Runtime::kStoreCallbackProperty);

View File

@ -585,50 +585,41 @@ void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
void NamedLoadHandlerCompiler::GenerateLoadCallback(
Register reg, Handle<AccessorInfo> callback) {
DCHECK(!AreAliased(scratch2(), scratch3(), scratch4(), receiver()));
DCHECK(!AreAliased(scratch2(), scratch3(), scratch4(), reg));
// Build v8::PropertyCallbackInfo::args_ array on the stack and push property
// name below the exit frame to make GC aware of them.
STATIC_ASSERT(PropertyCallbackArguments::kShouldThrowOnErrorIndex == 0);
STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 1);
STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 2);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 3);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 4);
STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 5);
STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 6);
STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 7);
// Here and below +1 is for name() pushed after the args_ array.
typedef PropertyCallbackArguments PCA;
__ Dsubu(sp, sp, (PCA::kArgsLength + 1) * kPointerSize);
__ sw(receiver(), MemOperand(sp, (PCA::kThisIndex + 1) * kPointerSize));
// Build AccessorInfo::args_ list on the stack and push property name below
// the exit frame to make GC aware of them and store pointers to them.
STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
DCHECK(!scratch2().is(reg));
DCHECK(!scratch3().is(reg));
DCHECK(!scratch4().is(reg));
__ push(receiver());
Handle<Object> data(callback->data(), isolate());
if (data->IsUndefined() || data->IsSmi()) {
__ li(scratch2(), data);
__ li(scratch3(), data);
} else {
Handle<WeakCell> cell =
isolate()->factory()->NewWeakCell(Handle<HeapObject>::cast(data));
// The callback is alive if this instruction is executed,
// so the weak cell is not cleared and points to data.
__ GetWeakValue(scratch2(), cell);
__ GetWeakValue(scratch3(), cell);
}
__ sd(scratch2(), MemOperand(sp, (PCA::kDataIndex + 1) * kPointerSize));
__ LoadRoot(scratch2(), Heap::kUndefinedValueRootIndex);
__ sd(scratch2(),
MemOperand(sp, (PCA::kReturnValueOffset + 1) * kPointerSize));
__ sd(scratch2(), MemOperand(sp, (PCA::kReturnValueDefaultValueIndex + 1) *
kPointerSize));
__ li(scratch2(), Operand(ExternalReference::isolate_address(isolate())));
__ sd(scratch2(), MemOperand(sp, (PCA::kIsolateIndex + 1) * kPointerSize));
__ sd(reg, MemOperand(sp, (PCA::kHolderIndex + 1) * kPointerSize));
// should_throw_on_error -> false
DCHECK(Smi::FromInt(0) == nullptr);
__ sd(zero_reg,
MemOperand(sp, (PCA::kShouldThrowOnErrorIndex + 1) * kPointerSize));
__ Dsubu(sp, sp, 6 * kPointerSize);
__ sd(scratch3(), MemOperand(sp, 5 * kPointerSize));
__ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex);
__ sd(scratch3(), MemOperand(sp, 4 * kPointerSize));
__ sd(scratch3(), MemOperand(sp, 3 * kPointerSize));
__ li(scratch4(), Operand(ExternalReference::isolate_address(isolate())));
__ sd(scratch4(), MemOperand(sp, 2 * kPointerSize));
__ sd(reg, MemOperand(sp, 1 * kPointerSize));
__ sd(name(), MemOperand(sp, 0 * kPointerSize));
__ Daddu(scratch2(), sp, 1 * kPointerSize);
__ mov(a2, scratch2()); // Saved in case scratch2 == a1.
// Abi for CallApiGetter.
Register getter_address_reg = ApiGetterDescriptor::function_address();
@ -714,8 +705,7 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback,
LanguageMode language_mode) {
Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback) {
Register holder_reg = Frontend(name);
__ Push(receiver(), holder_reg); // Receiver.
@ -730,7 +720,6 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
__ push(at);
__ li(at, Operand(name));
__ Push(at, value());
__ Push(Smi::FromInt(language_mode));
// Do tail-call to the runtime system.
__ TailCallRuntime(Runtime::kStoreCallbackProperty);

View File

@ -593,39 +593,37 @@ void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
void NamedLoadHandlerCompiler::GenerateLoadCallback(
Register reg, Handle<AccessorInfo> callback) {
DCHECK(!AreAliased(scratch2(), scratch3(), scratch4(), receiver()));
DCHECK(!AreAliased(scratch2(), scratch3(), scratch4(), reg));
// Build v8::PropertyCallbackInfo::args_ array on the stack and push property
// name below the exit frame to make GC aware of them.
STATIC_ASSERT(PropertyCallbackArguments::kShouldThrowOnErrorIndex == 0);
STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 1);
STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 2);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 3);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 4);
STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 5);
STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 6);
STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 7);
// Build AccessorInfo::args_ list on the stack and push property name below
// the exit frame to make GC aware of them and store pointers to them.
STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
DCHECK(!scratch2().is(reg));
DCHECK(!scratch3().is(reg));
DCHECK(!scratch4().is(reg));
__ push(receiver());
// Push data from AccessorInfo.
Handle<Object> data(callback->data(), isolate());
if (data->IsUndefined() || data->IsSmi()) {
__ Move(scratch2(), data);
__ Move(scratch3(), data);
} else {
Handle<WeakCell> cell =
isolate()->factory()->NewWeakCell(Handle<HeapObject>::cast(data));
// The callback is alive if this instruction is executed,
// so the weak cell is not cleared and points to data.
__ GetWeakValue(scratch2(), cell);
__ GetWeakValue(scratch3(), cell);
}
__ push(scratch2());
__ LoadRoot(scratch2(), Heap::kUndefinedValueRootIndex);
__ Push(scratch2(), scratch2());
__ mov(scratch2(), Operand(ExternalReference::isolate_address(isolate())));
// should_throw_on_error -> false
__ mov(scratch3(), Operand(Smi::FromInt(0)));
__ Push(scratch2(), reg, scratch3(), name());
__ push(scratch3());
__ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex);
__ mr(scratch4(), scratch3());
__ Push(scratch3(), scratch4());
__ mov(scratch4(), Operand(ExternalReference::isolate_address(isolate())));
__ Push(scratch4(), reg);
__ push(name());
// Abi for CallApiGetter
Register getter_address_reg = ApiGetterDescriptor::function_address();
@ -713,8 +711,7 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback,
LanguageMode language_mode) {
Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback) {
Register holder_reg = Frontend(name);
__ Push(receiver(), holder_reg); // receiver
@ -730,7 +727,6 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
__ push(ip);
__ mov(ip, Operand(name));
__ Push(ip, value());
__ Push(Smi::FromInt(language_mode));
// Do tail-call to the runtime system.
__ TailCallRuntime(Runtime::kStoreCallbackProperty);

View File

@ -593,28 +593,23 @@ void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
void NamedLoadHandlerCompiler::GenerateLoadCallback(
Register reg, Handle<AccessorInfo> callback) {
DCHECK(!AreAliased(kScratchRegister, scratch2(), scratch3(), receiver()));
DCHECK(!AreAliased(kScratchRegister, scratch2(), scratch3(), reg));
// Insert additional parameters into the stack frame above return address.
__ PopReturnAddressTo(scratch3());
// Build v8::PropertyCallbackInfo::args_ array on the stack and push property
// name below the exit frame to make GC aware of them.
STATIC_ASSERT(PropertyCallbackArguments::kShouldThrowOnErrorIndex == 0);
STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 1);
STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 2);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 3);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 4);
STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 5);
STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 6);
STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 7);
DCHECK(!scratch4().is(reg));
__ PopReturnAddressTo(scratch4());
STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
__ Push(receiver()); // receiver
Handle<Object> data(callback->data(), isolate());
if (data->IsUndefined() || data->IsSmi()) {
__ Push(data);
} else {
DCHECK(!scratch2().is(reg));
Handle<WeakCell> cell =
isolate()->factory()->NewWeakCell(Handle<HeapObject>::cast(data));
// The callback is alive if this instruction is executed,
@ -622,15 +617,17 @@ void NamedLoadHandlerCompiler::GenerateLoadCallback(
__ GetWeakValue(scratch2(), cell);
__ Push(scratch2());
}
DCHECK(!kScratchRegister.is(reg));
__ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
__ Push(kScratchRegister); // return value
__ Push(kScratchRegister); // return value default
__ PushAddress(ExternalReference::isolate_address(isolate()));
__ Push(reg); // holder
__ Push(Smi::FromInt(0)); // should_throw_on_error -> false
__ Push(name()); // name
__ PushReturnAddressFrom(scratch3());
// Save a pointer to where we pushed the arguments pointer. This will be
// passed as the const PropertyAccessorInfo& to the C++ callback.
__ PushReturnAddressFrom(scratch4());
// Abi for CallApiGetter
Register api_function_address = ApiGetterDescriptor::function_address();
@ -725,8 +722,7 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback,
LanguageMode language_mode) {
Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback) {
Register holder_reg = Frontend(name);
__ PopReturnAddressTo(scratch1());
@ -742,7 +738,6 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
}
__ Push(name);
__ Push(value());
__ Push(Smi::FromInt(language_mode));
__ PushReturnAddressFrom(scratch1());
// Do tail-call to the runtime system.

View File

@ -594,29 +594,23 @@ void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
void NamedLoadHandlerCompiler::GenerateLoadCallback(
Register reg, Handle<AccessorInfo> callback) {
DCHECK(!AreAliased(scratch2(), scratch3(), receiver()));
DCHECK(!AreAliased(scratch2(), scratch3(), reg));
// Insert additional parameters into the stack frame above return address.
DCHECK(!scratch3().is(reg));
__ pop(scratch3()); // Get return address to place it below.
// Build v8::PropertyCallbackInfo::args_ array on the stack and push property
// name below the exit frame to make GC aware of them.
STATIC_ASSERT(PropertyCallbackArguments::kShouldThrowOnErrorIndex == 0);
STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 1);
STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 2);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 3);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 4);
STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 5);
STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 6);
STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 7);
STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
__ push(receiver()); // receiver
// Push data from AccessorInfo.
Handle<Object> data(callback->data(), isolate());
if (data->IsUndefined() || data->IsSmi()) {
__ push(Immediate(data));
} else {
DCHECK(!scratch2().is(reg));
Handle<WeakCell> cell =
isolate()->factory()->NewWeakCell(Handle<HeapObject>::cast(data));
// The callback is alive if this instruction is executed,
@ -629,9 +623,13 @@ void NamedLoadHandlerCompiler::GenerateLoadCallback(
__ push(Immediate(isolate()->factory()->undefined_value()));
__ push(Immediate(reinterpret_cast<int>(isolate())));
__ push(reg); // holder
__ push(Immediate(Smi::FromInt(0))); // should_throw_on_error -> false
// Save a pointer to where we pushed the arguments. This will be
// passed as the const PropertyAccessorInfo& to the C++ callback.
__ push(esp);
__ push(name()); // name
__ push(scratch3()); // Restore return address.
// Abi for CallApiGetter
@ -733,8 +731,7 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback,
LanguageMode language_mode) {
Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback) {
Register holder_reg = Frontend(name);
__ pop(scratch1()); // remove the return address
@ -750,7 +747,6 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
}
__ Push(name);
__ push(value());
__ push(Immediate(Smi::FromInt(language_mode)));
__ push(scratch1()); // restore return address
// Do tail-call to the runtime system.

View File

@ -5548,40 +5548,34 @@ void CallApiAccessorStub::Generate(MacroAssembler* masm) {
void CallApiGetterStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- sp[0] : name
// -- sp[4 .. (4 + kArgsLength*4)] : v8::PropertyCallbackInfo::args_
// -- sp[0] : name
// -- sp[4 - kArgsLength*4] : PropertyCallbackArguments object
// -- ...
// -- a2 : api_function_address
// -- a2 : api_function_address
// -----------------------------------
Register api_function_address = ApiGetterDescriptor::function_address();
DCHECK(api_function_address.is(a2));
// v8::PropertyCallbackInfo::args_ array and name handle.
const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
// Load address of v8::PropertyAccessorInfo::args_ array and name handle.
__ mov(a0, sp); // a0 = Handle<Name>
__ Addu(a1, a0, Operand(1 * kPointerSize)); // a1 = v8::PCI::args_
__ mov(a0, sp); // a0 = Handle<Name>
__ Addu(a1, a0, Operand(1 * kPointerSize)); // a1 = PCA
const int kApiStackSpace = 1;
FrameScope frame_scope(masm, StackFrame::MANUAL);
__ EnterExitFrame(false, kApiStackSpace);
// Create v8::PropertyCallbackInfo object on the stack and initialize
// it's args_ field.
// Create PropertyAccessorInfo instance on the stack above the exit frame with
// a1 (internal::Object** args_) as the data.
__ sw(a1, MemOperand(sp, 1 * kPointerSize));
__ Addu(a1, sp, Operand(1 * kPointerSize)); // a1 = v8::PropertyCallbackInfo&
__ Addu(a1, sp, Operand(1 * kPointerSize)); // a1 = AccessorInfo&
const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
ExternalReference thunk_ref =
ExternalReference::invoke_accessor_getter_callback(isolate());
// +3 is to skip prolog, return address and name handle.
MemOperand return_value_operand(
fp, (PropertyCallbackArguments::kReturnValueOffset + 3) * kPointerSize);
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
kStackUnwindSpace, kInvalidStackOffset,
return_value_operand, NULL);
MemOperand(fp, 6 * kPointerSize), NULL);
}

View File

@ -5607,41 +5607,34 @@ void CallApiAccessorStub::Generate(MacroAssembler* masm) {
void CallApiGetterStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- sp[0] : name
// -- sp[8 .. (8 + kArgsLength*8)] : v8::PropertyCallbackInfo::args_
// -- sp[0] : name
// -- sp[4 - kArgsLength*4] : PropertyCallbackArguments object
// -- ...
// -- a2 : api_function_address
// -- a2 : api_function_address
// -----------------------------------
Register api_function_address = ApiGetterDescriptor::function_address();
DCHECK(api_function_address.is(a2));
// v8::PropertyCallbackInfo::args_ array and name handle.
const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
// Load address of v8::PropertyAccessorInfo::args_ array and name handle.
__ mov(a0, sp); // a0 = Handle<Name>
__ Daddu(a1, a0, Operand(1 * kPointerSize)); // a1 = v8::PCI::args_
__ mov(a0, sp); // a0 = Handle<Name>
__ Daddu(a1, a0, Operand(1 * kPointerSize)); // a1 = PCA
const int kApiStackSpace = 1;
FrameScope frame_scope(masm, StackFrame::MANUAL);
__ EnterExitFrame(false, kApiStackSpace);
// Create v8::PropertyCallbackInfo object on the stack and initialize
// it's args_ field.
// Create PropertyAccessorInfo instance on the stack above the exit frame with
// a1 (internal::Object** args_) as the data.
__ sd(a1, MemOperand(sp, 1 * kPointerSize));
__ Daddu(a1, sp, Operand(1 * kPointerSize));
// a1 = v8::PropertyCallbackInfo&
__ Daddu(a1, sp, Operand(1 * kPointerSize)); // a1 = AccessorInfo&
const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
ExternalReference thunk_ref =
ExternalReference::invoke_accessor_getter_callback(isolate());
// +3 is to skip prolog, return address and name handle.
MemOperand return_value_operand(
fp, (PropertyCallbackArguments::kReturnValueOffset + 3) * kPointerSize);
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
kStackUnwindSpace, kInvalidStackOffset,
return_value_operand, NULL);
MemOperand(fp, 6 * kPointerSize), NULL);
}

View File

@ -371,7 +371,6 @@ void JSObject::PrintElements(std::ostream& os) { // NOLINT
#undef PRINT_ELEMENTS
case DICTIONARY_ELEMENTS:
os << "\n - elements: ";
elements()->Print(os);
break;
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:

View File

@ -1159,8 +1159,7 @@ MaybeHandle<Object> Object::GetPropertyWithAccessor(
if (call_fun == nullptr) return isolate->factory()->undefined_value();
LOG(isolate, ApiNamedPropertyAccess("load", *holder, *name));
PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder,
Object::DONT_THROW);
PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder);
v8::Local<v8::Value> result = args.Call(call_fun, v8::Utils::ToLocal(name));
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
if (result.IsEmpty()) {
@ -1225,8 +1224,7 @@ Maybe<bool> Object::SetPropertyWithAccessor(LookupIterator* it,
// earlier?
LOG(isolate, ApiNamedPropertyAccess("store", *holder, *name));
PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder,
should_throw);
PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder);
args.Call(call_fun, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value));
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
return Just(true);
@ -3998,7 +3996,6 @@ Handle<Map> Map::Update(Handle<Map> map) {
Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it,
ShouldThrow should_throw,
Handle<Object> value) {
Isolate* isolate = it->isolate();
// Make sure that the top context does not change when doing callbacks or
@ -4012,7 +4009,7 @@ Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it,
Handle<JSObject> holder = it->GetHolder<JSObject>();
v8::Local<v8::Value> result;
PropertyCallbackArguments args(isolate, interceptor->data(),
*it->GetReceiver(), *holder, should_throw);
*it->GetReceiver(), *holder);
if (it->IsElement()) {
uint32_t index = it->index();
@ -4093,8 +4090,7 @@ Maybe<bool> Object::SetPropertyInternal(LookupIterator* it,
case LookupIterator::INTERCEPTOR:
if (it->HolderIsReceiverOrHiddenPrototype()) {
Maybe<bool> result =
JSObject::SetPropertyWithInterceptor(it, should_throw, value);
Maybe<bool> result = JSObject::SetPropertyWithInterceptor(it, value);
if (result.IsNothing() || result.FromJust()) return result;
} else {
Maybe<PropertyAttributes> maybe_attributes =
@ -5254,8 +5250,7 @@ Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes(
// they throw. Here we should do the same.
case LookupIterator::INTERCEPTOR:
if (handling == DONT_FORCE_FIELD) {
Maybe<bool> result =
JSObject::SetPropertyWithInterceptor(it, should_throw, value);
Maybe<bool> result = JSObject::SetPropertyWithInterceptor(it, value);
if (result.IsNothing() || result.FromJust()) return result;
}
break;
@ -5378,8 +5373,7 @@ Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor(
return Just(ABSENT);
}
PropertyCallbackArguments args(isolate, interceptor->data(),
*it->GetReceiver(), *holder,
Object::DONT_THROW);
*it->GetReceiver(), *holder);
if (!interceptor->query()->IsUndefined()) {
v8::Local<v8::Integer> result;
if (it->IsElement()) {
@ -6135,8 +6129,7 @@ Handle<Object> JSObject::SetHiddenPropertiesHashTable(Handle<JSObject> object,
}
Maybe<bool> JSObject::DeletePropertyWithInterceptor(LookupIterator* it,
ShouldThrow should_throw) {
Maybe<bool> JSObject::DeletePropertyWithInterceptor(LookupIterator* it) {
Isolate* isolate = it->isolate();
// Make sure that the top context does not change when doing callbacks or
// interceptor calls.
@ -6149,7 +6142,7 @@ Maybe<bool> JSObject::DeletePropertyWithInterceptor(LookupIterator* it,
Handle<JSObject> holder = it->GetHolder<JSObject>();
PropertyCallbackArguments args(isolate, interceptor->data(),
*it->GetReceiver(), *holder, should_throw);
*it->GetReceiver(), *holder);
v8::Local<v8::Boolean> result;
if (it->IsElement()) {
uint32_t index = it->index();
@ -6247,10 +6240,7 @@ Maybe<bool> JSReceiver::DeleteProperty(LookupIterator* it,
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
return Just(false);
case LookupIterator::INTERCEPTOR: {
ShouldThrow should_throw =
is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR;
Maybe<bool> result =
JSObject::DeletePropertyWithInterceptor(it, should_throw);
Maybe<bool> result = JSObject::DeletePropertyWithInterceptor(it);
// An exception was thrown in the interceptor. Propagate.
if (isolate->has_pending_exception()) return Nothing<bool>();
// Delete with interceptor succeeded. Return result.
@ -8575,7 +8565,7 @@ static Maybe<bool> GetKeysFromInterceptor(Isolate* isolate,
return Just(true);
}
PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
*object, Object::DONT_THROW);
*object);
v8::Local<v8::Object> result;
if (!interceptor->enumerator()->IsUndefined()) {
Callback enum_fun = v8::ToCData<Callback>(interceptor->enumerator());
@ -16225,8 +16215,7 @@ MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it,
Handle<JSObject> holder = it->GetHolder<JSObject>();
v8::Local<v8::Value> result;
PropertyCallbackArguments args(isolate, interceptor->data(),
*it->GetReceiver(), *holder,
Object::DONT_THROW);
*it->GetReceiver(), *holder);
if (it->IsElement()) {
uint32_t index = it->index();

View File

@ -2066,7 +2066,7 @@ class JSObject: public JSReceiver {
uint32_t limit);
MUST_USE_RESULT static Maybe<bool> SetPropertyWithInterceptor(
LookupIterator* it, ShouldThrow should_throw, Handle<Object> value);
LookupIterator* it, Handle<Object> value);
// SetLocalPropertyIgnoreAttributes converts callbacks to fields. We need to
// grant an exemption to AccessorInfo callbacks in some cases.
@ -2517,7 +2517,7 @@ class JSObject: public JSReceiver {
PropertyAttributes attributes);
MUST_USE_RESULT static Maybe<bool> DeletePropertyWithInterceptor(
LookupIterator* it, ShouldThrow should_throw);
LookupIterator* it);
bool ReferencesObjectFromElements(FixedArray* elements,
ElementsKind kind,

View File

@ -5585,10 +5585,10 @@ void CallApiAccessorStub::Generate(MacroAssembler* masm) {
void CallApiGetterStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- sp[0] : name
// -- sp[4 .. (4 + kArgsLength*4)] : v8::PropertyCallbackInfo::args_
// -- sp[0] : name
// -- sp[4 - kArgsLength*4] : PropertyCallbackArguments object
// -- ...
// -- r5 : api_function_address
// -- r5 : api_function_address
// -----------------------------------
Register api_function_address = ApiGetterDescriptor::function_address();
@ -5597,12 +5597,8 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) {
int apiStackSpace = 0;
DCHECK(api_function_address.is(r5));
// v8::PropertyCallbackInfo::args_ array and name handle.
const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
// Load address of v8::PropertyAccessorInfo::args_ array and name handle.
__ mr(r3, sp); // r0 = Handle<Name>
__ addi(r4, r3, Operand(1 * kPointerSize)); // r4 = v8::PCI::args_
__ addi(r4, r3, Operand(1 * kPointerSize)); // r4 = PCA
// If ABI passes Handles (pointer-sized struct) in a register:
//
@ -5634,20 +5630,19 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) {
__ addi(r3, sp, Operand(arg0Slot * kPointerSize));
}
// Create v8::PropertyCallbackInfo object on the stack and initialize
// it's args_ field.
// Create PropertyAccessorInfo instance on the stack above the exit frame with
// r4 (internal::Object** args_) as the data.
__ StoreP(r4, MemOperand(sp, accessorInfoSlot * kPointerSize));
// r4 = AccessorInfo&
__ addi(r4, sp, Operand(accessorInfoSlot * kPointerSize));
// r4 = v8::PropertyCallbackInfo&
const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
ExternalReference thunk_ref =
ExternalReference::invoke_accessor_getter_callback(isolate());
// +3 is to skip prolog, return address and name handle.
MemOperand return_value_operand(
fp, (PropertyCallbackArguments::kReturnValueOffset + 3) * kPointerSize);
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
kStackUnwindSpace, NULL, return_value_operand, NULL);
kStackUnwindSpace, NULL,
MemOperand(fp, 6 * kPointerSize), NULL);
}

View File

@ -1030,7 +1030,7 @@ namespace internal {
F(LoadIC_MissFromStubFailure, 4, 1) \
F(LoadPropertyWithInterceptor, 3, 1) \
F(LoadPropertyWithInterceptorOnly, 3, 1) \
F(StoreCallbackProperty, 6, 1) \
F(StoreCallbackProperty, 5, 1) \
F(StoreIC_Miss, 5, 1) \
F(StoreIC_MissFromStubFailure, 5, 1) \
F(StoreIC_Slow, 5, 1) \

View File

@ -5368,11 +5368,11 @@ void CallApiAccessorStub::Generate(MacroAssembler* masm) {
void CallApiGetterStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- rsp[0] : return address
// -- rsp[8] : name
// -- rsp[16 .. (16 + kArgsLength*8)] : v8::PropertyCallbackInfo::args_
// -- rsp[0] : return address
// -- rsp[8] : name
// -- rsp[16 - kArgsLength*8] : PropertyCallbackArguments object
// -- ...
// -- r8 : api_function_address
// -- r8 : api_function_address
// -----------------------------------
#if defined(__MINGW64__) || defined(_WIN64)
@ -5388,25 +5388,23 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) {
DCHECK(api_function_address.is(r8));
Register scratch = rax;
// v8::PropertyCallbackInfo::args_ array and name handle.
const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
// v8::Arguments::values_ and handler for name.
const int kStackSpace = PropertyCallbackArguments::kArgsLength + 1;
// Allocate v8::PropertyCallbackInfo in non-GCed stack space.
// Allocate v8::AccessorInfo in non-GCed stack space.
const int kArgStackSpace = 1;
// Load address of v8::PropertyAccessorInfo::args_ array.
__ leap(scratch, Operand(rsp, 2 * kPointerSize));
__ leap(name_arg, Operand(rsp, kPCOnStackSize));
PrepareCallApiFunction(masm, kArgStackSpace);
// Create v8::PropertyCallbackInfo object on the stack and initialize
// it's args_ field.
Operand info_object = StackSpaceOperand(0);
__ movp(info_object, scratch);
__ leap(scratch, Operand(name_arg, 1 * kPointerSize));
// v8::PropertyAccessorInfo::args_.
__ movp(StackSpaceOperand(0), scratch);
__ leap(name_arg, Operand(scratch, -kPointerSize));
// The context register (rsi) has been saved in PrepareCallApiFunction and
// could be used to pass arguments.
__ leap(accessor_info_arg, info_object);
__ leap(accessor_info_arg, StackSpaceOperand(0));
ExternalReference thunk_ref =
ExternalReference::invoke_accessor_getter_callback(isolate());
@ -5416,12 +5414,13 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) {
DCHECK(!api_function_address.is(accessor_info_arg) &&
!api_function_address.is(name_arg));
// +3 is to skip prolog, return address and name handle.
Operand return_value_operand(
rbp, (PropertyCallbackArguments::kReturnValueOffset + 3) * kPointerSize);
// The name handler is counted as an argument.
StackArgumentsAccessor args(rbp, PropertyCallbackArguments::kArgsLength);
Operand return_value_operand = args.GetArgumentOperand(
PropertyCallbackArguments::kArgsLength - 1 -
PropertyCallbackArguments::kReturnValueOffset);
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, getter_arg,
kStackUnwindSpace, nullptr, return_value_operand,
NULL);
kStackSpace, nullptr, return_value_operand, NULL);
}

View File

@ -5344,50 +5344,38 @@ void CallApiAccessorStub::Generate(MacroAssembler* masm) {
void CallApiGetterStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- esp[0] : return address
// -- esp[4] : name
// -- esp[8 .. (8 + kArgsLength*4)] : v8::PropertyCallbackInfo::args_
// -- esp[0] : return address
// -- esp[4] : name
// -- esp[8 - kArgsLength*4] : PropertyCallbackArguments object
// -- ...
// -- edx : api_function_address
// -- edx : api_function_address
// -----------------------------------
DCHECK(edx.is(ApiGetterDescriptor::function_address()));
// v8::PropertyCallbackInfo::args_ array and name handle.
const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
// Allocate v8::PropertyCallbackInfo object, arguments for callback and
// space for optional callback address parameter (in case CPU profiler is
// active) in non-GCed stack space.
const int kApiArgc = 3 + 1;
// array for v8::Arguments::values_, handler for name and pointer
// to the values (it considered as smi in GC).
const int kStackSpace = PropertyCallbackArguments::kArgsLength + 2;
// Allocate space for opional callback address parameter in case
// CPU profiler is active.
const int kApiArgc = 2 + 1;
Register api_function_address = edx;
Register scratch = ebx;
// Load address of v8::PropertyAccessorInfo::args_ array.
__ lea(scratch, Operand(esp, 2 * kPointerSize));
// load address of name
__ lea(scratch, Operand(esp, 1 * kPointerSize));
PrepareCallApiFunction(masm, kApiArgc);
// Create v8::PropertyCallbackInfo object on the stack and initialize
// it's args_ field.
Operand info_object = ApiParameterOperand(3);
__ mov(info_object, scratch);
__ sub(scratch, Immediate(kPointerSize));
__ mov(ApiParameterOperand(0), scratch); // name.
__ lea(scratch, info_object);
__ add(scratch, Immediate(kPointerSize));
__ mov(ApiParameterOperand(1), scratch); // arguments pointer.
// Reserve space for optional callback address parameter.
Operand thunk_last_arg = ApiParameterOperand(2);
ExternalReference thunk_ref =
ExternalReference::invoke_accessor_getter_callback(isolate());
// +3 is to skip prolog, return address and name handle.
Operand return_value_operand(
ebp, (PropertyCallbackArguments::kReturnValueOffset + 3) * kPointerSize);
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
thunk_last_arg, kStackUnwindSpace, nullptr,
return_value_operand, NULL);
ApiParameterOperand(2), kStackSpace, nullptr,
Operand(ebp, 7 * kPointerSize), NULL);
}

View File

@ -12792,203 +12792,6 @@ THREADED_TEST(Overriding) {
}
static void ShouldThrowOnErrorGetter(
Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
v8::Isolate* isolate = info.GetIsolate();
Local<Boolean> should_throw_on_error =
Boolean::New(isolate, info.ShouldThrowOnError());
info.GetReturnValue().Set(should_throw_on_error);
}
template <typename T>
static void ShouldThrowOnErrorSetter(Local<Name> name, Local<v8::Value> value,
const v8::PropertyCallbackInfo<T>& info) {
ApiTestFuzzer::Fuzz();
v8::Isolate* isolate = info.GetIsolate();
auto context = isolate->GetCurrentContext();
Local<Boolean> should_throw_on_error_value =
Boolean::New(isolate, info.ShouldThrowOnError());
CHECK(context->Global()
->Set(isolate->GetCurrentContext(), v8_str("should_throw_setter"),
should_throw_on_error_value)
.FromJust());
}
THREADED_TEST(AccessorShouldThrowOnError) {
i::FLAG_strong_mode = true;
LocalContext context;
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
Local<Object> global = context->Global();
Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
Local<ObjectTemplate> instance_templ = templ->InstanceTemplate();
instance_templ->SetAccessor(v8_str("f"), ShouldThrowOnErrorGetter,
ShouldThrowOnErrorSetter<void>);
Local<v8::Object> instance = templ->GetFunction(context.local())
.ToLocalChecked()
->NewInstance(context.local())
.ToLocalChecked();
CHECK(global->Set(context.local(), v8_str("o"), instance).FromJust());
// SLOPPY mode
Local<Value> value = v8_compile("o.f")->Run(context.local()).ToLocalChecked();
CHECK(value->IsFalse());
v8_compile("o.f = 153")->Run(context.local()).ToLocalChecked();
value = global->Get(context.local(), v8_str("should_throw_setter"))
.ToLocalChecked();
CHECK(value->IsFalse());
// STRICT mode
value = v8_compile("'use strict';o.f")->Run(context.local()).ToLocalChecked();
CHECK(value->IsFalse());
v8_compile("'use strict'; o.f = 153")->Run(context.local()).ToLocalChecked();
value = global->Get(context.local(), v8_str("should_throw_setter"))
.ToLocalChecked();
CHECK(value->IsTrue());
// STRONG mode
value = v8_compile("'use strong';o.f")->Run(context.local()).ToLocalChecked();
CHECK(value->IsFalse());
v8_compile("'use strong'; o.f = 153")->Run(context.local()).ToLocalChecked();
value = global->Get(context.local(), v8_str("should_throw_setter"))
.ToLocalChecked();
CHECK(value->IsTrue());
}
static void ShouldThrowOnErrorQuery(
Local<Name> name, const v8::PropertyCallbackInfo<v8::Integer>& info) {
ApiTestFuzzer::Fuzz();
v8::Isolate* isolate = info.GetIsolate();
info.GetReturnValue().Set(v8::None);
auto context = isolate->GetCurrentContext();
Local<Boolean> should_throw_on_error_value =
Boolean::New(isolate, info.ShouldThrowOnError());
CHECK(context->Global()
->Set(isolate->GetCurrentContext(), v8_str("should_throw_query"),
should_throw_on_error_value)
.FromJust());
}
static void ShouldThrowOnErrorDeleter(
Local<Name> name, const v8::PropertyCallbackInfo<v8::Boolean>& info) {
ApiTestFuzzer::Fuzz();
v8::Isolate* isolate = info.GetIsolate();
info.GetReturnValue().Set(v8::True(isolate));
auto context = isolate->GetCurrentContext();
Local<Boolean> should_throw_on_error_value =
Boolean::New(isolate, info.ShouldThrowOnError());
CHECK(context->Global()
->Set(isolate->GetCurrentContext(), v8_str("should_throw_deleter"),
should_throw_on_error_value)
.FromJust());
}
static void ShouldThrowOnErrorPropertyEnumerator(
const v8::PropertyCallbackInfo<v8::Array>& info) {
ApiTestFuzzer::Fuzz();
v8::Isolate* isolate = info.GetIsolate();
Local<v8::Array> names = v8::Array::New(isolate, 1);
CHECK(names->Set(isolate->GetCurrentContext(), names, v8_num(1)).FromJust());
info.GetReturnValue().Set(names);
auto context = isolate->GetCurrentContext();
Local<Boolean> should_throw_on_error_value =
Boolean::New(isolate, info.ShouldThrowOnError());
CHECK(context->Global()
->Set(isolate->GetCurrentContext(),
v8_str("should_throw_enumerator"),
should_throw_on_error_value)
.FromJust());
}
THREADED_TEST(InterceptorShouldThrowOnError) {
i::FLAG_strong_mode = true;
LocalContext context;
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
Local<Object> global = context->Global();
auto interceptor_templ = v8::ObjectTemplate::New(isolate);
v8::NamedPropertyHandlerConfiguration handler(
ShouldThrowOnErrorGetter, ShouldThrowOnErrorSetter<Value>,
ShouldThrowOnErrorQuery, ShouldThrowOnErrorDeleter,
ShouldThrowOnErrorPropertyEnumerator);
interceptor_templ->SetHandler(handler);
Local<v8::Object> instance =
interceptor_templ->NewInstance(context.local()).ToLocalChecked();
CHECK(global->Set(context.local(), v8_str("o"), instance).FromJust());
// SLOPPY mode
Local<Value> value = v8_compile("o.f")->Run(context.local()).ToLocalChecked();
CHECK(value->IsFalse());
v8_compile("o.f = 153")->Run(context.local()).ToLocalChecked();
value = global->Get(context.local(), v8_str("should_throw_setter"))
.ToLocalChecked();
CHECK(value->IsFalse());
v8_compile("delete o.f")->Run(context.local()).ToLocalChecked();
value = global->Get(context.local(), v8_str("should_throw_deleter"))
.ToLocalChecked();
CHECK(value->IsFalse());
v8_compile("Object.getOwnPropertyNames(o)")
->Run(context.local())
.ToLocalChecked();
value = global->Get(context.local(), v8_str("should_throw_enumerator"))
.ToLocalChecked();
CHECK(value->IsFalse());
// STRICT mode
value = v8_compile("'use strict';o.f")->Run(context.local()).ToLocalChecked();
CHECK(value->IsFalse());
v8_compile("'use strict'; o.f = 153")->Run(context.local()).ToLocalChecked();
value = global->Get(context.local(), v8_str("should_throw_setter"))
.ToLocalChecked();
CHECK(value->IsTrue());
v8_compile("'use strict'; delete o.f")->Run(context.local()).ToLocalChecked();
value = global->Get(context.local(), v8_str("should_throw_deleter"))
.ToLocalChecked();
CHECK(value->IsTrue());
v8_compile("'use strict'; Object.getOwnPropertyNames(o)")
->Run(context.local())
.ToLocalChecked();
value = global->Get(context.local(), v8_str("should_throw_enumerator"))
.ToLocalChecked();
CHECK(value->IsFalse());
// STRONG mode
value = v8_compile("'use strong';o.f")->Run(context.local()).ToLocalChecked();
CHECK(value->IsFalse());
v8_compile("'use strong'; o.f = 153")->Run(context.local()).ToLocalChecked();
value = global->Get(context.local(), v8_str("should_throw_setter"))
.ToLocalChecked();
CHECK(value->IsTrue());
v8_compile("'use strong'; Object.getOwnPropertyNames(o)")
->Run(context.local())
.ToLocalChecked();
value = global->Get(context.local(), v8_str("should_throw_enumerator"))
.ToLocalChecked();
CHECK(value->IsFalse());
}
static void IsConstructHandler(
const v8::FunctionCallbackInfo<v8::Value>& args) {
ApiTestFuzzer::Fuzz();

View File

@ -1,16 +0,0 @@
// Copyright 2016 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.
// Flags: --allow-natives-syntax
"use strict";
var a = [];
Object.defineProperty(a, "0", {configurable: false, value: 10});
assertEquals(1, a.length);
var setter = ()=>{ a.length = 0; };
assertThrows(setter);
assertThrows(setter);
%OptimizeFunctionOnNextCall(setter);
assertThrows(setter);