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 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 bool function_in_register = true; | 236 bool function_in_register = true; |
237 | 237 |
238 // Possibly allocate a local context. | 238 // Possibly allocate a local context. |
239 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 239 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
240 if (heap_slots > 0) { | 240 if (heap_slots > 0) { |
241 Comment cmnt(masm_, "[ Allocate context"); | 241 Comment cmnt(masm_, "[ Allocate context"); |
242 // Argument to NewContext is the function, which is still in a1. | 242 // Argument to NewContext is the function, which is still in a1. |
243 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { | 243 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { |
244 __ push(a1); | 244 __ push(a1); |
245 __ Push(info->scope()->GetScopeInfo()); | 245 __ Push(info->scope()->GetScopeInfo()); |
246 __ CallRuntime(Runtime::kNewGlobalContext, 2); | 246 __ CallRuntime(Runtime::kHiddenNewGlobalContext, 2); |
247 } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { | 247 } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { |
248 FastNewContextStub stub(heap_slots); | 248 FastNewContextStub stub(heap_slots); |
249 __ CallStub(&stub); | 249 __ CallStub(&stub); |
250 } else { | 250 } else { |
251 __ push(a1); | 251 __ push(a1); |
252 __ CallRuntime(Runtime::kNewFunctionContext, 1); | 252 __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); |
253 } | 253 } |
254 function_in_register = false; | 254 function_in_register = false; |
255 // Context is returned in v0. It replaces the context passed to us. | 255 // Context is returned in v0. It replaces the context passed to us. |
256 // It's saved in the stack and kept live in cp. | 256 // It's saved in the stack and kept live in cp. |
257 __ mov(cp, v0); | 257 __ mov(cp, v0); |
258 __ sw(v0, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 258 __ sw(v0, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
259 // Copy any necessary parameters into the context. | 259 // Copy any necessary parameters into the context. |
260 int num_parameters = info->scope()->num_parameters(); | 260 int num_parameters = info->scope()->num_parameters(); |
261 for (int i = 0; i < num_parameters; i++) { | 261 for (int i = 0; i < num_parameters; i++) { |
262 Variable* var = scope()->parameter(i); | 262 Variable* var = scope()->parameter(i); |
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
870 // 'undefined') because we may have a (legal) redeclaration and we | 870 // 'undefined') because we may have a (legal) redeclaration and we |
871 // must not destroy the current value. | 871 // must not destroy the current value. |
872 if (hole_init) { | 872 if (hole_init) { |
873 __ LoadRoot(a0, Heap::kTheHoleValueRootIndex); | 873 __ LoadRoot(a0, Heap::kTheHoleValueRootIndex); |
874 __ Push(cp, a2, a1, a0); | 874 __ Push(cp, a2, a1, a0); |
875 } else { | 875 } else { |
876 ASSERT(Smi::FromInt(0) == 0); | 876 ASSERT(Smi::FromInt(0) == 0); |
877 __ mov(a0, zero_reg); // Smi::FromInt(0) indicates no initial value. | 877 __ mov(a0, zero_reg); // Smi::FromInt(0) indicates no initial value. |
878 __ Push(cp, a2, a1, a0); | 878 __ Push(cp, a2, a1, a0); |
879 } | 879 } |
880 __ CallRuntime(Runtime::kDeclareContextSlot, 4); | 880 __ CallRuntime(Runtime::kHiddenDeclareContextSlot, 4); |
881 break; | 881 break; |
882 } | 882 } |
883 } | 883 } |
884 } | 884 } |
885 | 885 |
886 | 886 |
887 void FullCodeGenerator::VisitFunctionDeclaration( | 887 void FullCodeGenerator::VisitFunctionDeclaration( |
888 FunctionDeclaration* declaration) { | 888 FunctionDeclaration* declaration) { |
889 VariableProxy* proxy = declaration->proxy(); | 889 VariableProxy* proxy = declaration->proxy(); |
890 Variable* variable = proxy->var(); | 890 Variable* variable = proxy->var(); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
926 break; | 926 break; |
927 } | 927 } |
928 | 928 |
929 case Variable::LOOKUP: { | 929 case Variable::LOOKUP: { |
930 Comment cmnt(masm_, "[ FunctionDeclaration"); | 930 Comment cmnt(masm_, "[ FunctionDeclaration"); |
931 __ li(a2, Operand(variable->name())); | 931 __ li(a2, Operand(variable->name())); |
932 __ li(a1, Operand(Smi::FromInt(NONE))); | 932 __ li(a1, Operand(Smi::FromInt(NONE))); |
933 __ Push(cp, a2, a1); | 933 __ Push(cp, a2, a1); |
934 // Push initial value for function declaration. | 934 // Push initial value for function declaration. |
935 VisitForStackValue(declaration->fun()); | 935 VisitForStackValue(declaration->fun()); |
936 __ CallRuntime(Runtime::kDeclareContextSlot, 4); | 936 __ CallRuntime(Runtime::kHiddenDeclareContextSlot, 4); |
937 break; | 937 break; |
938 } | 938 } |
939 } | 939 } |
940 } | 940 } |
941 | 941 |
942 | 942 |
943 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { | 943 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { |
944 Variable* variable = declaration->proxy()->var(); | 944 Variable* variable = declaration->proxy()->var(); |
945 ASSERT(variable->location() == Variable::CONTEXT); | 945 ASSERT(variable->location() == Variable::CONTEXT); |
946 ASSERT(variable->interface()->IsFrozen()); | 946 ASSERT(variable->interface()->IsFrozen()); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
998 // TODO(rossberg) | 998 // TODO(rossberg) |
999 } | 999 } |
1000 | 1000 |
1001 | 1001 |
1002 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 1002 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
1003 // Call the runtime to declare the globals. | 1003 // Call the runtime to declare the globals. |
1004 // The context is the first argument. | 1004 // The context is the first argument. |
1005 __ li(a1, Operand(pairs)); | 1005 __ li(a1, Operand(pairs)); |
1006 __ li(a0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); | 1006 __ li(a0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); |
1007 __ Push(cp, a1, a0); | 1007 __ Push(cp, a1, a0); |
1008 __ CallRuntime(Runtime::kDeclareGlobals, 3); | 1008 __ CallRuntime(Runtime::kHiddenDeclareGlobals, 3); |
1009 // Return value is ignored. | 1009 // Return value is ignored. |
1010 } | 1010 } |
1011 | 1011 |
1012 | 1012 |
1013 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) { | 1013 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) { |
1014 // Call the runtime to declare the modules. | 1014 // Call the runtime to declare the modules. |
1015 __ Push(descriptions); | 1015 __ Push(descriptions); |
1016 __ CallRuntime(Runtime::kDeclareModules, 1); | 1016 __ CallRuntime(Runtime::kHiddenDeclareModules, 1); |
1017 // Return value is ignored. | 1017 // Return value is ignored. |
1018 } | 1018 } |
1019 | 1019 |
1020 | 1020 |
1021 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { | 1021 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { |
1022 Comment cmnt(masm_, "[ SwitchStatement"); | 1022 Comment cmnt(masm_, "[ SwitchStatement"); |
1023 Breakable nested_statement(this, stmt); | 1023 Breakable nested_statement(this, stmt); |
1024 SetStatementPosition(stmt); | 1024 SetStatementPosition(stmt); |
1025 | 1025 |
1026 // Keep the switch value on the stack until a case matches. | 1026 // Keep the switch value on the stack until a case matches. |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1365 scope()->is_function_scope() && | 1365 scope()->is_function_scope() && |
1366 info->num_literals() == 0) { | 1366 info->num_literals() == 0) { |
1367 FastNewClosureStub stub(info->strict_mode(), info->is_generator()); | 1367 FastNewClosureStub stub(info->strict_mode(), info->is_generator()); |
1368 __ li(a2, Operand(info)); | 1368 __ li(a2, Operand(info)); |
1369 __ CallStub(&stub); | 1369 __ CallStub(&stub); |
1370 } else { | 1370 } else { |
1371 __ li(a0, Operand(info)); | 1371 __ li(a0, Operand(info)); |
1372 __ LoadRoot(a1, pretenure ? Heap::kTrueValueRootIndex | 1372 __ LoadRoot(a1, pretenure ? Heap::kTrueValueRootIndex |
1373 : Heap::kFalseValueRootIndex); | 1373 : Heap::kFalseValueRootIndex); |
1374 __ Push(cp, a0, a1); | 1374 __ Push(cp, a0, a1); |
1375 __ CallRuntime(Runtime::kNewClosure, 3); | 1375 __ CallRuntime(Runtime::kHiddenNewClosure, 3); |
1376 } | 1376 } |
1377 context()->Plug(v0); | 1377 context()->Plug(v0); |
1378 } | 1378 } |
1379 | 1379 |
1380 | 1380 |
1381 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { | 1381 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
1382 Comment cmnt(masm_, "[ VariableProxy"); | 1382 Comment cmnt(masm_, "[ VariableProxy"); |
1383 EmitVariableLoad(expr); | 1383 EmitVariableLoad(expr); |
1384 } | 1384 } |
1385 | 1385 |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1487 local->mode() == CONST_LEGACY) { | 1487 local->mode() == CONST_LEGACY) { |
1488 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 1488 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
1489 __ subu(at, v0, at); // Sub as compare: at == 0 on eq. | 1489 __ subu(at, v0, at); // Sub as compare: at == 0 on eq. |
1490 if (local->mode() == CONST_LEGACY) { | 1490 if (local->mode() == CONST_LEGACY) { |
1491 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); | 1491 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); |
1492 __ Movz(v0, a0, at); // Conditional move: return Undefined if TheHole. | 1492 __ Movz(v0, a0, at); // Conditional move: return Undefined if TheHole. |
1493 } else { // LET || CONST | 1493 } else { // LET || CONST |
1494 __ Branch(done, ne, at, Operand(zero_reg)); | 1494 __ Branch(done, ne, at, Operand(zero_reg)); |
1495 __ li(a0, Operand(var->name())); | 1495 __ li(a0, Operand(var->name())); |
1496 __ push(a0); | 1496 __ push(a0); |
1497 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 1497 __ CallRuntime(Runtime::kHiddenThrowReferenceError, 1); |
1498 } | 1498 } |
1499 } | 1499 } |
1500 __ Branch(done); | 1500 __ Branch(done); |
1501 } | 1501 } |
1502 } | 1502 } |
1503 | 1503 |
1504 | 1504 |
1505 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { | 1505 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
1506 // Record position before possible IC call. | 1506 // Record position before possible IC call. |
1507 SetSourcePosition(proxy->position()); | 1507 SetSourcePosition(proxy->position()); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1566 GetVar(v0, var); | 1566 GetVar(v0, var); |
1567 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 1567 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
1568 __ subu(at, v0, at); // Sub as compare: at == 0 on eq. | 1568 __ subu(at, v0, at); // Sub as compare: at == 0 on eq. |
1569 if (var->mode() == LET || var->mode() == CONST) { | 1569 if (var->mode() == LET || var->mode() == CONST) { |
1570 // Throw a reference error when using an uninitialized let/const | 1570 // Throw a reference error when using an uninitialized let/const |
1571 // binding in harmony mode. | 1571 // binding in harmony mode. |
1572 Label done; | 1572 Label done; |
1573 __ Branch(&done, ne, at, Operand(zero_reg)); | 1573 __ Branch(&done, ne, at, Operand(zero_reg)); |
1574 __ li(a0, Operand(var->name())); | 1574 __ li(a0, Operand(var->name())); |
1575 __ push(a0); | 1575 __ push(a0); |
1576 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 1576 __ CallRuntime(Runtime::kHiddenThrowReferenceError, 1); |
1577 __ bind(&done); | 1577 __ bind(&done); |
1578 } else { | 1578 } else { |
1579 // Uninitalized const bindings outside of harmony mode are unholed. | 1579 // Uninitalized const bindings outside of harmony mode are unholed. |
1580 ASSERT(var->mode() == CONST_LEGACY); | 1580 ASSERT(var->mode() == CONST_LEGACY); |
1581 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); | 1581 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); |
1582 __ Movz(v0, a0, at); // Conditional move: Undefined if TheHole. | 1582 __ Movz(v0, a0, at); // Conditional move: Undefined if TheHole. |
1583 } | 1583 } |
1584 context()->Plug(v0); | 1584 context()->Plug(v0); |
1585 break; | 1585 break; |
1586 } | 1586 } |
1587 } | 1587 } |
1588 context()->Plug(var); | 1588 context()->Plug(var); |
1589 break; | 1589 break; |
1590 } | 1590 } |
1591 | 1591 |
1592 case Variable::LOOKUP: { | 1592 case Variable::LOOKUP: { |
1593 Comment cmnt(masm_, "[ Lookup variable"); | 1593 Comment cmnt(masm_, "[ Lookup variable"); |
1594 Label done, slow; | 1594 Label done, slow; |
1595 // Generate code for loading from variables potentially shadowed | 1595 // Generate code for loading from variables potentially shadowed |
1596 // by eval-introduced variables. | 1596 // by eval-introduced variables. |
1597 EmitDynamicLookupFastCase(var, NOT_INSIDE_TYPEOF, &slow, &done); | 1597 EmitDynamicLookupFastCase(var, NOT_INSIDE_TYPEOF, &slow, &done); |
1598 __ bind(&slow); | 1598 __ bind(&slow); |
1599 __ li(a1, Operand(var->name())); | 1599 __ li(a1, Operand(var->name())); |
1600 __ Push(cp, a1); // Context and name. | 1600 __ Push(cp, a1); // Context and name. |
1601 __ CallRuntime(Runtime::kLoadContextSlot, 2); | 1601 __ CallRuntime(Runtime::kHiddenLoadContextSlot, 2); |
1602 __ bind(&done); | 1602 __ bind(&done); |
1603 context()->Plug(v0); | 1603 context()->Plug(v0); |
1604 } | 1604 } |
1605 } | 1605 } |
1606 } | 1606 } |
1607 | 1607 |
1608 | 1608 |
1609 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 1609 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
1610 Comment cmnt(masm_, "[ RegExpLiteral"); | 1610 Comment cmnt(masm_, "[ RegExpLiteral"); |
1611 Label materialized; | 1611 Label materialized; |
(...skipping 11 matching lines...) Expand all Loading... |
1623 __ lw(t1, FieldMemOperand(t0, literal_offset)); | 1623 __ lw(t1, FieldMemOperand(t0, literal_offset)); |
1624 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 1624 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
1625 __ Branch(&materialized, ne, t1, Operand(at)); | 1625 __ Branch(&materialized, ne, t1, Operand(at)); |
1626 | 1626 |
1627 // Create regexp literal using runtime function. | 1627 // Create regexp literal using runtime function. |
1628 // Result will be in v0. | 1628 // Result will be in v0. |
1629 __ li(a3, Operand(Smi::FromInt(expr->literal_index()))); | 1629 __ li(a3, Operand(Smi::FromInt(expr->literal_index()))); |
1630 __ li(a2, Operand(expr->pattern())); | 1630 __ li(a2, Operand(expr->pattern())); |
1631 __ li(a1, Operand(expr->flags())); | 1631 __ li(a1, Operand(expr->flags())); |
1632 __ Push(t0, a3, a2, a1); | 1632 __ Push(t0, a3, a2, a1); |
1633 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); | 1633 __ CallRuntime(Runtime::kHiddenMaterializeRegExpLiteral, 4); |
1634 __ mov(t1, v0); | 1634 __ mov(t1, v0); |
1635 | 1635 |
1636 __ bind(&materialized); | 1636 __ bind(&materialized); |
1637 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; | 1637 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; |
1638 Label allocated, runtime_allocate; | 1638 Label allocated, runtime_allocate; |
1639 __ Allocate(size, v0, a2, a3, &runtime_allocate, TAG_OBJECT); | 1639 __ Allocate(size, v0, a2, a3, &runtime_allocate, TAG_OBJECT); |
1640 __ jmp(&allocated); | 1640 __ jmp(&allocated); |
1641 | 1641 |
1642 __ bind(&runtime_allocate); | 1642 __ bind(&runtime_allocate); |
1643 __ li(a0, Operand(Smi::FromInt(size))); | 1643 __ li(a0, Operand(Smi::FromInt(size))); |
1644 __ Push(t1, a0); | 1644 __ Push(t1, a0); |
1645 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); | 1645 __ CallRuntime(Runtime::kHiddenAllocateInNewSpace, 1); |
1646 __ pop(t1); | 1646 __ pop(t1); |
1647 | 1647 |
1648 __ bind(&allocated); | 1648 __ bind(&allocated); |
1649 | 1649 |
1650 // After this, registers are used as follows: | 1650 // After this, registers are used as follows: |
1651 // v0: Newly allocated regexp. | 1651 // v0: Newly allocated regexp. |
1652 // t1: Materialized regexp. | 1652 // t1: Materialized regexp. |
1653 // a2: temp. | 1653 // a2: temp. |
1654 __ CopyFields(v0, t1, a2.bit(), size / kPointerSize); | 1654 __ CopyFields(v0, t1, a2.bit(), size / kPointerSize); |
1655 context()->Plug(v0); | 1655 context()->Plug(v0); |
(...skipping 24 matching lines...) Expand all Loading... |
1680 : ObjectLiteral::kNoFlags; | 1680 : ObjectLiteral::kNoFlags; |
1681 flags |= expr->has_function() | 1681 flags |= expr->has_function() |
1682 ? ObjectLiteral::kHasFunction | 1682 ? ObjectLiteral::kHasFunction |
1683 : ObjectLiteral::kNoFlags; | 1683 : ObjectLiteral::kNoFlags; |
1684 __ li(a0, Operand(Smi::FromInt(flags))); | 1684 __ li(a0, Operand(Smi::FromInt(flags))); |
1685 int properties_count = constant_properties->length() / 2; | 1685 int properties_count = constant_properties->length() / 2; |
1686 if (expr->may_store_doubles() || expr->depth() > 1 || Serializer::enabled() || | 1686 if (expr->may_store_doubles() || expr->depth() > 1 || Serializer::enabled() || |
1687 flags != ObjectLiteral::kFastElements || | 1687 flags != ObjectLiteral::kFastElements || |
1688 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { | 1688 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { |
1689 __ Push(a3, a2, a1, a0); | 1689 __ Push(a3, a2, a1, a0); |
1690 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); | 1690 __ CallRuntime(Runtime::kHiddenCreateObjectLiteral, 4); |
1691 } else { | 1691 } else { |
1692 FastCloneShallowObjectStub stub(properties_count); | 1692 FastCloneShallowObjectStub stub(properties_count); |
1693 __ CallStub(&stub); | 1693 __ CallStub(&stub); |
1694 } | 1694 } |
1695 | 1695 |
1696 // If result_saved is true the result is on top of the stack. If | 1696 // If result_saved is true the result is on top of the stack. If |
1697 // result_saved is false the result is in v0. | 1697 // result_saved is false the result is in v0. |
1698 bool result_saved = false; | 1698 bool result_saved = false; |
1699 | 1699 |
1700 // Mark all computed expressions that are bound to a key that | 1700 // Mark all computed expressions that are bound to a key that |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1834 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, | 1834 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, |
1835 allocation_site_mode, | 1835 allocation_site_mode, |
1836 length); | 1836 length); |
1837 __ CallStub(&stub); | 1837 __ CallStub(&stub); |
1838 __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), | 1838 __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), |
1839 1, a1, a2); | 1839 1, a1, a2); |
1840 } else if (expr->depth() > 1 || Serializer::enabled() || | 1840 } else if (expr->depth() > 1 || Serializer::enabled() || |
1841 length > FastCloneShallowArrayStub::kMaximumClonedLength) { | 1841 length > FastCloneShallowArrayStub::kMaximumClonedLength) { |
1842 __ li(a0, Operand(Smi::FromInt(flags))); | 1842 __ li(a0, Operand(Smi::FromInt(flags))); |
1843 __ Push(a3, a2, a1, a0); | 1843 __ Push(a3, a2, a1, a0); |
1844 __ CallRuntime(Runtime::kCreateArrayLiteral, 4); | 1844 __ CallRuntime(Runtime::kHiddenCreateArrayLiteral, 4); |
1845 } else { | 1845 } else { |
1846 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) || | 1846 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) || |
1847 FLAG_smi_only_arrays); | 1847 FLAG_smi_only_arrays); |
1848 FastCloneShallowArrayStub::Mode mode = | 1848 FastCloneShallowArrayStub::Mode mode = |
1849 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS; | 1849 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS; |
1850 | 1850 |
1851 if (has_fast_elements) { | 1851 if (has_fast_elements) { |
1852 mode = FastCloneShallowArrayStub::CLONE_ELEMENTS; | 1852 mode = FastCloneShallowArrayStub::CLONE_ELEMENTS; |
1853 } | 1853 } |
1854 | 1854 |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2036 ASSERT(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); | 2036 ASSERT(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); |
2037 __ li(a1, Operand(Smi::FromInt(continuation.pos()))); | 2037 __ li(a1, Operand(Smi::FromInt(continuation.pos()))); |
2038 __ sw(a1, FieldMemOperand(v0, JSGeneratorObject::kContinuationOffset)); | 2038 __ sw(a1, FieldMemOperand(v0, JSGeneratorObject::kContinuationOffset)); |
2039 __ sw(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset)); | 2039 __ sw(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset)); |
2040 __ mov(a1, cp); | 2040 __ mov(a1, cp); |
2041 __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2, | 2041 __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2, |
2042 kRAHasBeenSaved, kDontSaveFPRegs); | 2042 kRAHasBeenSaved, kDontSaveFPRegs); |
2043 __ Addu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); | 2043 __ Addu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); |
2044 __ Branch(&post_runtime, eq, sp, Operand(a1)); | 2044 __ Branch(&post_runtime, eq, sp, Operand(a1)); |
2045 __ push(v0); // generator object | 2045 __ push(v0); // generator object |
2046 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 2046 __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1); |
2047 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2047 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2048 __ bind(&post_runtime); | 2048 __ bind(&post_runtime); |
2049 __ pop(result_register()); | 2049 __ pop(result_register()); |
2050 EmitReturnSequence(); | 2050 EmitReturnSequence(); |
2051 | 2051 |
2052 __ bind(&resume); | 2052 __ bind(&resume); |
2053 context()->Plug(result_register()); | 2053 context()->Plug(result_register()); |
2054 break; | 2054 break; |
2055 } | 2055 } |
2056 | 2056 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2104 const int generator_object_depth = kPointerSize + handler_size; | 2104 const int generator_object_depth = kPointerSize + handler_size; |
2105 __ lw(a0, MemOperand(sp, generator_object_depth)); | 2105 __ lw(a0, MemOperand(sp, generator_object_depth)); |
2106 __ push(a0); // g | 2106 __ push(a0); // g |
2107 ASSERT(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos())); | 2107 ASSERT(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos())); |
2108 __ li(a1, Operand(Smi::FromInt(l_continuation.pos()))); | 2108 __ li(a1, Operand(Smi::FromInt(l_continuation.pos()))); |
2109 __ sw(a1, FieldMemOperand(a0, JSGeneratorObject::kContinuationOffset)); | 2109 __ sw(a1, FieldMemOperand(a0, JSGeneratorObject::kContinuationOffset)); |
2110 __ sw(cp, FieldMemOperand(a0, JSGeneratorObject::kContextOffset)); | 2110 __ sw(cp, FieldMemOperand(a0, JSGeneratorObject::kContextOffset)); |
2111 __ mov(a1, cp); | 2111 __ mov(a1, cp); |
2112 __ RecordWriteField(a0, JSGeneratorObject::kContextOffset, a1, a2, | 2112 __ RecordWriteField(a0, JSGeneratorObject::kContextOffset, a1, a2, |
2113 kRAHasBeenSaved, kDontSaveFPRegs); | 2113 kRAHasBeenSaved, kDontSaveFPRegs); |
2114 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 2114 __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1); |
2115 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2115 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2116 __ pop(v0); // result | 2116 __ pop(v0); // result |
2117 EmitReturnSequence(); | 2117 EmitReturnSequence(); |
2118 __ mov(a0, v0); | 2118 __ mov(a0, v0); |
2119 __ bind(&l_resume); // received in a0 | 2119 __ bind(&l_resume); // received in a0 |
2120 __ PopTryHandler(); | 2120 __ PopTryHandler(); |
2121 | 2121 |
2122 // receiver = iter; f = 'next'; arg = received; | 2122 // receiver = iter; f = 'next'; arg = received; |
2123 __ bind(&l_next); | 2123 __ bind(&l_next); |
2124 __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next" | 2124 __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next" |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2159 break; | 2159 break; |
2160 } | 2160 } |
2161 } | 2161 } |
2162 } | 2162 } |
2163 | 2163 |
2164 | 2164 |
2165 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 2165 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
2166 Expression *value, | 2166 Expression *value, |
2167 JSGeneratorObject::ResumeMode resume_mode) { | 2167 JSGeneratorObject::ResumeMode resume_mode) { |
2168 // The value stays in a0, and is ultimately read by the resumed generator, as | 2168 // The value stays in a0, and is ultimately read by the resumed generator, as |
2169 // if the CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it | 2169 // if CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject) returned it. Or it |
2170 // is read to throw the value when the resumed generator is already closed. | 2170 // is read to throw the value when the resumed generator is already closed. |
2171 // a1 will hold the generator object until the activation has been resumed. | 2171 // a1 will hold the generator object until the activation has been resumed. |
2172 VisitForStackValue(generator); | 2172 VisitForStackValue(generator); |
2173 VisitForAccumulatorValue(value); | 2173 VisitForAccumulatorValue(value); |
2174 __ pop(a1); | 2174 __ pop(a1); |
2175 | 2175 |
2176 // Check generator state. | 2176 // Check generator state. |
2177 Label wrong_state, closed_state, done; | 2177 Label wrong_state, closed_state, done; |
2178 __ lw(a3, FieldMemOperand(a1, JSGeneratorObject::kContinuationOffset)); | 2178 __ lw(a3, FieldMemOperand(a1, JSGeneratorObject::kContinuationOffset)); |
2179 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0); | 2179 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2241 Label push_operand_holes, call_resume; | 2241 Label push_operand_holes, call_resume; |
2242 __ bind(&push_operand_holes); | 2242 __ bind(&push_operand_holes); |
2243 __ Subu(a3, a3, Operand(1)); | 2243 __ Subu(a3, a3, Operand(1)); |
2244 __ Branch(&call_resume, lt, a3, Operand(zero_reg)); | 2244 __ Branch(&call_resume, lt, a3, Operand(zero_reg)); |
2245 __ push(a2); | 2245 __ push(a2); |
2246 __ Branch(&push_operand_holes); | 2246 __ Branch(&push_operand_holes); |
2247 __ bind(&call_resume); | 2247 __ bind(&call_resume); |
2248 ASSERT(!result_register().is(a1)); | 2248 ASSERT(!result_register().is(a1)); |
2249 __ Push(a1, result_register()); | 2249 __ Push(a1, result_register()); |
2250 __ Push(Smi::FromInt(resume_mode)); | 2250 __ Push(Smi::FromInt(resume_mode)); |
2251 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); | 2251 __ CallRuntime(Runtime::kHiddenResumeJSGeneratorObject, 3); |
2252 // Not reached: the runtime call returns elsewhere. | 2252 // Not reached: the runtime call returns elsewhere. |
2253 __ stop("not-reached"); | 2253 __ stop("not-reached"); |
2254 | 2254 |
2255 // Reach here when generator is closed. | 2255 // Reach here when generator is closed. |
2256 __ bind(&closed_state); | 2256 __ bind(&closed_state); |
2257 if (resume_mode == JSGeneratorObject::NEXT) { | 2257 if (resume_mode == JSGeneratorObject::NEXT) { |
2258 // Return completed iterator result when generator is closed. | 2258 // Return completed iterator result when generator is closed. |
2259 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); | 2259 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); |
2260 __ push(a2); | 2260 __ push(a2); |
2261 // Pop value from top-of-stack slot; box result into result register. | 2261 // Pop value from top-of-stack slot; box result into result register. |
2262 EmitCreateIteratorResult(true); | 2262 EmitCreateIteratorResult(true); |
2263 } else { | 2263 } else { |
2264 // Throw the provided value. | 2264 // Throw the provided value. |
2265 __ push(a0); | 2265 __ push(a0); |
2266 __ CallRuntime(Runtime::kThrow, 1); | 2266 __ CallRuntime(Runtime::kHiddenThrow, 1); |
2267 } | 2267 } |
2268 __ jmp(&done); | 2268 __ jmp(&done); |
2269 | 2269 |
2270 // Throw error if we attempt to operate on a running generator. | 2270 // Throw error if we attempt to operate on a running generator. |
2271 __ bind(&wrong_state); | 2271 __ bind(&wrong_state); |
2272 __ push(a1); | 2272 __ push(a1); |
2273 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); | 2273 __ CallRuntime(Runtime::kHiddenThrowGeneratorStateError, 1); |
2274 | 2274 |
2275 __ bind(&done); | 2275 __ bind(&done); |
2276 context()->Plug(result_register()); | 2276 context()->Plug(result_register()); |
2277 } | 2277 } |
2278 | 2278 |
2279 | 2279 |
2280 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { | 2280 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { |
2281 Label gc_required; | 2281 Label gc_required; |
2282 Label allocated; | 2282 Label allocated; |
2283 | 2283 |
2284 Handle<Map> map(isolate()->native_context()->generator_result_map()); | 2284 Handle<Map> map(isolate()->native_context()->generator_result_map()); |
2285 | 2285 |
2286 __ Allocate(map->instance_size(), v0, a2, a3, &gc_required, TAG_OBJECT); | 2286 __ Allocate(map->instance_size(), v0, a2, a3, &gc_required, TAG_OBJECT); |
2287 __ jmp(&allocated); | 2287 __ jmp(&allocated); |
2288 | 2288 |
2289 __ bind(&gc_required); | 2289 __ bind(&gc_required); |
2290 __ Push(Smi::FromInt(map->instance_size())); | 2290 __ Push(Smi::FromInt(map->instance_size())); |
2291 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); | 2291 __ CallRuntime(Runtime::kHiddenAllocateInNewSpace, 1); |
2292 __ lw(context_register(), | 2292 __ lw(context_register(), |
2293 MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2293 MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2294 | 2294 |
2295 __ bind(&allocated); | 2295 __ bind(&allocated); |
2296 __ li(a1, Operand(map)); | 2296 __ li(a1, Operand(map)); |
2297 __ pop(a2); | 2297 __ pop(a2); |
2298 __ li(a3, Operand(isolate()->factory()->ToBoolean(done))); | 2298 __ li(a3, Operand(isolate()->factory()->ToBoolean(done))); |
2299 __ li(t0, Operand(isolate()->factory()->empty_fixed_array())); | 2299 __ li(t0, Operand(isolate()->factory()->empty_fixed_array())); |
2300 ASSERT_EQ(map->instance_size(), 5 * kPointerSize); | 2300 ASSERT_EQ(map->instance_size(), 5 * kPointerSize); |
2301 __ sw(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); | 2301 __ sw(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2499 a1, offset, a3, a2, kRAHasBeenSaved, kDontSaveFPRegs); | 2499 a1, offset, a3, a2, kRAHasBeenSaved, kDontSaveFPRegs); |
2500 } | 2500 } |
2501 } | 2501 } |
2502 | 2502 |
2503 | 2503 |
2504 void FullCodeGenerator::EmitCallStoreContextSlot( | 2504 void FullCodeGenerator::EmitCallStoreContextSlot( |
2505 Handle<String> name, StrictMode strict_mode) { | 2505 Handle<String> name, StrictMode strict_mode) { |
2506 __ li(a1, Operand(name)); | 2506 __ li(a1, Operand(name)); |
2507 __ li(a0, Operand(Smi::FromInt(strict_mode))); | 2507 __ li(a0, Operand(Smi::FromInt(strict_mode))); |
2508 __ Push(v0, cp, a1, a0); // Value, context, name, strict mode. | 2508 __ Push(v0, cp, a1, a0); // Value, context, name, strict mode. |
2509 __ CallRuntime(Runtime::kStoreContextSlot, 4); | 2509 __ CallRuntime(Runtime::kHiddenStoreContextSlot, 4); |
2510 } | 2510 } |
2511 | 2511 |
2512 | 2512 |
2513 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) { | 2513 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) { |
2514 if (var->IsUnallocated()) { | 2514 if (var->IsUnallocated()) { |
2515 // Global var, const, or let. | 2515 // Global var, const, or let. |
2516 __ mov(a0, result_register()); | 2516 __ mov(a0, result_register()); |
2517 __ li(a2, Operand(var->name())); | 2517 __ li(a2, Operand(var->name())); |
2518 __ lw(a1, GlobalObjectOperand()); | 2518 __ lw(a1, GlobalObjectOperand()); |
2519 CallStoreIC(); | 2519 CallStoreIC(); |
2520 | 2520 |
2521 } else if (op == Token::INIT_CONST_LEGACY) { | 2521 } else if (op == Token::INIT_CONST_LEGACY) { |
2522 // Const initializers need a write barrier. | 2522 // Const initializers need a write barrier. |
2523 ASSERT(!var->IsParameter()); // No const parameters. | 2523 ASSERT(!var->IsParameter()); // No const parameters. |
2524 if (var->IsLookupSlot()) { | 2524 if (var->IsLookupSlot()) { |
2525 __ li(a0, Operand(var->name())); | 2525 __ li(a0, Operand(var->name())); |
2526 __ Push(v0, cp, a0); // Context and name. | 2526 __ Push(v0, cp, a0); // Context and name. |
2527 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); | 2527 __ CallRuntime(Runtime::kHiddenInitializeConstContextSlot, 3); |
2528 } else { | 2528 } else { |
2529 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 2529 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); |
2530 Label skip; | 2530 Label skip; |
2531 MemOperand location = VarOperand(var, a1); | 2531 MemOperand location = VarOperand(var, a1); |
2532 __ lw(a2, location); | 2532 __ lw(a2, location); |
2533 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 2533 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
2534 __ Branch(&skip, ne, a2, Operand(at)); | 2534 __ Branch(&skip, ne, a2, Operand(at)); |
2535 EmitStoreToStackLocalOrContextSlot(var, location); | 2535 EmitStoreToStackLocalOrContextSlot(var, location); |
2536 __ bind(&skip); | 2536 __ bind(&skip); |
2537 } | 2537 } |
2538 | 2538 |
2539 } else if (var->mode() == LET && op != Token::INIT_LET) { | 2539 } else if (var->mode() == LET && op != Token::INIT_LET) { |
2540 // Non-initializing assignment to let variable needs a write barrier. | 2540 // Non-initializing assignment to let variable needs a write barrier. |
2541 if (var->IsLookupSlot()) { | 2541 if (var->IsLookupSlot()) { |
2542 EmitCallStoreContextSlot(var->name(), strict_mode()); | 2542 EmitCallStoreContextSlot(var->name(), strict_mode()); |
2543 } else { | 2543 } else { |
2544 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 2544 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); |
2545 Label assign; | 2545 Label assign; |
2546 MemOperand location = VarOperand(var, a1); | 2546 MemOperand location = VarOperand(var, a1); |
2547 __ lw(a3, location); | 2547 __ lw(a3, location); |
2548 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); | 2548 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); |
2549 __ Branch(&assign, ne, a3, Operand(t0)); | 2549 __ Branch(&assign, ne, a3, Operand(t0)); |
2550 __ li(a3, Operand(var->name())); | 2550 __ li(a3, Operand(var->name())); |
2551 __ push(a3); | 2551 __ push(a3); |
2552 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 2552 __ CallRuntime(Runtime::kHiddenThrowReferenceError, 1); |
2553 // Perform the assignment. | 2553 // Perform the assignment. |
2554 __ bind(&assign); | 2554 __ bind(&assign); |
2555 EmitStoreToStackLocalOrContextSlot(var, location); | 2555 EmitStoreToStackLocalOrContextSlot(var, location); |
2556 } | 2556 } |
2557 | 2557 |
2558 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { | 2558 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { |
2559 // Assignment to var or initializing assignment to let/const | 2559 // Assignment to var or initializing assignment to let/const |
2560 // in harmony mode. | 2560 // in harmony mode. |
2561 if (var->IsLookupSlot()) { | 2561 if (var->IsLookupSlot()) { |
2562 EmitCallStoreContextSlot(var->name(), strict_mode()); | 2562 EmitCallStoreContextSlot(var->name(), strict_mode()); |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2778 __ lw(t1, MemOperand(fp, receiver_offset * kPointerSize)); | 2778 __ lw(t1, MemOperand(fp, receiver_offset * kPointerSize)); |
2779 | 2779 |
2780 // t0: the strict mode. | 2780 // t0: the strict mode. |
2781 __ li(t0, Operand(Smi::FromInt(strict_mode()))); | 2781 __ li(t0, Operand(Smi::FromInt(strict_mode()))); |
2782 | 2782 |
2783 // a1: the start position of the scope the calls resides in. | 2783 // a1: the start position of the scope the calls resides in. |
2784 __ li(a1, Operand(Smi::FromInt(scope()->start_position()))); | 2784 __ li(a1, Operand(Smi::FromInt(scope()->start_position()))); |
2785 | 2785 |
2786 // Do the runtime call. | 2786 // Do the runtime call. |
2787 __ Push(t2, t1, t0, a1); | 2787 __ Push(t2, t1, t0, a1); |
2788 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); | 2788 __ CallRuntime(Runtime::kHiddenResolvePossiblyDirectEval, 5); |
2789 } | 2789 } |
2790 | 2790 |
2791 | 2791 |
2792 void FullCodeGenerator::VisitCall(Call* expr) { | 2792 void FullCodeGenerator::VisitCall(Call* expr) { |
2793 #ifdef DEBUG | 2793 #ifdef DEBUG |
2794 // We want to verify that RecordJSReturnSite gets called on all paths | 2794 // We want to verify that RecordJSReturnSite gets called on all paths |
2795 // through this function. Avoid early returns. | 2795 // through this function. Avoid early returns. |
2796 expr->return_is_recorded_ = false; | 2796 expr->return_is_recorded_ = false; |
2797 #endif | 2797 #endif |
2798 | 2798 |
2799 Comment cmnt(masm_, "[ Call"); | 2799 Comment cmnt(masm_, "[ Call"); |
2800 Expression* callee = expr->expression(); | 2800 Expression* callee = expr->expression(); |
2801 Call::CallType call_type = expr->GetCallType(isolate()); | 2801 Call::CallType call_type = expr->GetCallType(isolate()); |
2802 | 2802 |
2803 if (call_type == Call::POSSIBLY_EVAL_CALL) { | 2803 if (call_type == Call::POSSIBLY_EVAL_CALL) { |
2804 // In a call to eval, we first call %ResolvePossiblyDirectEval to | 2804 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval |
2805 // resolve the function we need to call and the receiver of the | 2805 // to resolve the function we need to call and the receiver of the |
2806 // call. Then we call the resolved function using the given | 2806 // call. Then we call the resolved function using the given |
2807 // arguments. | 2807 // arguments. |
2808 ZoneList<Expression*>* args = expr->arguments(); | 2808 ZoneList<Expression*>* args = expr->arguments(); |
2809 int arg_count = args->length(); | 2809 int arg_count = args->length(); |
2810 | 2810 |
2811 { PreservePositionScope pos_scope(masm()->positions_recorder()); | 2811 { PreservePositionScope pos_scope(masm()->positions_recorder()); |
2812 VisitForStackValue(callee); | 2812 VisitForStackValue(callee); |
2813 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); | 2813 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); |
2814 __ push(a2); // Reserved receiver slot. | 2814 __ push(a2); // Reserved receiver slot. |
2815 | 2815 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2850 // by eval-introduced variables. | 2850 // by eval-introduced variables. |
2851 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); | 2851 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); |
2852 } | 2852 } |
2853 | 2853 |
2854 __ bind(&slow); | 2854 __ bind(&slow); |
2855 // Call the runtime to find the function to call (returned in v0) | 2855 // Call the runtime to find the function to call (returned in v0) |
2856 // and the object holding it (returned in v1). | 2856 // and the object holding it (returned in v1). |
2857 ASSERT(!context_register().is(a2)); | 2857 ASSERT(!context_register().is(a2)); |
2858 __ li(a2, Operand(proxy->name())); | 2858 __ li(a2, Operand(proxy->name())); |
2859 __ Push(context_register(), a2); | 2859 __ Push(context_register(), a2); |
2860 __ CallRuntime(Runtime::kLoadContextSlot, 2); | 2860 __ CallRuntime(Runtime::kHiddenLoadContextSlot, 2); |
2861 __ Push(v0, v1); // Function, receiver. | 2861 __ Push(v0, v1); // Function, receiver. |
2862 | 2862 |
2863 // If fast case code has been generated, emit code to push the | 2863 // If fast case code has been generated, emit code to push the |
2864 // function and receiver and have the slow path jump around this | 2864 // function and receiver and have the slow path jump around this |
2865 // code. | 2865 // code. |
2866 if (done.is_linked()) { | 2866 if (done.is_linked()) { |
2867 Label call; | 2867 Label call; |
2868 __ Branch(&call); | 2868 __ Branch(&call); |
2869 __ bind(&done); | 2869 __ bind(&done); |
2870 // Push function. | 2870 // Push function. |
(...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3514 } | 3514 } |
3515 __ bind(&runtime); | 3515 __ bind(&runtime); |
3516 __ PrepareCallCFunction(2, scratch1); | 3516 __ PrepareCallCFunction(2, scratch1); |
3517 __ li(a1, Operand(index)); | 3517 __ li(a1, Operand(index)); |
3518 __ Move(a0, object); | 3518 __ Move(a0, object); |
3519 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); | 3519 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); |
3520 __ jmp(&done); | 3520 __ jmp(&done); |
3521 } | 3521 } |
3522 | 3522 |
3523 __ bind(¬_date_object); | 3523 __ bind(¬_date_object); |
3524 __ CallRuntime(Runtime::kThrowNotDateError, 0); | 3524 __ CallRuntime(Runtime::kHiddenThrowNotDateError, 0); |
3525 __ bind(&done); | 3525 __ bind(&done); |
3526 context()->Plug(v0); | 3526 context()->Plug(v0); |
3527 } | 3527 } |
3528 | 3528 |
3529 | 3529 |
3530 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { | 3530 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { |
3531 ZoneList<Expression*>* args = expr->arguments(); | 3531 ZoneList<Expression*>* args = expr->arguments(); |
3532 ASSERT_EQ(3, args->length()); | 3532 ASSERT_EQ(3, args->length()); |
3533 | 3533 |
3534 Register string = v0; | 3534 Register string = v0; |
(...skipping 741 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4276 } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 4276 } else if (var->IsStackAllocated() || var->IsContextSlot()) { |
4277 // Result of deleting non-global, non-dynamic variables is false. | 4277 // Result of deleting non-global, non-dynamic variables is false. |
4278 // The subexpression does not have side effects. | 4278 // The subexpression does not have side effects. |
4279 context()->Plug(var->is_this()); | 4279 context()->Plug(var->is_this()); |
4280 } else { | 4280 } else { |
4281 // Non-global variable. Call the runtime to try to delete from the | 4281 // Non-global variable. Call the runtime to try to delete from the |
4282 // context where the variable was introduced. | 4282 // context where the variable was introduced. |
4283 ASSERT(!context_register().is(a2)); | 4283 ASSERT(!context_register().is(a2)); |
4284 __ li(a2, Operand(var->name())); | 4284 __ li(a2, Operand(var->name())); |
4285 __ Push(context_register(), a2); | 4285 __ Push(context_register(), a2); |
4286 __ CallRuntime(Runtime::kDeleteContextSlot, 2); | 4286 __ CallRuntime(Runtime::kHiddenDeleteContextSlot, 2); |
4287 context()->Plug(v0); | 4287 context()->Plug(v0); |
4288 } | 4288 } |
4289 } else { | 4289 } else { |
4290 // Result of deleting non-property, non-variable reference is true. | 4290 // Result of deleting non-property, non-variable reference is true. |
4291 // The subexpression may have side effects. | 4291 // The subexpression may have side effects. |
4292 VisitForEffect(expr->expression()); | 4292 VisitForEffect(expr->expression()); |
4293 context()->Plug(true); | 4293 context()->Plug(true); |
4294 } | 4294 } |
4295 break; | 4295 break; |
4296 } | 4296 } |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4558 Comment cmnt(masm_, "[ Lookup slot"); | 4558 Comment cmnt(masm_, "[ Lookup slot"); |
4559 Label done, slow; | 4559 Label done, slow; |
4560 | 4560 |
4561 // Generate code for loading from variables potentially shadowed | 4561 // Generate code for loading from variables potentially shadowed |
4562 // by eval-introduced variables. | 4562 // by eval-introduced variables. |
4563 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); | 4563 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); |
4564 | 4564 |
4565 __ bind(&slow); | 4565 __ bind(&slow); |
4566 __ li(a0, Operand(proxy->name())); | 4566 __ li(a0, Operand(proxy->name())); |
4567 __ Push(cp, a0); | 4567 __ Push(cp, a0); |
4568 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); | 4568 __ CallRuntime(Runtime::kHiddenLoadContextSlotNoReferenceError, 2); |
4569 PrepareForBailout(expr, TOS_REG); | 4569 PrepareForBailout(expr, TOS_REG); |
4570 __ bind(&done); | 4570 __ bind(&done); |
4571 | 4571 |
4572 context()->Plug(v0); | 4572 context()->Plug(v0); |
4573 } else { | 4573 } else { |
4574 // This expression cannot throw a reference error at the top level. | 4574 // This expression cannot throw a reference error at the top level. |
4575 VisitInDuplicateContext(expr); | 4575 VisitInDuplicateContext(expr); |
4576 } | 4576 } |
4577 } | 4577 } |
4578 | 4578 |
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4977 Assembler::target_address_at(pc_immediate_load_address)) == | 4977 Assembler::target_address_at(pc_immediate_load_address)) == |
4978 reinterpret_cast<uint32_t>( | 4978 reinterpret_cast<uint32_t>( |
4979 isolate->builtins()->OsrAfterStackCheck()->entry())); | 4979 isolate->builtins()->OsrAfterStackCheck()->entry())); |
4980 return OSR_AFTER_STACK_CHECK; | 4980 return OSR_AFTER_STACK_CHECK; |
4981 } | 4981 } |
4982 | 4982 |
4983 | 4983 |
4984 } } // namespace v8::internal | 4984 } } // namespace v8::internal |
4985 | 4985 |
4986 #endif // V8_TARGET_ARCH_MIPS | 4986 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |