| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_ARM | 7 #if V8_TARGET_ARCH_ARM |
| 8 | 8 |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 | 190 |
| 191 // Possibly allocate a local context. | 191 // Possibly allocate a local context. |
| 192 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 192 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
| 193 if (heap_slots > 0) { | 193 if (heap_slots > 0) { |
| 194 // Argument to NewContext is the function, which is still in r1. | 194 // Argument to NewContext is the function, which is still in r1. |
| 195 Comment cmnt(masm_, "[ Allocate context"); | 195 Comment cmnt(masm_, "[ Allocate context"); |
| 196 bool need_write_barrier = true; | 196 bool need_write_barrier = true; |
| 197 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { | 197 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { |
| 198 __ push(r1); | 198 __ push(r1); |
| 199 __ Push(info->scope()->GetScopeInfo()); | 199 __ Push(info->scope()->GetScopeInfo()); |
| 200 __ CallRuntime(Runtime::kHiddenNewGlobalContext, 2); | 200 __ CallRuntime(Runtime::kNewGlobalContext, 2); |
| 201 } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { | 201 } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { |
| 202 FastNewContextStub stub(isolate(), heap_slots); | 202 FastNewContextStub stub(isolate(), heap_slots); |
| 203 __ CallStub(&stub); | 203 __ CallStub(&stub); |
| 204 // Result of FastNewContextStub is always in new space. | 204 // Result of FastNewContextStub is always in new space. |
| 205 need_write_barrier = false; | 205 need_write_barrier = false; |
| 206 } else { | 206 } else { |
| 207 __ push(r1); | 207 __ push(r1); |
| 208 __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); | 208 __ CallRuntime(Runtime::kNewFunctionContext, 1); |
| 209 } | 209 } |
| 210 function_in_register = false; | 210 function_in_register = false; |
| 211 // Context is returned in r0. It replaces the context passed to us. | 211 // Context is returned in r0. It replaces the context passed to us. |
| 212 // It's saved in the stack and kept live in cp. | 212 // It's saved in the stack and kept live in cp. |
| 213 __ mov(cp, r0); | 213 __ mov(cp, r0); |
| 214 __ str(r0, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 214 __ str(r0, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 215 // Copy any necessary parameters into the context. | 215 // Copy any necessary parameters into the context. |
| 216 int num_parameters = info->scope()->num_parameters(); | 216 int num_parameters = info->scope()->num_parameters(); |
| 217 for (int i = 0; i < num_parameters; i++) { | 217 for (int i = 0; i < num_parameters; i++) { |
| 218 Variable* var = scope()->parameter(i); | 218 Variable* var = scope()->parameter(i); |
| (...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 834 // Note: For variables we must not push an initial value (such as | 834 // Note: For variables we must not push an initial value (such as |
| 835 // 'undefined') because we may have a (legal) redeclaration and we | 835 // 'undefined') because we may have a (legal) redeclaration and we |
| 836 // must not destroy the current value. | 836 // must not destroy the current value. |
| 837 if (hole_init) { | 837 if (hole_init) { |
| 838 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); | 838 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); |
| 839 __ Push(cp, r2, r1, r0); | 839 __ Push(cp, r2, r1, r0); |
| 840 } else { | 840 } else { |
| 841 __ mov(r0, Operand(Smi::FromInt(0))); // Indicates no initial value. | 841 __ mov(r0, Operand(Smi::FromInt(0))); // Indicates no initial value. |
| 842 __ Push(cp, r2, r1, r0); | 842 __ Push(cp, r2, r1, r0); |
| 843 } | 843 } |
| 844 __ CallRuntime(Runtime::kHiddenDeclareContextSlot, 4); | 844 __ CallRuntime(Runtime::kDeclareContextSlot, 4); |
| 845 break; | 845 break; |
| 846 } | 846 } |
| 847 } | 847 } |
| 848 } | 848 } |
| 849 | 849 |
| 850 | 850 |
| 851 void FullCodeGenerator::VisitFunctionDeclaration( | 851 void FullCodeGenerator::VisitFunctionDeclaration( |
| 852 FunctionDeclaration* declaration) { | 852 FunctionDeclaration* declaration) { |
| 853 VariableProxy* proxy = declaration->proxy(); | 853 VariableProxy* proxy = declaration->proxy(); |
| 854 Variable* variable = proxy->var(); | 854 Variable* variable = proxy->var(); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 890 break; | 890 break; |
| 891 } | 891 } |
| 892 | 892 |
| 893 case Variable::LOOKUP: { | 893 case Variable::LOOKUP: { |
| 894 Comment cmnt(masm_, "[ FunctionDeclaration"); | 894 Comment cmnt(masm_, "[ FunctionDeclaration"); |
| 895 __ mov(r2, Operand(variable->name())); | 895 __ mov(r2, Operand(variable->name())); |
| 896 __ mov(r1, Operand(Smi::FromInt(NONE))); | 896 __ mov(r1, Operand(Smi::FromInt(NONE))); |
| 897 __ Push(cp, r2, r1); | 897 __ Push(cp, r2, r1); |
| 898 // Push initial value for function declaration. | 898 // Push initial value for function declaration. |
| 899 VisitForStackValue(declaration->fun()); | 899 VisitForStackValue(declaration->fun()); |
| 900 __ CallRuntime(Runtime::kHiddenDeclareContextSlot, 4); | 900 __ CallRuntime(Runtime::kDeclareContextSlot, 4); |
| 901 break; | 901 break; |
| 902 } | 902 } |
| 903 } | 903 } |
| 904 } | 904 } |
| 905 | 905 |
| 906 | 906 |
| 907 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { | 907 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { |
| 908 Variable* variable = declaration->proxy()->var(); | 908 Variable* variable = declaration->proxy()->var(); |
| 909 ASSERT(variable->location() == Variable::CONTEXT); | 909 ASSERT(variable->location() == Variable::CONTEXT); |
| 910 ASSERT(variable->interface()->IsFrozen()); | 910 ASSERT(variable->interface()->IsFrozen()); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 // TODO(rossberg) | 962 // TODO(rossberg) |
| 963 } | 963 } |
| 964 | 964 |
| 965 | 965 |
| 966 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 966 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
| 967 // Call the runtime to declare the globals. | 967 // Call the runtime to declare the globals. |
| 968 // The context is the first argument. | 968 // The context is the first argument. |
| 969 __ mov(r1, Operand(pairs)); | 969 __ mov(r1, Operand(pairs)); |
| 970 __ mov(r0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); | 970 __ mov(r0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); |
| 971 __ Push(cp, r1, r0); | 971 __ Push(cp, r1, r0); |
| 972 __ CallRuntime(Runtime::kHiddenDeclareGlobals, 3); | 972 __ CallRuntime(Runtime::kDeclareGlobals, 3); |
| 973 // Return value is ignored. | 973 // Return value is ignored. |
| 974 } | 974 } |
| 975 | 975 |
| 976 | 976 |
| 977 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) { | 977 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) { |
| 978 // Call the runtime to declare the modules. | 978 // Call the runtime to declare the modules. |
| 979 __ Push(descriptions); | 979 __ Push(descriptions); |
| 980 __ CallRuntime(Runtime::kHiddenDeclareModules, 1); | 980 __ CallRuntime(Runtime::kDeclareModules, 1); |
| 981 // Return value is ignored. | 981 // Return value is ignored. |
| 982 } | 982 } |
| 983 | 983 |
| 984 | 984 |
| 985 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { | 985 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { |
| 986 Comment cmnt(masm_, "[ SwitchStatement"); | 986 Comment cmnt(masm_, "[ SwitchStatement"); |
| 987 Breakable nested_statement(this, stmt); | 987 Breakable nested_statement(this, stmt); |
| 988 SetStatementPosition(stmt); | 988 SetStatementPosition(stmt); |
| 989 | 989 |
| 990 // Keep the switch value on the stack until a case matches. | 990 // Keep the switch value on the stack until a case matches. |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1322 FastNewClosureStub stub(isolate(), | 1322 FastNewClosureStub stub(isolate(), |
| 1323 info->strict_mode(), | 1323 info->strict_mode(), |
| 1324 info->is_generator()); | 1324 info->is_generator()); |
| 1325 __ mov(r2, Operand(info)); | 1325 __ mov(r2, Operand(info)); |
| 1326 __ CallStub(&stub); | 1326 __ CallStub(&stub); |
| 1327 } else { | 1327 } else { |
| 1328 __ mov(r0, Operand(info)); | 1328 __ mov(r0, Operand(info)); |
| 1329 __ LoadRoot(r1, pretenure ? Heap::kTrueValueRootIndex | 1329 __ LoadRoot(r1, pretenure ? Heap::kTrueValueRootIndex |
| 1330 : Heap::kFalseValueRootIndex); | 1330 : Heap::kFalseValueRootIndex); |
| 1331 __ Push(cp, r0, r1); | 1331 __ Push(cp, r0, r1); |
| 1332 __ CallRuntime(Runtime::kHiddenNewClosure, 3); | 1332 __ CallRuntime(Runtime::kNewClosure, 3); |
| 1333 } | 1333 } |
| 1334 context()->Plug(r0); | 1334 context()->Plug(r0); |
| 1335 } | 1335 } |
| 1336 | 1336 |
| 1337 | 1337 |
| 1338 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { | 1338 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
| 1339 Comment cmnt(masm_, "[ VariableProxy"); | 1339 Comment cmnt(masm_, "[ VariableProxy"); |
| 1340 EmitVariableLoad(expr); | 1340 EmitVariableLoad(expr); |
| 1341 } | 1341 } |
| 1342 | 1342 |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1447 __ ldr(r0, ContextSlotOperandCheckExtensions(local, slow)); | 1447 __ ldr(r0, ContextSlotOperandCheckExtensions(local, slow)); |
| 1448 if (local->mode() == LET || local->mode() == CONST || | 1448 if (local->mode() == LET || local->mode() == CONST || |
| 1449 local->mode() == CONST_LEGACY) { | 1449 local->mode() == CONST_LEGACY) { |
| 1450 __ CompareRoot(r0, Heap::kTheHoleValueRootIndex); | 1450 __ CompareRoot(r0, Heap::kTheHoleValueRootIndex); |
| 1451 if (local->mode() == CONST_LEGACY) { | 1451 if (local->mode() == CONST_LEGACY) { |
| 1452 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); | 1452 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); |
| 1453 } else { // LET || CONST | 1453 } else { // LET || CONST |
| 1454 __ b(ne, done); | 1454 __ b(ne, done); |
| 1455 __ mov(r0, Operand(var->name())); | 1455 __ mov(r0, Operand(var->name())); |
| 1456 __ push(r0); | 1456 __ push(r0); |
| 1457 __ CallRuntime(Runtime::kHiddenThrowReferenceError, 1); | 1457 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 1458 } | 1458 } |
| 1459 } | 1459 } |
| 1460 __ jmp(done); | 1460 __ jmp(done); |
| 1461 } | 1461 } |
| 1462 } | 1462 } |
| 1463 | 1463 |
| 1464 | 1464 |
| 1465 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { | 1465 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
| 1466 // Record position before possible IC call. | 1466 // Record position before possible IC call. |
| 1467 SetSourcePosition(proxy->position()); | 1467 SetSourcePosition(proxy->position()); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1525 // Let and const need a read barrier. | 1525 // Let and const need a read barrier. |
| 1526 GetVar(r0, var); | 1526 GetVar(r0, var); |
| 1527 __ CompareRoot(r0, Heap::kTheHoleValueRootIndex); | 1527 __ CompareRoot(r0, Heap::kTheHoleValueRootIndex); |
| 1528 if (var->mode() == LET || var->mode() == CONST) { | 1528 if (var->mode() == LET || var->mode() == CONST) { |
| 1529 // Throw a reference error when using an uninitialized let/const | 1529 // Throw a reference error when using an uninitialized let/const |
| 1530 // binding in harmony mode. | 1530 // binding in harmony mode. |
| 1531 Label done; | 1531 Label done; |
| 1532 __ b(ne, &done); | 1532 __ b(ne, &done); |
| 1533 __ mov(r0, Operand(var->name())); | 1533 __ mov(r0, Operand(var->name())); |
| 1534 __ push(r0); | 1534 __ push(r0); |
| 1535 __ CallRuntime(Runtime::kHiddenThrowReferenceError, 1); | 1535 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 1536 __ bind(&done); | 1536 __ bind(&done); |
| 1537 } else { | 1537 } else { |
| 1538 // Uninitalized const bindings outside of harmony mode are unholed. | 1538 // Uninitalized const bindings outside of harmony mode are unholed. |
| 1539 ASSERT(var->mode() == CONST_LEGACY); | 1539 ASSERT(var->mode() == CONST_LEGACY); |
| 1540 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); | 1540 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); |
| 1541 } | 1541 } |
| 1542 context()->Plug(r0); | 1542 context()->Plug(r0); |
| 1543 break; | 1543 break; |
| 1544 } | 1544 } |
| 1545 } | 1545 } |
| 1546 context()->Plug(var); | 1546 context()->Plug(var); |
| 1547 break; | 1547 break; |
| 1548 } | 1548 } |
| 1549 | 1549 |
| 1550 case Variable::LOOKUP: { | 1550 case Variable::LOOKUP: { |
| 1551 Comment cmnt(masm_, "[ Lookup variable"); | 1551 Comment cmnt(masm_, "[ Lookup variable"); |
| 1552 Label done, slow; | 1552 Label done, slow; |
| 1553 // Generate code for loading from variables potentially shadowed | 1553 // Generate code for loading from variables potentially shadowed |
| 1554 // by eval-introduced variables. | 1554 // by eval-introduced variables. |
| 1555 EmitDynamicLookupFastCase(var, NOT_INSIDE_TYPEOF, &slow, &done); | 1555 EmitDynamicLookupFastCase(var, NOT_INSIDE_TYPEOF, &slow, &done); |
| 1556 __ bind(&slow); | 1556 __ bind(&slow); |
| 1557 __ mov(r1, Operand(var->name())); | 1557 __ mov(r1, Operand(var->name())); |
| 1558 __ Push(cp, r1); // Context and name. | 1558 __ Push(cp, r1); // Context and name. |
| 1559 __ CallRuntime(Runtime::kHiddenLoadContextSlot, 2); | 1559 __ CallRuntime(Runtime::kLoadContextSlot, 2); |
| 1560 __ bind(&done); | 1560 __ bind(&done); |
| 1561 context()->Plug(r0); | 1561 context()->Plug(r0); |
| 1562 } | 1562 } |
| 1563 } | 1563 } |
| 1564 } | 1564 } |
| 1565 | 1565 |
| 1566 | 1566 |
| 1567 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 1567 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
| 1568 Comment cmnt(masm_, "[ RegExpLiteral"); | 1568 Comment cmnt(masm_, "[ RegExpLiteral"); |
| 1569 Label materialized; | 1569 Label materialized; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1582 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 1582 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
| 1583 __ cmp(r5, ip); | 1583 __ cmp(r5, ip); |
| 1584 __ b(ne, &materialized); | 1584 __ b(ne, &materialized); |
| 1585 | 1585 |
| 1586 // Create regexp literal using runtime function. | 1586 // Create regexp literal using runtime function. |
| 1587 // Result will be in r0. | 1587 // Result will be in r0. |
| 1588 __ mov(r3, Operand(Smi::FromInt(expr->literal_index()))); | 1588 __ mov(r3, Operand(Smi::FromInt(expr->literal_index()))); |
| 1589 __ mov(r2, Operand(expr->pattern())); | 1589 __ mov(r2, Operand(expr->pattern())); |
| 1590 __ mov(r1, Operand(expr->flags())); | 1590 __ mov(r1, Operand(expr->flags())); |
| 1591 __ Push(r4, r3, r2, r1); | 1591 __ Push(r4, r3, r2, r1); |
| 1592 __ CallRuntime(Runtime::kHiddenMaterializeRegExpLiteral, 4); | 1592 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); |
| 1593 __ mov(r5, r0); | 1593 __ mov(r5, r0); |
| 1594 | 1594 |
| 1595 __ bind(&materialized); | 1595 __ bind(&materialized); |
| 1596 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; | 1596 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; |
| 1597 Label allocated, runtime_allocate; | 1597 Label allocated, runtime_allocate; |
| 1598 __ Allocate(size, r0, r2, r3, &runtime_allocate, TAG_OBJECT); | 1598 __ Allocate(size, r0, r2, r3, &runtime_allocate, TAG_OBJECT); |
| 1599 __ jmp(&allocated); | 1599 __ jmp(&allocated); |
| 1600 | 1600 |
| 1601 __ bind(&runtime_allocate); | 1601 __ bind(&runtime_allocate); |
| 1602 __ mov(r0, Operand(Smi::FromInt(size))); | 1602 __ mov(r0, Operand(Smi::FromInt(size))); |
| 1603 __ Push(r5, r0); | 1603 __ Push(r5, r0); |
| 1604 __ CallRuntime(Runtime::kHiddenAllocateInNewSpace, 1); | 1604 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); |
| 1605 __ pop(r5); | 1605 __ pop(r5); |
| 1606 | 1606 |
| 1607 __ bind(&allocated); | 1607 __ bind(&allocated); |
| 1608 // After this, registers are used as follows: | 1608 // After this, registers are used as follows: |
| 1609 // r0: Newly allocated regexp. | 1609 // r0: Newly allocated regexp. |
| 1610 // r5: Materialized regexp. | 1610 // r5: Materialized regexp. |
| 1611 // r2: temp. | 1611 // r2: temp. |
| 1612 __ CopyFields(r0, r5, d0, size / kPointerSize); | 1612 __ CopyFields(r0, r5, d0, size / kPointerSize); |
| 1613 context()->Plug(r0); | 1613 context()->Plug(r0); |
| 1614 } | 1614 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1638 : ObjectLiteral::kNoFlags; | 1638 : ObjectLiteral::kNoFlags; |
| 1639 flags |= expr->has_function() | 1639 flags |= expr->has_function() |
| 1640 ? ObjectLiteral::kHasFunction | 1640 ? ObjectLiteral::kHasFunction |
| 1641 : ObjectLiteral::kNoFlags; | 1641 : ObjectLiteral::kNoFlags; |
| 1642 __ mov(r0, Operand(Smi::FromInt(flags))); | 1642 __ mov(r0, Operand(Smi::FromInt(flags))); |
| 1643 int properties_count = constant_properties->length() / 2; | 1643 int properties_count = constant_properties->length() / 2; |
| 1644 if (expr->may_store_doubles() || expr->depth() > 1 || | 1644 if (expr->may_store_doubles() || expr->depth() > 1 || |
| 1645 masm()->serializer_enabled() || flags != ObjectLiteral::kFastElements || | 1645 masm()->serializer_enabled() || flags != ObjectLiteral::kFastElements || |
| 1646 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { | 1646 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { |
| 1647 __ Push(r3, r2, r1, r0); | 1647 __ Push(r3, r2, r1, r0); |
| 1648 __ CallRuntime(Runtime::kHiddenCreateObjectLiteral, 4); | 1648 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); |
| 1649 } else { | 1649 } else { |
| 1650 FastCloneShallowObjectStub stub(isolate(), properties_count); | 1650 FastCloneShallowObjectStub stub(isolate(), properties_count); |
| 1651 __ CallStub(&stub); | 1651 __ CallStub(&stub); |
| 1652 } | 1652 } |
| 1653 | 1653 |
| 1654 // If result_saved is true the result is on top of the stack. If | 1654 // If result_saved is true the result is on top of the stack. If |
| 1655 // result_saved is false the result is in r0. | 1655 // result_saved is false the result is in r0. |
| 1656 bool result_saved = false; | 1656 bool result_saved = false; |
| 1657 | 1657 |
| 1658 // Mark all computed expressions that are bound to a key that | 1658 // Mark all computed expressions that are bound to a key that |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1779 allocation_site_mode = DONT_TRACK_ALLOCATION_SITE; | 1779 allocation_site_mode = DONT_TRACK_ALLOCATION_SITE; |
| 1780 } | 1780 } |
| 1781 | 1781 |
| 1782 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1782 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1783 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); | 1783 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); |
| 1784 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); | 1784 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); |
| 1785 __ mov(r1, Operand(constant_elements)); | 1785 __ mov(r1, Operand(constant_elements)); |
| 1786 if (expr->depth() > 1 || length > JSObject::kInitialMaxFastElementArray) { | 1786 if (expr->depth() > 1 || length > JSObject::kInitialMaxFastElementArray) { |
| 1787 __ mov(r0, Operand(Smi::FromInt(flags))); | 1787 __ mov(r0, Operand(Smi::FromInt(flags))); |
| 1788 __ Push(r3, r2, r1, r0); | 1788 __ Push(r3, r2, r1, r0); |
| 1789 __ CallRuntime(Runtime::kHiddenCreateArrayLiteral, 4); | 1789 __ CallRuntime(Runtime::kCreateArrayLiteral, 4); |
| 1790 } else { | 1790 } else { |
| 1791 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); | 1791 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); |
| 1792 __ CallStub(&stub); | 1792 __ CallStub(&stub); |
| 1793 } | 1793 } |
| 1794 | 1794 |
| 1795 bool result_saved = false; // Is the result saved to the stack? | 1795 bool result_saved = false; // Is the result saved to the stack? |
| 1796 | 1796 |
| 1797 // Emit code to evaluate all the non-constant subexpressions and to store | 1797 // Emit code to evaluate all the non-constant subexpressions and to store |
| 1798 // them into the newly cloned array. | 1798 // them into the newly cloned array. |
| 1799 for (int i = 0; i < length; i++) { | 1799 for (int i = 0; i < length; i++) { |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1971 __ mov(r1, Operand(Smi::FromInt(continuation.pos()))); | 1971 __ mov(r1, Operand(Smi::FromInt(continuation.pos()))); |
| 1972 __ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset)); | 1972 __ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset)); |
| 1973 __ str(cp, FieldMemOperand(r0, JSGeneratorObject::kContextOffset)); | 1973 __ str(cp, FieldMemOperand(r0, JSGeneratorObject::kContextOffset)); |
| 1974 __ mov(r1, cp); | 1974 __ mov(r1, cp); |
| 1975 __ RecordWriteField(r0, JSGeneratorObject::kContextOffset, r1, r2, | 1975 __ RecordWriteField(r0, JSGeneratorObject::kContextOffset, r1, r2, |
| 1976 kLRHasBeenSaved, kDontSaveFPRegs); | 1976 kLRHasBeenSaved, kDontSaveFPRegs); |
| 1977 __ add(r1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); | 1977 __ add(r1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); |
| 1978 __ cmp(sp, r1); | 1978 __ cmp(sp, r1); |
| 1979 __ b(eq, &post_runtime); | 1979 __ b(eq, &post_runtime); |
| 1980 __ push(r0); // generator object | 1980 __ push(r0); // generator object |
| 1981 __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1); | 1981 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
| 1982 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1982 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 1983 __ bind(&post_runtime); | 1983 __ bind(&post_runtime); |
| 1984 __ pop(result_register()); | 1984 __ pop(result_register()); |
| 1985 EmitReturnSequence(); | 1985 EmitReturnSequence(); |
| 1986 | 1986 |
| 1987 __ bind(&resume); | 1987 __ bind(&resume); |
| 1988 context()->Plug(result_register()); | 1988 context()->Plug(result_register()); |
| 1989 break; | 1989 break; |
| 1990 } | 1990 } |
| 1991 | 1991 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2037 const int generator_object_depth = kPointerSize + handler_size; | 2037 const int generator_object_depth = kPointerSize + handler_size; |
| 2038 __ ldr(r0, MemOperand(sp, generator_object_depth)); | 2038 __ ldr(r0, MemOperand(sp, generator_object_depth)); |
| 2039 __ push(r0); // g | 2039 __ push(r0); // g |
| 2040 ASSERT(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos())); | 2040 ASSERT(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos())); |
| 2041 __ mov(r1, Operand(Smi::FromInt(l_continuation.pos()))); | 2041 __ mov(r1, Operand(Smi::FromInt(l_continuation.pos()))); |
| 2042 __ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset)); | 2042 __ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset)); |
| 2043 __ str(cp, FieldMemOperand(r0, JSGeneratorObject::kContextOffset)); | 2043 __ str(cp, FieldMemOperand(r0, JSGeneratorObject::kContextOffset)); |
| 2044 __ mov(r1, cp); | 2044 __ mov(r1, cp); |
| 2045 __ RecordWriteField(r0, JSGeneratorObject::kContextOffset, r1, r2, | 2045 __ RecordWriteField(r0, JSGeneratorObject::kContextOffset, r1, r2, |
| 2046 kLRHasBeenSaved, kDontSaveFPRegs); | 2046 kLRHasBeenSaved, kDontSaveFPRegs); |
| 2047 __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1); | 2047 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
| 2048 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2048 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2049 __ pop(r0); // result | 2049 __ pop(r0); // result |
| 2050 EmitReturnSequence(); | 2050 EmitReturnSequence(); |
| 2051 __ bind(&l_resume); // received in r0 | 2051 __ bind(&l_resume); // received in r0 |
| 2052 __ PopTryHandler(); | 2052 __ PopTryHandler(); |
| 2053 | 2053 |
| 2054 // receiver = iter; f = 'next'; arg = received; | 2054 // receiver = iter; f = 'next'; arg = received; |
| 2055 __ bind(&l_next); | 2055 __ bind(&l_next); |
| 2056 __ LoadRoot(r2, Heap::knext_stringRootIndex); // "next" | 2056 __ LoadRoot(r2, Heap::knext_stringRootIndex); // "next" |
| 2057 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter | 2057 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2089 break; | 2089 break; |
| 2090 } | 2090 } |
| 2091 } | 2091 } |
| 2092 } | 2092 } |
| 2093 | 2093 |
| 2094 | 2094 |
| 2095 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 2095 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
| 2096 Expression *value, | 2096 Expression *value, |
| 2097 JSGeneratorObject::ResumeMode resume_mode) { | 2097 JSGeneratorObject::ResumeMode resume_mode) { |
| 2098 // The value stays in r0, and is ultimately read by the resumed generator, as | 2098 // The value stays in r0, and is ultimately read by the resumed generator, as |
| 2099 // if CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject) returned it. Or it | 2099 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it |
| 2100 // is read to throw the value when the resumed generator is already closed. | 2100 // is read to throw the value when the resumed generator is already closed. |
| 2101 // r1 will hold the generator object until the activation has been resumed. | 2101 // r1 will hold the generator object until the activation has been resumed. |
| 2102 VisitForStackValue(generator); | 2102 VisitForStackValue(generator); |
| 2103 VisitForAccumulatorValue(value); | 2103 VisitForAccumulatorValue(value); |
| 2104 __ pop(r1); | 2104 __ pop(r1); |
| 2105 | 2105 |
| 2106 // Check generator state. | 2106 // Check generator state. |
| 2107 Label wrong_state, closed_state, done; | 2107 Label wrong_state, closed_state, done; |
| 2108 __ ldr(r3, FieldMemOperand(r1, JSGeneratorObject::kContinuationOffset)); | 2108 __ ldr(r3, FieldMemOperand(r1, JSGeneratorObject::kContinuationOffset)); |
| 2109 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0); | 2109 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2183 Label push_operand_holes, call_resume; | 2183 Label push_operand_holes, call_resume; |
| 2184 __ bind(&push_operand_holes); | 2184 __ bind(&push_operand_holes); |
| 2185 __ sub(r3, r3, Operand(1), SetCC); | 2185 __ sub(r3, r3, Operand(1), SetCC); |
| 2186 __ b(mi, &call_resume); | 2186 __ b(mi, &call_resume); |
| 2187 __ push(r2); | 2187 __ push(r2); |
| 2188 __ b(&push_operand_holes); | 2188 __ b(&push_operand_holes); |
| 2189 __ bind(&call_resume); | 2189 __ bind(&call_resume); |
| 2190 ASSERT(!result_register().is(r1)); | 2190 ASSERT(!result_register().is(r1)); |
| 2191 __ Push(r1, result_register()); | 2191 __ Push(r1, result_register()); |
| 2192 __ Push(Smi::FromInt(resume_mode)); | 2192 __ Push(Smi::FromInt(resume_mode)); |
| 2193 __ CallRuntime(Runtime::kHiddenResumeJSGeneratorObject, 3); | 2193 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); |
| 2194 // Not reached: the runtime call returns elsewhere. | 2194 // Not reached: the runtime call returns elsewhere. |
| 2195 __ stop("not-reached"); | 2195 __ stop("not-reached"); |
| 2196 | 2196 |
| 2197 // Reach here when generator is closed. | 2197 // Reach here when generator is closed. |
| 2198 __ bind(&closed_state); | 2198 __ bind(&closed_state); |
| 2199 if (resume_mode == JSGeneratorObject::NEXT) { | 2199 if (resume_mode == JSGeneratorObject::NEXT) { |
| 2200 // Return completed iterator result when generator is closed. | 2200 // Return completed iterator result when generator is closed. |
| 2201 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); | 2201 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
| 2202 __ push(r2); | 2202 __ push(r2); |
| 2203 // Pop value from top-of-stack slot; box result into result register. | 2203 // Pop value from top-of-stack slot; box result into result register. |
| 2204 EmitCreateIteratorResult(true); | 2204 EmitCreateIteratorResult(true); |
| 2205 } else { | 2205 } else { |
| 2206 // Throw the provided value. | 2206 // Throw the provided value. |
| 2207 __ push(r0); | 2207 __ push(r0); |
| 2208 __ CallRuntime(Runtime::kHiddenThrow, 1); | 2208 __ CallRuntime(Runtime::kThrow, 1); |
| 2209 } | 2209 } |
| 2210 __ jmp(&done); | 2210 __ jmp(&done); |
| 2211 | 2211 |
| 2212 // Throw error if we attempt to operate on a running generator. | 2212 // Throw error if we attempt to operate on a running generator. |
| 2213 __ bind(&wrong_state); | 2213 __ bind(&wrong_state); |
| 2214 __ push(r1); | 2214 __ push(r1); |
| 2215 __ CallRuntime(Runtime::kHiddenThrowGeneratorStateError, 1); | 2215 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); |
| 2216 | 2216 |
| 2217 __ bind(&done); | 2217 __ bind(&done); |
| 2218 context()->Plug(result_register()); | 2218 context()->Plug(result_register()); |
| 2219 } | 2219 } |
| 2220 | 2220 |
| 2221 | 2221 |
| 2222 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { | 2222 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { |
| 2223 Label gc_required; | 2223 Label gc_required; |
| 2224 Label allocated; | 2224 Label allocated; |
| 2225 | 2225 |
| 2226 Handle<Map> map(isolate()->native_context()->iterator_result_map()); | 2226 Handle<Map> map(isolate()->native_context()->iterator_result_map()); |
| 2227 | 2227 |
| 2228 __ Allocate(map->instance_size(), r0, r2, r3, &gc_required, TAG_OBJECT); | 2228 __ Allocate(map->instance_size(), r0, r2, r3, &gc_required, TAG_OBJECT); |
| 2229 __ jmp(&allocated); | 2229 __ jmp(&allocated); |
| 2230 | 2230 |
| 2231 __ bind(&gc_required); | 2231 __ bind(&gc_required); |
| 2232 __ Push(Smi::FromInt(map->instance_size())); | 2232 __ Push(Smi::FromInt(map->instance_size())); |
| 2233 __ CallRuntime(Runtime::kHiddenAllocateInNewSpace, 1); | 2233 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); |
| 2234 __ ldr(context_register(), | 2234 __ ldr(context_register(), |
| 2235 MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2235 MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2236 | 2236 |
| 2237 __ bind(&allocated); | 2237 __ bind(&allocated); |
| 2238 __ mov(r1, Operand(map)); | 2238 __ mov(r1, Operand(map)); |
| 2239 __ pop(r2); | 2239 __ pop(r2); |
| 2240 __ mov(r3, Operand(isolate()->factory()->ToBoolean(done))); | 2240 __ mov(r3, Operand(isolate()->factory()->ToBoolean(done))); |
| 2241 __ mov(r4, Operand(isolate()->factory()->empty_fixed_array())); | 2241 __ mov(r4, Operand(isolate()->factory()->empty_fixed_array())); |
| 2242 ASSERT_EQ(map->instance_size(), 5 * kPointerSize); | 2242 ASSERT_EQ(map->instance_size(), 5 * kPointerSize); |
| 2243 __ str(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); | 2243 __ str(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2437 } | 2437 } |
| 2438 } | 2438 } |
| 2439 | 2439 |
| 2440 | 2440 |
| 2441 void FullCodeGenerator::EmitCallStoreContextSlot( | 2441 void FullCodeGenerator::EmitCallStoreContextSlot( |
| 2442 Handle<String> name, StrictMode strict_mode) { | 2442 Handle<String> name, StrictMode strict_mode) { |
| 2443 __ push(r0); // Value. | 2443 __ push(r0); // Value. |
| 2444 __ mov(r1, Operand(name)); | 2444 __ mov(r1, Operand(name)); |
| 2445 __ mov(r0, Operand(Smi::FromInt(strict_mode))); | 2445 __ mov(r0, Operand(Smi::FromInt(strict_mode))); |
| 2446 __ Push(cp, r1, r0); // Context, name, strict mode. | 2446 __ Push(cp, r1, r0); // Context, name, strict mode. |
| 2447 __ CallRuntime(Runtime::kHiddenStoreContextSlot, 4); | 2447 __ CallRuntime(Runtime::kStoreContextSlot, 4); |
| 2448 } | 2448 } |
| 2449 | 2449 |
| 2450 | 2450 |
| 2451 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) { | 2451 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) { |
| 2452 if (var->IsUnallocated()) { | 2452 if (var->IsUnallocated()) { |
| 2453 // Global var, const, or let. | 2453 // Global var, const, or let. |
| 2454 __ mov(r2, Operand(var->name())); | 2454 __ mov(r2, Operand(var->name())); |
| 2455 __ ldr(r1, GlobalObjectOperand()); | 2455 __ ldr(r1, GlobalObjectOperand()); |
| 2456 CallStoreIC(); | 2456 CallStoreIC(); |
| 2457 | 2457 |
| 2458 } else if (op == Token::INIT_CONST_LEGACY) { | 2458 } else if (op == Token::INIT_CONST_LEGACY) { |
| 2459 // Const initializers need a write barrier. | 2459 // Const initializers need a write barrier. |
| 2460 ASSERT(!var->IsParameter()); // No const parameters. | 2460 ASSERT(!var->IsParameter()); // No const parameters. |
| 2461 if (var->IsLookupSlot()) { | 2461 if (var->IsLookupSlot()) { |
| 2462 __ push(r0); | 2462 __ push(r0); |
| 2463 __ mov(r0, Operand(var->name())); | 2463 __ mov(r0, Operand(var->name())); |
| 2464 __ Push(cp, r0); // Context and name. | 2464 __ Push(cp, r0); // Context and name. |
| 2465 __ CallRuntime(Runtime::kHiddenInitializeConstContextSlot, 3); | 2465 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); |
| 2466 } else { | 2466 } else { |
| 2467 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 2467 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); |
| 2468 Label skip; | 2468 Label skip; |
| 2469 MemOperand location = VarOperand(var, r1); | 2469 MemOperand location = VarOperand(var, r1); |
| 2470 __ ldr(r2, location); | 2470 __ ldr(r2, location); |
| 2471 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); | 2471 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); |
| 2472 __ b(ne, &skip); | 2472 __ b(ne, &skip); |
| 2473 EmitStoreToStackLocalOrContextSlot(var, location); | 2473 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2474 __ bind(&skip); | 2474 __ bind(&skip); |
| 2475 } | 2475 } |
| 2476 | 2476 |
| 2477 } else if (var->mode() == LET && op != Token::INIT_LET) { | 2477 } else if (var->mode() == LET && op != Token::INIT_LET) { |
| 2478 // Non-initializing assignment to let variable needs a write barrier. | 2478 // Non-initializing assignment to let variable needs a write barrier. |
| 2479 if (var->IsLookupSlot()) { | 2479 if (var->IsLookupSlot()) { |
| 2480 EmitCallStoreContextSlot(var->name(), strict_mode()); | 2480 EmitCallStoreContextSlot(var->name(), strict_mode()); |
| 2481 } else { | 2481 } else { |
| 2482 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 2482 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); |
| 2483 Label assign; | 2483 Label assign; |
| 2484 MemOperand location = VarOperand(var, r1); | 2484 MemOperand location = VarOperand(var, r1); |
| 2485 __ ldr(r3, location); | 2485 __ ldr(r3, location); |
| 2486 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); | 2486 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); |
| 2487 __ b(ne, &assign); | 2487 __ b(ne, &assign); |
| 2488 __ mov(r3, Operand(var->name())); | 2488 __ mov(r3, Operand(var->name())); |
| 2489 __ push(r3); | 2489 __ push(r3); |
| 2490 __ CallRuntime(Runtime::kHiddenThrowReferenceError, 1); | 2490 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 2491 // Perform the assignment. | 2491 // Perform the assignment. |
| 2492 __ bind(&assign); | 2492 __ bind(&assign); |
| 2493 EmitStoreToStackLocalOrContextSlot(var, location); | 2493 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2494 } | 2494 } |
| 2495 | 2495 |
| 2496 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { | 2496 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { |
| 2497 // Assignment to var or initializing assignment to let/const | 2497 // Assignment to var or initializing assignment to let/const |
| 2498 // in harmony mode. | 2498 // in harmony mode. |
| 2499 if (var->IsLookupSlot()) { | 2499 if (var->IsLookupSlot()) { |
| 2500 EmitCallStoreContextSlot(var->name(), strict_mode()); | 2500 EmitCallStoreContextSlot(var->name(), strict_mode()); |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2674 __ ldr(r3, MemOperand(fp, receiver_offset * kPointerSize)); | 2674 __ ldr(r3, MemOperand(fp, receiver_offset * kPointerSize)); |
| 2675 | 2675 |
| 2676 // r2: strict mode. | 2676 // r2: strict mode. |
| 2677 __ mov(r2, Operand(Smi::FromInt(strict_mode()))); | 2677 __ mov(r2, Operand(Smi::FromInt(strict_mode()))); |
| 2678 | 2678 |
| 2679 // r1: the start position of the scope the calls resides in. | 2679 // r1: the start position of the scope the calls resides in. |
| 2680 __ mov(r1, Operand(Smi::FromInt(scope()->start_position()))); | 2680 __ mov(r1, Operand(Smi::FromInt(scope()->start_position()))); |
| 2681 | 2681 |
| 2682 // Do the runtime call. | 2682 // Do the runtime call. |
| 2683 __ Push(r4, r3, r2, r1); | 2683 __ Push(r4, r3, r2, r1); |
| 2684 __ CallRuntime(Runtime::kHiddenResolvePossiblyDirectEval, 5); | 2684 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); |
| 2685 } | 2685 } |
| 2686 | 2686 |
| 2687 | 2687 |
| 2688 void FullCodeGenerator::VisitCall(Call* expr) { | 2688 void FullCodeGenerator::VisitCall(Call* expr) { |
| 2689 #ifdef DEBUG | 2689 #ifdef DEBUG |
| 2690 // We want to verify that RecordJSReturnSite gets called on all paths | 2690 // We want to verify that RecordJSReturnSite gets called on all paths |
| 2691 // through this function. Avoid early returns. | 2691 // through this function. Avoid early returns. |
| 2692 expr->return_is_recorded_ = false; | 2692 expr->return_is_recorded_ = false; |
| 2693 #endif | 2693 #endif |
| 2694 | 2694 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2748 // by eval-introduced variables. | 2748 // by eval-introduced variables. |
| 2749 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); | 2749 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); |
| 2750 } | 2750 } |
| 2751 | 2751 |
| 2752 __ bind(&slow); | 2752 __ bind(&slow); |
| 2753 // Call the runtime to find the function to call (returned in r0) | 2753 // Call the runtime to find the function to call (returned in r0) |
| 2754 // and the object holding it (returned in edx). | 2754 // and the object holding it (returned in edx). |
| 2755 ASSERT(!context_register().is(r2)); | 2755 ASSERT(!context_register().is(r2)); |
| 2756 __ mov(r2, Operand(proxy->name())); | 2756 __ mov(r2, Operand(proxy->name())); |
| 2757 __ Push(context_register(), r2); | 2757 __ Push(context_register(), r2); |
| 2758 __ CallRuntime(Runtime::kHiddenLoadContextSlot, 2); | 2758 __ CallRuntime(Runtime::kLoadContextSlot, 2); |
| 2759 __ Push(r0, r1); // Function, receiver. | 2759 __ Push(r0, r1); // Function, receiver. |
| 2760 | 2760 |
| 2761 // If fast case code has been generated, emit code to push the | 2761 // If fast case code has been generated, emit code to push the |
| 2762 // function and receiver and have the slow path jump around this | 2762 // function and receiver and have the slow path jump around this |
| 2763 // code. | 2763 // code. |
| 2764 if (done.is_linked()) { | 2764 if (done.is_linked()) { |
| 2765 Label call; | 2765 Label call; |
| 2766 __ b(&call); | 2766 __ b(&call); |
| 2767 __ bind(&done); | 2767 __ bind(&done); |
| 2768 // Push function. | 2768 // Push function. |
| (...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3377 __ jmp(&done); | 3377 __ jmp(&done); |
| 3378 } | 3378 } |
| 3379 __ bind(&runtime); | 3379 __ bind(&runtime); |
| 3380 __ PrepareCallCFunction(2, scratch1); | 3380 __ PrepareCallCFunction(2, scratch1); |
| 3381 __ mov(r1, Operand(index)); | 3381 __ mov(r1, Operand(index)); |
| 3382 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); | 3382 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); |
| 3383 __ jmp(&done); | 3383 __ jmp(&done); |
| 3384 } | 3384 } |
| 3385 | 3385 |
| 3386 __ bind(¬_date_object); | 3386 __ bind(¬_date_object); |
| 3387 __ CallRuntime(Runtime::kHiddenThrowNotDateError, 0); | 3387 __ CallRuntime(Runtime::kThrowNotDateError, 0); |
| 3388 __ bind(&done); | 3388 __ bind(&done); |
| 3389 context()->Plug(r0); | 3389 context()->Plug(r0); |
| 3390 } | 3390 } |
| 3391 | 3391 |
| 3392 | 3392 |
| 3393 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { | 3393 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { |
| 3394 ZoneList<Expression*>* args = expr->arguments(); | 3394 ZoneList<Expression*>* args = expr->arguments(); |
| 3395 ASSERT_EQ(3, args->length()); | 3395 ASSERT_EQ(3, args->length()); |
| 3396 | 3396 |
| 3397 Register string = r0; | 3397 Register string = r0; |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3726 // Note side effect of PreIndex: r3 now points to the key of the pair. | 3726 // Note side effect of PreIndex: r3 now points to the key of the pair. |
| 3727 __ cmp(key, r2); | 3727 __ cmp(key, r2); |
| 3728 __ b(ne, ¬_found); | 3728 __ b(ne, ¬_found); |
| 3729 | 3729 |
| 3730 __ ldr(r0, MemOperand(r3, kPointerSize)); | 3730 __ ldr(r0, MemOperand(r3, kPointerSize)); |
| 3731 __ b(&done); | 3731 __ b(&done); |
| 3732 | 3732 |
| 3733 __ bind(¬_found); | 3733 __ bind(¬_found); |
| 3734 // Call runtime to perform the lookup. | 3734 // Call runtime to perform the lookup. |
| 3735 __ Push(cache, key); | 3735 __ Push(cache, key); |
| 3736 __ CallRuntime(Runtime::kHiddenGetFromCache, 2); | 3736 __ CallRuntime(Runtime::kGetFromCache, 2); |
| 3737 | 3737 |
| 3738 __ bind(&done); | 3738 __ bind(&done); |
| 3739 context()->Plug(r0); | 3739 context()->Plug(r0); |
| 3740 } | 3740 } |
| 3741 | 3741 |
| 3742 | 3742 |
| 3743 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { | 3743 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { |
| 3744 ZoneList<Expression*>* args = expr->arguments(); | 3744 ZoneList<Expression*>* args = expr->arguments(); |
| 3745 VisitForAccumulatorValue(args->at(0)); | 3745 VisitForAccumulatorValue(args->at(0)); |
| 3746 | 3746 |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4105 } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 4105 } else if (var->IsStackAllocated() || var->IsContextSlot()) { |
| 4106 // Result of deleting non-global, non-dynamic variables is false. | 4106 // Result of deleting non-global, non-dynamic variables is false. |
| 4107 // The subexpression does not have side effects. | 4107 // The subexpression does not have side effects. |
| 4108 context()->Plug(var->is_this()); | 4108 context()->Plug(var->is_this()); |
| 4109 } else { | 4109 } else { |
| 4110 // Non-global variable. Call the runtime to try to delete from the | 4110 // Non-global variable. Call the runtime to try to delete from the |
| 4111 // context where the variable was introduced. | 4111 // context where the variable was introduced. |
| 4112 ASSERT(!context_register().is(r2)); | 4112 ASSERT(!context_register().is(r2)); |
| 4113 __ mov(r2, Operand(var->name())); | 4113 __ mov(r2, Operand(var->name())); |
| 4114 __ Push(context_register(), r2); | 4114 __ Push(context_register(), r2); |
| 4115 __ CallRuntime(Runtime::kHiddenDeleteContextSlot, 2); | 4115 __ CallRuntime(Runtime::kDeleteContextSlot, 2); |
| 4116 context()->Plug(r0); | 4116 context()->Plug(r0); |
| 4117 } | 4117 } |
| 4118 } else { | 4118 } else { |
| 4119 // Result of deleting non-property, non-variable reference is true. | 4119 // Result of deleting non-property, non-variable reference is true. |
| 4120 // The subexpression may have side effects. | 4120 // The subexpression may have side effects. |
| 4121 VisitForEffect(expr->expression()); | 4121 VisitForEffect(expr->expression()); |
| 4122 context()->Plug(true); | 4122 context()->Plug(true); |
| 4123 } | 4123 } |
| 4124 break; | 4124 break; |
| 4125 } | 4125 } |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4382 Comment cmnt(masm_, "[ Lookup slot"); | 4382 Comment cmnt(masm_, "[ Lookup slot"); |
| 4383 Label done, slow; | 4383 Label done, slow; |
| 4384 | 4384 |
| 4385 // Generate code for loading from variables potentially shadowed | 4385 // Generate code for loading from variables potentially shadowed |
| 4386 // by eval-introduced variables. | 4386 // by eval-introduced variables. |
| 4387 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); | 4387 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); |
| 4388 | 4388 |
| 4389 __ bind(&slow); | 4389 __ bind(&slow); |
| 4390 __ mov(r0, Operand(proxy->name())); | 4390 __ mov(r0, Operand(proxy->name())); |
| 4391 __ Push(cp, r0); | 4391 __ Push(cp, r0); |
| 4392 __ CallRuntime(Runtime::kHiddenLoadContextSlotNoReferenceError, 2); | 4392 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); |
| 4393 PrepareForBailout(expr, TOS_REG); | 4393 PrepareForBailout(expr, TOS_REG); |
| 4394 __ bind(&done); | 4394 __ bind(&done); |
| 4395 | 4395 |
| 4396 context()->Plug(r0); | 4396 context()->Plug(r0); |
| 4397 } else { | 4397 } else { |
| 4398 // This expression cannot throw a reference error at the top level. | 4398 // This expression cannot throw a reference error at the top level. |
| 4399 VisitInDuplicateContext(expr); | 4399 VisitInDuplicateContext(expr); |
| 4400 } | 4400 } |
| 4401 } | 4401 } |
| 4402 | 4402 |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4821 | 4821 |
| 4822 ASSERT(interrupt_address == | 4822 ASSERT(interrupt_address == |
| 4823 isolate->builtins()->OsrAfterStackCheck()->entry()); | 4823 isolate->builtins()->OsrAfterStackCheck()->entry()); |
| 4824 return OSR_AFTER_STACK_CHECK; | 4824 return OSR_AFTER_STACK_CHECK; |
| 4825 } | 4825 } |
| 4826 | 4826 |
| 4827 | 4827 |
| 4828 } } // namespace v8::internal | 4828 } } // namespace v8::internal |
| 4829 | 4829 |
| 4830 #endif // V8_TARGET_ARCH_ARM | 4830 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |