Add isolate accessor to AccessorInfo and Arguments.

This passes the isolate through to API callback functions so that it is
available through AccessorInfo and Arguments. This allows bindings to
avoid unnecessary TLS lookups to retrieve the current isolate.

R=danno@chromium.org
TEST=cctest/test-api,cctest/test-accessors

Review URL: https://chromiumcodereview.appspot.com/10069050

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11306 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 436098b4
// Copyright 2011 the V8 project authors. All rights reserved.
// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
......@@ -107,6 +107,7 @@ class Data;
class AccessorInfo;
class StackTrace;
class StackFrame;
class Isolate;
namespace internal {
......@@ -1967,10 +1968,12 @@ class Arguments {
inline Local<Object> Holder() const;
inline bool IsConstructCall() const;
inline Local<Value> Data() const;
inline Isolate* GetIsolate() const;
private:
static const int kDataIndex = 0;
static const int kCalleeIndex = -1;
static const int kHolderIndex = -2;
static const int kIsolateIndex = 0;
static const int kDataIndex = -1;
static const int kCalleeIndex = -2;
static const int kHolderIndex = -3;
friend class ImplementationUtilities;
inline Arguments(internal::Object** implicit_args,
......@@ -1992,6 +1995,7 @@ class V8EXPORT AccessorInfo {
public:
inline AccessorInfo(internal::Object** args)
: args_(args) { }
inline Isolate* GetIsolate() const;
inline Local<Value> Data() const;
inline Local<Object> This() const;
inline Local<Object> Holder() const;
......@@ -4055,6 +4059,11 @@ Local<Value> Arguments::Data() const {
}
Isolate* Arguments::GetIsolate() const {
return *reinterpret_cast<Isolate**>(&implicit_args_[kIsolateIndex]);
}
bool Arguments::IsConstructCall() const {
return is_construct_call_;
}
......@@ -4290,6 +4299,11 @@ External* External::Cast(v8::Value* value) {
}
Isolate* AccessorInfo::GetIsolate() const {
return *reinterpret_cast<Isolate**>(&args_[-3]);
}
Local<Value> AccessorInfo::Data() const {
return Local<Value>(reinterpret_cast<Value*>(&args_[-2]));
}
......
// Copyright 2009 the V8 project authors. All rights reserved.
// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
......@@ -40,14 +40,17 @@ class ImplementationUtilities {
}
// Packs additional parameters for the NewArguments function. |implicit_args|
// is a pointer to the last element of 3-elements array controlled by GC.
// is a pointer to the last element of 4-elements array controlled by GC.
static void PrepareArgumentsData(internal::Object** implicit_args,
internal::Isolate* isolate,
internal::Object* data,
internal::JSFunction* callee,
internal::Object* holder) {
implicit_args[v8::Arguments::kDataIndex] = data;
implicit_args[v8::Arguments::kCalleeIndex] = callee;
implicit_args[v8::Arguments::kHolderIndex] = holder;
implicit_args[v8::Arguments::kIsolateIndex] =
reinterpret_cast<internal::Object*>(isolate);
}
static v8::Arguments NewArguments(internal::Object** implicit_args,
......@@ -55,6 +58,8 @@ class ImplementationUtilities {
bool is_construct_call) {
ASSERT(implicit_args[v8::Arguments::kCalleeIndex]->IsJSFunction());
ASSERT(implicit_args[v8::Arguments::kHolderIndex]->IsHeapObject());
// The implicit isolate argument is not tagged and looks like a SMI.
ASSERT(implicit_args[v8::Arguments::kIsolateIndex]->IsSmi());
return v8::Arguments(implicit_args, argv, argc, is_construct_call);
}
......
// Copyright 2006-2008 the V8 project authors. All rights reserved.
// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
......@@ -91,9 +91,11 @@ class CustomArguments : public Relocatable {
Object* data,
Object* self,
JSObject* holder) : Relocatable(isolate) {
values_[2] = self;
values_[1] = holder;
values_[0] = data;
ASSERT(reinterpret_cast<Object*>(isolate)->IsSmi());
values_[3] = self;
values_[2] = holder;
values_[1] = data;
values_[0] = reinterpret_cast<Object*>(isolate);
}
inline explicit CustomArguments(Isolate* isolate) : Relocatable(isolate) {
......@@ -107,7 +109,7 @@ class CustomArguments : public Relocatable {
void IterateInstance(ObjectVisitor* v);
Object** end() { return values_ + ARRAY_SIZE(values_) - 1; }
private:
Object* values_[3];
Object* values_[4];
};
......
......@@ -582,6 +582,8 @@ static void PushInterceptorArguments(MacroAssembler* masm,
__ push(holder);
__ ldr(scratch, FieldMemOperand(scratch, InterceptorInfo::kDataOffset));
__ push(scratch);
__ mov(scratch, Operand(ExternalReference::isolate_address()));
__ push(scratch);
}
......@@ -596,7 +598,7 @@ static void CompileCallLoadPropertyWithInterceptor(
ExternalReference ref =
ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly),
masm->isolate());
__ mov(r0, Operand(5));
__ mov(r0, Operand(6));
__ mov(r1, Operand(ref));
CEntryStub stub(1);
......@@ -604,9 +606,9 @@ static void CompileCallLoadPropertyWithInterceptor(
}
static const int kFastApiCallArguments = 3;
static const int kFastApiCallArguments = 4;
// Reserves space for the extra arguments to FastHandleApiCall in the
// Reserves space for the extra arguments to API function in the
// caller's frame.
//
// These arguments are set by CheckPrototypes and GenerateFastApiDirectCall.
......@@ -632,7 +634,8 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
// -- sp[0] : holder (set by CheckPrototypes)
// -- sp[4] : callee JS function
// -- sp[8] : call data
// -- sp[12] : last JS argument
// -- sp[12] : isolate
// -- sp[16] : last JS argument
// -- ...
// -- sp[(argc + 3) * 4] : first JS argument
// -- sp[(argc + 4) * 4] : receiver
......@@ -642,7 +645,7 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
__ LoadHeapObject(r5, function);
__ ldr(cp, FieldMemOperand(r5, JSFunction::kContextOffset));
// Pass the additional arguments FastHandleApiCall expects.
// Pass the additional arguments.
Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
Handle<Object> call_data(api_call_info->data());
if (masm->isolate()->heap()->InNewSpace(*call_data)) {
......@@ -651,13 +654,15 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
} else {
__ Move(r6, call_data);
}
// Store JS function and call data.
__ stm(ib, sp, r5.bit() | r6.bit());
__ mov(r7, Operand(ExternalReference::isolate_address()));
// Store JS function, call data and isolate.
__ stm(ib, sp, r5.bit() | r6.bit() | r7.bit());
// r2 points to call data as expected by Arguments
// (refer to layout above).
__ add(r2, sp, Operand(2 * kPointerSize));
// Prepare arguments.
__ add(r2, sp, Operand(3 * kPointerSize));
// Allocate the v8::Arguments structure in the arguments' space since
// it's not controlled by GC.
const int kApiStackSpace = 4;
FrameScope frame_scope(masm, StackFrame::MANUAL);
......@@ -666,9 +671,9 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
// r0 = v8::Arguments&
// Arguments is after the return address.
__ add(r0, sp, Operand(1 * kPointerSize));
// v8::Arguments::implicit_args = data
// v8::Arguments::implicit_args_
__ str(r2, MemOperand(r0, 0 * kPointerSize));
// v8::Arguments::values = last argument
// v8::Arguments::values_
__ add(ip, r2, Operand(argc * kPointerSize));
__ str(ip, MemOperand(r0, 1 * kPointerSize));
// v8::Arguments::length_ = argc
......@@ -845,7 +850,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
__ CallExternalReference(
ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall),
masm->isolate()),
5);
6);
// Restore the name_ register.
__ pop(name_);
// Leave the internal frame.
......@@ -1204,7 +1209,9 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
} else {
__ Move(scratch3, Handle<Object>(callback->data()));
}
__ Push(reg, scratch3, name_reg);
__ Push(reg, scratch3);
__ mov(scratch3, Operand(ExternalReference::isolate_address()));
__ Push(scratch3, name_reg);
__ mov(r0, sp); // r0 = Handle<String>
const int kApiStackSpace = 1;
......@@ -1216,7 +1223,7 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
__ str(scratch2, MemOperand(sp, 1 * kPointerSize));
__ add(r1, sp, Operand(1 * kPointerSize)); // r1 = AccessorInfo&
const int kStackUnwindSpace = 4;
const int kStackUnwindSpace = 5;
Address getter_address = v8::ToCData<Address>(callback->getter());
ApiFunction fun(getter_address);
ExternalReference ref =
......@@ -1337,20 +1344,19 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
if (!receiver.is(holder_reg)) {
ASSERT(scratch1.is(holder_reg));
__ Push(receiver, holder_reg);
__ ldr(scratch3,
FieldMemOperand(scratch2, AccessorInfo::kDataOffset));
__ Push(scratch3, scratch2, name_reg);
} else {
__ push(receiver);
__ ldr(scratch3,
FieldMemOperand(scratch2, AccessorInfo::kDataOffset));
__ Push(holder_reg, scratch3, scratch2, name_reg);
__ push(holder_reg);
}
__ ldr(scratch3,
FieldMemOperand(scratch2, AccessorInfo::kDataOffset));
__ mov(scratch1, Operand(ExternalReference::isolate_address()));
__ Push(scratch3, scratch1, scratch2, name_reg);
ExternalReference ref =
ExternalReference(IC_Utility(IC::kLoadCallbackProperty),
masm()->isolate());
__ TailCallExternalReference(ref, 5, 1);
__ TailCallExternalReference(ref, 6, 1);
}
} else { // !compile_followup_inline
// Call the runtime system to load the interceptor.
......@@ -1364,7 +1370,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
ExternalReference ref =
ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad),
masm()->isolate());
__ TailCallExternalReference(ref, 5, 1);
__ TailCallExternalReference(ref, 6, 1);
}
}
......
......@@ -1098,7 +1098,7 @@ MUST_USE_RESULT static MaybeObject* HandleApiCallHelper(
CustomArguments custom(isolate);
v8::ImplementationUtilities::PrepareArgumentsData(custom.end(),
data_obj, *function, raw_holder);
isolate, data_obj, *function, raw_holder);
v8::Arguments new_args = v8::ImplementationUtilities::NewArguments(
custom.end(),
......@@ -1138,68 +1138,6 @@ BUILTIN(HandleApiCallConstruct) {
}
#ifdef DEBUG
static void VerifyTypeCheck(Handle<JSObject> object,
Handle<JSFunction> function) {
ASSERT(function->shared()->IsApiFunction());
FunctionTemplateInfo* info = function->shared()->get_api_func_data();
if (info->signature()->IsUndefined()) return;
SignatureInfo* signature = SignatureInfo::cast(info->signature());
Object* receiver_type = signature->receiver();
if (receiver_type->IsUndefined()) return;
FunctionTemplateInfo* type = FunctionTemplateInfo::cast(receiver_type);
ASSERT(object->IsInstanceOf(type));
}
#endif
BUILTIN(FastHandleApiCall) {
ASSERT(!CalledAsConstructor(isolate));
Heap* heap = isolate->heap();
const bool is_construct = false;
// We expect four more arguments: callback, function, call data, and holder.
const int args_length = args.length() - 4;
ASSERT(args_length >= 0);
Object* callback_obj = args[args_length];
v8::Arguments new_args = v8::ImplementationUtilities::NewArguments(
&args[args_length + 1],
&args[0] - 1,
args_length - 1,
is_construct);
#ifdef DEBUG
VerifyTypeCheck(Utils::OpenHandle(*new_args.Holder()),
Utils::OpenHandle(*new_args.Callee()));
#endif
HandleScope scope(isolate);
Object* result;
v8::Handle<v8::Value> value;
{
// Leaving JavaScript.
VMState state(isolate, EXTERNAL);
ExternalCallbackScope call_scope(isolate,
v8::ToCData<Address>(callback_obj));
v8::InvocationCallback callback =
v8::ToCData<v8::InvocationCallback>(callback_obj);
value = callback(new_args);
}
if (value.IsEmpty()) {
result = heap->undefined_value();
} else {
result = *reinterpret_cast<Object**>(*value);
}
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return result;
}
// Helper function to handle calls to non-function objects created through the
// API. The object can be called as either a constructor (using new) or just as
// a function (without new).
......@@ -1238,7 +1176,7 @@ MUST_USE_RESULT static MaybeObject* HandleApiCallAsFunctionOrConstructor(
CustomArguments custom(isolate);
v8::ImplementationUtilities::PrepareArgumentsData(custom.end(),
call_data->data(), constructor, obj);
isolate, call_data->data(), constructor, obj);
v8::Arguments new_args = v8::ImplementationUtilities::NewArguments(
custom.end(),
&args[0] - 1,
......
......@@ -56,7 +56,6 @@ enum BuiltinExtraArguments {
V(ArrayConcat, NO_EXTRA_ARGUMENTS) \
\
V(HandleApiCall, NEEDS_CALLED_FUNCTION) \
V(FastHandleApiCall, NO_EXTRA_ARGUMENTS) \
V(HandleApiCallConstruct, NEEDS_CALLED_FUNCTION) \
V(HandleApiCallAsFunction, NO_EXTRA_ARGUMENTS) \
V(HandleApiCallAsConstructor, NO_EXTRA_ARGUMENTS) \
......
......@@ -406,6 +406,7 @@ static void PushInterceptorArguments(MacroAssembler* masm,
__ push(receiver);
__ push(holder);
__ push(FieldOperand(scratch, InterceptorInfo::kDataOffset));
__ push(Immediate(reinterpret_cast<int>(masm->isolate())));
}
......@@ -419,12 +420,12 @@ static void CompileCallLoadPropertyWithInterceptor(
__ CallExternalReference(
ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly),
masm->isolate()),
5);
6);
}
// Number of pointers to be reserved on stack for fast API call.
static const int kFastApiCallArguments = 3;
static const int kFastApiCallArguments = 4;
// Reserves space for the extra arguments to API function in the
......@@ -472,10 +473,11 @@ static void GenerateFastApiCall(MacroAssembler* masm,
// -- esp[8] : api function
// (first fast api call extra argument)
// -- esp[12] : api call data
// -- esp[16] : last argument
// -- esp[16] : isolate
// -- esp[20] : last argument
// -- ...
// -- esp[(argc + 3) * 4] : first argument
// -- esp[(argc + 4) * 4] : receiver
// -- esp[(argc + 4) * 4] : first argument
// -- esp[(argc + 5) * 4] : receiver
// -----------------------------------
// Get the function and setup the context.
Handle<JSFunction> function = optimization.constant_function();
......@@ -493,9 +495,11 @@ static void GenerateFastApiCall(MacroAssembler* masm,
} else {
__ mov(Operand(esp, 3 * kPointerSize), Immediate(call_data));
}
__ mov(Operand(esp, 4 * kPointerSize),
Immediate(reinterpret_cast<int>(masm->isolate())));
// Prepare arguments.
__ lea(eax, Operand(esp, 3 * kPointerSize));
__ lea(eax, Operand(esp, 4 * kPointerSize));
const int kApiArgc = 1; // API function gets reference to the v8::Arguments.
......@@ -679,7 +683,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
__ CallExternalReference(
ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall),
masm->isolate()),
5);
6);
// Restore the name_ register.
__ pop(name_);
......@@ -1034,6 +1038,7 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
} else {
__ push(Immediate(Handle<Object>(callback->data())));
}
__ push(Immediate(reinterpret_cast<int>(isolate())));
// Save a pointer to where we pushed the arguments pointer.
// This will be passed as the const AccessorInfo& to the C++ callback.
......@@ -1044,9 +1049,9 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
__ push(scratch3); // Restore return address.
// 3 elements array for v8::Arguments::values_, handler for name and pointer
// 4 elements array for v8::Arguments::values_, handler for name and pointer
// to the values (it considered as smi in GC).
const int kStackSpace = 5;
const int kStackSpace = 6;
const int kApiArgc = 2;
__ PrepareCallApiFunction(kApiArgc);
......@@ -1199,6 +1204,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
__ push(holder_reg);
__ mov(holder_reg, Immediate(callback));
__ push(FieldOperand(holder_reg, AccessorInfo::kDataOffset));
__ push(Immediate(reinterpret_cast<int>(isolate())));
__ push(holder_reg);
__ push(name_reg);
__ push(scratch2); // restore return address
......@@ -1206,7 +1212,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
ExternalReference ref =
ExternalReference(IC_Utility(IC::kLoadCallbackProperty),
masm()->isolate());
__ TailCallExternalReference(ref, 5, 1);
__ TailCallExternalReference(ref, 6, 1);
}
} else { // !compile_followup_inline
// Call the runtime system to load the interceptor.
......@@ -1222,7 +1228,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
ExternalReference ref =
ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad),
isolate());
__ TailCallExternalReference(ref, 5, 1);
__ TailCallExternalReference(ref, 6, 1);
}
}
......@@ -2160,7 +2166,7 @@ Handle<Code> CallStubCompiler::CompileFastApiCall(
name, depth, &miss);
// Move the return address on top of the stack.
__ mov(eax, Operand(esp, 3 * kPointerSize));
__ mov(eax, Operand(esp, 4 * kPointerSize));
__ mov(Operand(esp, 0 * kPointerSize), eax);
// esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains
......
......@@ -939,7 +939,8 @@ void StubCache::CollectMatchingMaps(SmallMapList* types,
RUNTIME_FUNCTION(MaybeObject*, LoadCallbackProperty) {
ASSERT(args[0]->IsJSObject());
ASSERT(args[1]->IsJSObject());
AccessorInfo* callback = AccessorInfo::cast(args[3]);
ASSERT(args[3]->IsSmi());
AccessorInfo* callback = AccessorInfo::cast(args[4]);
Address getter_address = v8::ToCData<Address>(callback->getter());
v8::AccessorGetter fun = FUNCTION_CAST<v8::AccessorGetter>(getter_address);
ASSERT(fun != NULL);
......@@ -950,7 +951,7 @@ RUNTIME_FUNCTION(MaybeObject*, LoadCallbackProperty) {
// Leaving JavaScript.
VMState state(isolate, EXTERNAL);
ExternalCallbackScope call_scope(isolate, getter_address);
result = fun(v8::Utils::ToLocal(args.at<String>(4)), info);
result = fun(v8::Utils::ToLocal(args.at<String>(5)), info);
}
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
if (result.IsEmpty()) return HEAP->undefined_value();
......@@ -997,7 +998,8 @@ RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorOnly) {
ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2);
ASSERT(args[2]->IsJSObject()); // Receiver.
ASSERT(args[3]->IsJSObject()); // Holder.
ASSERT(args.length() == 5); // Last arg is data object.
ASSERT(args[5]->IsSmi()); // Isolate.
ASSERT(args.length() == 6);
Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
v8::NamedPropertyGetter getter =
......@@ -1050,7 +1052,7 @@ static MaybeObject* LoadWithInterceptor(Arguments* args,
ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2);
Handle<JSObject> receiver_handle = args->at<JSObject>(2);
Handle<JSObject> holder_handle = args->at<JSObject>(3);
ASSERT(args->length() == 5); // Last arg is data object.
ASSERT(args->length() == 6);
Isolate* isolate = receiver_handle->GetIsolate();
......
......@@ -379,6 +379,7 @@ static void PushInterceptorArguments(MacroAssembler* masm,
__ push(receiver);
__ push(holder);
__ push(FieldOperand(kScratchRegister, InterceptorInfo::kDataOffset));
__ push(Immediate(reinterpret_cast<intptr_t>(masm->isolate())));
}
......@@ -393,7 +394,7 @@ static void CompileCallLoadPropertyWithInterceptor(
ExternalReference ref =
ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly),
masm->isolate());
__ Set(rax, 5);
__ Set(rax, 6);
__ LoadAddress(rbx, ref);
CEntryStub stub(1);
......@@ -402,7 +403,7 @@ static void CompileCallLoadPropertyWithInterceptor(
// Number of pointers to be reserved on stack for fast API call.
static const int kFastApiCallArguments = 3;
static const int kFastApiCallArguments = 4;
// Reserves space for the extra arguments to API function in the
......@@ -452,10 +453,11 @@ static void GenerateFastApiCall(MacroAssembler* masm,
// -- rsp[16] : api function
// (first fast api call extra argument)
// -- rsp[24] : api call data
// -- rsp[32] : last argument
// -- rsp[32] : isolate
// -- rsp[40] : last argument
// -- ...
// -- rsp[(argc + 3) * 8] : first argument
// -- rsp[(argc + 4) * 8] : receiver
// -- rsp[(argc + 4) * 8] : first argument
// -- rsp[(argc + 5) * 8] : receiver
// -----------------------------------
// Get the function and setup the context.
Handle<JSFunction> function = optimization.constant_function();
......@@ -473,9 +475,11 @@ static void GenerateFastApiCall(MacroAssembler* masm,
} else {
__ Move(Operand(rsp, 3 * kPointerSize), call_data);
}
__ movq(Operand(rsp, 4 * kPointerSize),
Immediate(reinterpret_cast<intptr_t>(masm->isolate())));
// Prepare arguments.
__ lea(rbx, Operand(rsp, 3 * kPointerSize));
__ lea(rbx, Operand(rsp, 4 * kPointerSize));
#ifdef _WIN64
// Win64 uses first register--rcx--for returned value.
......@@ -663,7 +667,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
__ CallExternalReference(
ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall),
masm->isolate()),
5);
6);
// Restore the name_ register.
__ pop(name_);
......@@ -1005,6 +1009,7 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
} else {
__ Push(Handle<Object>(callback->data()));
}
__ push(Immediate(reinterpret_cast<intptr_t>(isolate()))); // isolate
__ push(name_reg); // name
// Save a pointer to where we pushed the arguments pointer.
// This will be passed as the const AccessorInfo& to the C++ callback.
......@@ -1022,14 +1027,14 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object,
__ movq(name_arg, rsp);
__ push(scratch2); // Restore return address.
// 3 elements array for v8::Arguments::values_ and handler for name.
const int kStackSpace = 4;
// 4 elements array for v8::Arguments::values_ and handler for name.
const int kStackSpace = 5;
// Allocate v8::AccessorInfo in non-GCed stack space.
const int kArgStackSpace = 1;
__ PrepareCallApiFunction(kArgStackSpace);
__ lea(rax, Operand(name_arg, 3 * kPointerSize));
__ lea(rax, Operand(name_arg, 4 * kPointerSize));
// v8::AccessorInfo::args_.
__ movq(StackSpaceOperand(0), rax);
......@@ -1179,6 +1184,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
__ push(holder_reg);
__ Move(holder_reg, callback);
__ push(FieldOperand(holder_reg, AccessorInfo::kDataOffset));
__ push(Immediate(reinterpret_cast<intptr_t>(isolate())));
__ push(holder_reg);
__ push(name_reg);
__ push(scratch2); // restore return address
......@@ -1186,7 +1192,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
ExternalReference ref =
ExternalReference(IC_Utility(IC::kLoadCallbackProperty),
isolate());
__ TailCallExternalReference(ref, 5, 1);
__ TailCallExternalReference(ref, 6, 1);
}
} else { // !compile_followup_inline
// Call the runtime system to load the interceptor.
......@@ -1201,7 +1207,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
ExternalReference ref = ExternalReference(
IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate());
__ TailCallExternalReference(ref, 5, 1);
__ TailCallExternalReference(ref, 6, 1);
}
}
......@@ -1993,7 +1999,7 @@ Handle<Code> CallStubCompiler::CompileFastApiCall(
name, depth, &miss);
// Move the return address on top of the stack.
__ movq(rax, Operand(rsp, 3 * kPointerSize));
__ movq(rax, Operand(rsp, 4 * kPointerSize));
__ movq(Operand(rsp, 0 * kPointerSize), rax);
GenerateFastApiCall(masm(), optimization, argc);
......
// Copyright 2009 the V8 project authors. All rights reserved.
// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
......@@ -116,6 +116,8 @@ static v8::Handle<v8::Object> x_holder;
static v8::Handle<Value> XGetter(Local<String> name, const AccessorInfo& info) {
ApiTestFuzzer::Fuzz();
v8::Isolate* isolate = v8::Isolate::GetCurrent();
CHECK_EQ(isolate, info.GetIsolate());
CHECK_EQ(x_receiver, info.This());
CHECK_EQ(x_holder, info.Holder());
return v8_num(x_register);
......@@ -125,6 +127,8 @@ static v8::Handle<Value> XGetter(Local<String> name, const AccessorInfo& info) {
static void XSetter(Local<String> name,
Local<Value> value,
const AccessorInfo& info) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
CHECK_EQ(isolate, info.GetIsolate());
CHECK_EQ(x_holder, info.This());
CHECK_EQ(x_holder, info.Holder());
x_register = value->Int32Value();
......@@ -236,12 +240,15 @@ THREADED_TEST(HandleScopePop) {
static v8::Handle<Value> CheckAccessorArgsCorrect(Local<String> name,
const AccessorInfo& info) {
CHECK(info.GetIsolate() == v8::Isolate::GetCurrent());
CHECK(info.This() == info.Holder());
CHECK(info.Data()->Equals(v8::String::New("data")));
ApiTestFuzzer::Fuzz();
CHECK(info.GetIsolate() == v8::Isolate::GetCurrent());
CHECK(info.This() == info.Holder());
CHECK(info.Data()->Equals(v8::String::New("data")));
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK(info.GetIsolate() == v8::Isolate::GetCurrent());
CHECK(info.This() == info.Holder());
CHECK(info.Data()->Equals(v8::String::New("data")));
return v8::Integer::New(17);
......
......@@ -8608,6 +8608,8 @@ static void CheckInterceptorLoadIC(NamedPropertyGetter getter,
static v8::Handle<Value> InterceptorLoadICGetter(Local<String> name,
const AccessorInfo& info) {
ApiTestFuzzer::Fuzz();
v8::Isolate* isolate = v8::Isolate::GetCurrent();
CHECK_EQ(isolate, info.GetIsolate());
CHECK_EQ(v8_str("data"), info.Data());
CHECK_EQ(v8_str("x"), name);
return v8::Integer::New(42);
......@@ -9334,6 +9336,8 @@ static v8::Handle<Value> InterceptorCallICFastApi(Local<String> name,
static v8::Handle<Value> FastApiCallback_TrivialSignature(
const v8::Arguments& args) {
ApiTestFuzzer::Fuzz();
v8::Isolate* isolate = v8::Isolate::GetCurrent();
CHECK_EQ(isolate, args.GetIsolate());
CHECK_EQ(args.This(), args.Holder());
CHECK(args.Data()->Equals(v8_str("method_data")));
return v8::Integer::New(args[0]->Int32Value() + 1);
......@@ -9342,6 +9346,8 @@ static v8::Handle<Value> FastApiCallback_TrivialSignature(
static v8::Handle<Value> FastApiCallback_SimpleSignature(
const v8::Arguments& args) {
ApiTestFuzzer::Fuzz();
v8::Isolate* isolate = v8::Isolate::GetCurrent();
CHECK_EQ(isolate, args.GetIsolate());
CHECK_EQ(args.This()->GetPrototype(), args.Holder());
CHECK(args.Data()->Equals(v8_str("method_data")));
// Note, we're using HasRealNamedProperty instead of Has to avoid
......
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