OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
8 | 8 |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 | 183 |
184 // Possibly allocate a local context. | 184 // Possibly allocate a local context. |
185 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 185 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
186 if (heap_slots > 0) { | 186 if (heap_slots > 0) { |
187 Comment cmnt(masm_, "[ Allocate context"); | 187 Comment cmnt(masm_, "[ Allocate context"); |
188 bool need_write_barrier = true; | 188 bool need_write_barrier = true; |
189 // Argument to NewContext is the function, which is still in edi. | 189 // Argument to NewContext is the function, which is still in edi. |
190 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { | 190 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { |
191 __ push(edi); | 191 __ push(edi); |
192 __ Push(info->scope()->GetScopeInfo()); | 192 __ Push(info->scope()->GetScopeInfo()); |
193 __ CallRuntime(Runtime::kHiddenNewGlobalContext, 2); | 193 __ CallRuntime(Runtime::kNewGlobalContext, 2); |
194 } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { | 194 } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { |
195 FastNewContextStub stub(isolate(), heap_slots); | 195 FastNewContextStub stub(isolate(), heap_slots); |
196 __ CallStub(&stub); | 196 __ CallStub(&stub); |
197 // Result of FastNewContextStub is always in new space. | 197 // Result of FastNewContextStub is always in new space. |
198 need_write_barrier = false; | 198 need_write_barrier = false; |
199 } else { | 199 } else { |
200 __ push(edi); | 200 __ push(edi); |
201 __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); | 201 __ CallRuntime(Runtime::kNewFunctionContext, 1); |
202 } | 202 } |
203 function_in_register = false; | 203 function_in_register = false; |
204 // Context is returned in eax. It replaces the context passed to us. | 204 // Context is returned in eax. It replaces the context passed to us. |
205 // It's saved in the stack and kept live in esi. | 205 // It's saved in the stack and kept live in esi. |
206 __ mov(esi, eax); | 206 __ mov(esi, eax); |
207 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), eax); | 207 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), eax); |
208 | 208 |
209 // Copy parameters into context if necessary. | 209 // Copy parameters into context if necessary. |
210 int num_parameters = info->scope()->num_parameters(); | 210 int num_parameters = info->scope()->num_parameters(); |
211 for (int i = 0; i < num_parameters; i++) { | 211 for (int i = 0; i < num_parameters; i++) { |
(...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
795 __ push(Immediate(Smi::FromInt(attr))); | 795 __ push(Immediate(Smi::FromInt(attr))); |
796 // Push initial value, if any. | 796 // Push initial value, if any. |
797 // Note: For variables we must not push an initial value (such as | 797 // Note: For variables we must not push an initial value (such as |
798 // 'undefined') because we may have a (legal) redeclaration and we | 798 // 'undefined') because we may have a (legal) redeclaration and we |
799 // must not destroy the current value. | 799 // must not destroy the current value. |
800 if (hole_init) { | 800 if (hole_init) { |
801 __ push(Immediate(isolate()->factory()->the_hole_value())); | 801 __ push(Immediate(isolate()->factory()->the_hole_value())); |
802 } else { | 802 } else { |
803 __ push(Immediate(Smi::FromInt(0))); // Indicates no initial value. | 803 __ push(Immediate(Smi::FromInt(0))); // Indicates no initial value. |
804 } | 804 } |
805 __ CallRuntime(Runtime::kHiddenDeclareContextSlot, 4); | 805 __ CallRuntime(Runtime::kDeclareContextSlot, 4); |
806 break; | 806 break; |
807 } | 807 } |
808 } | 808 } |
809 } | 809 } |
810 | 810 |
811 | 811 |
812 void FullCodeGenerator::VisitFunctionDeclaration( | 812 void FullCodeGenerator::VisitFunctionDeclaration( |
813 FunctionDeclaration* declaration) { | 813 FunctionDeclaration* declaration) { |
814 VariableProxy* proxy = declaration->proxy(); | 814 VariableProxy* proxy = declaration->proxy(); |
815 Variable* variable = proxy->var(); | 815 Variable* variable = proxy->var(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
848 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); | 848 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); |
849 break; | 849 break; |
850 } | 850 } |
851 | 851 |
852 case Variable::LOOKUP: { | 852 case Variable::LOOKUP: { |
853 Comment cmnt(masm_, "[ FunctionDeclaration"); | 853 Comment cmnt(masm_, "[ FunctionDeclaration"); |
854 __ push(esi); | 854 __ push(esi); |
855 __ push(Immediate(variable->name())); | 855 __ push(Immediate(variable->name())); |
856 __ push(Immediate(Smi::FromInt(NONE))); | 856 __ push(Immediate(Smi::FromInt(NONE))); |
857 VisitForStackValue(declaration->fun()); | 857 VisitForStackValue(declaration->fun()); |
858 __ CallRuntime(Runtime::kHiddenDeclareContextSlot, 4); | 858 __ CallRuntime(Runtime::kDeclareContextSlot, 4); |
859 break; | 859 break; |
860 } | 860 } |
861 } | 861 } |
862 } | 862 } |
863 | 863 |
864 | 864 |
865 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { | 865 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { |
866 Variable* variable = declaration->proxy()->var(); | 866 Variable* variable = declaration->proxy()->var(); |
867 ASSERT(variable->location() == Variable::CONTEXT); | 867 ASSERT(variable->location() == Variable::CONTEXT); |
868 ASSERT(variable->interface()->IsFrozen()); | 868 ASSERT(variable->interface()->IsFrozen()); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
918 void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) { | 918 void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) { |
919 // TODO(rossberg) | 919 // TODO(rossberg) |
920 } | 920 } |
921 | 921 |
922 | 922 |
923 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 923 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
924 // Call the runtime to declare the globals. | 924 // Call the runtime to declare the globals. |
925 __ push(esi); // The context is the first argument. | 925 __ push(esi); // The context is the first argument. |
926 __ Push(pairs); | 926 __ Push(pairs); |
927 __ Push(Smi::FromInt(DeclareGlobalsFlags())); | 927 __ Push(Smi::FromInt(DeclareGlobalsFlags())); |
928 __ CallRuntime(Runtime::kHiddenDeclareGlobals, 3); | 928 __ CallRuntime(Runtime::kDeclareGlobals, 3); |
929 // Return value is ignored. | 929 // Return value is ignored. |
930 } | 930 } |
931 | 931 |
932 | 932 |
933 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) { | 933 void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) { |
934 // Call the runtime to declare the modules. | 934 // Call the runtime to declare the modules. |
935 __ Push(descriptions); | 935 __ Push(descriptions); |
936 __ CallRuntime(Runtime::kHiddenDeclareModules, 1); | 936 __ CallRuntime(Runtime::kDeclareModules, 1); |
937 // Return value is ignored. | 937 // Return value is ignored. |
938 } | 938 } |
939 | 939 |
940 | 940 |
941 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { | 941 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { |
942 Comment cmnt(masm_, "[ SwitchStatement"); | 942 Comment cmnt(masm_, "[ SwitchStatement"); |
943 Breakable nested_statement(this, stmt); | 943 Breakable nested_statement(this, stmt); |
944 SetStatementPosition(stmt); | 944 SetStatementPosition(stmt); |
945 | 945 |
946 // Keep the switch value on the stack until a case matches. | 946 // Keep the switch value on the stack until a case matches. |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1268 info->strict_mode(), | 1268 info->strict_mode(), |
1269 info->is_generator()); | 1269 info->is_generator()); |
1270 __ mov(ebx, Immediate(info)); | 1270 __ mov(ebx, Immediate(info)); |
1271 __ CallStub(&stub); | 1271 __ CallStub(&stub); |
1272 } else { | 1272 } else { |
1273 __ push(esi); | 1273 __ push(esi); |
1274 __ push(Immediate(info)); | 1274 __ push(Immediate(info)); |
1275 __ push(Immediate(pretenure | 1275 __ push(Immediate(pretenure |
1276 ? isolate()->factory()->true_value() | 1276 ? isolate()->factory()->true_value() |
1277 : isolate()->factory()->false_value())); | 1277 : isolate()->factory()->false_value())); |
1278 __ CallRuntime(Runtime::kHiddenNewClosure, 3); | 1278 __ CallRuntime(Runtime::kNewClosure, 3); |
1279 } | 1279 } |
1280 context()->Plug(eax); | 1280 context()->Plug(eax); |
1281 } | 1281 } |
1282 | 1282 |
1283 | 1283 |
1284 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { | 1284 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
1285 Comment cmnt(masm_, "[ VariableProxy"); | 1285 Comment cmnt(masm_, "[ VariableProxy"); |
1286 EmitVariableLoad(expr); | 1286 EmitVariableLoad(expr); |
1287 } | 1287 } |
1288 | 1288 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1393 Variable* local = var->local_if_not_shadowed(); | 1393 Variable* local = var->local_if_not_shadowed(); |
1394 __ mov(eax, ContextSlotOperandCheckExtensions(local, slow)); | 1394 __ mov(eax, ContextSlotOperandCheckExtensions(local, slow)); |
1395 if (local->mode() == LET || local->mode() == CONST || | 1395 if (local->mode() == LET || local->mode() == CONST || |
1396 local->mode() == CONST_LEGACY) { | 1396 local->mode() == CONST_LEGACY) { |
1397 __ cmp(eax, isolate()->factory()->the_hole_value()); | 1397 __ cmp(eax, isolate()->factory()->the_hole_value()); |
1398 __ j(not_equal, done); | 1398 __ j(not_equal, done); |
1399 if (local->mode() == CONST_LEGACY) { | 1399 if (local->mode() == CONST_LEGACY) { |
1400 __ mov(eax, isolate()->factory()->undefined_value()); | 1400 __ mov(eax, isolate()->factory()->undefined_value()); |
1401 } else { // LET || CONST | 1401 } else { // LET || CONST |
1402 __ push(Immediate(var->name())); | 1402 __ push(Immediate(var->name())); |
1403 __ CallRuntime(Runtime::kHiddenThrowReferenceError, 1); | 1403 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
1404 } | 1404 } |
1405 } | 1405 } |
1406 __ jmp(done); | 1406 __ jmp(done); |
1407 } | 1407 } |
1408 } | 1408 } |
1409 | 1409 |
1410 | 1410 |
1411 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { | 1411 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
1412 // Record position before possible IC call. | 1412 // Record position before possible IC call. |
1413 SetSourcePosition(proxy->position()); | 1413 SetSourcePosition(proxy->position()); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1470 if (!skip_init_check) { | 1470 if (!skip_init_check) { |
1471 // Let and const need a read barrier. | 1471 // Let and const need a read barrier. |
1472 Label done; | 1472 Label done; |
1473 GetVar(eax, var); | 1473 GetVar(eax, var); |
1474 __ cmp(eax, isolate()->factory()->the_hole_value()); | 1474 __ cmp(eax, isolate()->factory()->the_hole_value()); |
1475 __ j(not_equal, &done, Label::kNear); | 1475 __ j(not_equal, &done, Label::kNear); |
1476 if (var->mode() == LET || var->mode() == CONST) { | 1476 if (var->mode() == LET || var->mode() == CONST) { |
1477 // Throw a reference error when using an uninitialized let/const | 1477 // Throw a reference error when using an uninitialized let/const |
1478 // binding in harmony mode. | 1478 // binding in harmony mode. |
1479 __ push(Immediate(var->name())); | 1479 __ push(Immediate(var->name())); |
1480 __ CallRuntime(Runtime::kHiddenThrowReferenceError, 1); | 1480 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
1481 } else { | 1481 } else { |
1482 // Uninitalized const bindings outside of harmony mode are unholed. | 1482 // Uninitalized const bindings outside of harmony mode are unholed. |
1483 ASSERT(var->mode() == CONST_LEGACY); | 1483 ASSERT(var->mode() == CONST_LEGACY); |
1484 __ mov(eax, isolate()->factory()->undefined_value()); | 1484 __ mov(eax, isolate()->factory()->undefined_value()); |
1485 } | 1485 } |
1486 __ bind(&done); | 1486 __ bind(&done); |
1487 context()->Plug(eax); | 1487 context()->Plug(eax); |
1488 break; | 1488 break; |
1489 } | 1489 } |
1490 } | 1490 } |
1491 context()->Plug(var); | 1491 context()->Plug(var); |
1492 break; | 1492 break; |
1493 } | 1493 } |
1494 | 1494 |
1495 case Variable::LOOKUP: { | 1495 case Variable::LOOKUP: { |
1496 Comment cmnt(masm_, "[ Lookup variable"); | 1496 Comment cmnt(masm_, "[ Lookup variable"); |
1497 Label done, slow; | 1497 Label done, slow; |
1498 // Generate code for loading from variables potentially shadowed | 1498 // Generate code for loading from variables potentially shadowed |
1499 // by eval-introduced variables. | 1499 // by eval-introduced variables. |
1500 EmitDynamicLookupFastCase(var, NOT_INSIDE_TYPEOF, &slow, &done); | 1500 EmitDynamicLookupFastCase(var, NOT_INSIDE_TYPEOF, &slow, &done); |
1501 __ bind(&slow); | 1501 __ bind(&slow); |
1502 __ push(esi); // Context. | 1502 __ push(esi); // Context. |
1503 __ push(Immediate(var->name())); | 1503 __ push(Immediate(var->name())); |
1504 __ CallRuntime(Runtime::kHiddenLoadContextSlot, 2); | 1504 __ CallRuntime(Runtime::kLoadContextSlot, 2); |
1505 __ bind(&done); | 1505 __ bind(&done); |
1506 context()->Plug(eax); | 1506 context()->Plug(eax); |
1507 break; | 1507 break; |
1508 } | 1508 } |
1509 } | 1509 } |
1510 } | 1510 } |
1511 | 1511 |
1512 | 1512 |
1513 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 1513 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
1514 Comment cmnt(masm_, "[ RegExpLiteral"); | 1514 Comment cmnt(masm_, "[ RegExpLiteral"); |
(...skipping 10 matching lines...) Expand all Loading... |
1525 __ mov(ebx, FieldOperand(ecx, literal_offset)); | 1525 __ mov(ebx, FieldOperand(ecx, literal_offset)); |
1526 __ cmp(ebx, isolate()->factory()->undefined_value()); | 1526 __ cmp(ebx, isolate()->factory()->undefined_value()); |
1527 __ j(not_equal, &materialized, Label::kNear); | 1527 __ j(not_equal, &materialized, Label::kNear); |
1528 | 1528 |
1529 // Create regexp literal using runtime function | 1529 // Create regexp literal using runtime function |
1530 // Result will be in eax. | 1530 // Result will be in eax. |
1531 __ push(ecx); | 1531 __ push(ecx); |
1532 __ push(Immediate(Smi::FromInt(expr->literal_index()))); | 1532 __ push(Immediate(Smi::FromInt(expr->literal_index()))); |
1533 __ push(Immediate(expr->pattern())); | 1533 __ push(Immediate(expr->pattern())); |
1534 __ push(Immediate(expr->flags())); | 1534 __ push(Immediate(expr->flags())); |
1535 __ CallRuntime(Runtime::kHiddenMaterializeRegExpLiteral, 4); | 1535 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); |
1536 __ mov(ebx, eax); | 1536 __ mov(ebx, eax); |
1537 | 1537 |
1538 __ bind(&materialized); | 1538 __ bind(&materialized); |
1539 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; | 1539 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; |
1540 Label allocated, runtime_allocate; | 1540 Label allocated, runtime_allocate; |
1541 __ Allocate(size, eax, ecx, edx, &runtime_allocate, TAG_OBJECT); | 1541 __ Allocate(size, eax, ecx, edx, &runtime_allocate, TAG_OBJECT); |
1542 __ jmp(&allocated); | 1542 __ jmp(&allocated); |
1543 | 1543 |
1544 __ bind(&runtime_allocate); | 1544 __ bind(&runtime_allocate); |
1545 __ push(ebx); | 1545 __ push(ebx); |
1546 __ push(Immediate(Smi::FromInt(size))); | 1546 __ push(Immediate(Smi::FromInt(size))); |
1547 __ CallRuntime(Runtime::kHiddenAllocateInNewSpace, 1); | 1547 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); |
1548 __ pop(ebx); | 1548 __ pop(ebx); |
1549 | 1549 |
1550 __ bind(&allocated); | 1550 __ bind(&allocated); |
1551 // Copy the content into the newly allocated memory. | 1551 // Copy the content into the newly allocated memory. |
1552 // (Unroll copy loop once for better throughput). | 1552 // (Unroll copy loop once for better throughput). |
1553 for (int i = 0; i < size - kPointerSize; i += 2 * kPointerSize) { | 1553 for (int i = 0; i < size - kPointerSize; i += 2 * kPointerSize) { |
1554 __ mov(edx, FieldOperand(ebx, i)); | 1554 __ mov(edx, FieldOperand(ebx, i)); |
1555 __ mov(ecx, FieldOperand(ebx, i + kPointerSize)); | 1555 __ mov(ecx, FieldOperand(ebx, i + kPointerSize)); |
1556 __ mov(FieldOperand(eax, i), edx); | 1556 __ mov(FieldOperand(eax, i), edx); |
1557 __ mov(FieldOperand(eax, i + kPointerSize), ecx); | 1557 __ mov(FieldOperand(eax, i + kPointerSize), ecx); |
(...skipping 29 matching lines...) Expand all Loading... |
1587 int properties_count = constant_properties->length() / 2; | 1587 int properties_count = constant_properties->length() / 2; |
1588 if (expr->may_store_doubles() || expr->depth() > 1 || | 1588 if (expr->may_store_doubles() || expr->depth() > 1 || |
1589 masm()->serializer_enabled() || | 1589 masm()->serializer_enabled() || |
1590 flags != ObjectLiteral::kFastElements || | 1590 flags != ObjectLiteral::kFastElements || |
1591 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { | 1591 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { |
1592 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 1592 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
1593 __ push(FieldOperand(edi, JSFunction::kLiteralsOffset)); | 1593 __ push(FieldOperand(edi, JSFunction::kLiteralsOffset)); |
1594 __ push(Immediate(Smi::FromInt(expr->literal_index()))); | 1594 __ push(Immediate(Smi::FromInt(expr->literal_index()))); |
1595 __ push(Immediate(constant_properties)); | 1595 __ push(Immediate(constant_properties)); |
1596 __ push(Immediate(Smi::FromInt(flags))); | 1596 __ push(Immediate(Smi::FromInt(flags))); |
1597 __ CallRuntime(Runtime::kHiddenCreateObjectLiteral, 4); | 1597 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); |
1598 } else { | 1598 } else { |
1599 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 1599 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
1600 __ mov(eax, FieldOperand(edi, JSFunction::kLiteralsOffset)); | 1600 __ mov(eax, FieldOperand(edi, JSFunction::kLiteralsOffset)); |
1601 __ mov(ebx, Immediate(Smi::FromInt(expr->literal_index()))); | 1601 __ mov(ebx, Immediate(Smi::FromInt(expr->literal_index()))); |
1602 __ mov(ecx, Immediate(constant_properties)); | 1602 __ mov(ecx, Immediate(constant_properties)); |
1603 __ mov(edx, Immediate(Smi::FromInt(flags))); | 1603 __ mov(edx, Immediate(Smi::FromInt(flags))); |
1604 FastCloneShallowObjectStub stub(isolate(), properties_count); | 1604 FastCloneShallowObjectStub stub(isolate(), properties_count); |
1605 __ CallStub(&stub); | 1605 __ CallStub(&stub); |
1606 } | 1606 } |
1607 | 1607 |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1724 // we can turn it off if we don't have anywhere else to transition to. | 1724 // we can turn it off if we don't have anywhere else to transition to. |
1725 allocation_site_mode = DONT_TRACK_ALLOCATION_SITE; | 1725 allocation_site_mode = DONT_TRACK_ALLOCATION_SITE; |
1726 } | 1726 } |
1727 | 1727 |
1728 if (expr->depth() > 1 || length > JSObject::kInitialMaxFastElementArray) { | 1728 if (expr->depth() > 1 || length > JSObject::kInitialMaxFastElementArray) { |
1729 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 1729 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
1730 __ push(FieldOperand(ebx, JSFunction::kLiteralsOffset)); | 1730 __ push(FieldOperand(ebx, JSFunction::kLiteralsOffset)); |
1731 __ push(Immediate(Smi::FromInt(expr->literal_index()))); | 1731 __ push(Immediate(Smi::FromInt(expr->literal_index()))); |
1732 __ push(Immediate(constant_elements)); | 1732 __ push(Immediate(constant_elements)); |
1733 __ push(Immediate(Smi::FromInt(flags))); | 1733 __ push(Immediate(Smi::FromInt(flags))); |
1734 __ CallRuntime(Runtime::kHiddenCreateArrayLiteral, 4); | 1734 __ CallRuntime(Runtime::kCreateArrayLiteral, 4); |
1735 } else { | 1735 } else { |
1736 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 1736 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
1737 __ mov(eax, FieldOperand(ebx, JSFunction::kLiteralsOffset)); | 1737 __ mov(eax, FieldOperand(ebx, JSFunction::kLiteralsOffset)); |
1738 __ mov(ebx, Immediate(Smi::FromInt(expr->literal_index()))); | 1738 __ mov(ebx, Immediate(Smi::FromInt(expr->literal_index()))); |
1739 __ mov(ecx, Immediate(constant_elements)); | 1739 __ mov(ecx, Immediate(constant_elements)); |
1740 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); | 1740 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); |
1741 __ CallStub(&stub); | 1741 __ CallStub(&stub); |
1742 } | 1742 } |
1743 | 1743 |
1744 bool result_saved = false; // Is the result saved to the stack? | 1744 bool result_saved = false; // Is the result saved to the stack? |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1926 __ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset), | 1926 __ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset), |
1927 Immediate(Smi::FromInt(continuation.pos()))); | 1927 Immediate(Smi::FromInt(continuation.pos()))); |
1928 __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi); | 1928 __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi); |
1929 __ mov(ecx, esi); | 1929 __ mov(ecx, esi); |
1930 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, | 1930 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, |
1931 kDontSaveFPRegs); | 1931 kDontSaveFPRegs); |
1932 __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset)); | 1932 __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset)); |
1933 __ cmp(esp, ebx); | 1933 __ cmp(esp, ebx); |
1934 __ j(equal, &post_runtime); | 1934 __ j(equal, &post_runtime); |
1935 __ push(eax); // generator object | 1935 __ push(eax); // generator object |
1936 __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1); | 1936 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
1937 __ mov(context_register(), | 1937 __ mov(context_register(), |
1938 Operand(ebp, StandardFrameConstants::kContextOffset)); | 1938 Operand(ebp, StandardFrameConstants::kContextOffset)); |
1939 __ bind(&post_runtime); | 1939 __ bind(&post_runtime); |
1940 __ pop(result_register()); | 1940 __ pop(result_register()); |
1941 EmitReturnSequence(); | 1941 EmitReturnSequence(); |
1942 | 1942 |
1943 __ bind(&resume); | 1943 __ bind(&resume); |
1944 context()->Plug(result_register()); | 1944 context()->Plug(result_register()); |
1945 break; | 1945 break; |
1946 } | 1946 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1994 const int generator_object_depth = kPointerSize + handler_size; | 1994 const int generator_object_depth = kPointerSize + handler_size; |
1995 __ mov(eax, Operand(esp, generator_object_depth)); | 1995 __ mov(eax, Operand(esp, generator_object_depth)); |
1996 __ push(eax); // g | 1996 __ push(eax); // g |
1997 ASSERT(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos())); | 1997 ASSERT(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos())); |
1998 __ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset), | 1998 __ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset), |
1999 Immediate(Smi::FromInt(l_continuation.pos()))); | 1999 Immediate(Smi::FromInt(l_continuation.pos()))); |
2000 __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi); | 2000 __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi); |
2001 __ mov(ecx, esi); | 2001 __ mov(ecx, esi); |
2002 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, | 2002 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, |
2003 kDontSaveFPRegs); | 2003 kDontSaveFPRegs); |
2004 __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1); | 2004 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
2005 __ mov(context_register(), | 2005 __ mov(context_register(), |
2006 Operand(ebp, StandardFrameConstants::kContextOffset)); | 2006 Operand(ebp, StandardFrameConstants::kContextOffset)); |
2007 __ pop(eax); // result | 2007 __ pop(eax); // result |
2008 EmitReturnSequence(); | 2008 EmitReturnSequence(); |
2009 __ bind(&l_resume); // received in eax | 2009 __ bind(&l_resume); // received in eax |
2010 __ PopTryHandler(); | 2010 __ PopTryHandler(); |
2011 | 2011 |
2012 // receiver = iter; f = iter.next; arg = received; | 2012 // receiver = iter; f = iter.next; arg = received; |
2013 __ bind(&l_next); | 2013 __ bind(&l_next); |
2014 __ mov(ecx, isolate()->factory()->next_string()); // "next" | 2014 __ mov(ecx, isolate()->factory()->next_string()); // "next" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2048 break; | 2048 break; |
2049 } | 2049 } |
2050 } | 2050 } |
2051 } | 2051 } |
2052 | 2052 |
2053 | 2053 |
2054 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 2054 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
2055 Expression *value, | 2055 Expression *value, |
2056 JSGeneratorObject::ResumeMode resume_mode) { | 2056 JSGeneratorObject::ResumeMode resume_mode) { |
2057 // The value stays in eax, and is ultimately read by the resumed generator, as | 2057 // The value stays in eax, and is ultimately read by the resumed generator, as |
2058 // if CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject) returned it. Or it | 2058 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it |
2059 // is read to throw the value when the resumed generator is already closed. | 2059 // is read to throw the value when the resumed generator is already closed. |
2060 // ebx will hold the generator object until the activation has been resumed. | 2060 // ebx will hold the generator object until the activation has been resumed. |
2061 VisitForStackValue(generator); | 2061 VisitForStackValue(generator); |
2062 VisitForAccumulatorValue(value); | 2062 VisitForAccumulatorValue(value); |
2063 __ pop(ebx); | 2063 __ pop(ebx); |
2064 | 2064 |
2065 // Check generator state. | 2065 // Check generator state. |
2066 Label wrong_state, closed_state, done; | 2066 Label wrong_state, closed_state, done; |
2067 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0); | 2067 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0); |
2068 STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0); | 2068 STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2128 Label push_operand_holes, call_resume; | 2128 Label push_operand_holes, call_resume; |
2129 __ bind(&push_operand_holes); | 2129 __ bind(&push_operand_holes); |
2130 __ sub(edx, Immediate(1)); | 2130 __ sub(edx, Immediate(1)); |
2131 __ j(carry, &call_resume); | 2131 __ j(carry, &call_resume); |
2132 __ push(ecx); | 2132 __ push(ecx); |
2133 __ jmp(&push_operand_holes); | 2133 __ jmp(&push_operand_holes); |
2134 __ bind(&call_resume); | 2134 __ bind(&call_resume); |
2135 __ push(ebx); | 2135 __ push(ebx); |
2136 __ push(result_register()); | 2136 __ push(result_register()); |
2137 __ Push(Smi::FromInt(resume_mode)); | 2137 __ Push(Smi::FromInt(resume_mode)); |
2138 __ CallRuntime(Runtime::kHiddenResumeJSGeneratorObject, 3); | 2138 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); |
2139 // Not reached: the runtime call returns elsewhere. | 2139 // Not reached: the runtime call returns elsewhere. |
2140 __ Abort(kGeneratorFailedToResume); | 2140 __ Abort(kGeneratorFailedToResume); |
2141 | 2141 |
2142 // Reach here when generator is closed. | 2142 // Reach here when generator is closed. |
2143 __ bind(&closed_state); | 2143 __ bind(&closed_state); |
2144 if (resume_mode == JSGeneratorObject::NEXT) { | 2144 if (resume_mode == JSGeneratorObject::NEXT) { |
2145 // Return completed iterator result when generator is closed. | 2145 // Return completed iterator result when generator is closed. |
2146 __ push(Immediate(isolate()->factory()->undefined_value())); | 2146 __ push(Immediate(isolate()->factory()->undefined_value())); |
2147 // Pop value from top-of-stack slot; box result into result register. | 2147 // Pop value from top-of-stack slot; box result into result register. |
2148 EmitCreateIteratorResult(true); | 2148 EmitCreateIteratorResult(true); |
2149 } else { | 2149 } else { |
2150 // Throw the provided value. | 2150 // Throw the provided value. |
2151 __ push(eax); | 2151 __ push(eax); |
2152 __ CallRuntime(Runtime::kHiddenThrow, 1); | 2152 __ CallRuntime(Runtime::kThrow, 1); |
2153 } | 2153 } |
2154 __ jmp(&done); | 2154 __ jmp(&done); |
2155 | 2155 |
2156 // Throw error if we attempt to operate on a running generator. | 2156 // Throw error if we attempt to operate on a running generator. |
2157 __ bind(&wrong_state); | 2157 __ bind(&wrong_state); |
2158 __ push(ebx); | 2158 __ push(ebx); |
2159 __ CallRuntime(Runtime::kHiddenThrowGeneratorStateError, 1); | 2159 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); |
2160 | 2160 |
2161 __ bind(&done); | 2161 __ bind(&done); |
2162 context()->Plug(result_register()); | 2162 context()->Plug(result_register()); |
2163 } | 2163 } |
2164 | 2164 |
2165 | 2165 |
2166 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { | 2166 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { |
2167 Label gc_required; | 2167 Label gc_required; |
2168 Label allocated; | 2168 Label allocated; |
2169 | 2169 |
2170 Handle<Map> map(isolate()->native_context()->iterator_result_map()); | 2170 Handle<Map> map(isolate()->native_context()->iterator_result_map()); |
2171 | 2171 |
2172 __ Allocate(map->instance_size(), eax, ecx, edx, &gc_required, TAG_OBJECT); | 2172 __ Allocate(map->instance_size(), eax, ecx, edx, &gc_required, TAG_OBJECT); |
2173 __ jmp(&allocated); | 2173 __ jmp(&allocated); |
2174 | 2174 |
2175 __ bind(&gc_required); | 2175 __ bind(&gc_required); |
2176 __ Push(Smi::FromInt(map->instance_size())); | 2176 __ Push(Smi::FromInt(map->instance_size())); |
2177 __ CallRuntime(Runtime::kHiddenAllocateInNewSpace, 1); | 2177 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); |
2178 __ mov(context_register(), | 2178 __ mov(context_register(), |
2179 Operand(ebp, StandardFrameConstants::kContextOffset)); | 2179 Operand(ebp, StandardFrameConstants::kContextOffset)); |
2180 | 2180 |
2181 __ bind(&allocated); | 2181 __ bind(&allocated); |
2182 __ mov(ebx, map); | 2182 __ mov(ebx, map); |
2183 __ pop(ecx); | 2183 __ pop(ecx); |
2184 __ mov(edx, isolate()->factory()->ToBoolean(done)); | 2184 __ mov(edx, isolate()->factory()->ToBoolean(done)); |
2185 ASSERT_EQ(map->instance_size(), 5 * kPointerSize); | 2185 ASSERT_EQ(map->instance_size(), 5 * kPointerSize); |
2186 __ mov(FieldOperand(eax, HeapObject::kMapOffset), ebx); | 2186 __ mov(FieldOperand(eax, HeapObject::kMapOffset), ebx); |
2187 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), | 2187 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2379 } | 2379 } |
2380 } | 2380 } |
2381 | 2381 |
2382 | 2382 |
2383 void FullCodeGenerator::EmitCallStoreContextSlot( | 2383 void FullCodeGenerator::EmitCallStoreContextSlot( |
2384 Handle<String> name, StrictMode strict_mode) { | 2384 Handle<String> name, StrictMode strict_mode) { |
2385 __ push(eax); // Value. | 2385 __ push(eax); // Value. |
2386 __ push(esi); // Context. | 2386 __ push(esi); // Context. |
2387 __ push(Immediate(name)); | 2387 __ push(Immediate(name)); |
2388 __ push(Immediate(Smi::FromInt(strict_mode))); | 2388 __ push(Immediate(Smi::FromInt(strict_mode))); |
2389 __ CallRuntime(Runtime::kHiddenStoreContextSlot, 4); | 2389 __ CallRuntime(Runtime::kStoreContextSlot, 4); |
2390 } | 2390 } |
2391 | 2391 |
2392 | 2392 |
2393 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 2393 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
2394 Token::Value op) { | 2394 Token::Value op) { |
2395 if (var->IsUnallocated()) { | 2395 if (var->IsUnallocated()) { |
2396 // Global var, const, or let. | 2396 // Global var, const, or let. |
2397 __ mov(ecx, var->name()); | 2397 __ mov(ecx, var->name()); |
2398 __ mov(edx, GlobalObjectOperand()); | 2398 __ mov(edx, GlobalObjectOperand()); |
2399 CallStoreIC(); | 2399 CallStoreIC(); |
2400 | 2400 |
2401 } else if (op == Token::INIT_CONST_LEGACY) { | 2401 } else if (op == Token::INIT_CONST_LEGACY) { |
2402 // Const initializers need a write barrier. | 2402 // Const initializers need a write barrier. |
2403 ASSERT(!var->IsParameter()); // No const parameters. | 2403 ASSERT(!var->IsParameter()); // No const parameters. |
2404 if (var->IsLookupSlot()) { | 2404 if (var->IsLookupSlot()) { |
2405 __ push(eax); | 2405 __ push(eax); |
2406 __ push(esi); | 2406 __ push(esi); |
2407 __ push(Immediate(var->name())); | 2407 __ push(Immediate(var->name())); |
2408 __ CallRuntime(Runtime::kHiddenInitializeConstContextSlot, 3); | 2408 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); |
2409 } else { | 2409 } else { |
2410 ASSERT(var->IsStackLocal() || var->IsContextSlot()); | 2410 ASSERT(var->IsStackLocal() || var->IsContextSlot()); |
2411 Label skip; | 2411 Label skip; |
2412 MemOperand location = VarOperand(var, ecx); | 2412 MemOperand location = VarOperand(var, ecx); |
2413 __ mov(edx, location); | 2413 __ mov(edx, location); |
2414 __ cmp(edx, isolate()->factory()->the_hole_value()); | 2414 __ cmp(edx, isolate()->factory()->the_hole_value()); |
2415 __ j(not_equal, &skip, Label::kNear); | 2415 __ j(not_equal, &skip, Label::kNear); |
2416 EmitStoreToStackLocalOrContextSlot(var, location); | 2416 EmitStoreToStackLocalOrContextSlot(var, location); |
2417 __ bind(&skip); | 2417 __ bind(&skip); |
2418 } | 2418 } |
2419 | 2419 |
2420 } else if (var->mode() == LET && op != Token::INIT_LET) { | 2420 } else if (var->mode() == LET && op != Token::INIT_LET) { |
2421 // Non-initializing assignment to let variable needs a write barrier. | 2421 // Non-initializing assignment to let variable needs a write barrier. |
2422 if (var->IsLookupSlot()) { | 2422 if (var->IsLookupSlot()) { |
2423 EmitCallStoreContextSlot(var->name(), strict_mode()); | 2423 EmitCallStoreContextSlot(var->name(), strict_mode()); |
2424 } else { | 2424 } else { |
2425 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 2425 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); |
2426 Label assign; | 2426 Label assign; |
2427 MemOperand location = VarOperand(var, ecx); | 2427 MemOperand location = VarOperand(var, ecx); |
2428 __ mov(edx, location); | 2428 __ mov(edx, location); |
2429 __ cmp(edx, isolate()->factory()->the_hole_value()); | 2429 __ cmp(edx, isolate()->factory()->the_hole_value()); |
2430 __ j(not_equal, &assign, Label::kNear); | 2430 __ j(not_equal, &assign, Label::kNear); |
2431 __ push(Immediate(var->name())); | 2431 __ push(Immediate(var->name())); |
2432 __ CallRuntime(Runtime::kHiddenThrowReferenceError, 1); | 2432 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
2433 __ bind(&assign); | 2433 __ bind(&assign); |
2434 EmitStoreToStackLocalOrContextSlot(var, location); | 2434 EmitStoreToStackLocalOrContextSlot(var, location); |
2435 } | 2435 } |
2436 | 2436 |
2437 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { | 2437 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { |
2438 // Assignment to var or initializing assignment to let/const | 2438 // Assignment to var or initializing assignment to let/const |
2439 // in harmony mode. | 2439 // in harmony mode. |
2440 if (var->IsLookupSlot()) { | 2440 if (var->IsLookupSlot()) { |
2441 EmitCallStoreContextSlot(var->name(), strict_mode()); | 2441 EmitCallStoreContextSlot(var->name(), strict_mode()); |
2442 } else { | 2442 } else { |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2616 | 2616 |
2617 // Push the receiver of the enclosing function. | 2617 // Push the receiver of the enclosing function. |
2618 __ push(Operand(ebp, (2 + info_->scope()->num_parameters()) * kPointerSize)); | 2618 __ push(Operand(ebp, (2 + info_->scope()->num_parameters()) * kPointerSize)); |
2619 // Push the language mode. | 2619 // Push the language mode. |
2620 __ push(Immediate(Smi::FromInt(strict_mode()))); | 2620 __ push(Immediate(Smi::FromInt(strict_mode()))); |
2621 | 2621 |
2622 // Push the start position of the scope the calls resides in. | 2622 // Push the start position of the scope the calls resides in. |
2623 __ push(Immediate(Smi::FromInt(scope()->start_position()))); | 2623 __ push(Immediate(Smi::FromInt(scope()->start_position()))); |
2624 | 2624 |
2625 // Do the runtime call. | 2625 // Do the runtime call. |
2626 __ CallRuntime(Runtime::kHiddenResolvePossiblyDirectEval, 5); | 2626 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); |
2627 } | 2627 } |
2628 | 2628 |
2629 | 2629 |
2630 void FullCodeGenerator::VisitCall(Call* expr) { | 2630 void FullCodeGenerator::VisitCall(Call* expr) { |
2631 #ifdef DEBUG | 2631 #ifdef DEBUG |
2632 // We want to verify that RecordJSReturnSite gets called on all paths | 2632 // We want to verify that RecordJSReturnSite gets called on all paths |
2633 // through this function. Avoid early returns. | 2633 // through this function. Avoid early returns. |
2634 expr->return_is_recorded_ = false; | 2634 expr->return_is_recorded_ = false; |
2635 #endif | 2635 #endif |
2636 | 2636 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2683 { PreservePositionScope scope(masm()->positions_recorder()); | 2683 { PreservePositionScope scope(masm()->positions_recorder()); |
2684 // Generate code for loading from variables potentially shadowed by | 2684 // Generate code for loading from variables potentially shadowed by |
2685 // eval-introduced variables. | 2685 // eval-introduced variables. |
2686 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); | 2686 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); |
2687 } | 2687 } |
2688 __ bind(&slow); | 2688 __ bind(&slow); |
2689 // Call the runtime to find the function to call (returned in eax) and | 2689 // Call the runtime to find the function to call (returned in eax) and |
2690 // the object holding it (returned in edx). | 2690 // the object holding it (returned in edx). |
2691 __ push(context_register()); | 2691 __ push(context_register()); |
2692 __ push(Immediate(proxy->name())); | 2692 __ push(Immediate(proxy->name())); |
2693 __ CallRuntime(Runtime::kHiddenLoadContextSlot, 2); | 2693 __ CallRuntime(Runtime::kLoadContextSlot, 2); |
2694 __ push(eax); // Function. | 2694 __ push(eax); // Function. |
2695 __ push(edx); // Receiver. | 2695 __ push(edx); // Receiver. |
2696 | 2696 |
2697 // If fast case code has been generated, emit code to push the function | 2697 // If fast case code has been generated, emit code to push the function |
2698 // and receiver and have the slow path jump around this code. | 2698 // and receiver and have the slow path jump around this code. |
2699 if (done.is_linked()) { | 2699 if (done.is_linked()) { |
2700 Label call; | 2700 Label call; |
2701 __ jmp(&call, Label::kNear); | 2701 __ jmp(&call, Label::kNear); |
2702 __ bind(&done); | 2702 __ bind(&done); |
2703 // Push function. | 2703 // Push function. |
(...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3322 } | 3322 } |
3323 __ bind(&runtime); | 3323 __ bind(&runtime); |
3324 __ PrepareCallCFunction(2, scratch); | 3324 __ PrepareCallCFunction(2, scratch); |
3325 __ mov(Operand(esp, 0), object); | 3325 __ mov(Operand(esp, 0), object); |
3326 __ mov(Operand(esp, 1 * kPointerSize), Immediate(index)); | 3326 __ mov(Operand(esp, 1 * kPointerSize), Immediate(index)); |
3327 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); | 3327 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); |
3328 __ jmp(&done); | 3328 __ jmp(&done); |
3329 } | 3329 } |
3330 | 3330 |
3331 __ bind(¬_date_object); | 3331 __ bind(¬_date_object); |
3332 __ CallRuntime(Runtime::kHiddenThrowNotDateError, 0); | 3332 __ CallRuntime(Runtime::kThrowNotDateError, 0); |
3333 __ bind(&done); | 3333 __ bind(&done); |
3334 context()->Plug(result); | 3334 context()->Plug(result); |
3335 } | 3335 } |
3336 | 3336 |
3337 | 3337 |
3338 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { | 3338 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { |
3339 ZoneList<Expression*>* args = expr->arguments(); | 3339 ZoneList<Expression*>* args = expr->arguments(); |
3340 ASSERT_EQ(3, args->length()); | 3340 ASSERT_EQ(3, args->length()); |
3341 | 3341 |
3342 Register string = eax; | 3342 Register string = eax; |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3680 __ cmp(key, FixedArrayElementOperand(cache, tmp)); | 3680 __ cmp(key, FixedArrayElementOperand(cache, tmp)); |
3681 __ j(not_equal, ¬_found); | 3681 __ j(not_equal, ¬_found); |
3682 | 3682 |
3683 __ mov(eax, FixedArrayElementOperand(cache, tmp, 1)); | 3683 __ mov(eax, FixedArrayElementOperand(cache, tmp, 1)); |
3684 __ jmp(&done); | 3684 __ jmp(&done); |
3685 | 3685 |
3686 __ bind(¬_found); | 3686 __ bind(¬_found); |
3687 // Call runtime to perform the lookup. | 3687 // Call runtime to perform the lookup. |
3688 __ push(cache); | 3688 __ push(cache); |
3689 __ push(key); | 3689 __ push(key); |
3690 __ CallRuntime(Runtime::kHiddenGetFromCache, 2); | 3690 __ CallRuntime(Runtime::kGetFromCache, 2); |
3691 | 3691 |
3692 __ bind(&done); | 3692 __ bind(&done); |
3693 context()->Plug(eax); | 3693 context()->Plug(eax); |
3694 } | 3694 } |
3695 | 3695 |
3696 | 3696 |
3697 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { | 3697 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { |
3698 ZoneList<Expression*>* args = expr->arguments(); | 3698 ZoneList<Expression*>* args = expr->arguments(); |
3699 ASSERT(args->length() == 1); | 3699 ASSERT(args->length() == 1); |
3700 | 3700 |
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4089 } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 4089 } else if (var->IsStackAllocated() || var->IsContextSlot()) { |
4090 // Result of deleting non-global variables is false. 'this' is | 4090 // Result of deleting non-global variables is false. 'this' is |
4091 // not really a variable, though we implement it as one. The | 4091 // not really a variable, though we implement it as one. The |
4092 // subexpression does not have side effects. | 4092 // subexpression does not have side effects. |
4093 context()->Plug(var->is_this()); | 4093 context()->Plug(var->is_this()); |
4094 } else { | 4094 } else { |
4095 // Non-global variable. Call the runtime to try to delete from the | 4095 // Non-global variable. Call the runtime to try to delete from the |
4096 // context where the variable was introduced. | 4096 // context where the variable was introduced. |
4097 __ push(context_register()); | 4097 __ push(context_register()); |
4098 __ push(Immediate(var->name())); | 4098 __ push(Immediate(var->name())); |
4099 __ CallRuntime(Runtime::kHiddenDeleteContextSlot, 2); | 4099 __ CallRuntime(Runtime::kDeleteContextSlot, 2); |
4100 context()->Plug(eax); | 4100 context()->Plug(eax); |
4101 } | 4101 } |
4102 } else { | 4102 } else { |
4103 // Result of deleting non-property, non-variable reference is true. | 4103 // Result of deleting non-property, non-variable reference is true. |
4104 // The subexpression may have side effects. | 4104 // The subexpression may have side effects. |
4105 VisitForEffect(expr->expression()); | 4105 VisitForEffect(expr->expression()); |
4106 context()->Plug(true); | 4106 context()->Plug(true); |
4107 } | 4107 } |
4108 break; | 4108 break; |
4109 } | 4109 } |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4382 Comment cmnt(masm_, "[ Lookup slot"); | 4382 Comment cmnt(masm_, "[ Lookup slot"); |
4383 Label done, slow; | 4383 Label done, slow; |
4384 | 4384 |
4385 // Generate code for loading from variables potentially shadowed | 4385 // Generate code for loading from variables potentially shadowed |
4386 // by eval-introduced variables. | 4386 // by eval-introduced variables. |
4387 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); | 4387 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); |
4388 | 4388 |
4389 __ bind(&slow); | 4389 __ bind(&slow); |
4390 __ push(esi); | 4390 __ push(esi); |
4391 __ push(Immediate(proxy->name())); | 4391 __ push(Immediate(proxy->name())); |
4392 __ CallRuntime(Runtime::kHiddenLoadContextSlotNoReferenceError, 2); | 4392 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); |
4393 PrepareForBailout(expr, TOS_REG); | 4393 PrepareForBailout(expr, TOS_REG); |
4394 __ bind(&done); | 4394 __ bind(&done); |
4395 | 4395 |
4396 context()->Plug(eax); | 4396 context()->Plug(eax); |
4397 } else { | 4397 } else { |
4398 // This expression cannot throw a reference error at the top level. | 4398 // This expression cannot throw a reference error at the top level. |
4399 VisitInDuplicateContext(expr); | 4399 VisitInDuplicateContext(expr); |
4400 } | 4400 } |
4401 } | 4401 } |
4402 | 4402 |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4799 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4799 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
4800 Assembler::target_address_at(call_target_address, | 4800 Assembler::target_address_at(call_target_address, |
4801 unoptimized_code)); | 4801 unoptimized_code)); |
4802 return OSR_AFTER_STACK_CHECK; | 4802 return OSR_AFTER_STACK_CHECK; |
4803 } | 4803 } |
4804 | 4804 |
4805 | 4805 |
4806 } } // namespace v8::internal | 4806 } } // namespace v8::internal |
4807 | 4807 |
4808 #endif // V8_TARGET_ARCH_IA32 | 4808 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |