| Index: src/ic-ia32.cc
|
| ===================================================================
|
| --- src/ic-ia32.cc (revision 784)
|
| +++ src/ic-ia32.cc (working copy)
|
| @@ -41,7 +41,7 @@
|
| #define __ masm->
|
|
|
|
|
| -// Helper function used from LoadIC/CallIC GenerateNormal.
|
| +// Helper function used to load a property from a dictionary backing storage.
|
| static void GenerateDictionaryLoad(MacroAssembler* masm, Label* miss_label,
|
| Register r0, Register r1, Register r2,
|
| Register name) {
|
| @@ -121,6 +121,29 @@
|
| }
|
|
|
|
|
| +// Helper function used to check that a value is either not a function
|
| +// or is loaded if it is a function.
|
| +static void GenerateCheckNonFunctionOrLoaded(MacroAssembler* masm, Label* miss,
|
| + Register value, Register scratch) {
|
| + Label done;
|
| + // Check if the value is a Smi.
|
| + __ test(value, Immediate(kSmiTagMask));
|
| + __ j(zero, &done, not_taken);
|
| + // Check if the value is a function.
|
| + __ mov(scratch, FieldOperand(value, HeapObject::kMapOffset));
|
| + __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
|
| + __ cmp(scratch, JS_FUNCTION_TYPE);
|
| + __ j(not_equal, &done, taken);
|
| + // Check if the function has been loaded.
|
| + __ mov(scratch, FieldOperand(value, JSFunction::kSharedFunctionInfoOffset));
|
| + __ mov(scratch,
|
| + FieldOperand(scratch, SharedFunctionInfo::kLazyLoadDataOffset));
|
| + __ cmp(scratch, Factory::undefined_value());
|
| + __ j(not_equal, miss, not_taken);
|
| + __ bind(&done);
|
| +}
|
| +
|
| +
|
| void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
|
| // ----------- S t a t e -------------
|
| // -- ecx : name
|
| @@ -236,6 +259,7 @@
|
| __ j(not_zero, &slow, not_taken);
|
| // Probe the dictionary leaving result in ecx.
|
| GenerateDictionaryLoad(masm, &slow, ebx, ecx, edx, eax);
|
| + GenerateCheckNonFunctionOrLoaded(masm, &slow, ecx, edx);
|
| __ mov(eax, Operand(ecx));
|
| __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1);
|
| __ ret(0);
|
| @@ -456,6 +480,12 @@
|
| __ cmp(edx, JS_FUNCTION_TYPE);
|
| __ j(not_equal, miss, not_taken);
|
|
|
| + // Check that the function has been loaded.
|
| + __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
|
| + __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kLazyLoadDataOffset));
|
| + __ cmp(edx, Factory::undefined_value());
|
| + __ 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));
|
| @@ -627,6 +657,7 @@
|
| // Search the dictionary placing the result in eax.
|
| __ bind(&probe);
|
| GenerateDictionaryLoad(masm, &miss, edx, eax, ebx, ecx);
|
| + GenerateCheckNonFunctionOrLoaded(masm, &miss, eax, edx);
|
| __ ret(0);
|
|
|
| // Global object access: Check access rights.
|
|
|