Win64 - Allow returning two values from a runtime function.
(Not yet fully functional) Review URL: http://codereview.chromium.org/201042 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2845 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
ae062d5df1
commit
8f60f1a46f
@ -5623,7 +5623,7 @@ void StackCheckStub::Generate(MacroAssembler* masm) {
|
||||
// argument, so give it a Smi.
|
||||
__ mov(r0, Operand(Smi::FromInt(0)));
|
||||
__ push(r0);
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kStackGuard), 1);
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kStackGuard), 1, 1);
|
||||
|
||||
__ StubReturn(1);
|
||||
}
|
||||
@ -5678,6 +5678,13 @@ void UnarySubStub::Generate(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
|
||||
int CEntryStub::MinorKey() {
|
||||
ASSERT(result_size_ <= 2);
|
||||
// Result returned in r0 or r0+r1 by default.
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
|
||||
// r0 holds the exception.
|
||||
|
||||
@ -6195,7 +6202,7 @@ void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
|
||||
// by calling the runtime system.
|
||||
__ bind(&slow);
|
||||
__ push(r1);
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1);
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -6216,7 +6223,7 @@ void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
|
||||
|
||||
// Do the runtime call to allocate the arguments object.
|
||||
__ bind(&runtime);
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3);
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -391,7 +391,7 @@ void CallIC::Generate(MacroAssembler* masm,
|
||||
__ mov(r0, Operand(2));
|
||||
__ mov(r1, Operand(f));
|
||||
|
||||
CEntryStub stub;
|
||||
CEntryStub stub(1);
|
||||
__ CallStub(&stub);
|
||||
|
||||
// Move result to r1 and leave the internal frame.
|
||||
@ -503,7 +503,7 @@ void LoadIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
|
||||
__ stm(db_w, sp, r2.bit() | r3.bit());
|
||||
|
||||
// Perform tail call to the entry.
|
||||
__ TailCallRuntime(f, 2);
|
||||
__ TailCallRuntime(f, 2, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -543,7 +543,7 @@ void KeyedLoadIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
|
||||
__ ldm(ia, sp, r2.bit() | r3.bit());
|
||||
__ stm(db_w, sp, r2.bit() | r3.bit());
|
||||
|
||||
__ TailCallRuntime(f, 2);
|
||||
__ TailCallRuntime(f, 2, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -599,7 +599,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
||||
__ ldm(ia, sp, r0.bit() | r1.bit());
|
||||
__ stm(db_w, sp, r0.bit() | r1.bit());
|
||||
// Do tail-call to runtime routine.
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kGetProperty), 2);
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kGetProperty), 2, 1);
|
||||
|
||||
// Fast case: Do the load.
|
||||
__ bind(&fast);
|
||||
@ -626,7 +626,7 @@ void KeyedStoreIC::Generate(MacroAssembler* masm,
|
||||
__ ldm(ia, sp, r2.bit() | r3.bit());
|
||||
__ stm(db_w, sp, r0.bit() | r2.bit() | r3.bit());
|
||||
|
||||
__ TailCallRuntime(f, 3);
|
||||
__ TailCallRuntime(f, 3, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -684,7 +684,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
|
||||
__ ldm(ia, sp, r1.bit() | r3.bit()); // r0 == value, r1 == key, r3 == object
|
||||
__ stm(db_w, sp, r0.bit() | r1.bit() | r3.bit());
|
||||
// Do tail-call to runtime routine.
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3);
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3, 1);
|
||||
|
||||
// Extra capacity case: Check if there is extra capacity to
|
||||
// perform the store and update the length. Used for adding one
|
||||
@ -761,7 +761,7 @@ void KeyedStoreIC::GenerateExtendStorage(MacroAssembler* masm) {
|
||||
|
||||
// Perform tail call to the entry.
|
||||
__ TailCallRuntime(
|
||||
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
|
||||
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -798,7 +798,7 @@ void StoreIC::GenerateExtendStorage(MacroAssembler* masm) {
|
||||
|
||||
// Perform tail call to the entry.
|
||||
__ TailCallRuntime(
|
||||
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
|
||||
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -814,7 +814,7 @@ void StoreIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
|
||||
__ stm(db_w, sp, r0.bit() | r2.bit() | r3.bit());
|
||||
|
||||
// Perform tail call to the entry.
|
||||
__ TailCallRuntime(f, 3);
|
||||
__ TailCallRuntime(f, 3, 1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -999,7 +999,8 @@ void MacroAssembler::CallRuntime(Runtime::FunctionId fid, int num_arguments) {
|
||||
|
||||
|
||||
void MacroAssembler::TailCallRuntime(const ExternalReference& ext,
|
||||
int num_arguments) {
|
||||
int num_arguments,
|
||||
int result_size) {
|
||||
// TODO(1236192): Most runtime routines don't need the number of
|
||||
// arguments passed in because it is constant. At some point we
|
||||
// should remove this need and make the runtime routine entry code
|
||||
@ -1015,7 +1016,7 @@ void MacroAssembler::JumpToBuiltin(const ExternalReference& builtin) {
|
||||
ASSERT((reinterpret_cast<intptr_t>(builtin.address()) & 1) == 1);
|
||||
#endif
|
||||
mov(r1, Operand(builtin));
|
||||
CEntryStub stub;
|
||||
CEntryStub stub(1);
|
||||
Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
|
@ -259,7 +259,9 @@ class MacroAssembler: public Assembler {
|
||||
// Tail call of a runtime routine (jump).
|
||||
// Like JumpToBuiltin, but also takes care of passing the number
|
||||
// of parameters.
|
||||
void TailCallRuntime(const ExternalReference& ext, int num_arguments);
|
||||
void TailCallRuntime(const ExternalReference& ext,
|
||||
int num_arguments,
|
||||
int result_size);
|
||||
|
||||
// Jump to the builtin routine.
|
||||
void JumpToBuiltin(const ExternalReference& builtin);
|
||||
|
@ -478,7 +478,7 @@ void StubCompiler::GenerateLoadCallback(JSObject* object,
|
||||
// Do tail-call to the runtime system.
|
||||
ExternalReference load_callback_property =
|
||||
ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
|
||||
__ TailCallRuntime(load_callback_property, 5);
|
||||
__ TailCallRuntime(load_callback_property, 5, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -514,7 +514,7 @@ void StubCompiler::GenerateLoadInterceptor(JSObject* object,
|
||||
// Do tail-call to the runtime system.
|
||||
ExternalReference load_ic_property =
|
||||
ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad));
|
||||
__ TailCallRuntime(load_ic_property, 5);
|
||||
__ TailCallRuntime(load_ic_property, 5, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -884,7 +884,7 @@ Object* StoreStubCompiler::CompileStoreCallback(JSObject* object,
|
||||
// Do tail-call to the runtime system.
|
||||
ExternalReference store_callback_property =
|
||||
ExternalReference(IC_Utility(IC::kStoreCallbackProperty));
|
||||
__ TailCallRuntime(store_callback_property, 4);
|
||||
__ TailCallRuntime(store_callback_property, 4, 1);
|
||||
|
||||
// Handle store cache miss.
|
||||
__ bind(&miss);
|
||||
@ -936,7 +936,7 @@ Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
|
||||
// Do tail-call to the runtime system.
|
||||
ExternalReference store_ic_property =
|
||||
ExternalReference(IC_Utility(IC::kStoreInterceptorProperty));
|
||||
__ TailCallRuntime(store_ic_property, 3);
|
||||
__ TailCallRuntime(store_ic_property, 3, 1);
|
||||
|
||||
// Handle store cache miss.
|
||||
__ bind(&miss);
|
||||
|
@ -517,7 +517,10 @@ const char* RuntimeStub::GetName() {
|
||||
|
||||
|
||||
void RuntimeStub::Generate(MacroAssembler* masm) {
|
||||
masm->TailCallRuntime(ExternalReference(id_), num_arguments_);
|
||||
Runtime::Function* f = Runtime::FunctionForId(id_);
|
||||
masm->TailCallRuntime(ExternalReference(f),
|
||||
num_arguments_,
|
||||
f->result_size);
|
||||
}
|
||||
|
||||
|
||||
|
@ -286,7 +286,7 @@ class CompareStub: public CodeStub {
|
||||
|
||||
class CEntryStub : public CodeStub {
|
||||
public:
|
||||
CEntryStub() { }
|
||||
explicit CEntryStub(int result_size) : result_size_(result_size) { }
|
||||
|
||||
void Generate(MacroAssembler* masm) { GenerateBody(masm, false); }
|
||||
|
||||
@ -302,10 +302,14 @@ class CEntryStub : public CodeStub {
|
||||
void GenerateThrowTOS(MacroAssembler* masm);
|
||||
void GenerateThrowUncatchable(MacroAssembler* masm,
|
||||
UncatchableExceptionType type);
|
||||
|
||||
private:
|
||||
// Number of pointers/values returned.
|
||||
int result_size_;
|
||||
|
||||
Major MajorKey() { return CEntry; }
|
||||
int MinorKey() { return 0; }
|
||||
// Minor key must differ if different result_size_ values means different
|
||||
// code is generated.
|
||||
int MinorKey();
|
||||
|
||||
const char* GetName() { return "CEntryStub"; }
|
||||
};
|
||||
@ -313,7 +317,7 @@ class CEntryStub : public CodeStub {
|
||||
|
||||
class CEntryDebugBreakStub : public CEntryStub {
|
||||
public:
|
||||
CEntryDebugBreakStub() { }
|
||||
CEntryDebugBreakStub() : CEntryStub(1) { }
|
||||
|
||||
void Generate(MacroAssembler* masm) { GenerateBody(masm, true); }
|
||||
|
||||
|
@ -1319,7 +1319,7 @@ bool Heap::CreateApiObjects() {
|
||||
|
||||
|
||||
void Heap::CreateCEntryStub() {
|
||||
CEntryStub stub;
|
||||
CEntryStub stub(1);
|
||||
set_c_entry_code(*stub.GetCode());
|
||||
}
|
||||
|
||||
|
@ -6886,7 +6886,7 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
|
||||
__ j(above_equal, &string1);
|
||||
|
||||
// First and second argument are strings.
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kStringAdd), 2);
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kStringAdd), 2, 1);
|
||||
|
||||
// Only first argument is a string.
|
||||
__ bind(&string1);
|
||||
@ -7175,7 +7175,7 @@ void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
|
||||
__ pop(ebx); // Return address.
|
||||
__ push(edx);
|
||||
__ push(ebx);
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1);
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -7200,7 +7200,7 @@ void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
|
||||
|
||||
// Do the runtime call to allocate the arguments object.
|
||||
__ bind(&runtime);
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3);
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -7436,7 +7436,7 @@ void StackCheckStub::Generate(MacroAssembler* masm) {
|
||||
__ push(eax);
|
||||
|
||||
// Do tail-call to runtime routine.
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kStackGuard), 1);
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kStackGuard), 1, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -7468,6 +7468,13 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
|
||||
int CEntryStub::MinorKey() {
|
||||
ASSERT(result_size_ <= 2);
|
||||
// Result returned in eax, or eax+edx if result_size_ is 2.
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
|
||||
// eax holds the exception.
|
||||
|
||||
|
@ -404,7 +404,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
|
||||
__ push(eax);
|
||||
__ push(ecx);
|
||||
// Do tail-call to runtime routine.
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3);
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3, 1);
|
||||
|
||||
// Check whether the elements is a pixel array.
|
||||
// eax: value
|
||||
@ -667,7 +667,7 @@ void CallIC::Generate(MacroAssembler* masm,
|
||||
__ push(ebx);
|
||||
|
||||
// Call the entry.
|
||||
CEntryStub stub;
|
||||
CEntryStub stub(1);
|
||||
__ mov(eax, Immediate(2));
|
||||
__ mov(ebx, Immediate(f));
|
||||
__ CallStub(&stub);
|
||||
@ -799,7 +799,7 @@ void LoadIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
|
||||
__ push(ebx); // return address
|
||||
|
||||
// Perform tail call to the entry.
|
||||
__ TailCallRuntime(f, 2);
|
||||
__ TailCallRuntime(f, 2, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -927,7 +927,7 @@ void KeyedLoadIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
|
||||
__ push(ebx); // return address
|
||||
|
||||
// Perform tail call to the entry.
|
||||
__ TailCallRuntime(f, 2);
|
||||
__ TailCallRuntime(f, 2, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -967,7 +967,7 @@ void StoreIC::GenerateExtendStorage(MacroAssembler* masm) {
|
||||
|
||||
// Perform tail call to the entry.
|
||||
__ TailCallRuntime(
|
||||
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
|
||||
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -987,7 +987,7 @@ void StoreIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
|
||||
__ push(ebx);
|
||||
|
||||
// Perform tail call to the entry.
|
||||
__ TailCallRuntime(f, 3);
|
||||
__ TailCallRuntime(f, 3, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -1010,7 +1010,7 @@ void KeyedStoreIC::Generate(MacroAssembler* masm, const ExternalReference& f) {
|
||||
__ push(ecx);
|
||||
|
||||
// Do tail-call to runtime routine.
|
||||
__ TailCallRuntime(f, 3);
|
||||
__ TailCallRuntime(f, 3, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -1032,7 +1032,7 @@ void KeyedStoreIC::GenerateExtendStorage(MacroAssembler* masm) {
|
||||
|
||||
// Do tail-call to runtime routine.
|
||||
__ TailCallRuntime(
|
||||
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
|
||||
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
|
||||
}
|
||||
|
||||
#undef __
|
||||
|
@ -896,7 +896,8 @@ void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
|
||||
|
||||
|
||||
void MacroAssembler::TailCallRuntime(const ExternalReference& ext,
|
||||
int num_arguments) {
|
||||
int num_arguments,
|
||||
int result_size) {
|
||||
// TODO(1236192): Most runtime routines don't need the number of
|
||||
// arguments passed in because it is constant. At some point we
|
||||
// should remove this need and make the runtime routine entry code
|
||||
@ -909,7 +910,7 @@ void MacroAssembler::TailCallRuntime(const ExternalReference& ext,
|
||||
void MacroAssembler::JumpToBuiltin(const ExternalReference& ext) {
|
||||
// Set the entry point and jump to the C entry runtime stub.
|
||||
mov(ebx, Immediate(ext));
|
||||
CEntryStub ces;
|
||||
CEntryStub ces(1);
|
||||
jmp(ces.GetCode(), RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
|
@ -256,7 +256,9 @@ class MacroAssembler: public Assembler {
|
||||
// Tail call of a runtime routine (jump).
|
||||
// Like JumpToBuiltin, but also takes care of passing the number
|
||||
// of arguments.
|
||||
void TailCallRuntime(const ExternalReference& ext, int num_arguments);
|
||||
void TailCallRuntime(const ExternalReference& ext,
|
||||
int num_arguments,
|
||||
int result_size);
|
||||
|
||||
// Jump to the builtin routine.
|
||||
void JumpToBuiltin(const ExternalReference& ext);
|
||||
|
@ -302,7 +302,7 @@ static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm,
|
||||
__ mov(eax, Immediate(5));
|
||||
__ mov(ebx, Immediate(ref));
|
||||
|
||||
CEntryStub stub;
|
||||
CEntryStub stub(1);
|
||||
__ CallStub(&stub);
|
||||
}
|
||||
|
||||
@ -467,7 +467,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
|
||||
|
||||
ExternalReference ref =
|
||||
ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
|
||||
__ TailCallRuntime(ref, 5);
|
||||
__ TailCallRuntime(ref, 5, 1);
|
||||
|
||||
__ bind(&cleanup);
|
||||
__ pop(scratch1);
|
||||
@ -489,7 +489,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
|
||||
|
||||
ExternalReference ref = ExternalReference(
|
||||
IC_Utility(IC::kLoadPropertyWithInterceptorForLoad));
|
||||
__ TailCallRuntime(ref, 5);
|
||||
__ TailCallRuntime(ref, 5, 1);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -593,7 +593,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
|
||||
__ mov(eax, Immediate(5));
|
||||
__ mov(ebx, Immediate(ref));
|
||||
|
||||
CEntryStub stub;
|
||||
CEntryStub stub(1);
|
||||
__ CallStub(&stub);
|
||||
|
||||
__ LeaveInternalFrame();
|
||||
@ -789,7 +789,7 @@ void StubCompiler::GenerateLoadCallback(JSObject* object,
|
||||
// Do tail-call to the runtime system.
|
||||
ExternalReference load_callback_property =
|
||||
ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
|
||||
__ TailCallRuntime(load_callback_property, 5);
|
||||
__ TailCallRuntime(load_callback_property, 5, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -1237,7 +1237,7 @@ Object* StoreStubCompiler::CompileStoreCallback(JSObject* object,
|
||||
// Do tail-call to the runtime system.
|
||||
ExternalReference store_callback_property =
|
||||
ExternalReference(IC_Utility(IC::kStoreCallbackProperty));
|
||||
__ TailCallRuntime(store_callback_property, 4);
|
||||
__ TailCallRuntime(store_callback_property, 4, 1);
|
||||
|
||||
// Handle store cache miss.
|
||||
__ bind(&miss);
|
||||
@ -1290,7 +1290,7 @@ Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
|
||||
// Do tail-call to the runtime system.
|
||||
ExternalReference store_ic_property =
|
||||
ExternalReference(IC_Utility(IC::kStoreInterceptorProperty));
|
||||
__ TailCallRuntime(store_ic_property, 3);
|
||||
__ TailCallRuntime(store_ic_property, 3, 1);
|
||||
|
||||
// Handle store cache miss.
|
||||
__ bind(&miss);
|
||||
|
@ -4556,22 +4556,25 @@ static Object* Runtime_LookupContext(Arguments args) {
|
||||
}
|
||||
|
||||
|
||||
// A mechanism to return pairs of Object*'s. This is somewhat
|
||||
// compiler-dependent as it assumes that a 64-bit value (a long long)
|
||||
// is returned via two registers (edx:eax on ia32). Both the ia32 and
|
||||
// arm platform support this; it is mostly an issue of "coaxing" the
|
||||
// compiler to do the right thing.
|
||||
//
|
||||
// TODO(1236026): This is a non-portable hack that should be removed.
|
||||
// A mechanism to return a pair of Object pointers in registers (if possible).
|
||||
// How this is achieved is calling convention-dependent.
|
||||
// All currently supported x86 compiles uses calling conventions that are cdecl
|
||||
// variants where a 64-bit value is returned in two 32-bit registers
|
||||
// (edx:eax on ia32, r1:r0 on ARM).
|
||||
// In AMD-64 calling convention a struct of two pointers is returned in rdx:rax.
|
||||
// In Win64 calling convention, a struct of two pointers is returned in space passed
|
||||
// as a hidden first parameter.
|
||||
#ifdef V8_HOST_ARCH_64_BIT
|
||||
// Tested with GCC, not with MSVC.
|
||||
struct ObjectPair {
|
||||
Object* x;
|
||||
Object* y;
|
||||
};
|
||||
|
||||
static inline ObjectPair MakePair(Object* x, Object* y) {
|
||||
ObjectPair result = {x, y};
|
||||
return result; // Pointers x and y returned in rax and rdx, in AMD-x64-abi.
|
||||
// Pointers x and y returned in rax and rdx, in AMD-x64-abi.
|
||||
// In Win64 they are assigned to a hidden first argument.
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
typedef uint64_t ObjectPair;
|
||||
@ -4582,8 +4585,6 @@ static inline ObjectPair MakePair(Object* x, Object* y) {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
static inline Object* Unhole(Object* x, PropertyAttributes attributes) {
|
||||
ASSERT(!x->IsTheHole() || (attributes & READ_ONLY) != 0);
|
||||
USE(attributes);
|
||||
@ -7619,7 +7620,7 @@ static Object* Runtime_ListNatives(Arguments args) {
|
||||
HandleScope scope;
|
||||
Handle<JSArray> result = Factory::NewJSArray(0);
|
||||
int index = 0;
|
||||
#define ADD_ENTRY(Name, argc) \
|
||||
#define ADD_ENTRY(Name, argc, ressize) \
|
||||
{ \
|
||||
HandleScope inner; \
|
||||
Handle<String> name = \
|
||||
@ -7655,13 +7656,13 @@ static Object* Runtime_IS_VAR(Arguments args) {
|
||||
// ----------------------------------------------------------------------------
|
||||
// Implementation of Runtime
|
||||
|
||||
#define F(name, nargs) \
|
||||
#define F(name, nargs, ressize) \
|
||||
{ #name, "RuntimeStub_" #name, FUNCTION_ADDR(Runtime_##name), nargs, \
|
||||
static_cast<int>(Runtime::k##name) },
|
||||
static_cast<int>(Runtime::k##name), ressize },
|
||||
|
||||
static Runtime::Function Runtime_functions[] = {
|
||||
RUNTIME_FUNCTION_LIST(F)
|
||||
{ NULL, NULL, NULL, 0, -1 }
|
||||
{ NULL, NULL, NULL, 0, -1, 0 }
|
||||
};
|
||||
|
||||
#undef F
|
||||
|
405
src/runtime.h
405
src/runtime.h
@ -43,269 +43,269 @@ namespace internal {
|
||||
// this problem. Please avoid large recursive macros whenever possible.
|
||||
#define RUNTIME_FUNCTION_LIST_ALWAYS_1(F) \
|
||||
/* Property access */ \
|
||||
F(GetProperty, 2) \
|
||||
F(KeyedGetProperty, 2) \
|
||||
F(DeleteProperty, 2) \
|
||||
F(HasLocalProperty, 2) \
|
||||
F(HasProperty, 2) \
|
||||
F(HasElement, 2) \
|
||||
F(IsPropertyEnumerable, 2) \
|
||||
F(GetPropertyNames, 1) \
|
||||
F(GetPropertyNamesFast, 1) \
|
||||
F(GetArgumentsProperty, 1) \
|
||||
F(ToFastProperties, 1) \
|
||||
F(ToSlowProperties, 1) \
|
||||
F(GetProperty, 2, 1) \
|
||||
F(KeyedGetProperty, 2, 1) \
|
||||
F(DeleteProperty, 2, 1) \
|
||||
F(HasLocalProperty, 2, 1) \
|
||||
F(HasProperty, 2, 1) \
|
||||
F(HasElement, 2, 1) \
|
||||
F(IsPropertyEnumerable, 2, 1) \
|
||||
F(GetPropertyNames, 1, 1) \
|
||||
F(GetPropertyNamesFast, 1, 1) \
|
||||
F(GetArgumentsProperty, 1, 1) \
|
||||
F(ToFastProperties, 1, 1) \
|
||||
F(ToSlowProperties, 1, 1) \
|
||||
\
|
||||
F(IsInPrototypeChain, 2) \
|
||||
F(SetHiddenPrototype, 2) \
|
||||
F(IsInPrototypeChain, 2, 1) \
|
||||
F(SetHiddenPrototype, 2, 1) \
|
||||
\
|
||||
F(IsConstructCall, 0) \
|
||||
F(IsConstructCall, 0, 1) \
|
||||
\
|
||||
/* Utilities */ \
|
||||
F(GetCalledFunction, 0) \
|
||||
F(GetFunctionDelegate, 1) \
|
||||
F(GetConstructorDelegate, 1) \
|
||||
F(NewArguments, 1) \
|
||||
F(NewArgumentsFast, 3) \
|
||||
F(LazyCompile, 1) \
|
||||
F(SetNewFunctionAttributes, 1) \
|
||||
F(GetCalledFunction, 0, 1) \
|
||||
F(GetFunctionDelegate, 1, 1) \
|
||||
F(GetConstructorDelegate, 1, 1) \
|
||||
F(NewArguments, 1, 1) \
|
||||
F(NewArgumentsFast, 3, 1) \
|
||||
F(LazyCompile, 1, 1) \
|
||||
F(SetNewFunctionAttributes, 1, 1) \
|
||||
\
|
||||
/* Array join support */ \
|
||||
F(PushIfAbsent, 2) \
|
||||
F(ArrayConcat, 1) \
|
||||
F(PushIfAbsent, 2, 1) \
|
||||
F(ArrayConcat, 1, 1) \
|
||||
\
|
||||
/* Conversions */ \
|
||||
F(ToBool, 1) \
|
||||
F(Typeof, 1) \
|
||||
F(ToBool, 1, 1) \
|
||||
F(Typeof, 1, 1) \
|
||||
\
|
||||
F(StringToNumber, 1) \
|
||||
F(StringFromCharCodeArray, 1) \
|
||||
F(StringParseInt, 2) \
|
||||
F(StringParseFloat, 1) \
|
||||
F(StringToLowerCase, 1) \
|
||||
F(StringToUpperCase, 1) \
|
||||
F(CharFromCode, 1) \
|
||||
F(URIEscape, 1) \
|
||||
F(URIUnescape, 1) \
|
||||
F(StringToNumber, 1, 1) \
|
||||
F(StringFromCharCodeArray, 1, 1) \
|
||||
F(StringParseInt, 2, 1) \
|
||||
F(StringParseFloat, 1, 1) \
|
||||
F(StringToLowerCase, 1, 1) \
|
||||
F(StringToUpperCase, 1, 1) \
|
||||
F(CharFromCode, 1, 1) \
|
||||
F(URIEscape, 1, 1) \
|
||||
F(URIUnescape, 1, 1) \
|
||||
\
|
||||
F(NumberToString, 1) \
|
||||
F(NumberToInteger, 1) \
|
||||
F(NumberToJSUint32, 1) \
|
||||
F(NumberToJSInt32, 1) \
|
||||
F(NumberToSmi, 1) \
|
||||
F(NumberToString, 1, 1) \
|
||||
F(NumberToInteger, 1, 1) \
|
||||
F(NumberToJSUint32, 1, 1) \
|
||||
F(NumberToJSInt32, 1, 1) \
|
||||
F(NumberToSmi, 1, 1) \
|
||||
\
|
||||
/* Arithmetic operations */ \
|
||||
F(NumberAdd, 2) \
|
||||
F(NumberSub, 2) \
|
||||
F(NumberMul, 2) \
|
||||
F(NumberDiv, 2) \
|
||||
F(NumberMod, 2) \
|
||||
F(NumberUnaryMinus, 1) \
|
||||
F(NumberAdd, 2, 1) \
|
||||
F(NumberSub, 2, 1) \
|
||||
F(NumberMul, 2, 1) \
|
||||
F(NumberDiv, 2, 1) \
|
||||
F(NumberMod, 2, 1) \
|
||||
F(NumberUnaryMinus, 1, 1) \
|
||||
\
|
||||
F(StringAdd, 2) \
|
||||
F(StringBuilderConcat, 2) \
|
||||
F(StringAdd, 2, 1) \
|
||||
F(StringBuilderConcat, 2, 1) \
|
||||
\
|
||||
/* Bit operations */ \
|
||||
F(NumberOr, 2) \
|
||||
F(NumberAnd, 2) \
|
||||
F(NumberXor, 2) \
|
||||
F(NumberNot, 1) \
|
||||
F(NumberOr, 2, 1) \
|
||||
F(NumberAnd, 2, 1) \
|
||||
F(NumberXor, 2, 1) \
|
||||
F(NumberNot, 1, 1) \
|
||||
\
|
||||
F(NumberShl, 2) \
|
||||
F(NumberShr, 2) \
|
||||
F(NumberSar, 2) \
|
||||
F(NumberShl, 2, 1) \
|
||||
F(NumberShr, 2, 1) \
|
||||
F(NumberSar, 2, 1) \
|
||||
\
|
||||
/* Comparisons */ \
|
||||
F(NumberEquals, 2) \
|
||||
F(StringEquals, 2) \
|
||||
F(NumberEquals, 2, 1) \
|
||||
F(StringEquals, 2, 1) \
|
||||
\
|
||||
F(NumberCompare, 3) \
|
||||
F(SmiLexicographicCompare, 2) \
|
||||
F(StringCompare, 2) \
|
||||
F(NumberCompare, 3, 1) \
|
||||
F(SmiLexicographicCompare, 2, 1) \
|
||||
F(StringCompare, 2, 1) \
|
||||
\
|
||||
/* Math */ \
|
||||
F(Math_abs, 1) \
|
||||
F(Math_acos, 1) \
|
||||
F(Math_asin, 1) \
|
||||
F(Math_atan, 1) \
|
||||
F(Math_atan2, 2) \
|
||||
F(Math_ceil, 1) \
|
||||
F(Math_cos, 1) \
|
||||
F(Math_exp, 1) \
|
||||
F(Math_floor, 1) \
|
||||
F(Math_log, 1) \
|
||||
F(Math_pow, 2) \
|
||||
F(Math_round, 1) \
|
||||
F(Math_sin, 1) \
|
||||
F(Math_sqrt, 1) \
|
||||
F(Math_tan, 1) \
|
||||
F(Math_abs, 1, 1) \
|
||||
F(Math_acos, 1, 1) \
|
||||
F(Math_asin, 1, 1) \
|
||||
F(Math_atan, 1, 1) \
|
||||
F(Math_atan2, 2, 1) \
|
||||
F(Math_ceil, 1, 1) \
|
||||
F(Math_cos, 1, 1) \
|
||||
F(Math_exp, 1, 1) \
|
||||
F(Math_floor, 1, 1) \
|
||||
F(Math_log, 1, 1) \
|
||||
F(Math_pow, 2, 1) \
|
||||
F(Math_round, 1, 1) \
|
||||
F(Math_sin, 1, 1) \
|
||||
F(Math_sqrt, 1, 1) \
|
||||
F(Math_tan, 1, 1) \
|
||||
\
|
||||
/* Regular expressions */ \
|
||||
F(RegExpCompile, 3) \
|
||||
F(RegExpExec, 4) \
|
||||
F(RegExpCompile, 3, 1) \
|
||||
F(RegExpExec, 4, 1) \
|
||||
\
|
||||
/* Strings */ \
|
||||
F(StringCharCodeAt, 2) \
|
||||
F(StringIndexOf, 3) \
|
||||
F(StringLastIndexOf, 3) \
|
||||
F(StringLocaleCompare, 2) \
|
||||
F(StringSlice, 3) \
|
||||
F(StringReplaceRegExpWithString, 4) \
|
||||
F(StringMatch, 3) \
|
||||
F(StringCharCodeAt, 2, 1) \
|
||||
F(StringIndexOf, 3, 1) \
|
||||
F(StringLastIndexOf, 3, 1) \
|
||||
F(StringLocaleCompare, 2, 1) \
|
||||
F(StringSlice, 3, 1) \
|
||||
F(StringReplaceRegExpWithString, 4, 1) \
|
||||
F(StringMatch, 3, 1) \
|
||||
\
|
||||
/* Numbers */ \
|
||||
F(NumberToRadixString, 2) \
|
||||
F(NumberToFixed, 2) \
|
||||
F(NumberToExponential, 2) \
|
||||
F(NumberToPrecision, 2)
|
||||
F(NumberToRadixString, 2, 1) \
|
||||
F(NumberToFixed, 2, 1) \
|
||||
F(NumberToExponential, 2, 1) \
|
||||
F(NumberToPrecision, 2, 1)
|
||||
|
||||
#define RUNTIME_FUNCTION_LIST_ALWAYS_2(F) \
|
||||
/* Reflection */ \
|
||||
F(FunctionSetInstanceClassName, 2) \
|
||||
F(FunctionSetLength, 2) \
|
||||
F(FunctionSetPrototype, 2) \
|
||||
F(FunctionGetName, 1) \
|
||||
F(FunctionSetName, 2) \
|
||||
F(FunctionGetSourceCode, 1) \
|
||||
F(FunctionGetScript, 1) \
|
||||
F(FunctionGetScriptSourcePosition, 1) \
|
||||
F(FunctionGetPositionForOffset, 2) \
|
||||
F(FunctionIsAPIFunction, 1) \
|
||||
F(GetScript, 1) \
|
||||
F(CollectStackTrace, 2) \
|
||||
F(FunctionSetInstanceClassName, 2, 1) \
|
||||
F(FunctionSetLength, 2, 1) \
|
||||
F(FunctionSetPrototype, 2, 1) \
|
||||
F(FunctionGetName, 1, 1) \
|
||||
F(FunctionSetName, 2, 1) \
|
||||
F(FunctionGetSourceCode, 1, 1) \
|
||||
F(FunctionGetScript, 1, 1) \
|
||||
F(FunctionGetScriptSourcePosition, 1, 1) \
|
||||
F(FunctionGetPositionForOffset, 2, 1) \
|
||||
F(FunctionIsAPIFunction, 1, 1) \
|
||||
F(GetScript, 1, 1) \
|
||||
F(CollectStackTrace, 2, 1) \
|
||||
\
|
||||
F(ClassOf, 1) \
|
||||
F(SetCode, 2) \
|
||||
F(ClassOf, 1, 1) \
|
||||
F(SetCode, 2, 1) \
|
||||
\
|
||||
F(CreateApiFunction, 1) \
|
||||
F(IsTemplate, 1) \
|
||||
F(GetTemplateField, 2) \
|
||||
F(DisableAccessChecks, 1) \
|
||||
F(EnableAccessChecks, 1) \
|
||||
F(CreateApiFunction, 1, 1) \
|
||||
F(IsTemplate, 1, 1) \
|
||||
F(GetTemplateField, 2, 1) \
|
||||
F(DisableAccessChecks, 1, 1) \
|
||||
F(EnableAccessChecks, 1, 1) \
|
||||
\
|
||||
/* Dates */ \
|
||||
F(DateCurrentTime, 0) \
|
||||
F(DateParseString, 2) \
|
||||
F(DateLocalTimezone, 1) \
|
||||
F(DateLocalTimeOffset, 0) \
|
||||
F(DateDaylightSavingsOffset, 1) \
|
||||
F(DateCurrentTime, 0, 1) \
|
||||
F(DateParseString, 2, 1) \
|
||||
F(DateLocalTimezone, 1, 1) \
|
||||
F(DateLocalTimeOffset, 0, 1) \
|
||||
F(DateDaylightSavingsOffset, 1, 1) \
|
||||
\
|
||||
/* Numbers */ \
|
||||
F(NumberIsFinite, 1) \
|
||||
F(NumberIsFinite, 1, 1) \
|
||||
\
|
||||
/* Globals */ \
|
||||
F(CompileString, 2) \
|
||||
F(GlobalPrint, 1) \
|
||||
F(CompileString, 2, 1) \
|
||||
F(GlobalPrint, 1, 1) \
|
||||
\
|
||||
/* Eval */ \
|
||||
F(GlobalReceiver, 1) \
|
||||
F(ResolvePossiblyDirectEval, 2) \
|
||||
F(GlobalReceiver, 1, 1) \
|
||||
F(ResolvePossiblyDirectEval, 2, 1) \
|
||||
\
|
||||
F(SetProperty, -1 /* 3 or 4 */) \
|
||||
F(IgnoreAttributesAndSetProperty, -1 /* 3 or 4 */) \
|
||||
F(SetProperty, -1 /* 3 or 4 */, 1) \
|
||||
F(IgnoreAttributesAndSetProperty, -1 /* 3 or 4 */, 1) \
|
||||
\
|
||||
/* Arrays */ \
|
||||
F(RemoveArrayHoles, 2) \
|
||||
F(GetArrayKeys, 2) \
|
||||
F(MoveArrayContents, 2) \
|
||||
F(EstimateNumberOfElements, 1) \
|
||||
F(RemoveArrayHoles, 2, 1) \
|
||||
F(GetArrayKeys, 2, 1) \
|
||||
F(MoveArrayContents, 2, 1) \
|
||||
F(EstimateNumberOfElements, 1, 1) \
|
||||
\
|
||||
/* Getters and Setters */ \
|
||||
F(DefineAccessor, -1 /* 4 or 5 */) \
|
||||
F(LookupAccessor, 3) \
|
||||
F(DefineAccessor, -1 /* 4 or 5 */, 1) \
|
||||
F(LookupAccessor, 3, 1) \
|
||||
\
|
||||
/* Literals */ \
|
||||
F(MaterializeRegExpLiteral, 4)\
|
||||
F(CreateArrayLiteralBoilerplate, 3) \
|
||||
F(CreateObjectLiteralBoilerplate, 3) \
|
||||
F(CloneLiteralBoilerplate, 1) \
|
||||
F(CloneShallowLiteralBoilerplate, 1) \
|
||||
F(MaterializeRegExpLiteral, 4, 1)\
|
||||
F(CreateArrayLiteralBoilerplate, 3, 1) \
|
||||
F(CreateObjectLiteralBoilerplate, 3, 1) \
|
||||
F(CloneLiteralBoilerplate, 1, 1) \
|
||||
F(CloneShallowLiteralBoilerplate, 1, 1) \
|
||||
\
|
||||
/* Catch context extension objects */ \
|
||||
F(CreateCatchExtensionObject, 2) \
|
||||
F(CreateCatchExtensionObject, 2, 1) \
|
||||
\
|
||||
/* Statements */ \
|
||||
F(NewClosure, 2) \
|
||||
F(NewObject, 1) \
|
||||
F(Throw, 1) \
|
||||
F(ReThrow, 1) \
|
||||
F(ThrowReferenceError, 1) \
|
||||
F(StackGuard, 1) \
|
||||
F(NewClosure, 2, 1) \
|
||||
F(NewObject, 1, 1) \
|
||||
F(Throw, 1, 1) \
|
||||
F(ReThrow, 1, 1) \
|
||||
F(ThrowReferenceError, 1, 1) \
|
||||
F(StackGuard, 1, 1) \
|
||||
\
|
||||
/* Contexts */ \
|
||||
F(NewContext, 1) \
|
||||
F(PushContext, 1) \
|
||||
F(PushCatchContext, 1) \
|
||||
F(LookupContext, 2) \
|
||||
F(LoadContextSlot, 2) \
|
||||
F(LoadContextSlotNoReferenceError, 2) \
|
||||
F(StoreContextSlot, 3) \
|
||||
F(NewContext, 1, 1) \
|
||||
F(PushContext, 1, 1) \
|
||||
F(PushCatchContext, 1, 1) \
|
||||
F(LookupContext, 2, 1) \
|
||||
F(LoadContextSlot, 2, 2) \
|
||||
F(LoadContextSlotNoReferenceError, 2, 2) \
|
||||
F(StoreContextSlot, 3, 1) \
|
||||
\
|
||||
/* Declarations and initialization */ \
|
||||
F(DeclareGlobals, 3) \
|
||||
F(DeclareContextSlot, 4) \
|
||||
F(InitializeVarGlobal, -1 /* 1 or 2 */) \
|
||||
F(InitializeConstGlobal, 2) \
|
||||
F(InitializeConstContextSlot, 3) \
|
||||
F(OptimizeObjectForAddingMultipleProperties, 2) \
|
||||
F(TransformToFastProperties, 1) \
|
||||
F(DeclareGlobals, 3, 1) \
|
||||
F(DeclareContextSlot, 4, 1) \
|
||||
F(InitializeVarGlobal, -1 /* 1 or 2 */, 1) \
|
||||
F(InitializeConstGlobal, 2, 1) \
|
||||
F(InitializeConstContextSlot, 3, 1) \
|
||||
F(OptimizeObjectForAddingMultipleProperties, 2, 1) \
|
||||
F(TransformToFastProperties, 1, 1) \
|
||||
\
|
||||
/* Debugging */ \
|
||||
F(DebugPrint, 1) \
|
||||
F(DebugTrace, 0) \
|
||||
F(TraceEnter, 0) \
|
||||
F(TraceExit, 1) \
|
||||
F(Abort, 2) \
|
||||
F(DebugPrint, 1, 1) \
|
||||
F(DebugTrace, 0, 1) \
|
||||
F(TraceEnter, 0, 1) \
|
||||
F(TraceExit, 1, 1) \
|
||||
F(Abort, 2, 1) \
|
||||
/* Logging */ \
|
||||
F(Log, 2) \
|
||||
F(Log, 2, 1) \
|
||||
\
|
||||
/* Pseudo functions - handled as macros by parser */ \
|
||||
F(IS_VAR, 1)
|
||||
F(IS_VAR, 1, 1)
|
||||
|
||||
#ifdef ENABLE_DEBUGGER_SUPPORT
|
||||
#define RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F) \
|
||||
/* Debugger support*/ \
|
||||
F(DebugBreak, 0) \
|
||||
F(SetDebugEventListener, 2) \
|
||||
F(Break, 0) \
|
||||
F(DebugGetPropertyDetails, 2) \
|
||||
F(DebugGetProperty, 2) \
|
||||
F(DebugLocalPropertyNames, 1) \
|
||||
F(DebugLocalElementNames, 1) \
|
||||
F(DebugPropertyTypeFromDetails, 1) \
|
||||
F(DebugPropertyAttributesFromDetails, 1) \
|
||||
F(DebugPropertyIndexFromDetails, 1) \
|
||||
F(DebugInterceptorInfo, 1) \
|
||||
F(DebugNamedInterceptorPropertyNames, 1) \
|
||||
F(DebugIndexedInterceptorElementNames, 1) \
|
||||
F(DebugNamedInterceptorPropertyValue, 2) \
|
||||
F(DebugIndexedInterceptorElementValue, 2) \
|
||||
F(CheckExecutionState, 1) \
|
||||
F(GetFrameCount, 1) \
|
||||
F(GetFrameDetails, 2) \
|
||||
F(GetScopeCount, 2) \
|
||||
F(GetScopeDetails, 3) \
|
||||
F(DebugPrintScopes, 0) \
|
||||
F(GetCFrames, 1) \
|
||||
F(GetThreadCount, 1) \
|
||||
F(GetThreadDetails, 2) \
|
||||
F(GetBreakLocations, 1) \
|
||||
F(SetFunctionBreakPoint, 3) \
|
||||
F(SetScriptBreakPoint, 3) \
|
||||
F(ClearBreakPoint, 1) \
|
||||
F(ChangeBreakOnException, 2) \
|
||||
F(PrepareStep, 3) \
|
||||
F(ClearStepping, 0) \
|
||||
F(DebugEvaluate, 4) \
|
||||
F(DebugEvaluateGlobal, 3) \
|
||||
F(DebugGetLoadedScripts, 0) \
|
||||
F(DebugReferencedBy, 3) \
|
||||
F(DebugConstructedBy, 2) \
|
||||
F(DebugGetPrototype, 1) \
|
||||
F(SystemBreak, 0) \
|
||||
F(DebugDisassembleFunction, 1) \
|
||||
F(DebugDisassembleConstructor, 1) \
|
||||
F(FunctionGetInferredName, 1)
|
||||
F(DebugBreak, 0, 1) \
|
||||
F(SetDebugEventListener, 2, 1) \
|
||||
F(Break, 0, 1) \
|
||||
F(DebugGetPropertyDetails, 2, 1) \
|
||||
F(DebugGetProperty, 2, 1) \
|
||||
F(DebugLocalPropertyNames, 1, 1) \
|
||||
F(DebugLocalElementNames, 1, 1) \
|
||||
F(DebugPropertyTypeFromDetails, 1, 1) \
|
||||
F(DebugPropertyAttributesFromDetails, 1, 1) \
|
||||
F(DebugPropertyIndexFromDetails, 1, 1) \
|
||||
F(DebugInterceptorInfo, 1, 1) \
|
||||
F(DebugNamedInterceptorPropertyNames, 1, 1) \
|
||||
F(DebugIndexedInterceptorElementNames, 1, 1) \
|
||||
F(DebugNamedInterceptorPropertyValue, 2, 1) \
|
||||
F(DebugIndexedInterceptorElementValue, 2, 1) \
|
||||
F(CheckExecutionState, 1, 1) \
|
||||
F(GetFrameCount, 1, 1) \
|
||||
F(GetFrameDetails, 2, 1) \
|
||||
F(GetScopeCount, 2, 1) \
|
||||
F(GetScopeDetails, 3, 1) \
|
||||
F(DebugPrintScopes, 0, 1) \
|
||||
F(GetCFrames, 1, 1) \
|
||||
F(GetThreadCount, 1, 1) \
|
||||
F(GetThreadDetails, 2, 1) \
|
||||
F(GetBreakLocations, 1, 1) \
|
||||
F(SetFunctionBreakPoint, 3, 1) \
|
||||
F(SetScriptBreakPoint, 3, 1) \
|
||||
F(ClearBreakPoint, 1, 1) \
|
||||
F(ChangeBreakOnException, 2, 1) \
|
||||
F(PrepareStep, 3, 1) \
|
||||
F(ClearStepping, 0, 1) \
|
||||
F(DebugEvaluate, 4, 1) \
|
||||
F(DebugEvaluateGlobal, 3, 1) \
|
||||
F(DebugGetLoadedScripts, 0, 1) \
|
||||
F(DebugReferencedBy, 3, 1) \
|
||||
F(DebugConstructedBy, 2, 1) \
|
||||
F(DebugGetPrototype, 1, 1) \
|
||||
F(SystemBreak, 0, 1) \
|
||||
F(DebugDisassembleFunction, 1, 1) \
|
||||
F(DebugDisassembleConstructor, 1, 1) \
|
||||
F(FunctionGetInferredName, 1, 1)
|
||||
#else
|
||||
#define RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F)
|
||||
#endif
|
||||
@ -313,7 +313,7 @@ namespace internal {
|
||||
#ifdef DEBUG
|
||||
#define RUNTIME_FUNCTION_LIST_DEBUG(F) \
|
||||
/* Testing */ \
|
||||
F(ListNatives, 0)
|
||||
F(ListNatives, 0, 1)
|
||||
#else
|
||||
#define RUNTIME_FUNCTION_LIST_DEBUG(F)
|
||||
#endif
|
||||
@ -336,7 +336,7 @@ namespace internal {
|
||||
class Runtime : public AllStatic {
|
||||
public:
|
||||
enum FunctionId {
|
||||
#define F(name, nargs) k##name,
|
||||
#define F(name, nargs, ressize) k##name,
|
||||
RUNTIME_FUNCTION_LIST(F)
|
||||
kNofFunctions
|
||||
#undef F
|
||||
@ -357,6 +357,9 @@ class Runtime : public AllStatic {
|
||||
// arguments.
|
||||
int nargs;
|
||||
int stub_id;
|
||||
// Size of result, if complex (larger than a single pointer),
|
||||
// otherwise zero.
|
||||
int result_size;
|
||||
};
|
||||
|
||||
// Get the runtime function with the given function id.
|
||||
|
@ -541,7 +541,7 @@ void ExternalReferenceTable::PopulateTable() {
|
||||
#undef DEF_ENTRY_A
|
||||
|
||||
// Runtime functions
|
||||
#define RUNTIME_ENTRY(name, nargs) \
|
||||
#define RUNTIME_ENTRY(name, nargs, ressize) \
|
||||
{ RUNTIME_FUNCTION, \
|
||||
Runtime::k##name, \
|
||||
"Runtime::" #name },
|
||||
|
@ -44,7 +44,7 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id) {
|
||||
// rax, but JumpToBuiltin expects rax to contain the number of
|
||||
// arguments including the receiver.
|
||||
__ incq(rax);
|
||||
__ JumpToBuiltin(ExternalReference(id));
|
||||
__ JumpToBuiltin(ExternalReference(id), 1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -6829,7 +6829,8 @@ void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
|
||||
|
||||
// Do the runtime call to allocate the arguments object.
|
||||
__ bind(&runtime);
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3);
|
||||
Runtime::Function* f = Runtime::FunctionForId(Runtime::kNewArgumentsFast);
|
||||
__ TailCallRuntime(ExternalReference(f), 3, f->result_size);
|
||||
}
|
||||
|
||||
|
||||
@ -6891,7 +6892,9 @@ void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
|
||||
__ pop(rbx); // Return address.
|
||||
__ push(rdx);
|
||||
__ push(rbx);
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1);
|
||||
Runtime::Function* f =
|
||||
Runtime::FunctionForId(Runtime::kGetArgumentsProperty);
|
||||
__ TailCallRuntime(ExternalReference(f), 1, f->result_size);
|
||||
}
|
||||
|
||||
|
||||
@ -6915,6 +6918,23 @@ void ArgumentsAccessStub::GenerateReadLength(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
|
||||
int CEntryStub::MinorKey() {
|
||||
ASSERT(result_size_ <= 2);
|
||||
#ifdef _WIN64
|
||||
// Simple results returned in rax (using default code).
|
||||
// Complex results must be written to address passed as first argument.
|
||||
// Use even numbers for minor keys, reserving the odd numbers for
|
||||
// CEntryDebugBreakStub.
|
||||
return (result_size_ < 2) ? 0 : result_size_ * 2;
|
||||
#else
|
||||
// Single results returned in rax (both AMD64 and Win64 calling conventions)
|
||||
// and a struct of two pointers in rax+rdx (AMD64 calling convention only)
|
||||
// by default.
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
|
||||
// Check that stack should contain next handler, frame pointer, state and
|
||||
// return address in that order.
|
||||
@ -6986,8 +7006,18 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
|
||||
// Store Arguments object on stack, below the 4 WIN64 ABI parameter slots.
|
||||
__ movq(Operand(rsp, 4 * kPointerSize), r14); // argc.
|
||||
__ movq(Operand(rsp, 5 * kPointerSize), r15); // argv.
|
||||
// Pass a pointer to the Arguments object as the first argument.
|
||||
__ lea(rcx, Operand(rsp, 4 * kPointerSize));
|
||||
if (result_size_ < 2) {
|
||||
// Pass a pointer to the Arguments object as the first argument.
|
||||
// Return result in single register (rax).
|
||||
__ lea(rcx, Operand(rsp, 4 * kPointerSize));
|
||||
} else {
|
||||
ASSERT_EQ(2, result_size_);
|
||||
// Pass a pointer to the result location as the first argument.
|
||||
__ lea(rcx, Operand(rsp, 6 * kPointerSize));
|
||||
// Pass a pointer to the Arguments object as the second argument.
|
||||
__ lea(rdx, Operand(rsp, 4 * kPointerSize));
|
||||
}
|
||||
|
||||
#else // ! defined(_WIN64)
|
||||
// GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9.
|
||||
__ movq(rdi, r14); // argc.
|
||||
@ -7010,7 +7040,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
|
||||
__ j(zero, &failure_returned);
|
||||
|
||||
// Exit the JavaScript to C++ exit frame.
|
||||
__ LeaveExitFrame(frame_type);
|
||||
__ LeaveExitFrame(frame_type, result_size_);
|
||||
__ ret(0);
|
||||
|
||||
// Handling of failure.
|
||||
@ -7146,7 +7176,7 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) {
|
||||
StackFrame::EXIT;
|
||||
|
||||
// Enter the exit frame that transitions from JavaScript to C++.
|
||||
__ EnterExitFrame(frame_type);
|
||||
__ EnterExitFrame(frame_type, result_size_);
|
||||
|
||||
// rax: Holds the context at this point, but should not be used.
|
||||
// On entry to code generated by GenerateCore, it must hold
|
||||
@ -7333,7 +7363,8 @@ void StackCheckStub::Generate(MacroAssembler* masm) {
|
||||
__ push(rax);
|
||||
|
||||
// Do tail-call to runtime routine.
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kStackGuard), 1);
|
||||
Runtime::Function* f = Runtime::FunctionForId(Runtime::kStackGuard);
|
||||
__ TailCallRuntime(ExternalReference(f), 1, f->result_size);
|
||||
}
|
||||
|
||||
|
||||
|
@ -236,7 +236,7 @@ void KeyedLoadIC::Generate(MacroAssembler* masm,
|
||||
__ push(rbx); // return address
|
||||
|
||||
// Perform tail call to the entry.
|
||||
__ TailCallRuntime(f, 2);
|
||||
__ TailCallRuntime(f, 2, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -373,7 +373,7 @@ void KeyedStoreIC::Generate(MacroAssembler* masm, ExternalReference const& f) {
|
||||
__ push(rcx); // return address
|
||||
|
||||
// Do tail-call to runtime routine.
|
||||
__ TailCallRuntime(f, 3);
|
||||
__ TailCallRuntime(f, 3, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -394,7 +394,7 @@ void KeyedStoreIC::GenerateExtendStorage(MacroAssembler* masm) {
|
||||
|
||||
// Do tail-call to runtime routine.
|
||||
__ TailCallRuntime(
|
||||
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
|
||||
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -460,7 +460,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
|
||||
__ push(rax);
|
||||
__ push(rcx);
|
||||
// Do tail-call to runtime routine.
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3);
|
||||
__ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3, 1);
|
||||
|
||||
|
||||
// Extra capacity case: Check if there is extra capacity to
|
||||
@ -532,7 +532,7 @@ void CallIC::Generate(MacroAssembler* masm,
|
||||
__ push(rbx);
|
||||
|
||||
// Call the entry.
|
||||
CEntryStub stub;
|
||||
CEntryStub stub(1);
|
||||
__ movq(rax, Immediate(2));
|
||||
__ movq(rbx, f);
|
||||
__ CallStub(&stub);
|
||||
@ -763,7 +763,7 @@ void LoadIC::Generate(MacroAssembler* masm, ExternalReference const& f) {
|
||||
__ push(rbx); // return address
|
||||
|
||||
// Perform tail call to the entry.
|
||||
__ TailCallRuntime(f, 2);
|
||||
__ TailCallRuntime(f, 2, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -940,7 +940,7 @@ void StoreIC::Generate(MacroAssembler* masm, ExternalReference const& f) {
|
||||
__ push(rbx); // return address
|
||||
|
||||
// Perform tail call to the entry.
|
||||
__ TailCallRuntime(f, 3);
|
||||
__ TailCallRuntime(f, 3, 1);
|
||||
}
|
||||
|
||||
void StoreIC::GenerateExtendStorage(MacroAssembler* masm) {
|
||||
@ -959,7 +959,7 @@ void StoreIC::GenerateExtendStorage(MacroAssembler* masm) {
|
||||
|
||||
// Perform tail call to the entry.
|
||||
__ TailCallRuntime(
|
||||
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
|
||||
ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3, 1);
|
||||
}
|
||||
|
||||
void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
|
||||
|
@ -318,7 +318,8 @@ void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
|
||||
|
||||
|
||||
void MacroAssembler::TailCallRuntime(ExternalReference const& ext,
|
||||
int num_arguments) {
|
||||
int num_arguments,
|
||||
int result_size) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- rsp[0] : return address
|
||||
// -- rsp[8] : argument num_arguments - 1
|
||||
@ -331,14 +332,15 @@ void MacroAssembler::TailCallRuntime(ExternalReference const& ext,
|
||||
// should remove this need and make the runtime routine entry code
|
||||
// smarter.
|
||||
movq(rax, Immediate(num_arguments));
|
||||
JumpToBuiltin(ext);
|
||||
JumpToBuiltin(ext, result_size);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::JumpToBuiltin(const ExternalReference& ext) {
|
||||
void MacroAssembler::JumpToBuiltin(const ExternalReference& ext,
|
||||
int result_size) {
|
||||
// Set the entry point and jump to the C entry runtime stub.
|
||||
movq(rbx, ext);
|
||||
CEntryStub ces;
|
||||
CEntryStub ces(result_size);
|
||||
movq(kScratchRegister, ces.GetCode(), RelocInfo::CODE_TARGET);
|
||||
jmp(kScratchRegister);
|
||||
}
|
||||
@ -971,7 +973,7 @@ void MacroAssembler::LeaveFrame(StackFrame::Type type) {
|
||||
|
||||
|
||||
|
||||
void MacroAssembler::EnterExitFrame(StackFrame::Type type) {
|
||||
void MacroAssembler::EnterExitFrame(StackFrame::Type type, int result_size) {
|
||||
ASSERT(type == StackFrame::EXIT || type == StackFrame::EXIT_DEBUG);
|
||||
|
||||
// Setup the frame structure on the stack.
|
||||
@ -1016,6 +1018,21 @@ void MacroAssembler::EnterExitFrame(StackFrame::Type type) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WIN64
|
||||
// Reserve space on stack for result and argument structures, if necessary.
|
||||
int result_stack_space = (result_size < 2) ? 0 : result_size * kPointerSize;
|
||||
// Reserve space for the Arguments object. The Windows 64-bit ABI
|
||||
// requires us to pass this structure as a pointer to its location on
|
||||
// the stack. The structure contains 2 values.
|
||||
int argument_stack_space = 2 * kPointerSize;
|
||||
// We also need backing space for 4 parameters, even though
|
||||
// we only pass one or two parameter, and it is in a register.
|
||||
int argument_mirror_space = 4 * kPointerSize;
|
||||
int total_stack_space =
|
||||
argument_mirror_space + argument_stack_space + result_stack_space;
|
||||
subq(rsp, Immediate(total_stack_space));
|
||||
#endif
|
||||
|
||||
// Get the required frame alignment for the OS.
|
||||
static const int kFrameAlignment = OS::ActivationFrameAlignment();
|
||||
if (kFrameAlignment > 0) {
|
||||
@ -1024,30 +1041,19 @@ void MacroAssembler::EnterExitFrame(StackFrame::Type type) {
|
||||
and_(rsp, kScratchRegister);
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
// Reserve space for the Arguments object. The Windows 64-bit ABI
|
||||
// requires us to pass this structure as a pointer to its location on
|
||||
// the stack. The structure contains 2 pointers.
|
||||
// The structure on the stack must be 16-byte aligned.
|
||||
// We also need backing space for 4 parameters, even though
|
||||
// we only pass one parameter, and it is in a register.
|
||||
subq(rsp, Immediate(6 * kPointerSize));
|
||||
ASSERT(kFrameAlignment == 2 * kPointerSize); // Change the padding if needed.
|
||||
#endif
|
||||
|
||||
// Patch the saved entry sp.
|
||||
movq(Operand(rbp, ExitFrameConstants::kSPOffset), rsp);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::LeaveExitFrame(StackFrame::Type type) {
|
||||
void MacroAssembler::LeaveExitFrame(StackFrame::Type type, int result_size) {
|
||||
// Registers:
|
||||
// r15 : argv
|
||||
#ifdef ENABLE_DEBUGGER_SUPPORT
|
||||
// Restore the memory copy of the registers by digging them out from
|
||||
// the stack. This is needed to allow nested break points.
|
||||
if (type == StackFrame::EXIT_DEBUG) {
|
||||
// It's okay to clobber register ebx below because we don't need
|
||||
// It's okay to clobber register rbx below because we don't need
|
||||
// the function pointer after this.
|
||||
const int kCallerSavedSize = kNumJSCallerSaved * kPointerSize;
|
||||
int kOffset = ExitFrameConstants::kDebugMarkOffset - kCallerSavedSize;
|
||||
@ -1060,7 +1066,18 @@ void MacroAssembler::LeaveExitFrame(StackFrame::Type type) {
|
||||
movq(rcx, Operand(rbp, 1 * kPointerSize));
|
||||
movq(rbp, Operand(rbp, 0 * kPointerSize));
|
||||
|
||||
// Pop the arguments and the receiver from the caller stack.
|
||||
#ifdef _WIN64
|
||||
// If return value is on the stack, pop it to registers.
|
||||
if (result_size > 1) {
|
||||
ASSERT_EQ(2, result_size);
|
||||
// Position above 4 argument mirrors and arguments object.
|
||||
movq(rax, Operand(rsp, 6 * kPointerSize));
|
||||
movq(rdx, Operand(rsp, 7 * kPointerSize));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Pop everything up to and including the arguments and the receiver
|
||||
// from the caller stack.
|
||||
lea(rsp, Operand(r15, 1 * kPointerSize));
|
||||
|
||||
// Restore current context from top and clear it in debug mode.
|
||||
|
@ -87,15 +87,15 @@ class MacroAssembler: public Assembler {
|
||||
void LeaveConstructFrame() { LeaveFrame(StackFrame::CONSTRUCT); }
|
||||
|
||||
// Enter specific kind of exit frame; either EXIT or
|
||||
// EXIT_DEBUG. Expects the number of arguments in register eax and
|
||||
// sets up the number of arguments in register edi and the pointer
|
||||
// to the first argument in register esi.
|
||||
void EnterExitFrame(StackFrame::Type type);
|
||||
// EXIT_DEBUG. Expects the number of arguments in register rax and
|
||||
// sets up the number of arguments in register rdi and the pointer
|
||||
// to the first argument in register rsi.
|
||||
void EnterExitFrame(StackFrame::Type type, int result_size = 1);
|
||||
|
||||
// Leave the current exit frame. Expects the return value in
|
||||
// register eax:edx (untouched) and the pointer to the first
|
||||
// argument in register esi.
|
||||
void LeaveExitFrame(StackFrame::Type type);
|
||||
// Leave the current exit frame. Expects/provides the return value in
|
||||
// register rax:rdx (untouched) and the pointer to the first
|
||||
// argument in register rsi.
|
||||
void LeaveExitFrame(StackFrame::Type type, int result_size = 1);
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@ -298,10 +298,12 @@ class MacroAssembler: public Assembler {
|
||||
// Tail call of a runtime routine (jump).
|
||||
// Like JumpToBuiltin, but also takes care of passing the number
|
||||
// of arguments.
|
||||
void TailCallRuntime(const ExternalReference& ext, int num_arguments);
|
||||
void TailCallRuntime(const ExternalReference& ext,
|
||||
int num_arguments,
|
||||
int result_size);
|
||||
|
||||
// Jump to the builtin routine.
|
||||
void JumpToBuiltin(const ExternalReference& ext);
|
||||
void JumpToBuiltin(const ExternalReference& ext, int result_size);
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -612,7 +612,7 @@ Handle<Object> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
|
||||
// MSVC passes arguments in rcx, rdx, r8, r9, with backing stack slots.
|
||||
// Store register parameters in pre-allocated stack slots,
|
||||
__ movq(Operand(rbp, kInputString), rcx);
|
||||
__ movzxlq(Operand(rbp, kStartIndex), rdx); // Passed as int in eax.
|
||||
__ movq(Operand(rbp, kStartIndex), rdx); // Passed as int32 in edx.
|
||||
__ movq(Operand(rbp, kInputStart), r8);
|
||||
__ movq(Operand(rbp, kInputEnd), r9);
|
||||
// Callee-save on Win64.
|
||||
|
@ -354,7 +354,7 @@ static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm,
|
||||
__ movq(rax, Immediate(5));
|
||||
__ movq(rbx, ref);
|
||||
|
||||
CEntryStub stub;
|
||||
CEntryStub stub(1);
|
||||
__ CallStub(&stub);
|
||||
}
|
||||
|
||||
@ -489,7 +489,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
|
||||
|
||||
ExternalReference ref =
|
||||
ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
|
||||
__ TailCallRuntime(ref, 5);
|
||||
__ TailCallRuntime(ref, 5, 1);
|
||||
|
||||
__ bind(&cleanup);
|
||||
__ pop(scratch1);
|
||||
@ -511,7 +511,7 @@ class LoadInterceptorCompiler BASE_EMBEDDED {
|
||||
|
||||
ExternalReference ref = ExternalReference(
|
||||
IC_Utility(IC::kLoadPropertyWithInterceptorForLoad));
|
||||
__ TailCallRuntime(ref, 5);
|
||||
__ TailCallRuntime(ref, 5, 1);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -661,7 +661,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
|
||||
__ movq(rax, Immediate(5));
|
||||
__ movq(rbx, ref);
|
||||
|
||||
CEntryStub stub;
|
||||
CEntryStub stub(1);
|
||||
__ CallStub(&stub);
|
||||
|
||||
__ LeaveInternalFrame();
|
||||
@ -1362,7 +1362,7 @@ Object* StoreStubCompiler::CompileStoreCallback(JSObject* object,
|
||||
// Do tail-call to the runtime system.
|
||||
ExternalReference store_callback_property =
|
||||
ExternalReference(IC_Utility(IC::kStoreCallbackProperty));
|
||||
__ TailCallRuntime(store_callback_property, 4);
|
||||
__ TailCallRuntime(store_callback_property, 4, 1);
|
||||
|
||||
// Handle store cache miss.
|
||||
__ bind(&miss);
|
||||
@ -1450,7 +1450,7 @@ Object* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
|
||||
// Do tail-call to the runtime system.
|
||||
ExternalReference store_ic_property =
|
||||
ExternalReference(IC_Utility(IC::kStoreInterceptorProperty));
|
||||
__ TailCallRuntime(store_ic_property, 3);
|
||||
__ TailCallRuntime(store_ic_property, 3, 1);
|
||||
|
||||
// Handle store cache miss.
|
||||
__ bind(&miss);
|
||||
@ -1652,7 +1652,7 @@ void StubCompiler::GenerateLoadCallback(JSObject* object,
|
||||
// Do tail-call to the runtime system.
|
||||
ExternalReference load_callback_property =
|
||||
ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
|
||||
__ TailCallRuntime(load_callback_property, 5);
|
||||
__ TailCallRuntime(load_callback_property, 5, 1);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user