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 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 bool function_in_register = true; | 218 bool function_in_register = true; |
219 | 219 |
220 // Possibly allocate a local context. | 220 // Possibly allocate a local context. |
221 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 221 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
222 if (heap_slots > 0) { | 222 if (heap_slots > 0) { |
223 Comment cmnt(masm_, "[ Allocate context"); | 223 Comment cmnt(masm_, "[ Allocate context"); |
224 // Argument to NewContext is the function, which is still in edi. | 224 // Argument to NewContext is the function, which is still in edi. |
225 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { | 225 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { |
226 __ push(edi); | 226 __ push(edi); |
227 __ Push(info->scope()->GetScopeInfo()); | 227 __ Push(info->scope()->GetScopeInfo()); |
228 __ CallRuntime(Runtime::kNewGlobalContext, 2); | 228 __ CallRuntime(Runtime::kHiddenNewGlobalContext, 2); |
229 } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { | 229 } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { |
230 FastNewContextStub stub(heap_slots); | 230 FastNewContextStub stub(heap_slots); |
231 __ CallStub(&stub); | 231 __ CallStub(&stub); |
232 } else { | 232 } else { |
233 __ push(edi); | 233 __ push(edi); |
234 __ CallRuntime(Runtime::kNewFunctionContext, 1); | 234 __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); |
235 } | 235 } |
236 function_in_register = false; | 236 function_in_register = false; |
237 // Context is returned in eax. It replaces the context passed to us. | 237 // Context is returned in eax. It replaces the context passed to us. |
238 // It's saved in the stack and kept live in esi. | 238 // It's saved in the stack and kept live in esi. |
239 __ mov(esi, eax); | 239 __ mov(esi, eax); |
240 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), eax); | 240 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), eax); |
241 | 241 |
242 // Copy parameters into context if necessary. | 242 // Copy parameters into context if necessary. |
243 int num_parameters = info->scope()->num_parameters(); | 243 int num_parameters = info->scope()->num_parameters(); |
244 for (int i = 0; i < num_parameters; i++) { | 244 for (int i = 0; i < num_parameters; i++) { |
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
817 __ push(Immediate(Smi::FromInt(attr))); | 817 __ push(Immediate(Smi::FromInt(attr))); |
818 // Push initial value, if any. | 818 // Push initial value, if any. |
819 // Note: For variables we must not push an initial value (such as | 819 // Note: For variables we must not push an initial value (such as |
820 // 'undefined') because we may have a (legal) redeclaration and we | 820 // 'undefined') because we may have a (legal) redeclaration and we |
821 // must not destroy the current value. | 821 // must not destroy the current value. |
822 if (hole_init) { | 822 if (hole_init) { |
823 __ push(Immediate(isolate()->factory()->the_hole_value())); | 823 __ push(Immediate(isolate()->factory()->the_hole_value())); |
824 } else { | 824 } else { |
825 __ push(Immediate(Smi::FromInt(0))); // Indicates no initial value. | 825 __ push(Immediate(Smi::FromInt(0))); // Indicates no initial value. |
826 } | 826 } |
827 __ CallRuntime(Runtime::kDeclareContextSlot, 4); | 827 __ CallRuntime(Runtime::kHiddenDeclareContextSlot, 4); |
828 break; | 828 break; |
829 } | 829 } |
830 } | 830 } |
831 } | 831 } |
832 | 832 |
833 | 833 |
834 void FullCodeGenerator::VisitFunctionDeclaration( | 834 void FullCodeGenerator::VisitFunctionDeclaration( |
835 FunctionDeclaration* declaration) { | 835 FunctionDeclaration* declaration) { |
836 VariableProxy* proxy = declaration->proxy(); | 836 VariableProxy* proxy = declaration->proxy(); |
837 Variable* variable = proxy->var(); | 837 Variable* variable = proxy->var(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
870 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); | 870 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); |
871 break; | 871 break; |
872 } | 872 } |
873 | 873 |
874 case Variable::LOOKUP: { | 874 case Variable::LOOKUP: { |
875 Comment cmnt(masm_, "[ FunctionDeclaration"); | 875 Comment cmnt(masm_, "[ FunctionDeclaration"); |
876 __ push(esi); | 876 __ push(esi); |
877 __ push(Immediate(variable->name())); | 877 __ push(Immediate(variable->name())); |
878 __ push(Immediate(Smi::FromInt(NONE))); | 878 __ push(Immediate(Smi::FromInt(NONE))); |
879 VisitForStackValue(declaration->fun()); | 879 VisitForStackValue(declaration->fun()); |
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::VisitModuleDeclaration(ModuleDeclaration* declaration) { | 887 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { |
888 Variable* variable = declaration->proxy()->var(); | 888 Variable* variable = declaration->proxy()->var(); |
889 ASSERT(variable->location() == Variable::CONTEXT); | 889 ASSERT(variable->location() == Variable::CONTEXT); |
890 ASSERT(variable->interface()->IsFrozen()); | 890 ASSERT(variable->interface()->IsFrozen()); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
940 void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) { | 940 void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) { |
941 // TODO(rossberg) | 941 // TODO(rossberg) |
942 } | 942 } |
943 | 943 |
944 | 944 |
945 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 945 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
946 // Call the runtime to declare the globals. | 946 // Call the runtime to declare the globals. |
947 __ push(esi); // The context is the first argument. | 947 __ push(esi); // The context is the first argument. |
948 __ Push(pairs); | 948 __ Push(pairs); |
949 __ Push(Smi::FromInt(DeclareGlobalsFlags())); | 949 __ Push(Smi::FromInt(DeclareGlobalsFlags())); |
950 __ CallRuntime(Runtime::kDeclareGlobals, 3); | 950 __ CallRuntime(Runtime::kHiddenDeclareGlobals, 3); |
951 // Return value is ignored. | 951 // Return value is ignored. |
952 } | 952 } |
953 | 953 |
954 | 954 |
955 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) { | 955 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) { |
956 // Call the runtime to declare the modules. | 956 // Call the runtime to declare the modules. |
957 __ Push(descriptions); | 957 __ Push(descriptions); |
958 __ CallRuntime(Runtime::kDeclareModules, 1); | 958 __ CallRuntime(Runtime::kHiddenDeclareModules, 1); |
959 // Return value is ignored. | 959 // Return value is ignored. |
960 } | 960 } |
961 | 961 |
962 | 962 |
963 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { | 963 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { |
964 Comment cmnt(masm_, "[ SwitchStatement"); | 964 Comment cmnt(masm_, "[ SwitchStatement"); |
965 Breakable nested_statement(this, stmt); | 965 Breakable nested_statement(this, stmt); |
966 SetStatementPosition(stmt); | 966 SetStatementPosition(stmt); |
967 | 967 |
968 // Keep the switch value on the stack until a case matches. | 968 // Keep the switch value on the stack until a case matches. |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1300 info->num_literals() == 0) { | 1300 info->num_literals() == 0) { |
1301 FastNewClosureStub stub(info->strict_mode(), info->is_generator()); | 1301 FastNewClosureStub stub(info->strict_mode(), info->is_generator()); |
1302 __ mov(ebx, Immediate(info)); | 1302 __ mov(ebx, Immediate(info)); |
1303 __ CallStub(&stub); | 1303 __ CallStub(&stub); |
1304 } else { | 1304 } else { |
1305 __ push(esi); | 1305 __ push(esi); |
1306 __ push(Immediate(info)); | 1306 __ push(Immediate(info)); |
1307 __ push(Immediate(pretenure | 1307 __ push(Immediate(pretenure |
1308 ? isolate()->factory()->true_value() | 1308 ? isolate()->factory()->true_value() |
1309 : isolate()->factory()->false_value())); | 1309 : isolate()->factory()->false_value())); |
1310 __ CallRuntime(Runtime::kNewClosure, 3); | 1310 __ CallRuntime(Runtime::kHiddenNewClosure, 3); |
1311 } | 1311 } |
1312 context()->Plug(eax); | 1312 context()->Plug(eax); |
1313 } | 1313 } |
1314 | 1314 |
1315 | 1315 |
1316 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { | 1316 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
1317 Comment cmnt(masm_, "[ VariableProxy"); | 1317 Comment cmnt(masm_, "[ VariableProxy"); |
1318 EmitVariableLoad(expr); | 1318 EmitVariableLoad(expr); |
1319 } | 1319 } |
1320 | 1320 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1425 Variable* local = var->local_if_not_shadowed(); | 1425 Variable* local = var->local_if_not_shadowed(); |
1426 __ mov(eax, ContextSlotOperandCheckExtensions(local, slow)); | 1426 __ mov(eax, ContextSlotOperandCheckExtensions(local, slow)); |
1427 if (local->mode() == LET || local->mode() == CONST || | 1427 if (local->mode() == LET || local->mode() == CONST || |
1428 local->mode() == CONST_LEGACY) { | 1428 local->mode() == CONST_LEGACY) { |
1429 __ cmp(eax, isolate()->factory()->the_hole_value()); | 1429 __ cmp(eax, isolate()->factory()->the_hole_value()); |
1430 __ j(not_equal, done); | 1430 __ j(not_equal, done); |
1431 if (local->mode() == CONST_LEGACY) { | 1431 if (local->mode() == CONST_LEGACY) { |
1432 __ mov(eax, isolate()->factory()->undefined_value()); | 1432 __ mov(eax, isolate()->factory()->undefined_value()); |
1433 } else { // LET || CONST | 1433 } else { // LET || CONST |
1434 __ push(Immediate(var->name())); | 1434 __ push(Immediate(var->name())); |
1435 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 1435 __ CallRuntime(Runtime::kHiddenThrowReferenceError, 1); |
1436 } | 1436 } |
1437 } | 1437 } |
1438 __ jmp(done); | 1438 __ jmp(done); |
1439 } | 1439 } |
1440 } | 1440 } |
1441 | 1441 |
1442 | 1442 |
1443 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { | 1443 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
1444 // Record position before possible IC call. | 1444 // Record position before possible IC call. |
1445 SetSourcePosition(proxy->position()); | 1445 SetSourcePosition(proxy->position()); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1502 if (!skip_init_check) { | 1502 if (!skip_init_check) { |
1503 // Let and const need a read barrier. | 1503 // Let and const need a read barrier. |
1504 Label done; | 1504 Label done; |
1505 GetVar(eax, var); | 1505 GetVar(eax, var); |
1506 __ cmp(eax, isolate()->factory()->the_hole_value()); | 1506 __ cmp(eax, isolate()->factory()->the_hole_value()); |
1507 __ j(not_equal, &done, Label::kNear); | 1507 __ j(not_equal, &done, Label::kNear); |
1508 if (var->mode() == LET || var->mode() == CONST) { | 1508 if (var->mode() == LET || var->mode() == CONST) { |
1509 // Throw a reference error when using an uninitialized let/const | 1509 // Throw a reference error when using an uninitialized let/const |
1510 // binding in harmony mode. | 1510 // binding in harmony mode. |
1511 __ push(Immediate(var->name())); | 1511 __ push(Immediate(var->name())); |
1512 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 1512 __ CallRuntime(Runtime::kHiddenThrowReferenceError, 1); |
1513 } else { | 1513 } else { |
1514 // Uninitalized const bindings outside of harmony mode are unholed. | 1514 // Uninitalized const bindings outside of harmony mode are unholed. |
1515 ASSERT(var->mode() == CONST_LEGACY); | 1515 ASSERT(var->mode() == CONST_LEGACY); |
1516 __ mov(eax, isolate()->factory()->undefined_value()); | 1516 __ mov(eax, isolate()->factory()->undefined_value()); |
1517 } | 1517 } |
1518 __ bind(&done); | 1518 __ bind(&done); |
1519 context()->Plug(eax); | 1519 context()->Plug(eax); |
1520 break; | 1520 break; |
1521 } | 1521 } |
1522 } | 1522 } |
1523 context()->Plug(var); | 1523 context()->Plug(var); |
1524 break; | 1524 break; |
1525 } | 1525 } |
1526 | 1526 |
1527 case Variable::LOOKUP: { | 1527 case Variable::LOOKUP: { |
1528 Comment cmnt(masm_, "[ Lookup variable"); | 1528 Comment cmnt(masm_, "[ Lookup variable"); |
1529 Label done, slow; | 1529 Label done, slow; |
1530 // Generate code for loading from variables potentially shadowed | 1530 // Generate code for loading from variables potentially shadowed |
1531 // by eval-introduced variables. | 1531 // by eval-introduced variables. |
1532 EmitDynamicLookupFastCase(var, NOT_INSIDE_TYPEOF, &slow, &done); | 1532 EmitDynamicLookupFastCase(var, NOT_INSIDE_TYPEOF, &slow, &done); |
1533 __ bind(&slow); | 1533 __ bind(&slow); |
1534 __ push(esi); // Context. | 1534 __ push(esi); // Context. |
1535 __ push(Immediate(var->name())); | 1535 __ push(Immediate(var->name())); |
1536 __ CallRuntime(Runtime::kLoadContextSlot, 2); | 1536 __ CallRuntime(Runtime::kHiddenLoadContextSlot, 2); |
1537 __ bind(&done); | 1537 __ bind(&done); |
1538 context()->Plug(eax); | 1538 context()->Plug(eax); |
1539 break; | 1539 break; |
1540 } | 1540 } |
1541 } | 1541 } |
1542 } | 1542 } |
1543 | 1543 |
1544 | 1544 |
1545 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 1545 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
1546 Comment cmnt(masm_, "[ RegExpLiteral"); | 1546 Comment cmnt(masm_, "[ RegExpLiteral"); |
(...skipping 10 matching lines...) Expand all Loading... |
1557 __ mov(ebx, FieldOperand(ecx, literal_offset)); | 1557 __ mov(ebx, FieldOperand(ecx, literal_offset)); |
1558 __ cmp(ebx, isolate()->factory()->undefined_value()); | 1558 __ cmp(ebx, isolate()->factory()->undefined_value()); |
1559 __ j(not_equal, &materialized, Label::kNear); | 1559 __ j(not_equal, &materialized, Label::kNear); |
1560 | 1560 |
1561 // Create regexp literal using runtime function | 1561 // Create regexp literal using runtime function |
1562 // Result will be in eax. | 1562 // Result will be in eax. |
1563 __ push(ecx); | 1563 __ push(ecx); |
1564 __ push(Immediate(Smi::FromInt(expr->literal_index()))); | 1564 __ push(Immediate(Smi::FromInt(expr->literal_index()))); |
1565 __ push(Immediate(expr->pattern())); | 1565 __ push(Immediate(expr->pattern())); |
1566 __ push(Immediate(expr->flags())); | 1566 __ push(Immediate(expr->flags())); |
1567 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); | 1567 __ CallRuntime(Runtime::kHiddenMaterializeRegExpLiteral, 4); |
1568 __ mov(ebx, eax); | 1568 __ mov(ebx, eax); |
1569 | 1569 |
1570 __ bind(&materialized); | 1570 __ bind(&materialized); |
1571 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; | 1571 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; |
1572 Label allocated, runtime_allocate; | 1572 Label allocated, runtime_allocate; |
1573 __ Allocate(size, eax, ecx, edx, &runtime_allocate, TAG_OBJECT); | 1573 __ Allocate(size, eax, ecx, edx, &runtime_allocate, TAG_OBJECT); |
1574 __ jmp(&allocated); | 1574 __ jmp(&allocated); |
1575 | 1575 |
1576 __ bind(&runtime_allocate); | 1576 __ bind(&runtime_allocate); |
1577 __ push(ebx); | 1577 __ push(ebx); |
1578 __ push(Immediate(Smi::FromInt(size))); | 1578 __ push(Immediate(Smi::FromInt(size))); |
1579 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); | 1579 __ CallRuntime(Runtime::kHiddenAllocateInNewSpace, 1); |
1580 __ pop(ebx); | 1580 __ pop(ebx); |
1581 | 1581 |
1582 __ bind(&allocated); | 1582 __ bind(&allocated); |
1583 // Copy the content into the newly allocated memory. | 1583 // Copy the content into the newly allocated memory. |
1584 // (Unroll copy loop once for better throughput). | 1584 // (Unroll copy loop once for better throughput). |
1585 for (int i = 0; i < size - kPointerSize; i += 2 * kPointerSize) { | 1585 for (int i = 0; i < size - kPointerSize; i += 2 * kPointerSize) { |
1586 __ mov(edx, FieldOperand(ebx, i)); | 1586 __ mov(edx, FieldOperand(ebx, i)); |
1587 __ mov(ecx, FieldOperand(ebx, i + kPointerSize)); | 1587 __ mov(ecx, FieldOperand(ebx, i + kPointerSize)); |
1588 __ mov(FieldOperand(eax, i), edx); | 1588 __ mov(FieldOperand(eax, i), edx); |
1589 __ mov(FieldOperand(eax, i + kPointerSize), ecx); | 1589 __ mov(FieldOperand(eax, i + kPointerSize), ecx); |
(...skipping 28 matching lines...) Expand all Loading... |
1618 : ObjectLiteral::kNoFlags; | 1618 : ObjectLiteral::kNoFlags; |
1619 int properties_count = constant_properties->length() / 2; | 1619 int properties_count = constant_properties->length() / 2; |
1620 if (expr->may_store_doubles() || expr->depth() > 1 || Serializer::enabled() || | 1620 if (expr->may_store_doubles() || expr->depth() > 1 || Serializer::enabled() || |
1621 flags != ObjectLiteral::kFastElements || | 1621 flags != ObjectLiteral::kFastElements || |
1622 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { | 1622 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { |
1623 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 1623 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
1624 __ push(FieldOperand(edi, JSFunction::kLiteralsOffset)); | 1624 __ push(FieldOperand(edi, JSFunction::kLiteralsOffset)); |
1625 __ push(Immediate(Smi::FromInt(expr->literal_index()))); | 1625 __ push(Immediate(Smi::FromInt(expr->literal_index()))); |
1626 __ push(Immediate(constant_properties)); | 1626 __ push(Immediate(constant_properties)); |
1627 __ push(Immediate(Smi::FromInt(flags))); | 1627 __ push(Immediate(Smi::FromInt(flags))); |
1628 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); | 1628 __ CallRuntime(Runtime::kHiddenCreateObjectLiteral, 4); |
1629 } else { | 1629 } else { |
1630 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 1630 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
1631 __ mov(eax, FieldOperand(edi, JSFunction::kLiteralsOffset)); | 1631 __ mov(eax, FieldOperand(edi, JSFunction::kLiteralsOffset)); |
1632 __ mov(ebx, Immediate(Smi::FromInt(expr->literal_index()))); | 1632 __ mov(ebx, Immediate(Smi::FromInt(expr->literal_index()))); |
1633 __ mov(ecx, Immediate(constant_properties)); | 1633 __ mov(ecx, Immediate(constant_properties)); |
1634 __ mov(edx, Immediate(Smi::FromInt(flags))); | 1634 __ mov(edx, Immediate(Smi::FromInt(flags))); |
1635 FastCloneShallowObjectStub stub(properties_count); | 1635 FastCloneShallowObjectStub stub(properties_count); |
1636 __ CallStub(&stub); | 1636 __ CallStub(&stub); |
1637 } | 1637 } |
1638 | 1638 |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1771 allocation_site_mode, | 1771 allocation_site_mode, |
1772 length); | 1772 length); |
1773 __ CallStub(&stub); | 1773 __ CallStub(&stub); |
1774 } else if (expr->depth() > 1 || Serializer::enabled() || | 1774 } else if (expr->depth() > 1 || Serializer::enabled() || |
1775 length > FastCloneShallowArrayStub::kMaximumClonedLength) { | 1775 length > FastCloneShallowArrayStub::kMaximumClonedLength) { |
1776 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 1776 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
1777 __ push(FieldOperand(ebx, JSFunction::kLiteralsOffset)); | 1777 __ push(FieldOperand(ebx, JSFunction::kLiteralsOffset)); |
1778 __ push(Immediate(Smi::FromInt(expr->literal_index()))); | 1778 __ push(Immediate(Smi::FromInt(expr->literal_index()))); |
1779 __ push(Immediate(constant_elements)); | 1779 __ push(Immediate(constant_elements)); |
1780 __ push(Immediate(Smi::FromInt(flags))); | 1780 __ push(Immediate(Smi::FromInt(flags))); |
1781 __ CallRuntime(Runtime::kCreateArrayLiteral, 4); | 1781 __ CallRuntime(Runtime::kHiddenCreateArrayLiteral, 4); |
1782 } else { | 1782 } else { |
1783 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) || | 1783 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) || |
1784 FLAG_smi_only_arrays); | 1784 FLAG_smi_only_arrays); |
1785 FastCloneShallowArrayStub::Mode mode = | 1785 FastCloneShallowArrayStub::Mode mode = |
1786 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS; | 1786 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS; |
1787 | 1787 |
1788 // If the elements are already FAST_*_ELEMENTS, the boilerplate cannot | 1788 // If the elements are already FAST_*_ELEMENTS, the boilerplate cannot |
1789 // change, so it's possible to specialize the stub in advance. | 1789 // change, so it's possible to specialize the stub in advance. |
1790 if (has_constant_fast_elements) { | 1790 if (has_constant_fast_elements) { |
1791 mode = FastCloneShallowArrayStub::CLONE_ELEMENTS; | 1791 mode = FastCloneShallowArrayStub::CLONE_ELEMENTS; |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1984 __ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset), | 1984 __ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset), |
1985 Immediate(Smi::FromInt(continuation.pos()))); | 1985 Immediate(Smi::FromInt(continuation.pos()))); |
1986 __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi); | 1986 __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi); |
1987 __ mov(ecx, esi); | 1987 __ mov(ecx, esi); |
1988 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, | 1988 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, |
1989 kDontSaveFPRegs); | 1989 kDontSaveFPRegs); |
1990 __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset)); | 1990 __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset)); |
1991 __ cmp(esp, ebx); | 1991 __ cmp(esp, ebx); |
1992 __ j(equal, &post_runtime); | 1992 __ j(equal, &post_runtime); |
1993 __ push(eax); // generator object | 1993 __ push(eax); // generator object |
1994 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 1994 __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1); |
1995 __ mov(context_register(), | 1995 __ mov(context_register(), |
1996 Operand(ebp, StandardFrameConstants::kContextOffset)); | 1996 Operand(ebp, StandardFrameConstants::kContextOffset)); |
1997 __ bind(&post_runtime); | 1997 __ bind(&post_runtime); |
1998 __ pop(result_register()); | 1998 __ pop(result_register()); |
1999 EmitReturnSequence(); | 1999 EmitReturnSequence(); |
2000 | 2000 |
2001 __ bind(&resume); | 2001 __ bind(&resume); |
2002 context()->Plug(result_register()); | 2002 context()->Plug(result_register()); |
2003 break; | 2003 break; |
2004 } | 2004 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2052 const int generator_object_depth = kPointerSize + handler_size; | 2052 const int generator_object_depth = kPointerSize + handler_size; |
2053 __ mov(eax, Operand(esp, generator_object_depth)); | 2053 __ mov(eax, Operand(esp, generator_object_depth)); |
2054 __ push(eax); // g | 2054 __ push(eax); // g |
2055 ASSERT(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos())); | 2055 ASSERT(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos())); |
2056 __ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset), | 2056 __ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset), |
2057 Immediate(Smi::FromInt(l_continuation.pos()))); | 2057 Immediate(Smi::FromInt(l_continuation.pos()))); |
2058 __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi); | 2058 __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi); |
2059 __ mov(ecx, esi); | 2059 __ mov(ecx, esi); |
2060 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, | 2060 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, |
2061 kDontSaveFPRegs); | 2061 kDontSaveFPRegs); |
2062 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 2062 __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1); |
2063 __ mov(context_register(), | 2063 __ mov(context_register(), |
2064 Operand(ebp, StandardFrameConstants::kContextOffset)); | 2064 Operand(ebp, StandardFrameConstants::kContextOffset)); |
2065 __ pop(eax); // result | 2065 __ pop(eax); // result |
2066 EmitReturnSequence(); | 2066 EmitReturnSequence(); |
2067 __ bind(&l_resume); // received in eax | 2067 __ bind(&l_resume); // received in eax |
2068 __ PopTryHandler(); | 2068 __ PopTryHandler(); |
2069 | 2069 |
2070 // receiver = iter; f = iter.next; arg = received; | 2070 // receiver = iter; f = iter.next; arg = received; |
2071 __ bind(&l_next); | 2071 __ bind(&l_next); |
2072 __ mov(ecx, isolate()->factory()->next_string()); // "next" | 2072 __ mov(ecx, isolate()->factory()->next_string()); // "next" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2106 break; | 2106 break; |
2107 } | 2107 } |
2108 } | 2108 } |
2109 } | 2109 } |
2110 | 2110 |
2111 | 2111 |
2112 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 2112 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
2113 Expression *value, | 2113 Expression *value, |
2114 JSGeneratorObject::ResumeMode resume_mode) { | 2114 JSGeneratorObject::ResumeMode resume_mode) { |
2115 // The value stays in eax, and is ultimately read by the resumed generator, as | 2115 // The value stays in eax, and is ultimately read by the resumed generator, as |
2116 // if the CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it | 2116 // if CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject) returned it. Or it |
2117 // is read to throw the value when the resumed generator is already closed. | 2117 // is read to throw the value when the resumed generator is already closed. |
2118 // ebx will hold the generator object until the activation has been resumed. | 2118 // ebx will hold the generator object until the activation has been resumed. |
2119 VisitForStackValue(generator); | 2119 VisitForStackValue(generator); |
2120 VisitForAccumulatorValue(value); | 2120 VisitForAccumulatorValue(value); |
2121 __ pop(ebx); | 2121 __ pop(ebx); |
2122 | 2122 |
2123 // Check generator state. | 2123 // Check generator state. |
2124 Label wrong_state, closed_state, done; | 2124 Label wrong_state, closed_state, done; |
2125 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0); | 2125 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0); |
2126 STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0); | 2126 STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2186 Label push_operand_holes, call_resume; | 2186 Label push_operand_holes, call_resume; |
2187 __ bind(&push_operand_holes); | 2187 __ bind(&push_operand_holes); |
2188 __ sub(edx, Immediate(1)); | 2188 __ sub(edx, Immediate(1)); |
2189 __ j(carry, &call_resume); | 2189 __ j(carry, &call_resume); |
2190 __ push(ecx); | 2190 __ push(ecx); |
2191 __ jmp(&push_operand_holes); | 2191 __ jmp(&push_operand_holes); |
2192 __ bind(&call_resume); | 2192 __ bind(&call_resume); |
2193 __ push(ebx); | 2193 __ push(ebx); |
2194 __ push(result_register()); | 2194 __ push(result_register()); |
2195 __ Push(Smi::FromInt(resume_mode)); | 2195 __ Push(Smi::FromInt(resume_mode)); |
2196 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); | 2196 __ CallRuntime(Runtime::kHiddenResumeJSGeneratorObject, 3); |
2197 // Not reached: the runtime call returns elsewhere. | 2197 // Not reached: the runtime call returns elsewhere. |
2198 __ Abort(kGeneratorFailedToResume); | 2198 __ Abort(kGeneratorFailedToResume); |
2199 | 2199 |
2200 // Reach here when generator is closed. | 2200 // Reach here when generator is closed. |
2201 __ bind(&closed_state); | 2201 __ bind(&closed_state); |
2202 if (resume_mode == JSGeneratorObject::NEXT) { | 2202 if (resume_mode == JSGeneratorObject::NEXT) { |
2203 // Return completed iterator result when generator is closed. | 2203 // Return completed iterator result when generator is closed. |
2204 __ push(Immediate(isolate()->factory()->undefined_value())); | 2204 __ push(Immediate(isolate()->factory()->undefined_value())); |
2205 // Pop value from top-of-stack slot; box result into result register. | 2205 // Pop value from top-of-stack slot; box result into result register. |
2206 EmitCreateIteratorResult(true); | 2206 EmitCreateIteratorResult(true); |
2207 } else { | 2207 } else { |
2208 // Throw the provided value. | 2208 // Throw the provided value. |
2209 __ push(eax); | 2209 __ push(eax); |
2210 __ CallRuntime(Runtime::kThrow, 1); | 2210 __ CallRuntime(Runtime::kHiddenThrow, 1); |
2211 } | 2211 } |
2212 __ jmp(&done); | 2212 __ jmp(&done); |
2213 | 2213 |
2214 // Throw error if we attempt to operate on a running generator. | 2214 // Throw error if we attempt to operate on a running generator. |
2215 __ bind(&wrong_state); | 2215 __ bind(&wrong_state); |
2216 __ push(ebx); | 2216 __ push(ebx); |
2217 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); | 2217 __ CallRuntime(Runtime::kHiddenThrowGeneratorStateError, 1); |
2218 | 2218 |
2219 __ bind(&done); | 2219 __ bind(&done); |
2220 context()->Plug(result_register()); | 2220 context()->Plug(result_register()); |
2221 } | 2221 } |
2222 | 2222 |
2223 | 2223 |
2224 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { | 2224 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { |
2225 Label gc_required; | 2225 Label gc_required; |
2226 Label allocated; | 2226 Label allocated; |
2227 | 2227 |
2228 Handle<Map> map(isolate()->native_context()->generator_result_map()); | 2228 Handle<Map> map(isolate()->native_context()->generator_result_map()); |
2229 | 2229 |
2230 __ Allocate(map->instance_size(), eax, ecx, edx, &gc_required, TAG_OBJECT); | 2230 __ Allocate(map->instance_size(), eax, ecx, edx, &gc_required, TAG_OBJECT); |
2231 __ jmp(&allocated); | 2231 __ jmp(&allocated); |
2232 | 2232 |
2233 __ bind(&gc_required); | 2233 __ bind(&gc_required); |
2234 __ Push(Smi::FromInt(map->instance_size())); | 2234 __ Push(Smi::FromInt(map->instance_size())); |
2235 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); | 2235 __ CallRuntime(Runtime::kHiddenAllocateInNewSpace, 1); |
2236 __ mov(context_register(), | 2236 __ mov(context_register(), |
2237 Operand(ebp, StandardFrameConstants::kContextOffset)); | 2237 Operand(ebp, StandardFrameConstants::kContextOffset)); |
2238 | 2238 |
2239 __ bind(&allocated); | 2239 __ bind(&allocated); |
2240 __ mov(ebx, map); | 2240 __ mov(ebx, map); |
2241 __ pop(ecx); | 2241 __ pop(ecx); |
2242 __ mov(edx, isolate()->factory()->ToBoolean(done)); | 2242 __ mov(edx, isolate()->factory()->ToBoolean(done)); |
2243 ASSERT_EQ(map->instance_size(), 5 * kPointerSize); | 2243 ASSERT_EQ(map->instance_size(), 5 * kPointerSize); |
2244 __ mov(FieldOperand(eax, HeapObject::kMapOffset), ebx); | 2244 __ mov(FieldOperand(eax, HeapObject::kMapOffset), ebx); |
2245 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), | 2245 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2437 } | 2437 } |
2438 } | 2438 } |
2439 | 2439 |
2440 | 2440 |
2441 void FullCodeGenerator::EmitCallStoreContextSlot( | 2441 void FullCodeGenerator::EmitCallStoreContextSlot( |
2442 Handle<String> name, StrictMode strict_mode) { | 2442 Handle<String> name, StrictMode strict_mode) { |
2443 __ push(eax); // Value. | 2443 __ push(eax); // Value. |
2444 __ push(esi); // Context. | 2444 __ push(esi); // Context. |
2445 __ push(Immediate(name)); | 2445 __ push(Immediate(name)); |
2446 __ push(Immediate(Smi::FromInt(strict_mode))); | 2446 __ push(Immediate(Smi::FromInt(strict_mode))); |
2447 __ CallRuntime(Runtime::kStoreContextSlot, 4); | 2447 __ CallRuntime(Runtime::kHiddenStoreContextSlot, 4); |
2448 } | 2448 } |
2449 | 2449 |
2450 | 2450 |
2451 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 2451 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
2452 Token::Value op) { | 2452 Token::Value op) { |
2453 if (var->IsUnallocated()) { | 2453 if (var->IsUnallocated()) { |
2454 // Global var, const, or let. | 2454 // Global var, const, or let. |
2455 __ mov(ecx, var->name()); | 2455 __ mov(ecx, var->name()); |
2456 __ mov(edx, GlobalObjectOperand()); | 2456 __ mov(edx, GlobalObjectOperand()); |
2457 CallStoreIC(); | 2457 CallStoreIC(); |
2458 | 2458 |
2459 } else if (op == Token::INIT_CONST_LEGACY) { | 2459 } else if (op == Token::INIT_CONST_LEGACY) { |
2460 // Const initializers need a write barrier. | 2460 // Const initializers need a write barrier. |
2461 ASSERT(!var->IsParameter()); // No const parameters. | 2461 ASSERT(!var->IsParameter()); // No const parameters. |
2462 if (var->IsLookupSlot()) { | 2462 if (var->IsLookupSlot()) { |
2463 __ push(eax); | 2463 __ push(eax); |
2464 __ push(esi); | 2464 __ push(esi); |
2465 __ push(Immediate(var->name())); | 2465 __ push(Immediate(var->name())); |
2466 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); | 2466 __ CallRuntime(Runtime::kHiddenInitializeConstContextSlot, 3); |
2467 } else { | 2467 } else { |
2468 ASSERT(var->IsStackLocal() || var->IsContextSlot()); | 2468 ASSERT(var->IsStackLocal() || var->IsContextSlot()); |
2469 Label skip; | 2469 Label skip; |
2470 MemOperand location = VarOperand(var, ecx); | 2470 MemOperand location = VarOperand(var, ecx); |
2471 __ mov(edx, location); | 2471 __ mov(edx, location); |
2472 __ cmp(edx, isolate()->factory()->the_hole_value()); | 2472 __ cmp(edx, isolate()->factory()->the_hole_value()); |
2473 __ j(not_equal, &skip, Label::kNear); | 2473 __ j(not_equal, &skip, Label::kNear); |
2474 EmitStoreToStackLocalOrContextSlot(var, location); | 2474 EmitStoreToStackLocalOrContextSlot(var, location); |
2475 __ bind(&skip); | 2475 __ bind(&skip); |
2476 } | 2476 } |
2477 | 2477 |
2478 } else if (var->mode() == LET && op != Token::INIT_LET) { | 2478 } else if (var->mode() == LET && op != Token::INIT_LET) { |
2479 // Non-initializing assignment to let variable needs a write barrier. | 2479 // Non-initializing assignment to let variable needs a write barrier. |
2480 if (var->IsLookupSlot()) { | 2480 if (var->IsLookupSlot()) { |
2481 EmitCallStoreContextSlot(var->name(), strict_mode()); | 2481 EmitCallStoreContextSlot(var->name(), strict_mode()); |
2482 } else { | 2482 } else { |
2483 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 2483 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); |
2484 Label assign; | 2484 Label assign; |
2485 MemOperand location = VarOperand(var, ecx); | 2485 MemOperand location = VarOperand(var, ecx); |
2486 __ mov(edx, location); | 2486 __ mov(edx, location); |
2487 __ cmp(edx, isolate()->factory()->the_hole_value()); | 2487 __ cmp(edx, isolate()->factory()->the_hole_value()); |
2488 __ j(not_equal, &assign, Label::kNear); | 2488 __ j(not_equal, &assign, Label::kNear); |
2489 __ push(Immediate(var->name())); | 2489 __ push(Immediate(var->name())); |
2490 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 2490 __ CallRuntime(Runtime::kHiddenThrowReferenceError, 1); |
2491 __ bind(&assign); | 2491 __ bind(&assign); |
2492 EmitStoreToStackLocalOrContextSlot(var, location); | 2492 EmitStoreToStackLocalOrContextSlot(var, location); |
2493 } | 2493 } |
2494 | 2494 |
2495 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { | 2495 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { |
2496 // Assignment to var or initializing assignment to let/const | 2496 // Assignment to var or initializing assignment to let/const |
2497 // in harmony mode. | 2497 // in harmony mode. |
2498 if (var->IsLookupSlot()) { | 2498 if (var->IsLookupSlot()) { |
2499 EmitCallStoreContextSlot(var->name(), strict_mode()); | 2499 EmitCallStoreContextSlot(var->name(), strict_mode()); |
2500 } else { | 2500 } else { |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2715 | 2715 |
2716 // Push the receiver of the enclosing function. | 2716 // Push the receiver of the enclosing function. |
2717 __ push(Operand(ebp, (2 + info_->scope()->num_parameters()) * kPointerSize)); | 2717 __ push(Operand(ebp, (2 + info_->scope()->num_parameters()) * kPointerSize)); |
2718 // Push the language mode. | 2718 // Push the language mode. |
2719 __ push(Immediate(Smi::FromInt(strict_mode()))); | 2719 __ push(Immediate(Smi::FromInt(strict_mode()))); |
2720 | 2720 |
2721 // Push the start position of the scope the calls resides in. | 2721 // Push the start position of the scope the calls resides in. |
2722 __ push(Immediate(Smi::FromInt(scope()->start_position()))); | 2722 __ push(Immediate(Smi::FromInt(scope()->start_position()))); |
2723 | 2723 |
2724 // Do the runtime call. | 2724 // Do the runtime call. |
2725 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); | 2725 __ CallRuntime(Runtime::kHiddenResolvePossiblyDirectEval, 5); |
2726 } | 2726 } |
2727 | 2727 |
2728 | 2728 |
2729 void FullCodeGenerator::VisitCall(Call* expr) { | 2729 void FullCodeGenerator::VisitCall(Call* expr) { |
2730 #ifdef DEBUG | 2730 #ifdef DEBUG |
2731 // We want to verify that RecordJSReturnSite gets called on all paths | 2731 // We want to verify that RecordJSReturnSite gets called on all paths |
2732 // through this function. Avoid early returns. | 2732 // through this function. Avoid early returns. |
2733 expr->return_is_recorded_ = false; | 2733 expr->return_is_recorded_ = false; |
2734 #endif | 2734 #endif |
2735 | 2735 |
2736 Comment cmnt(masm_, "[ Call"); | 2736 Comment cmnt(masm_, "[ Call"); |
2737 Expression* callee = expr->expression(); | 2737 Expression* callee = expr->expression(); |
2738 Call::CallType call_type = expr->GetCallType(isolate()); | 2738 Call::CallType call_type = expr->GetCallType(isolate()); |
2739 | 2739 |
2740 if (call_type == Call::POSSIBLY_EVAL_CALL) { | 2740 if (call_type == Call::POSSIBLY_EVAL_CALL) { |
2741 // In a call to eval, we first call %ResolvePossiblyDirectEval to | 2741 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval |
2742 // resolve the function we need to call and the receiver of the call. | 2742 // to resolve the function we need to call and the receiver of the call. |
2743 // Then we call the resolved function using the given arguments. | 2743 // Then we call the resolved function using the given arguments. |
2744 ZoneList<Expression*>* args = expr->arguments(); | 2744 ZoneList<Expression*>* args = expr->arguments(); |
2745 int arg_count = args->length(); | 2745 int arg_count = args->length(); |
2746 { PreservePositionScope pos_scope(masm()->positions_recorder()); | 2746 { PreservePositionScope pos_scope(masm()->positions_recorder()); |
2747 VisitForStackValue(callee); | 2747 VisitForStackValue(callee); |
2748 // Reserved receiver slot. | 2748 // Reserved receiver slot. |
2749 __ push(Immediate(isolate()->factory()->undefined_value())); | 2749 __ push(Immediate(isolate()->factory()->undefined_value())); |
2750 // Push the arguments. | 2750 // Push the arguments. |
2751 for (int i = 0; i < arg_count; i++) { | 2751 for (int i = 0; i < arg_count; i++) { |
2752 VisitForStackValue(args->at(i)); | 2752 VisitForStackValue(args->at(i)); |
(...skipping 29 matching lines...) Expand all Loading... |
2782 { PreservePositionScope scope(masm()->positions_recorder()); | 2782 { PreservePositionScope scope(masm()->positions_recorder()); |
2783 // Generate code for loading from variables potentially shadowed by | 2783 // Generate code for loading from variables potentially shadowed by |
2784 // eval-introduced variables. | 2784 // eval-introduced variables. |
2785 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); | 2785 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); |
2786 } | 2786 } |
2787 __ bind(&slow); | 2787 __ bind(&slow); |
2788 // Call the runtime to find the function to call (returned in eax) and | 2788 // Call the runtime to find the function to call (returned in eax) and |
2789 // the object holding it (returned in edx). | 2789 // the object holding it (returned in edx). |
2790 __ push(context_register()); | 2790 __ push(context_register()); |
2791 __ push(Immediate(proxy->name())); | 2791 __ push(Immediate(proxy->name())); |
2792 __ CallRuntime(Runtime::kLoadContextSlot, 2); | 2792 __ CallRuntime(Runtime::kHiddenLoadContextSlot, 2); |
2793 __ push(eax); // Function. | 2793 __ push(eax); // Function. |
2794 __ push(edx); // Receiver. | 2794 __ push(edx); // Receiver. |
2795 | 2795 |
2796 // If fast case code has been generated, emit code to push the function | 2796 // If fast case code has been generated, emit code to push the function |
2797 // and receiver and have the slow path jump around this code. | 2797 // and receiver and have the slow path jump around this code. |
2798 if (done.is_linked()) { | 2798 if (done.is_linked()) { |
2799 Label call; | 2799 Label call; |
2800 __ jmp(&call, Label::kNear); | 2800 __ jmp(&call, Label::kNear); |
2801 __ bind(&done); | 2801 __ bind(&done); |
2802 // Push function. | 2802 // Push function. |
(...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3446 } | 3446 } |
3447 __ bind(&runtime); | 3447 __ bind(&runtime); |
3448 __ PrepareCallCFunction(2, scratch); | 3448 __ PrepareCallCFunction(2, scratch); |
3449 __ mov(Operand(esp, 0), object); | 3449 __ mov(Operand(esp, 0), object); |
3450 __ mov(Operand(esp, 1 * kPointerSize), Immediate(index)); | 3450 __ mov(Operand(esp, 1 * kPointerSize), Immediate(index)); |
3451 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); | 3451 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); |
3452 __ jmp(&done); | 3452 __ jmp(&done); |
3453 } | 3453 } |
3454 | 3454 |
3455 __ bind(¬_date_object); | 3455 __ bind(¬_date_object); |
3456 __ CallRuntime(Runtime::kThrowNotDateError, 0); | 3456 __ CallRuntime(Runtime::kHiddenThrowNotDateError, 0); |
3457 __ bind(&done); | 3457 __ bind(&done); |
3458 context()->Plug(result); | 3458 context()->Plug(result); |
3459 } | 3459 } |
3460 | 3460 |
3461 | 3461 |
3462 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { | 3462 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { |
3463 ZoneList<Expression*>* args = expr->arguments(); | 3463 ZoneList<Expression*>* args = expr->arguments(); |
3464 ASSERT_EQ(3, args->length()); | 3464 ASSERT_EQ(3, args->length()); |
3465 | 3465 |
3466 Register string = eax; | 3466 Register string = eax; |
(...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4227 } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 4227 } else if (var->IsStackAllocated() || var->IsContextSlot()) { |
4228 // Result of deleting non-global variables is false. 'this' is | 4228 // Result of deleting non-global variables is false. 'this' is |
4229 // not really a variable, though we implement it as one. The | 4229 // not really a variable, though we implement it as one. The |
4230 // subexpression does not have side effects. | 4230 // 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 __ push(context_register()); | 4235 __ push(context_register()); |
4236 __ push(Immediate(var->name())); | 4236 __ push(Immediate(var->name())); |
4237 __ CallRuntime(Runtime::kDeleteContextSlot, 2); | 4237 __ CallRuntime(Runtime::kHiddenDeleteContextSlot, 2); |
4238 context()->Plug(eax); | 4238 context()->Plug(eax); |
4239 } | 4239 } |
4240 } else { | 4240 } else { |
4241 // Result of deleting non-property, non-variable reference is true. | 4241 // Result of deleting non-property, non-variable reference is true. |
4242 // The subexpression may have side effects. | 4242 // The subexpression may have side effects. |
4243 VisitForEffect(expr->expression()); | 4243 VisitForEffect(expr->expression()); |
4244 context()->Plug(true); | 4244 context()->Plug(true); |
4245 } | 4245 } |
4246 break; | 4246 break; |
4247 } | 4247 } |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4520 Comment cmnt(masm_, "[ Lookup slot"); | 4520 Comment cmnt(masm_, "[ Lookup slot"); |
4521 Label done, slow; | 4521 Label done, slow; |
4522 | 4522 |
4523 // Generate code for loading from variables potentially shadowed | 4523 // Generate code for loading from variables potentially shadowed |
4524 // by eval-introduced variables. | 4524 // by eval-introduced variables. |
4525 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); | 4525 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); |
4526 | 4526 |
4527 __ bind(&slow); | 4527 __ bind(&slow); |
4528 __ push(esi); | 4528 __ push(esi); |
4529 __ push(Immediate(proxy->name())); | 4529 __ push(Immediate(proxy->name())); |
4530 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); | 4530 __ CallRuntime(Runtime::kHiddenLoadContextSlotNoReferenceError, 2); |
4531 PrepareForBailout(expr, TOS_REG); | 4531 PrepareForBailout(expr, TOS_REG); |
4532 __ bind(&done); | 4532 __ bind(&done); |
4533 | 4533 |
4534 context()->Plug(eax); | 4534 context()->Plug(eax); |
4535 } else { | 4535 } else { |
4536 // This expression cannot throw a reference error at the top level. | 4536 // This expression cannot throw a reference error at the top level. |
4537 VisitInDuplicateContext(expr); | 4537 VisitInDuplicateContext(expr); |
4538 } | 4538 } |
4539 } | 4539 } |
4540 | 4540 |
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4936 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4936 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
4937 Assembler::target_address_at(call_target_address, | 4937 Assembler::target_address_at(call_target_address, |
4938 unoptimized_code)); | 4938 unoptimized_code)); |
4939 return OSR_AFTER_STACK_CHECK; | 4939 return OSR_AFTER_STACK_CHECK; |
4940 } | 4940 } |
4941 | 4941 |
4942 | 4942 |
4943 } } // namespace v8::internal | 4943 } } // namespace v8::internal |
4944 | 4944 |
4945 #endif // V8_TARGET_ARCH_IA32 | 4945 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |