| Index: src/ic-ia32.cc
|
| ===================================================================
|
| --- src/ic-ia32.cc (revision 599)
|
| +++ src/ic-ia32.cc (working copy)
|
| @@ -472,11 +472,42 @@
|
| }
|
|
|
|
|
| +static void GenerateNormalHelper(MacroAssembler* masm,
|
| + int argc,
|
| + bool is_global_object,
|
| + Label* miss) {
|
| + // Search dictionary - put result in register edx.
|
| + GenerateDictionaryLoad(masm, miss, eax, edx, ebx, ecx);
|
| +
|
| + // Move the result to register edi and check that it isn't a smi.
|
| + __ mov(edi, Operand(edx));
|
| + __ test(edx, Immediate(kSmiTagMask));
|
| + __ j(zero, miss, not_taken);
|
| +
|
| + // Check that the value is a JavaScript function.
|
| + __ mov(edx, FieldOperand(edx, HeapObject::kMapOffset));
|
| + __ movzx_b(edx, FieldOperand(edx, Map::kInstanceTypeOffset));
|
| + __ cmp(edx, JS_FUNCTION_TYPE);
|
| + __ j(not_equal, miss, not_taken);
|
| +
|
| + // Patch the receiver with the global proxy if necessary.
|
| + if (is_global_object) {
|
| + __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
|
| + __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
|
| + __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
|
| + }
|
| +
|
| + // Invoke the function.
|
| + ParameterCount actual(argc);
|
| + __ InvokeFunction(edi, actual, JUMP_FUNCTION);
|
| +}
|
| +
|
| +
|
| void CallIC::GenerateNormal(MacroAssembler* masm, int argc) {
|
| // ----------- S t a t e -------------
|
| // -----------------------------------
|
|
|
| - Label miss, probe, global;
|
| + Label miss, global_object, non_global_object;
|
|
|
| // Get the receiver of the function from the stack; 1 ~ return address.
|
| __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
|
| @@ -496,36 +527,28 @@
|
| // If this assert fails, we have to check upper bound too.
|
| ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
|
|
|
| - // Check for access to global proxy.
|
| - __ cmp(eax, JS_GLOBAL_PROXY_TYPE);
|
| - __ j(equal, &global, not_taken);
|
| + // Check for access to global object.
|
| + __ cmp(eax, JS_GLOBAL_OBJECT_TYPE);
|
| + __ j(equal, &global_object);
|
| + __ cmp(eax, JS_BUILTINS_OBJECT_TYPE);
|
| + __ j(not_equal, &non_global_object);
|
|
|
| - // Search the dictionary placing the result in edx.
|
| - __ bind(&probe);
|
| - GenerateDictionaryLoad(masm, &miss, eax, edx, ebx, ecx);
|
| + // Accessing global object: Load and invoke.
|
| + __ bind(&global_object);
|
| + GenerateNormalHelper(masm, argc, true, &miss);
|
|
|
| - // Move the result to register edi and check that it isn't a smi.
|
| - __ mov(edi, Operand(edx));
|
| - __ test(edx, Immediate(kSmiTagMask));
|
| - __ j(zero, &miss, not_taken);
|
| + // Accessing non-global object: Check for access to global proxy.
|
| + Label global_proxy, invoke;
|
| + __ bind(&non_global_object);
|
| + __ cmp(eax, JS_GLOBAL_PROXY_TYPE);
|
| + __ j(equal, &global_proxy, not_taken);
|
| + __ bind(&invoke);
|
| + GenerateNormalHelper(masm, argc, false, &miss);
|
|
|
| - // Check that the value is a JavaScript function.
|
| - __ mov(edx, FieldOperand(edx, HeapObject::kMapOffset));
|
| - __ movzx_b(edx, FieldOperand(edx, Map::kInstanceTypeOffset));
|
| - __ cmp(edx, JS_FUNCTION_TYPE);
|
| - __ j(not_equal, &miss, not_taken);
|
| -
|
| - // TODO(120): Check for access to global object. Needs patching of
|
| - // receiver but no security check.
|
| -
|
| - // Invoke the function.
|
| - ParameterCount actual(argc);
|
| - __ InvokeFunction(edi, actual, JUMP_FUNCTION);
|
| -
|
| // Global object proxy access: Check access rights.
|
| - __ bind(&global);
|
| + __ bind(&global_proxy);
|
| __ CheckAccessGlobalProxy(edx, eax, &miss);
|
| - __ jmp(&probe);
|
| + __ jmp(&invoke);
|
|
|
| // Cache miss: Jump to runtime.
|
| __ bind(&miss);
|
| @@ -562,11 +585,26 @@
|
| __ mov(Operand(edi), eax);
|
| __ LeaveInternalFrame();
|
|
|
| - // TODO(120): Check for access to to global object. Needs patching
|
| - // of receiver but no security check.
|
| + // Check if the receiver is a global object of some sort.
|
| + Label invoke, global;
|
| + __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); // receiver
|
| + __ test(edx, Immediate(kSmiTagMask));
|
| + __ j(zero, &invoke, not_taken);
|
| + __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
|
| + __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
|
| + __ cmp(ecx, JS_GLOBAL_OBJECT_TYPE);
|
| + __ j(equal, &global);
|
| + __ cmp(ecx, JS_BUILTINS_OBJECT_TYPE);
|
| + __ j(not_equal, &invoke);
|
|
|
| + // Patch the receiver on the stack.
|
| + __ bind(&global);
|
| + __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
|
| + __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
|
| +
|
| // Invoke the function.
|
| ParameterCount actual(argc);
|
| + __ bind(&invoke);
|
| __ InvokeFunction(edi, actual, JUMP_FUNCTION);
|
| }
|
|
|
|
|