OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 2004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2015 // eval-introduced variables. Eval is used a lot without | 2015 // eval-introduced variables. Eval is used a lot without |
2016 // introducing variables. In those cases, we do not want to | 2016 // introducing variables. In those cases, we do not want to |
2017 // perform a runtime call for all variables in the scope | 2017 // perform a runtime call for all variables in the scope |
2018 // containing the eval. | 2018 // containing the eval. |
2019 if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) { | 2019 if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) { |
2020 LoadFromGlobalSlotCheckExtensions(slot, typeof_state, r1, r2, &slow); | 2020 LoadFromGlobalSlotCheckExtensions(slot, typeof_state, r1, r2, &slow); |
2021 __ b(&done); | 2021 __ b(&done); |
2022 | 2022 |
2023 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) { | 2023 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) { |
2024 Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot(); | 2024 Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot(); |
2025 __ ldr(r0, | 2025 // Only generate the fast case for locals that rewrite to slots. |
2026 ContextSlotOperandCheckExtensions(potential_slot, | 2026 // This rules out argument loads. |
2027 r1, | 2027 if (potential_slot != NULL) { |
2028 r2, | 2028 __ ldr(r0, |
2029 &slow)); | 2029 ContextSlotOperandCheckExtensions(potential_slot, |
2030 __ b(&done); | 2030 r1, |
| 2031 r2, |
| 2032 &slow)); |
| 2033 __ b(&done); |
| 2034 } |
2031 } | 2035 } |
2032 | 2036 |
2033 __ bind(&slow); | 2037 __ bind(&slow); |
2034 frame_->Push(cp); | 2038 frame_->Push(cp); |
2035 __ mov(r0, Operand(slot->var()->name())); | 2039 __ mov(r0, Operand(slot->var()->name())); |
2036 frame_->Push(r0); | 2040 frame_->Push(r0); |
2037 | 2041 |
2038 if (typeof_state == INSIDE_TYPEOF) { | 2042 if (typeof_state == INSIDE_TYPEOF) { |
2039 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); | 2043 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); |
2040 } else { | 2044 } else { |
(...skipping 26 matching lines...) Expand all Loading... |
2067 | 2071 |
2068 | 2072 |
2069 void CodeGenerator::LoadFromGlobalSlotCheckExtensions(Slot* slot, | 2073 void CodeGenerator::LoadFromGlobalSlotCheckExtensions(Slot* slot, |
2070 TypeofState typeof_state, | 2074 TypeofState typeof_state, |
2071 Register tmp, | 2075 Register tmp, |
2072 Register tmp2, | 2076 Register tmp2, |
2073 Label* slow) { | 2077 Label* slow) { |
2074 // Check that no extension objects have been created by calls to | 2078 // Check that no extension objects have been created by calls to |
2075 // eval from the current scope to the global scope. | 2079 // eval from the current scope to the global scope. |
2076 Register context = cp; | 2080 Register context = cp; |
2077 for (Scope* s = scope(); s != NULL; s = s->outer_scope()) { | 2081 Scope* s = scope(); |
| 2082 while (s != NULL) { |
2078 if (s->num_heap_slots() > 0) { | 2083 if (s->num_heap_slots() > 0) { |
2079 if (s->calls_eval()) { | 2084 if (s->calls_eval()) { |
2080 // Check that extension is NULL. | 2085 // Check that extension is NULL. |
2081 __ ldr(tmp2, ContextOperand(context, Context::EXTENSION_INDEX)); | 2086 __ ldr(tmp2, ContextOperand(context, Context::EXTENSION_INDEX)); |
2082 __ tst(tmp2, tmp2); | 2087 __ tst(tmp2, tmp2); |
2083 __ b(ne, slow); | 2088 __ b(ne, slow); |
2084 } | 2089 } |
2085 // Load next context in chain. | 2090 // Load next context in chain. |
2086 __ ldr(tmp, ContextOperand(context, Context::CLOSURE_INDEX)); | 2091 __ ldr(tmp, ContextOperand(context, Context::CLOSURE_INDEX)); |
2087 __ ldr(tmp, FieldMemOperand(tmp, JSFunction::kContextOffset)); | 2092 __ ldr(tmp, FieldMemOperand(tmp, JSFunction::kContextOffset)); |
2088 context = tmp; | 2093 context = tmp; |
2089 } | 2094 } |
2090 // If no outer scope calls eval, we do not need to check more | 2095 // If no outer scope calls eval, we do not need to check more |
2091 // context extensions. | 2096 // context extensions. |
2092 if (!s->outer_scope_calls_eval()) break; | 2097 if (!s->outer_scope_calls_eval() || s->is_eval_scope()) break; |
| 2098 s = s->outer_scope(); |
| 2099 } |
| 2100 |
| 2101 if (s->is_eval_scope()) { |
| 2102 Label next, fast; |
| 2103 if (!context.is(tmp)) __ mov(tmp, Operand(context)); |
| 2104 __ bind(&next); |
| 2105 // Terminate at global context. |
| 2106 __ ldr(tmp2, FieldMemOperand(tmp, HeapObject::kMapOffset)); |
| 2107 __ cmp(tmp2, Operand(Factory::global_context_map())); |
| 2108 __ b(eq, &fast); |
| 2109 // Check that extension is NULL. |
| 2110 __ ldr(tmp2, ContextOperand(tmp, Context::EXTENSION_INDEX)); |
| 2111 __ tst(tmp2, tmp2); |
| 2112 __ b(ne, slow); |
| 2113 // Load next context in chain. |
| 2114 __ ldr(tmp, ContextOperand(tmp, Context::CLOSURE_INDEX)); |
| 2115 __ ldr(tmp, FieldMemOperand(tmp, JSFunction::kContextOffset)); |
| 2116 __ b(&next); |
| 2117 __ bind(&fast); |
2093 } | 2118 } |
2094 | 2119 |
2095 // All extension objects were empty and it is safe to use a global | 2120 // All extension objects were empty and it is safe to use a global |
2096 // load IC call. | 2121 // load IC call. |
2097 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 2122 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
2098 // Load the global object. | 2123 // Load the global object. |
2099 LoadGlobal(); | 2124 LoadGlobal(); |
2100 // Setup the name register. | 2125 // Setup the name register. |
2101 __ mov(r2, Operand(slot->var()->name())); | 2126 __ mov(r2, Operand(slot->var()->name())); |
2102 // Call IC stub. | 2127 // Call IC stub. |
(...skipping 2350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4453 __ mov(r2, Operand(0)); | 4478 __ mov(r2, Operand(0)); |
4454 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); | 4479 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); |
4455 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), | 4480 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), |
4456 RelocInfo::CODE_TARGET); | 4481 RelocInfo::CODE_TARGET); |
4457 } | 4482 } |
4458 | 4483 |
4459 | 4484 |
4460 #undef __ | 4485 #undef __ |
4461 | 4486 |
4462 } } // namespace v8::internal | 4487 } } // namespace v8::internal |
OLD | NEW |