| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 bool function_in_register = true; | 227 bool function_in_register = true; |
| 228 | 228 |
| 229 // Possibly allocate a local context. | 229 // Possibly allocate a local context. |
| 230 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 230 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
| 231 if (heap_slots > 0) { | 231 if (heap_slots > 0) { |
| 232 // Argument to NewContext is the function, which is still in r1. | 232 // Argument to NewContext is the function, which is still in r1. |
| 233 Comment cmnt(masm_, "[ Allocate context"); | 233 Comment cmnt(masm_, "[ Allocate context"); |
| 234 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { | 234 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { |
| 235 __ push(r1); | 235 __ push(r1); |
| 236 __ Push(info->scope()->GetScopeInfo()); | 236 __ Push(info->scope()->GetScopeInfo()); |
| 237 __ CallRuntime(Runtime::kNewGlobalContext, 2); | 237 __ CallRuntime(Runtime::kHiddenNewGlobalContext, 2); |
| 238 } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { | 238 } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { |
| 239 FastNewContextStub stub(heap_slots); | 239 FastNewContextStub stub(heap_slots); |
| 240 __ CallStub(&stub); | 240 __ CallStub(&stub); |
| 241 } else { | 241 } else { |
| 242 __ push(r1); | 242 __ push(r1); |
| 243 __ CallRuntime(Runtime::kNewFunctionContext, 1); | 243 __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); |
| 244 } | 244 } |
| 245 function_in_register = false; | 245 function_in_register = false; |
| 246 // Context is returned in r0. It replaces the context passed to us. | 246 // Context is returned in r0. It replaces the context passed to us. |
| 247 // It's saved in the stack and kept live in cp. | 247 // It's saved in the stack and kept live in cp. |
| 248 __ mov(cp, r0); | 248 __ mov(cp, r0); |
| 249 __ str(r0, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 249 __ str(r0, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 250 // Copy any necessary parameters into the context. | 250 // Copy any necessary parameters into the context. |
| 251 int num_parameters = info->scope()->num_parameters(); | 251 int num_parameters = info->scope()->num_parameters(); |
| 252 for (int i = 0; i < num_parameters; i++) { | 252 for (int i = 0; i < num_parameters; i++) { |
| 253 Variable* var = scope()->parameter(i); | 253 Variable* var = scope()->parameter(i); |
| (...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 854 // Note: For variables we must not push an initial value (such as | 854 // Note: For variables we must not push an initial value (such as |
| 855 // 'undefined') because we may have a (legal) redeclaration and we | 855 // 'undefined') because we may have a (legal) redeclaration and we |
| 856 // must not destroy the current value. | 856 // must not destroy the current value. |
| 857 if (hole_init) { | 857 if (hole_init) { |
| 858 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); | 858 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); |
| 859 __ Push(cp, r2, r1, r0); | 859 __ Push(cp, r2, r1, r0); |
| 860 } else { | 860 } else { |
| 861 __ mov(r0, Operand(Smi::FromInt(0))); // Indicates no initial value. | 861 __ mov(r0, Operand(Smi::FromInt(0))); // Indicates no initial value. |
| 862 __ Push(cp, r2, r1, r0); | 862 __ Push(cp, r2, r1, r0); |
| 863 } | 863 } |
| 864 __ CallRuntime(Runtime::kDeclareContextSlot, 4); | 864 __ CallRuntime(Runtime::kHiddenDeclareContextSlot, 4); |
| 865 break; | 865 break; |
| 866 } | 866 } |
| 867 } | 867 } |
| 868 } | 868 } |
| 869 | 869 |
| 870 | 870 |
| 871 void FullCodeGenerator::VisitFunctionDeclaration( | 871 void FullCodeGenerator::VisitFunctionDeclaration( |
| 872 FunctionDeclaration* declaration) { | 872 FunctionDeclaration* declaration) { |
| 873 VariableProxy* proxy = declaration->proxy(); | 873 VariableProxy* proxy = declaration->proxy(); |
| 874 Variable* variable = proxy->var(); | 874 Variable* variable = proxy->var(); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 910 break; | 910 break; |
| 911 } | 911 } |
| 912 | 912 |
| 913 case Variable::LOOKUP: { | 913 case Variable::LOOKUP: { |
| 914 Comment cmnt(masm_, "[ FunctionDeclaration"); | 914 Comment cmnt(masm_, "[ FunctionDeclaration"); |
| 915 __ mov(r2, Operand(variable->name())); | 915 __ mov(r2, Operand(variable->name())); |
| 916 __ mov(r1, Operand(Smi::FromInt(NONE))); | 916 __ mov(r1, Operand(Smi::FromInt(NONE))); |
| 917 __ Push(cp, r2, r1); | 917 __ Push(cp, r2, r1); |
| 918 // Push initial value for function declaration. | 918 // Push initial value for function declaration. |
| 919 VisitForStackValue(declaration->fun()); | 919 VisitForStackValue(declaration->fun()); |
| 920 __ CallRuntime(Runtime::kDeclareContextSlot, 4); | 920 __ CallRuntime(Runtime::kHiddenDeclareContextSlot, 4); |
| 921 break; | 921 break; |
| 922 } | 922 } |
| 923 } | 923 } |
| 924 } | 924 } |
| 925 | 925 |
| 926 | 926 |
| 927 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { | 927 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { |
| 928 Variable* variable = declaration->proxy()->var(); | 928 Variable* variable = declaration->proxy()->var(); |
| 929 ASSERT(variable->location() == Variable::CONTEXT); | 929 ASSERT(variable->location() == Variable::CONTEXT); |
| 930 ASSERT(variable->interface()->IsFrozen()); | 930 ASSERT(variable->interface()->IsFrozen()); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 982 // TODO(rossberg) | 982 // TODO(rossberg) |
| 983 } | 983 } |
| 984 | 984 |
| 985 | 985 |
| 986 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 986 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
| 987 // Call the runtime to declare the globals. | 987 // Call the runtime to declare the globals. |
| 988 // The context is the first argument. | 988 // The context is the first argument. |
| 989 __ mov(r1, Operand(pairs)); | 989 __ mov(r1, Operand(pairs)); |
| 990 __ mov(r0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); | 990 __ mov(r0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); |
| 991 __ Push(cp, r1, r0); | 991 __ Push(cp, r1, r0); |
| 992 __ CallRuntime(Runtime::kDeclareGlobals, 3); | 992 __ CallRuntime(Runtime::kHiddenDeclareGlobals, 3); |
| 993 // Return value is ignored. | 993 // Return value is ignored. |
| 994 } | 994 } |
| 995 | 995 |
| 996 | 996 |
| 997 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) { | 997 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) { |
| 998 // Call the runtime to declare the modules. | 998 // Call the runtime to declare the modules. |
| 999 __ Push(descriptions); | 999 __ Push(descriptions); |
| 1000 __ CallRuntime(Runtime::kDeclareModules, 1); | 1000 __ CallRuntime(Runtime::kHiddenDeclareModules, 1); |
| 1001 // Return value is ignored. | 1001 // Return value is ignored. |
| 1002 } | 1002 } |
| 1003 | 1003 |
| 1004 | 1004 |
| 1005 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { | 1005 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { |
| 1006 Comment cmnt(masm_, "[ SwitchStatement"); | 1006 Comment cmnt(masm_, "[ SwitchStatement"); |
| 1007 Breakable nested_statement(this, stmt); | 1007 Breakable nested_statement(this, stmt); |
| 1008 SetStatementPosition(stmt); | 1008 SetStatementPosition(stmt); |
| 1009 | 1009 |
| 1010 // Keep the switch value on the stack until a case matches. | 1010 // Keep the switch value on the stack until a case matches. |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1352 scope()->is_function_scope() && | 1352 scope()->is_function_scope() && |
| 1353 info->num_literals() == 0) { | 1353 info->num_literals() == 0) { |
| 1354 FastNewClosureStub stub(info->strict_mode(), info->is_generator()); | 1354 FastNewClosureStub stub(info->strict_mode(), info->is_generator()); |
| 1355 __ mov(r2, Operand(info)); | 1355 __ mov(r2, Operand(info)); |
| 1356 __ CallStub(&stub); | 1356 __ CallStub(&stub); |
| 1357 } else { | 1357 } else { |
| 1358 __ mov(r0, Operand(info)); | 1358 __ mov(r0, Operand(info)); |
| 1359 __ LoadRoot(r1, pretenure ? Heap::kTrueValueRootIndex | 1359 __ LoadRoot(r1, pretenure ? Heap::kTrueValueRootIndex |
| 1360 : Heap::kFalseValueRootIndex); | 1360 : Heap::kFalseValueRootIndex); |
| 1361 __ Push(cp, r0, r1); | 1361 __ Push(cp, r0, r1); |
| 1362 __ CallRuntime(Runtime::kNewClosure, 3); | 1362 __ CallRuntime(Runtime::kHiddenNewClosure, 3); |
| 1363 } | 1363 } |
| 1364 context()->Plug(r0); | 1364 context()->Plug(r0); |
| 1365 } | 1365 } |
| 1366 | 1366 |
| 1367 | 1367 |
| 1368 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { | 1368 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
| 1369 Comment cmnt(masm_, "[ VariableProxy"); | 1369 Comment cmnt(masm_, "[ VariableProxy"); |
| 1370 EmitVariableLoad(expr); | 1370 EmitVariableLoad(expr); |
| 1371 } | 1371 } |
| 1372 | 1372 |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1477 __ ldr(r0, ContextSlotOperandCheckExtensions(local, slow)); | 1477 __ ldr(r0, ContextSlotOperandCheckExtensions(local, slow)); |
| 1478 if (local->mode() == LET || local->mode() == CONST || | 1478 if (local->mode() == LET || local->mode() == CONST || |
| 1479 local->mode() == CONST_LEGACY) { | 1479 local->mode() == CONST_LEGACY) { |
| 1480 __ CompareRoot(r0, Heap::kTheHoleValueRootIndex); | 1480 __ CompareRoot(r0, Heap::kTheHoleValueRootIndex); |
| 1481 if (local->mode() == CONST_LEGACY) { | 1481 if (local->mode() == CONST_LEGACY) { |
| 1482 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); | 1482 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); |
| 1483 } else { // LET || CONST | 1483 } else { // LET || CONST |
| 1484 __ b(ne, done); | 1484 __ b(ne, done); |
| 1485 __ mov(r0, Operand(var->name())); | 1485 __ mov(r0, Operand(var->name())); |
| 1486 __ push(r0); | 1486 __ push(r0); |
| 1487 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 1487 __ CallRuntime(Runtime::kHiddenThrowReferenceError, 1); |
| 1488 } | 1488 } |
| 1489 } | 1489 } |
| 1490 __ jmp(done); | 1490 __ jmp(done); |
| 1491 } | 1491 } |
| 1492 } | 1492 } |
| 1493 | 1493 |
| 1494 | 1494 |
| 1495 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { | 1495 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
| 1496 // Record position before possible IC call. | 1496 // Record position before possible IC call. |
| 1497 SetSourcePosition(proxy->position()); | 1497 SetSourcePosition(proxy->position()); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1555 // Let and const need a read barrier. | 1555 // Let and const need a read barrier. |
| 1556 GetVar(r0, var); | 1556 GetVar(r0, var); |
| 1557 __ CompareRoot(r0, Heap::kTheHoleValueRootIndex); | 1557 __ CompareRoot(r0, Heap::kTheHoleValueRootIndex); |
| 1558 if (var->mode() == LET || var->mode() == CONST) { | 1558 if (var->mode() == LET || var->mode() == CONST) { |
| 1559 // Throw a reference error when using an uninitialized let/const | 1559 // Throw a reference error when using an uninitialized let/const |
| 1560 // binding in harmony mode. | 1560 // binding in harmony mode. |
| 1561 Label done; | 1561 Label done; |
| 1562 __ b(ne, &done); | 1562 __ b(ne, &done); |
| 1563 __ mov(r0, Operand(var->name())); | 1563 __ mov(r0, Operand(var->name())); |
| 1564 __ push(r0); | 1564 __ push(r0); |
| 1565 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 1565 __ CallRuntime(Runtime::kHiddenThrowReferenceError, 1); |
| 1566 __ bind(&done); | 1566 __ bind(&done); |
| 1567 } else { | 1567 } else { |
| 1568 // Uninitalized const bindings outside of harmony mode are unholed. | 1568 // Uninitalized const bindings outside of harmony mode are unholed. |
| 1569 ASSERT(var->mode() == CONST_LEGACY); | 1569 ASSERT(var->mode() == CONST_LEGACY); |
| 1570 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); | 1570 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); |
| 1571 } | 1571 } |
| 1572 context()->Plug(r0); | 1572 context()->Plug(r0); |
| 1573 break; | 1573 break; |
| 1574 } | 1574 } |
| 1575 } | 1575 } |
| 1576 context()->Plug(var); | 1576 context()->Plug(var); |
| 1577 break; | 1577 break; |
| 1578 } | 1578 } |
| 1579 | 1579 |
| 1580 case Variable::LOOKUP: { | 1580 case Variable::LOOKUP: { |
| 1581 Comment cmnt(masm_, "[ Lookup variable"); | 1581 Comment cmnt(masm_, "[ Lookup variable"); |
| 1582 Label done, slow; | 1582 Label done, slow; |
| 1583 // Generate code for loading from variables potentially shadowed | 1583 // Generate code for loading from variables potentially shadowed |
| 1584 // by eval-introduced variables. | 1584 // by eval-introduced variables. |
| 1585 EmitDynamicLookupFastCase(var, NOT_INSIDE_TYPEOF, &slow, &done); | 1585 EmitDynamicLookupFastCase(var, NOT_INSIDE_TYPEOF, &slow, &done); |
| 1586 __ bind(&slow); | 1586 __ bind(&slow); |
| 1587 __ mov(r1, Operand(var->name())); | 1587 __ mov(r1, Operand(var->name())); |
| 1588 __ Push(cp, r1); // Context and name. | 1588 __ Push(cp, r1); // Context and name. |
| 1589 __ CallRuntime(Runtime::kLoadContextSlot, 2); | 1589 __ CallRuntime(Runtime::kHiddenLoadContextSlot, 2); |
| 1590 __ bind(&done); | 1590 __ bind(&done); |
| 1591 context()->Plug(r0); | 1591 context()->Plug(r0); |
| 1592 } | 1592 } |
| 1593 } | 1593 } |
| 1594 } | 1594 } |
| 1595 | 1595 |
| 1596 | 1596 |
| 1597 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 1597 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
| 1598 Comment cmnt(masm_, "[ RegExpLiteral"); | 1598 Comment cmnt(masm_, "[ RegExpLiteral"); |
| 1599 Label materialized; | 1599 Label materialized; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1612 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 1612 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
| 1613 __ cmp(r5, ip); | 1613 __ cmp(r5, ip); |
| 1614 __ b(ne, &materialized); | 1614 __ b(ne, &materialized); |
| 1615 | 1615 |
| 1616 // Create regexp literal using runtime function. | 1616 // Create regexp literal using runtime function. |
| 1617 // Result will be in r0. | 1617 // Result will be in r0. |
| 1618 __ mov(r3, Operand(Smi::FromInt(expr->literal_index()))); | 1618 __ mov(r3, Operand(Smi::FromInt(expr->literal_index()))); |
| 1619 __ mov(r2, Operand(expr->pattern())); | 1619 __ mov(r2, Operand(expr->pattern())); |
| 1620 __ mov(r1, Operand(expr->flags())); | 1620 __ mov(r1, Operand(expr->flags())); |
| 1621 __ Push(r4, r3, r2, r1); | 1621 __ Push(r4, r3, r2, r1); |
| 1622 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); | 1622 __ CallRuntime(Runtime::kHiddenMaterializeRegExpLiteral, 4); |
| 1623 __ mov(r5, r0); | 1623 __ mov(r5, r0); |
| 1624 | 1624 |
| 1625 __ bind(&materialized); | 1625 __ bind(&materialized); |
| 1626 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; | 1626 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; |
| 1627 Label allocated, runtime_allocate; | 1627 Label allocated, runtime_allocate; |
| 1628 __ Allocate(size, r0, r2, r3, &runtime_allocate, TAG_OBJECT); | 1628 __ Allocate(size, r0, r2, r3, &runtime_allocate, TAG_OBJECT); |
| 1629 __ jmp(&allocated); | 1629 __ jmp(&allocated); |
| 1630 | 1630 |
| 1631 __ bind(&runtime_allocate); | 1631 __ bind(&runtime_allocate); |
| 1632 __ mov(r0, Operand(Smi::FromInt(size))); | 1632 __ mov(r0, Operand(Smi::FromInt(size))); |
| 1633 __ Push(r5, r0); | 1633 __ Push(r5, r0); |
| 1634 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); | 1634 __ CallRuntime(Runtime::kHiddenAllocateInNewSpace, 1); |
| 1635 __ pop(r5); | 1635 __ pop(r5); |
| 1636 | 1636 |
| 1637 __ bind(&allocated); | 1637 __ bind(&allocated); |
| 1638 // After this, registers are used as follows: | 1638 // After this, registers are used as follows: |
| 1639 // r0: Newly allocated regexp. | 1639 // r0: Newly allocated regexp. |
| 1640 // r5: Materialized regexp. | 1640 // r5: Materialized regexp. |
| 1641 // r2: temp. | 1641 // r2: temp. |
| 1642 __ CopyFields(r0, r5, d0, size / kPointerSize); | 1642 __ CopyFields(r0, r5, d0, size / kPointerSize); |
| 1643 context()->Plug(r0); | 1643 context()->Plug(r0); |
| 1644 } | 1644 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1668 : ObjectLiteral::kNoFlags; | 1668 : ObjectLiteral::kNoFlags; |
| 1669 flags |= expr->has_function() | 1669 flags |= expr->has_function() |
| 1670 ? ObjectLiteral::kHasFunction | 1670 ? ObjectLiteral::kHasFunction |
| 1671 : ObjectLiteral::kNoFlags; | 1671 : ObjectLiteral::kNoFlags; |
| 1672 __ mov(r0, Operand(Smi::FromInt(flags))); | 1672 __ mov(r0, Operand(Smi::FromInt(flags))); |
| 1673 int properties_count = constant_properties->length() / 2; | 1673 int properties_count = constant_properties->length() / 2; |
| 1674 if (expr->may_store_doubles() || expr->depth() > 1 || Serializer::enabled() || | 1674 if (expr->may_store_doubles() || expr->depth() > 1 || Serializer::enabled() || |
| 1675 flags != ObjectLiteral::kFastElements || | 1675 flags != ObjectLiteral::kFastElements || |
| 1676 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { | 1676 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { |
| 1677 __ Push(r3, r2, r1, r0); | 1677 __ Push(r3, r2, r1, r0); |
| 1678 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); | 1678 __ CallRuntime(Runtime::kHiddenCreateObjectLiteral, 4); |
| 1679 } else { | 1679 } else { |
| 1680 FastCloneShallowObjectStub stub(properties_count); | 1680 FastCloneShallowObjectStub stub(properties_count); |
| 1681 __ CallStub(&stub); | 1681 __ CallStub(&stub); |
| 1682 } | 1682 } |
| 1683 | 1683 |
| 1684 // If result_saved is true the result is on top of the stack. If | 1684 // If result_saved is true the result is on top of the stack. If |
| 1685 // result_saved is false the result is in r0. | 1685 // result_saved is false the result is in r0. |
| 1686 bool result_saved = false; | 1686 bool result_saved = false; |
| 1687 | 1687 |
| 1688 // Mark all computed expressions that are bound to a key that | 1688 // Mark all computed expressions that are bound to a key that |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1819 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, | 1819 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, |
| 1820 allocation_site_mode, | 1820 allocation_site_mode, |
| 1821 length); | 1821 length); |
| 1822 __ CallStub(&stub); | 1822 __ CallStub(&stub); |
| 1823 __ IncrementCounter( | 1823 __ IncrementCounter( |
| 1824 isolate()->counters()->cow_arrays_created_stub(), 1, r1, r2); | 1824 isolate()->counters()->cow_arrays_created_stub(), 1, r1, r2); |
| 1825 } else if (expr->depth() > 1 || Serializer::enabled() || | 1825 } else if (expr->depth() > 1 || Serializer::enabled() || |
| 1826 length > FastCloneShallowArrayStub::kMaximumClonedLength) { | 1826 length > FastCloneShallowArrayStub::kMaximumClonedLength) { |
| 1827 __ mov(r0, Operand(Smi::FromInt(flags))); | 1827 __ mov(r0, Operand(Smi::FromInt(flags))); |
| 1828 __ Push(r3, r2, r1, r0); | 1828 __ Push(r3, r2, r1, r0); |
| 1829 __ CallRuntime(Runtime::kCreateArrayLiteral, 4); | 1829 __ CallRuntime(Runtime::kHiddenCreateArrayLiteral, 4); |
| 1830 } else { | 1830 } else { |
| 1831 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) || | 1831 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) || |
| 1832 FLAG_smi_only_arrays); | 1832 FLAG_smi_only_arrays); |
| 1833 FastCloneShallowArrayStub::Mode mode = | 1833 FastCloneShallowArrayStub::Mode mode = |
| 1834 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS; | 1834 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS; |
| 1835 | 1835 |
| 1836 if (has_fast_elements) { | 1836 if (has_fast_elements) { |
| 1837 mode = FastCloneShallowArrayStub::CLONE_ELEMENTS; | 1837 mode = FastCloneShallowArrayStub::CLONE_ELEMENTS; |
| 1838 } | 1838 } |
| 1839 | 1839 |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2020 __ mov(r1, Operand(Smi::FromInt(continuation.pos()))); | 2020 __ mov(r1, Operand(Smi::FromInt(continuation.pos()))); |
| 2021 __ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset)); | 2021 __ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset)); |
| 2022 __ str(cp, FieldMemOperand(r0, JSGeneratorObject::kContextOffset)); | 2022 __ str(cp, FieldMemOperand(r0, JSGeneratorObject::kContextOffset)); |
| 2023 __ mov(r1, cp); | 2023 __ mov(r1, cp); |
| 2024 __ RecordWriteField(r0, JSGeneratorObject::kContextOffset, r1, r2, | 2024 __ RecordWriteField(r0, JSGeneratorObject::kContextOffset, r1, r2, |
| 2025 kLRHasBeenSaved, kDontSaveFPRegs); | 2025 kLRHasBeenSaved, kDontSaveFPRegs); |
| 2026 __ add(r1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); | 2026 __ add(r1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); |
| 2027 __ cmp(sp, r1); | 2027 __ cmp(sp, r1); |
| 2028 __ b(eq, &post_runtime); | 2028 __ b(eq, &post_runtime); |
| 2029 __ push(r0); // generator object | 2029 __ push(r0); // generator object |
| 2030 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 2030 __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1); |
| 2031 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2031 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2032 __ bind(&post_runtime); | 2032 __ bind(&post_runtime); |
| 2033 __ pop(result_register()); | 2033 __ pop(result_register()); |
| 2034 EmitReturnSequence(); | 2034 EmitReturnSequence(); |
| 2035 | 2035 |
| 2036 __ bind(&resume); | 2036 __ bind(&resume); |
| 2037 context()->Plug(result_register()); | 2037 context()->Plug(result_register()); |
| 2038 break; | 2038 break; |
| 2039 } | 2039 } |
| 2040 | 2040 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2086 const int generator_object_depth = kPointerSize + handler_size; | 2086 const int generator_object_depth = kPointerSize + handler_size; |
| 2087 __ ldr(r0, MemOperand(sp, generator_object_depth)); | 2087 __ ldr(r0, MemOperand(sp, generator_object_depth)); |
| 2088 __ push(r0); // g | 2088 __ push(r0); // g |
| 2089 ASSERT(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos())); | 2089 ASSERT(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos())); |
| 2090 __ mov(r1, Operand(Smi::FromInt(l_continuation.pos()))); | 2090 __ mov(r1, Operand(Smi::FromInt(l_continuation.pos()))); |
| 2091 __ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset)); | 2091 __ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset)); |
| 2092 __ str(cp, FieldMemOperand(r0, JSGeneratorObject::kContextOffset)); | 2092 __ str(cp, FieldMemOperand(r0, JSGeneratorObject::kContextOffset)); |
| 2093 __ mov(r1, cp); | 2093 __ mov(r1, cp); |
| 2094 __ RecordWriteField(r0, JSGeneratorObject::kContextOffset, r1, r2, | 2094 __ RecordWriteField(r0, JSGeneratorObject::kContextOffset, r1, r2, |
| 2095 kLRHasBeenSaved, kDontSaveFPRegs); | 2095 kLRHasBeenSaved, kDontSaveFPRegs); |
| 2096 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 2096 __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1); |
| 2097 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2097 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2098 __ pop(r0); // result | 2098 __ pop(r0); // result |
| 2099 EmitReturnSequence(); | 2099 EmitReturnSequence(); |
| 2100 __ bind(&l_resume); // received in r0 | 2100 __ bind(&l_resume); // received in r0 |
| 2101 __ PopTryHandler(); | 2101 __ PopTryHandler(); |
| 2102 | 2102 |
| 2103 // receiver = iter; f = 'next'; arg = received; | 2103 // receiver = iter; f = 'next'; arg = received; |
| 2104 __ bind(&l_next); | 2104 __ bind(&l_next); |
| 2105 __ LoadRoot(r2, Heap::knext_stringRootIndex); // "next" | 2105 __ LoadRoot(r2, Heap::knext_stringRootIndex); // "next" |
| 2106 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter | 2106 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2138 break; | 2138 break; |
| 2139 } | 2139 } |
| 2140 } | 2140 } |
| 2141 } | 2141 } |
| 2142 | 2142 |
| 2143 | 2143 |
| 2144 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 2144 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
| 2145 Expression *value, | 2145 Expression *value, |
| 2146 JSGeneratorObject::ResumeMode resume_mode) { | 2146 JSGeneratorObject::ResumeMode resume_mode) { |
| 2147 // The value stays in r0, and is ultimately read by the resumed generator, as | 2147 // The value stays in r0, and is ultimately read by the resumed generator, as |
| 2148 // if the CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it | 2148 // if CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject) returned it. Or it |
| 2149 // is read to throw the value when the resumed generator is already closed. | 2149 // is read to throw the value when the resumed generator is already closed. |
| 2150 // r1 will hold the generator object until the activation has been resumed. | 2150 // r1 will hold the generator object until the activation has been resumed. |
| 2151 VisitForStackValue(generator); | 2151 VisitForStackValue(generator); |
| 2152 VisitForAccumulatorValue(value); | 2152 VisitForAccumulatorValue(value); |
| 2153 __ pop(r1); | 2153 __ pop(r1); |
| 2154 | 2154 |
| 2155 // Check generator state. | 2155 // Check generator state. |
| 2156 Label wrong_state, closed_state, done; | 2156 Label wrong_state, closed_state, done; |
| 2157 __ ldr(r3, FieldMemOperand(r1, JSGeneratorObject::kContinuationOffset)); | 2157 __ ldr(r3, FieldMemOperand(r1, JSGeneratorObject::kContinuationOffset)); |
| 2158 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0); | 2158 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2232 Label push_operand_holes, call_resume; | 2232 Label push_operand_holes, call_resume; |
| 2233 __ bind(&push_operand_holes); | 2233 __ bind(&push_operand_holes); |
| 2234 __ sub(r3, r3, Operand(1), SetCC); | 2234 __ sub(r3, r3, Operand(1), SetCC); |
| 2235 __ b(mi, &call_resume); | 2235 __ b(mi, &call_resume); |
| 2236 __ push(r2); | 2236 __ push(r2); |
| 2237 __ b(&push_operand_holes); | 2237 __ b(&push_operand_holes); |
| 2238 __ bind(&call_resume); | 2238 __ bind(&call_resume); |
| 2239 ASSERT(!result_register().is(r1)); | 2239 ASSERT(!result_register().is(r1)); |
| 2240 __ Push(r1, result_register()); | 2240 __ Push(r1, result_register()); |
| 2241 __ Push(Smi::FromInt(resume_mode)); | 2241 __ Push(Smi::FromInt(resume_mode)); |
| 2242 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); | 2242 __ CallRuntime(Runtime::kHiddenResumeJSGeneratorObject, 3); |
| 2243 // Not reached: the runtime call returns elsewhere. | 2243 // Not reached: the runtime call returns elsewhere. |
| 2244 __ stop("not-reached"); | 2244 __ stop("not-reached"); |
| 2245 | 2245 |
| 2246 // Reach here when generator is closed. | 2246 // Reach here when generator is closed. |
| 2247 __ bind(&closed_state); | 2247 __ bind(&closed_state); |
| 2248 if (resume_mode == JSGeneratorObject::NEXT) { | 2248 if (resume_mode == JSGeneratorObject::NEXT) { |
| 2249 // Return completed iterator result when generator is closed. | 2249 // Return completed iterator result when generator is closed. |
| 2250 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); | 2250 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
| 2251 __ push(r2); | 2251 __ push(r2); |
| 2252 // Pop value from top-of-stack slot; box result into result register. | 2252 // Pop value from top-of-stack slot; box result into result register. |
| 2253 EmitCreateIteratorResult(true); | 2253 EmitCreateIteratorResult(true); |
| 2254 } else { | 2254 } else { |
| 2255 // Throw the provided value. | 2255 // Throw the provided value. |
| 2256 __ push(r0); | 2256 __ push(r0); |
| 2257 __ CallRuntime(Runtime::kThrow, 1); | 2257 __ CallRuntime(Runtime::kHiddenThrow, 1); |
| 2258 } | 2258 } |
| 2259 __ jmp(&done); | 2259 __ jmp(&done); |
| 2260 | 2260 |
| 2261 // Throw error if we attempt to operate on a running generator. | 2261 // Throw error if we attempt to operate on a running generator. |
| 2262 __ bind(&wrong_state); | 2262 __ bind(&wrong_state); |
| 2263 __ push(r1); | 2263 __ push(r1); |
| 2264 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); | 2264 __ CallRuntime(Runtime::kHiddenThrowGeneratorStateError, 1); |
| 2265 | 2265 |
| 2266 __ bind(&done); | 2266 __ bind(&done); |
| 2267 context()->Plug(result_register()); | 2267 context()->Plug(result_register()); |
| 2268 } | 2268 } |
| 2269 | 2269 |
| 2270 | 2270 |
| 2271 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { | 2271 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { |
| 2272 Label gc_required; | 2272 Label gc_required; |
| 2273 Label allocated; | 2273 Label allocated; |
| 2274 | 2274 |
| 2275 Handle<Map> map(isolate()->native_context()->generator_result_map()); | 2275 Handle<Map> map(isolate()->native_context()->generator_result_map()); |
| 2276 | 2276 |
| 2277 __ Allocate(map->instance_size(), r0, r2, r3, &gc_required, TAG_OBJECT); | 2277 __ Allocate(map->instance_size(), r0, r2, r3, &gc_required, TAG_OBJECT); |
| 2278 __ jmp(&allocated); | 2278 __ jmp(&allocated); |
| 2279 | 2279 |
| 2280 __ bind(&gc_required); | 2280 __ bind(&gc_required); |
| 2281 __ Push(Smi::FromInt(map->instance_size())); | 2281 __ Push(Smi::FromInt(map->instance_size())); |
| 2282 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); | 2282 __ CallRuntime(Runtime::kHiddenAllocateInNewSpace, 1); |
| 2283 __ ldr(context_register(), | 2283 __ ldr(context_register(), |
| 2284 MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2284 MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2285 | 2285 |
| 2286 __ bind(&allocated); | 2286 __ bind(&allocated); |
| 2287 __ mov(r1, Operand(map)); | 2287 __ mov(r1, Operand(map)); |
| 2288 __ pop(r2); | 2288 __ pop(r2); |
| 2289 __ mov(r3, Operand(isolate()->factory()->ToBoolean(done))); | 2289 __ mov(r3, Operand(isolate()->factory()->ToBoolean(done))); |
| 2290 __ mov(r4, Operand(isolate()->factory()->empty_fixed_array())); | 2290 __ mov(r4, Operand(isolate()->factory()->empty_fixed_array())); |
| 2291 ASSERT_EQ(map->instance_size(), 5 * kPointerSize); | 2291 ASSERT_EQ(map->instance_size(), 5 * kPointerSize); |
| 2292 __ str(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); | 2292 __ str(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2486 } | 2486 } |
| 2487 } | 2487 } |
| 2488 | 2488 |
| 2489 | 2489 |
| 2490 void FullCodeGenerator::EmitCallStoreContextSlot( | 2490 void FullCodeGenerator::EmitCallStoreContextSlot( |
| 2491 Handle<String> name, StrictMode strict_mode) { | 2491 Handle<String> name, StrictMode strict_mode) { |
| 2492 __ push(r0); // Value. | 2492 __ push(r0); // Value. |
| 2493 __ mov(r1, Operand(name)); | 2493 __ mov(r1, Operand(name)); |
| 2494 __ mov(r0, Operand(Smi::FromInt(strict_mode))); | 2494 __ mov(r0, Operand(Smi::FromInt(strict_mode))); |
| 2495 __ Push(cp, r1, r0); // Context, name, strict mode. | 2495 __ Push(cp, r1, r0); // Context, name, strict mode. |
| 2496 __ CallRuntime(Runtime::kStoreContextSlot, 4); | 2496 __ CallRuntime(Runtime::kHiddenStoreContextSlot, 4); |
| 2497 } | 2497 } |
| 2498 | 2498 |
| 2499 | 2499 |
| 2500 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) { | 2500 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) { |
| 2501 if (var->IsUnallocated()) { | 2501 if (var->IsUnallocated()) { |
| 2502 // Global var, const, or let. | 2502 // Global var, const, or let. |
| 2503 __ mov(r2, Operand(var->name())); | 2503 __ mov(r2, Operand(var->name())); |
| 2504 __ ldr(r1, GlobalObjectOperand()); | 2504 __ ldr(r1, GlobalObjectOperand()); |
| 2505 CallStoreIC(); | 2505 CallStoreIC(); |
| 2506 | 2506 |
| 2507 } else if (op == Token::INIT_CONST_LEGACY) { | 2507 } else if (op == Token::INIT_CONST_LEGACY) { |
| 2508 // Const initializers need a write barrier. | 2508 // Const initializers need a write barrier. |
| 2509 ASSERT(!var->IsParameter()); // No const parameters. | 2509 ASSERT(!var->IsParameter()); // No const parameters. |
| 2510 if (var->IsLookupSlot()) { | 2510 if (var->IsLookupSlot()) { |
| 2511 __ push(r0); | 2511 __ push(r0); |
| 2512 __ mov(r0, Operand(var->name())); | 2512 __ mov(r0, Operand(var->name())); |
| 2513 __ Push(cp, r0); // Context and name. | 2513 __ Push(cp, r0); // Context and name. |
| 2514 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); | 2514 __ CallRuntime(Runtime::kHiddenInitializeConstContextSlot, 3); |
| 2515 } else { | 2515 } else { |
| 2516 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 2516 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); |
| 2517 Label skip; | 2517 Label skip; |
| 2518 MemOperand location = VarOperand(var, r1); | 2518 MemOperand location = VarOperand(var, r1); |
| 2519 __ ldr(r2, location); | 2519 __ ldr(r2, location); |
| 2520 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); | 2520 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); |
| 2521 __ b(ne, &skip); | 2521 __ b(ne, &skip); |
| 2522 EmitStoreToStackLocalOrContextSlot(var, location); | 2522 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2523 __ bind(&skip); | 2523 __ bind(&skip); |
| 2524 } | 2524 } |
| 2525 | 2525 |
| 2526 } else if (var->mode() == LET && op != Token::INIT_LET) { | 2526 } else if (var->mode() == LET && op != Token::INIT_LET) { |
| 2527 // Non-initializing assignment to let variable needs a write barrier. | 2527 // Non-initializing assignment to let variable needs a write barrier. |
| 2528 if (var->IsLookupSlot()) { | 2528 if (var->IsLookupSlot()) { |
| 2529 EmitCallStoreContextSlot(var->name(), strict_mode()); | 2529 EmitCallStoreContextSlot(var->name(), strict_mode()); |
| 2530 } else { | 2530 } else { |
| 2531 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 2531 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); |
| 2532 Label assign; | 2532 Label assign; |
| 2533 MemOperand location = VarOperand(var, r1); | 2533 MemOperand location = VarOperand(var, r1); |
| 2534 __ ldr(r3, location); | 2534 __ ldr(r3, location); |
| 2535 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); | 2535 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); |
| 2536 __ b(ne, &assign); | 2536 __ b(ne, &assign); |
| 2537 __ mov(r3, Operand(var->name())); | 2537 __ mov(r3, Operand(var->name())); |
| 2538 __ push(r3); | 2538 __ push(r3); |
| 2539 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 2539 __ CallRuntime(Runtime::kHiddenThrowReferenceError, 1); |
| 2540 // Perform the assignment. | 2540 // Perform the assignment. |
| 2541 __ bind(&assign); | 2541 __ bind(&assign); |
| 2542 EmitStoreToStackLocalOrContextSlot(var, location); | 2542 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2543 } | 2543 } |
| 2544 | 2544 |
| 2545 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { | 2545 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { |
| 2546 // Assignment to var or initializing assignment to let/const | 2546 // Assignment to var or initializing assignment to let/const |
| 2547 // in harmony mode. | 2547 // in harmony mode. |
| 2548 if (var->IsLookupSlot()) { | 2548 if (var->IsLookupSlot()) { |
| 2549 EmitCallStoreContextSlot(var->name(), strict_mode()); | 2549 EmitCallStoreContextSlot(var->name(), strict_mode()); |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2762 __ ldr(r3, MemOperand(fp, receiver_offset * kPointerSize)); | 2762 __ ldr(r3, MemOperand(fp, receiver_offset * kPointerSize)); |
| 2763 | 2763 |
| 2764 // r2: strict mode. | 2764 // r2: strict mode. |
| 2765 __ mov(r2, Operand(Smi::FromInt(strict_mode()))); | 2765 __ mov(r2, Operand(Smi::FromInt(strict_mode()))); |
| 2766 | 2766 |
| 2767 // r1: the start position of the scope the calls resides in. | 2767 // r1: the start position of the scope the calls resides in. |
| 2768 __ mov(r1, Operand(Smi::FromInt(scope()->start_position()))); | 2768 __ mov(r1, Operand(Smi::FromInt(scope()->start_position()))); |
| 2769 | 2769 |
| 2770 // Do the runtime call. | 2770 // Do the runtime call. |
| 2771 __ Push(r4, r3, r2, r1); | 2771 __ Push(r4, r3, r2, r1); |
| 2772 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); | 2772 __ CallRuntime(Runtime::kHiddenResolvePossiblyDirectEval, 5); |
| 2773 } | 2773 } |
| 2774 | 2774 |
| 2775 | 2775 |
| 2776 void FullCodeGenerator::VisitCall(Call* expr) { | 2776 void FullCodeGenerator::VisitCall(Call* expr) { |
| 2777 #ifdef DEBUG | 2777 #ifdef DEBUG |
| 2778 // We want to verify that RecordJSReturnSite gets called on all paths | 2778 // We want to verify that RecordJSReturnSite gets called on all paths |
| 2779 // through this function. Avoid early returns. | 2779 // through this function. Avoid early returns. |
| 2780 expr->return_is_recorded_ = false; | 2780 expr->return_is_recorded_ = false; |
| 2781 #endif | 2781 #endif |
| 2782 | 2782 |
| 2783 Comment cmnt(masm_, "[ Call"); | 2783 Comment cmnt(masm_, "[ Call"); |
| 2784 Expression* callee = expr->expression(); | 2784 Expression* callee = expr->expression(); |
| 2785 Call::CallType call_type = expr->GetCallType(isolate()); | 2785 Call::CallType call_type = expr->GetCallType(isolate()); |
| 2786 | 2786 |
| 2787 if (call_type == Call::POSSIBLY_EVAL_CALL) { | 2787 if (call_type == Call::POSSIBLY_EVAL_CALL) { |
| 2788 // In a call to eval, we first call %ResolvePossiblyDirectEval to | 2788 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval |
| 2789 // resolve the function we need to call and the receiver of the | 2789 // to resolve the function we need to call and the receiver of the |
| 2790 // call. Then we call the resolved function using the given | 2790 // call. Then we call the resolved function using the given |
| 2791 // arguments. | 2791 // arguments. |
| 2792 ZoneList<Expression*>* args = expr->arguments(); | 2792 ZoneList<Expression*>* args = expr->arguments(); |
| 2793 int arg_count = args->length(); | 2793 int arg_count = args->length(); |
| 2794 | 2794 |
| 2795 { PreservePositionScope pos_scope(masm()->positions_recorder()); | 2795 { PreservePositionScope pos_scope(masm()->positions_recorder()); |
| 2796 VisitForStackValue(callee); | 2796 VisitForStackValue(callee); |
| 2797 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); | 2797 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
| 2798 __ push(r2); // Reserved receiver slot. | 2798 __ push(r2); // Reserved receiver slot. |
| 2799 | 2799 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2836 // by eval-introduced variables. | 2836 // by eval-introduced variables. |
| 2837 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); | 2837 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); |
| 2838 } | 2838 } |
| 2839 | 2839 |
| 2840 __ bind(&slow); | 2840 __ bind(&slow); |
| 2841 // Call the runtime to find the function to call (returned in r0) | 2841 // Call the runtime to find the function to call (returned in r0) |
| 2842 // and the object holding it (returned in edx). | 2842 // and the object holding it (returned in edx). |
| 2843 ASSERT(!context_register().is(r2)); | 2843 ASSERT(!context_register().is(r2)); |
| 2844 __ mov(r2, Operand(proxy->name())); | 2844 __ mov(r2, Operand(proxy->name())); |
| 2845 __ Push(context_register(), r2); | 2845 __ Push(context_register(), r2); |
| 2846 __ CallRuntime(Runtime::kLoadContextSlot, 2); | 2846 __ CallRuntime(Runtime::kHiddenLoadContextSlot, 2); |
| 2847 __ Push(r0, r1); // Function, receiver. | 2847 __ Push(r0, r1); // Function, receiver. |
| 2848 | 2848 |
| 2849 // If fast case code has been generated, emit code to push the | 2849 // If fast case code has been generated, emit code to push the |
| 2850 // function and receiver and have the slow path jump around this | 2850 // function and receiver and have the slow path jump around this |
| 2851 // code. | 2851 // code. |
| 2852 if (done.is_linked()) { | 2852 if (done.is_linked()) { |
| 2853 Label call; | 2853 Label call; |
| 2854 __ b(&call); | 2854 __ b(&call); |
| 2855 __ bind(&done); | 2855 __ bind(&done); |
| 2856 // Push function. | 2856 // Push function. |
| (...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3491 __ jmp(&done); | 3491 __ jmp(&done); |
| 3492 } | 3492 } |
| 3493 __ bind(&runtime); | 3493 __ bind(&runtime); |
| 3494 __ PrepareCallCFunction(2, scratch1); | 3494 __ PrepareCallCFunction(2, scratch1); |
| 3495 __ mov(r1, Operand(index)); | 3495 __ mov(r1, Operand(index)); |
| 3496 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); | 3496 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); |
| 3497 __ jmp(&done); | 3497 __ jmp(&done); |
| 3498 } | 3498 } |
| 3499 | 3499 |
| 3500 __ bind(¬_date_object); | 3500 __ bind(¬_date_object); |
| 3501 __ CallRuntime(Runtime::kThrowNotDateError, 0); | 3501 __ CallRuntime(Runtime::kHiddenThrowNotDateError, 0); |
| 3502 __ bind(&done); | 3502 __ bind(&done); |
| 3503 context()->Plug(r0); | 3503 context()->Plug(r0); |
| 3504 } | 3504 } |
| 3505 | 3505 |
| 3506 | 3506 |
| 3507 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { | 3507 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { |
| 3508 ZoneList<Expression*>* args = expr->arguments(); | 3508 ZoneList<Expression*>* args = expr->arguments(); |
| 3509 ASSERT_EQ(3, args->length()); | 3509 ASSERT_EQ(3, args->length()); |
| 3510 | 3510 |
| 3511 Register string = r0; | 3511 Register string = r0; |
| (...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4228 } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 4228 } else if (var->IsStackAllocated() || var->IsContextSlot()) { |
| 4229 // Result of deleting non-global, non-dynamic variables is false. | 4229 // Result of deleting non-global, non-dynamic variables is false. |
| 4230 // The subexpression does not have side effects. | 4230 // The subexpression does not have side effects. |
| 4231 context()->Plug(var->is_this()); | 4231 context()->Plug(var->is_this()); |
| 4232 } else { | 4232 } else { |
| 4233 // Non-global variable. Call the runtime to try to delete from the | 4233 // Non-global variable. Call the runtime to try to delete from the |
| 4234 // context where the variable was introduced. | 4234 // context where the variable was introduced. |
| 4235 ASSERT(!context_register().is(r2)); | 4235 ASSERT(!context_register().is(r2)); |
| 4236 __ mov(r2, Operand(var->name())); | 4236 __ mov(r2, Operand(var->name())); |
| 4237 __ Push(context_register(), r2); | 4237 __ Push(context_register(), r2); |
| 4238 __ CallRuntime(Runtime::kDeleteContextSlot, 2); | 4238 __ CallRuntime(Runtime::kHiddenDeleteContextSlot, 2); |
| 4239 context()->Plug(r0); | 4239 context()->Plug(r0); |
| 4240 } | 4240 } |
| 4241 } else { | 4241 } else { |
| 4242 // Result of deleting non-property, non-variable reference is true. | 4242 // Result of deleting non-property, non-variable reference is true. |
| 4243 // The subexpression may have side effects. | 4243 // The subexpression may have side effects. |
| 4244 VisitForEffect(expr->expression()); | 4244 VisitForEffect(expr->expression()); |
| 4245 context()->Plug(true); | 4245 context()->Plug(true); |
| 4246 } | 4246 } |
| 4247 break; | 4247 break; |
| 4248 } | 4248 } |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4505 Comment cmnt(masm_, "[ Lookup slot"); | 4505 Comment cmnt(masm_, "[ Lookup slot"); |
| 4506 Label done, slow; | 4506 Label done, slow; |
| 4507 | 4507 |
| 4508 // Generate code for loading from variables potentially shadowed | 4508 // Generate code for loading from variables potentially shadowed |
| 4509 // by eval-introduced variables. | 4509 // by eval-introduced variables. |
| 4510 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); | 4510 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); |
| 4511 | 4511 |
| 4512 __ bind(&slow); | 4512 __ bind(&slow); |
| 4513 __ mov(r0, Operand(proxy->name())); | 4513 __ mov(r0, Operand(proxy->name())); |
| 4514 __ Push(cp, r0); | 4514 __ Push(cp, r0); |
| 4515 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); | 4515 __ CallRuntime(Runtime::kHiddenLoadContextSlotNoReferenceError, 2); |
| 4516 PrepareForBailout(expr, TOS_REG); | 4516 PrepareForBailout(expr, TOS_REG); |
| 4517 __ bind(&done); | 4517 __ bind(&done); |
| 4518 | 4518 |
| 4519 context()->Plug(r0); | 4519 context()->Plug(r0); |
| 4520 } else { | 4520 } else { |
| 4521 // This expression cannot throw a reference error at the top level. | 4521 // This expression cannot throw a reference error at the top level. |
| 4522 VisitInDuplicateContext(expr); | 4522 VisitInDuplicateContext(expr); |
| 4523 } | 4523 } |
| 4524 } | 4524 } |
| 4525 | 4525 |
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4943 | 4943 |
| 4944 ASSERT(interrupt_address == | 4944 ASSERT(interrupt_address == |
| 4945 isolate->builtins()->OsrAfterStackCheck()->entry()); | 4945 isolate->builtins()->OsrAfterStackCheck()->entry()); |
| 4946 return OSR_AFTER_STACK_CHECK; | 4946 return OSR_AFTER_STACK_CHECK; |
| 4947 } | 4947 } |
| 4948 | 4948 |
| 4949 | 4949 |
| 4950 } } // namespace v8::internal | 4950 } } // namespace v8::internal |
| 4951 | 4951 |
| 4952 #endif // V8_TARGET_ARCH_ARM | 4952 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |