| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 673 VisitForStackValue(prop->key()); | 673 VisitForStackValue(prop->key()); |
| 674 VisitForAccumulatorValue(function); | 674 VisitForAccumulatorValue(function); |
| 675 __ pop(r1); // Key. | 675 __ pop(r1); // Key. |
| 676 } else { | 676 } else { |
| 677 VisitForAccumulatorValue(prop->key()); | 677 VisitForAccumulatorValue(prop->key()); |
| 678 __ mov(r1, result_register()); // Key. | 678 __ mov(r1, result_register()); // Key. |
| 679 __ LoadRoot(result_register(), Heap::kTheHoleValueRootIndex); | 679 __ LoadRoot(result_register(), Heap::kTheHoleValueRootIndex); |
| 680 } | 680 } |
| 681 __ pop(r2); // Receiver. | 681 __ pop(r2); // Receiver. |
| 682 | 682 |
| 683 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 683 Handle<Code> ic(isolate()->builtins()->builtin( |
| 684 Builtins::KeyedStoreIC_Initialize)); | 684 Builtins::KeyedStoreIC_Initialize)); |
| 685 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 685 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 686 // Value in r0 is ignored (declarations are statements). | 686 // Value in r0 is ignored (declarations are statements). |
| 687 } | 687 } |
| 688 } | 688 } |
| 689 } | 689 } |
| 690 | 690 |
| 691 | 691 |
| 692 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { | 692 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { |
| 693 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); | 693 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1010 key_literal != NULL && | 1010 key_literal != NULL && |
| 1011 obj_proxy->IsArguments() && | 1011 obj_proxy->IsArguments() && |
| 1012 key_literal->handle()->IsSmi()) { | 1012 key_literal->handle()->IsSmi()) { |
| 1013 // Load arguments object if there are no eval-introduced | 1013 // Load arguments object if there are no eval-introduced |
| 1014 // variables. Then load the argument from the arguments | 1014 // variables. Then load the argument from the arguments |
| 1015 // object using keyed load. | 1015 // object using keyed load. |
| 1016 __ ldr(r1, | 1016 __ ldr(r1, |
| 1017 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), | 1017 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), |
| 1018 slow)); | 1018 slow)); |
| 1019 __ mov(r0, Operand(key_literal->handle())); | 1019 __ mov(r0, Operand(key_literal->handle())); |
| 1020 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 1020 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1021 Builtins::KeyedLoadIC_Initialize)); | 1021 Builtins::KeyedLoadIC_Initialize)); |
| 1022 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1022 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1023 __ jmp(done); | 1023 __ jmp(done); |
| 1024 } | 1024 } |
| 1025 } | 1025 } |
| 1026 } | 1026 } |
| 1027 } | 1027 } |
| 1028 } | 1028 } |
| 1029 | 1029 |
| 1030 | 1030 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1077 __ ldr(next, FieldMemOperand(next, JSFunction::kContextOffset)); | 1077 __ ldr(next, FieldMemOperand(next, JSFunction::kContextOffset)); |
| 1078 __ b(&loop); | 1078 __ b(&loop); |
| 1079 __ bind(&fast); | 1079 __ bind(&fast); |
| 1080 } | 1080 } |
| 1081 | 1081 |
| 1082 __ ldr(r0, GlobalObjectOperand()); | 1082 __ ldr(r0, GlobalObjectOperand()); |
| 1083 __ mov(r2, Operand(slot->var()->name())); | 1083 __ mov(r2, Operand(slot->var()->name())); |
| 1084 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 1084 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) |
| 1085 ? RelocInfo::CODE_TARGET | 1085 ? RelocInfo::CODE_TARGET |
| 1086 : RelocInfo::CODE_TARGET_CONTEXT; | 1086 : RelocInfo::CODE_TARGET_CONTEXT; |
| 1087 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 1087 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1088 Builtins::LoadIC_Initialize)); | 1088 Builtins::LoadIC_Initialize)); |
| 1089 EmitCallIC(ic, mode); | 1089 EmitCallIC(ic, mode); |
| 1090 } | 1090 } |
| 1091 | 1091 |
| 1092 | 1092 |
| 1093 void FullCodeGenerator::EmitVariableLoad(Variable* var) { | 1093 void FullCodeGenerator::EmitVariableLoad(Variable* var) { |
| 1094 // Four cases: non-this global variables, lookup slots, all other | 1094 // Four cases: non-this global variables, lookup slots, all other |
| 1095 // types of slots, and parameters that rewrite to explicit property | 1095 // types of slots, and parameters that rewrite to explicit property |
| 1096 // accesses on the arguments object. | 1096 // accesses on the arguments object. |
| 1097 Slot* slot = var->AsSlot(); | 1097 Slot* slot = var->AsSlot(); |
| 1098 Property* property = var->AsProperty(); | 1098 Property* property = var->AsProperty(); |
| 1099 | 1099 |
| 1100 if (var->is_global() && !var->is_this()) { | 1100 if (var->is_global() && !var->is_this()) { |
| 1101 Comment cmnt(masm_, "Global variable"); | 1101 Comment cmnt(masm_, "Global variable"); |
| 1102 // Use inline caching. Variable name is passed in r2 and the global | 1102 // Use inline caching. Variable name is passed in r2 and the global |
| 1103 // object (receiver) in r0. | 1103 // object (receiver) in r0. |
| 1104 __ ldr(r0, GlobalObjectOperand()); | 1104 __ ldr(r0, GlobalObjectOperand()); |
| 1105 __ mov(r2, Operand(var->name())); | 1105 __ mov(r2, Operand(var->name())); |
| 1106 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 1106 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1107 Builtins::LoadIC_Initialize)); | 1107 Builtins::LoadIC_Initialize)); |
| 1108 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1108 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 1109 context()->Plug(r0); | 1109 context()->Plug(r0); |
| 1110 | 1110 |
| 1111 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { | 1111 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
| 1112 Label done, slow; | 1112 Label done, slow; |
| 1113 | 1113 |
| 1114 // Generate code for loading from variables potentially shadowed | 1114 // Generate code for loading from variables potentially shadowed |
| 1115 // by eval-introduced variables. | 1115 // by eval-introduced variables. |
| 1116 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); | 1116 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1156 | 1156 |
| 1157 // Assert that the key is a smi. | 1157 // Assert that the key is a smi. |
| 1158 Literal* key_literal = property->key()->AsLiteral(); | 1158 Literal* key_literal = property->key()->AsLiteral(); |
| 1159 ASSERT_NOT_NULL(key_literal); | 1159 ASSERT_NOT_NULL(key_literal); |
| 1160 ASSERT(key_literal->handle()->IsSmi()); | 1160 ASSERT(key_literal->handle()->IsSmi()); |
| 1161 | 1161 |
| 1162 // Load the key. | 1162 // Load the key. |
| 1163 __ mov(r0, Operand(key_literal->handle())); | 1163 __ mov(r0, Operand(key_literal->handle())); |
| 1164 | 1164 |
| 1165 // Call keyed load IC. It has arguments key and receiver in r0 and r1. | 1165 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
| 1166 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 1166 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1167 Builtins::KeyedLoadIC_Initialize)); | 1167 Builtins::KeyedLoadIC_Initialize)); |
| 1168 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1168 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1169 context()->Plug(r0); | 1169 context()->Plug(r0); |
| 1170 } | 1170 } |
| 1171 } | 1171 } |
| 1172 | 1172 |
| 1173 | 1173 |
| 1174 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 1174 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
| 1175 Comment cmnt(masm_, "[ RegExpLiteral"); | 1175 Comment cmnt(masm_, "[ RegExpLiteral"); |
| 1176 Label materialized; | 1176 Label materialized; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1252 UNREACHABLE(); | 1252 UNREACHABLE(); |
| 1253 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1253 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1254 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1254 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); |
| 1255 // Fall through. | 1255 // Fall through. |
| 1256 case ObjectLiteral::Property::COMPUTED: | 1256 case ObjectLiteral::Property::COMPUTED: |
| 1257 if (key->handle()->IsSymbol()) { | 1257 if (key->handle()->IsSymbol()) { |
| 1258 if (property->emit_store()) { | 1258 if (property->emit_store()) { |
| 1259 VisitForAccumulatorValue(value); | 1259 VisitForAccumulatorValue(value); |
| 1260 __ mov(r2, Operand(key->handle())); | 1260 __ mov(r2, Operand(key->handle())); |
| 1261 __ ldr(r1, MemOperand(sp)); | 1261 __ ldr(r1, MemOperand(sp)); |
| 1262 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 1262 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1263 Builtins::StoreIC_Initialize)); | 1263 Builtins::StoreIC_Initialize)); |
| 1264 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1264 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1265 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1265 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1266 } else { | 1266 } else { |
| 1267 VisitForEffect(value); | 1267 VisitForEffect(value); |
| 1268 } | 1268 } |
| 1269 break; | 1269 break; |
| 1270 } | 1270 } |
| 1271 // Fall through. | 1271 // Fall through. |
| 1272 case ObjectLiteral::Property::PROTOTYPE: | 1272 case ObjectLiteral::Property::PROTOTYPE: |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1309 Comment cmnt(masm_, "[ ArrayLiteral"); | 1309 Comment cmnt(masm_, "[ ArrayLiteral"); |
| 1310 | 1310 |
| 1311 ZoneList<Expression*>* subexprs = expr->values(); | 1311 ZoneList<Expression*>* subexprs = expr->values(); |
| 1312 int length = subexprs->length(); | 1312 int length = subexprs->length(); |
| 1313 | 1313 |
| 1314 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1314 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1315 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); | 1315 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); |
| 1316 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); | 1316 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); |
| 1317 __ mov(r1, Operand(expr->constant_elements())); | 1317 __ mov(r1, Operand(expr->constant_elements())); |
| 1318 __ Push(r3, r2, r1); | 1318 __ Push(r3, r2, r1); |
| 1319 if (expr->constant_elements()->map() == HEAP->fixed_cow_array_map()) { | 1319 if (expr->constant_elements()->map() == |
| 1320 isolate()->heap()->fixed_cow_array_map()) { |
| 1320 FastCloneShallowArrayStub stub( | 1321 FastCloneShallowArrayStub stub( |
| 1321 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length); | 1322 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length); |
| 1322 __ CallStub(&stub); | 1323 __ CallStub(&stub); |
| 1323 __ IncrementCounter(COUNTERS->cow_arrays_created_stub(), 1, r1, r2); | 1324 __ IncrementCounter( |
| 1325 isolate()->counters()->cow_arrays_created_stub(), 1, r1, r2); |
| 1324 } else if (expr->depth() > 1) { | 1326 } else if (expr->depth() > 1) { |
| 1325 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); | 1327 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); |
| 1326 } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { | 1328 } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { |
| 1327 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3); | 1329 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3); |
| 1328 } else { | 1330 } else { |
| 1329 FastCloneShallowArrayStub stub( | 1331 FastCloneShallowArrayStub stub( |
| 1330 FastCloneShallowArrayStub::CLONE_ELEMENTS, length); | 1332 FastCloneShallowArrayStub::CLONE_ELEMENTS, length); |
| 1331 __ CallStub(&stub); | 1333 __ CallStub(&stub); |
| 1332 } | 1334 } |
| 1333 | 1335 |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1502 break; | 1504 break; |
| 1503 } | 1505 } |
| 1504 } | 1506 } |
| 1505 | 1507 |
| 1506 | 1508 |
| 1507 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1509 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 1508 SetSourcePosition(prop->position()); | 1510 SetSourcePosition(prop->position()); |
| 1509 Literal* key = prop->key()->AsLiteral(); | 1511 Literal* key = prop->key()->AsLiteral(); |
| 1510 __ mov(r2, Operand(key->handle())); | 1512 __ mov(r2, Operand(key->handle())); |
| 1511 // Call load IC. It has arguments receiver and property name r0 and r2. | 1513 // Call load IC. It has arguments receiver and property name r0 and r2. |
| 1512 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 1514 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1513 Builtins::LoadIC_Initialize)); | 1515 Builtins::LoadIC_Initialize)); |
| 1514 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1516 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1515 } | 1517 } |
| 1516 | 1518 |
| 1517 | 1519 |
| 1518 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1520 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 1519 SetSourcePosition(prop->position()); | 1521 SetSourcePosition(prop->position()); |
| 1520 // Call keyed load IC. It has arguments key and receiver in r0 and r1. | 1522 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
| 1521 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 1523 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1522 Builtins::KeyedLoadIC_Initialize)); | 1524 Builtins::KeyedLoadIC_Initialize)); |
| 1523 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1525 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1524 } | 1526 } |
| 1525 | 1527 |
| 1526 | 1528 |
| 1527 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, | 1529 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, |
| 1528 Token::Value op, | 1530 Token::Value op, |
| 1529 OverwriteMode mode, | 1531 OverwriteMode mode, |
| 1530 Expression* left, | 1532 Expression* left, |
| 1531 Expression* right, | 1533 Expression* right, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1569 EffectContext context(this); | 1571 EffectContext context(this); |
| 1570 EmitVariableAssignment(var, Token::ASSIGN); | 1572 EmitVariableAssignment(var, Token::ASSIGN); |
| 1571 break; | 1573 break; |
| 1572 } | 1574 } |
| 1573 case NAMED_PROPERTY: { | 1575 case NAMED_PROPERTY: { |
| 1574 __ push(r0); // Preserve value. | 1576 __ push(r0); // Preserve value. |
| 1575 VisitForAccumulatorValue(prop->obj()); | 1577 VisitForAccumulatorValue(prop->obj()); |
| 1576 __ mov(r1, r0); | 1578 __ mov(r1, r0); |
| 1577 __ pop(r0); // Restore value. | 1579 __ pop(r0); // Restore value. |
| 1578 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 1580 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
| 1579 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 1581 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1580 Builtins::StoreIC_Initialize)); | 1582 Builtins::StoreIC_Initialize)); |
| 1581 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1583 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1582 break; | 1584 break; |
| 1583 } | 1585 } |
| 1584 case KEYED_PROPERTY: { | 1586 case KEYED_PROPERTY: { |
| 1585 __ push(r0); // Preserve value. | 1587 __ push(r0); // Preserve value. |
| 1586 VisitForStackValue(prop->obj()); | 1588 VisitForStackValue(prop->obj()); |
| 1587 VisitForAccumulatorValue(prop->key()); | 1589 VisitForAccumulatorValue(prop->key()); |
| 1588 __ mov(r1, r0); | 1590 __ mov(r1, r0); |
| 1589 __ pop(r2); | 1591 __ pop(r2); |
| 1590 __ pop(r0); // Restore value. | 1592 __ pop(r0); // Restore value. |
| 1591 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 1593 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1592 Builtins::KeyedStoreIC_Initialize)); | 1594 Builtins::KeyedStoreIC_Initialize)); |
| 1593 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1595 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1594 break; | 1596 break; |
| 1595 } | 1597 } |
| 1596 } | 1598 } |
| 1597 } | 1599 } |
| 1598 | 1600 |
| 1599 | 1601 |
| 1600 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 1602 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
| 1601 Token::Value op) { | 1603 Token::Value op) { |
| 1602 // Left-hand sides that rewrite to explicit property accesses do not reach | 1604 // Left-hand sides that rewrite to explicit property accesses do not reach |
| 1603 // here. | 1605 // here. |
| 1604 ASSERT(var != NULL); | 1606 ASSERT(var != NULL); |
| 1605 ASSERT(var->is_global() || var->AsSlot() != NULL); | 1607 ASSERT(var->is_global() || var->AsSlot() != NULL); |
| 1606 | 1608 |
| 1607 if (var->is_global()) { | 1609 if (var->is_global()) { |
| 1608 ASSERT(!var->is_this()); | 1610 ASSERT(!var->is_this()); |
| 1609 // Assignment to a global variable. Use inline caching for the | 1611 // Assignment to a global variable. Use inline caching for the |
| 1610 // assignment. Right-hand-side value is passed in r0, variable name in | 1612 // assignment. Right-hand-side value is passed in r0, variable name in |
| 1611 // r2, and the global object in r1. | 1613 // r2, and the global object in r1. |
| 1612 __ mov(r2, Operand(var->name())); | 1614 __ mov(r2, Operand(var->name())); |
| 1613 __ ldr(r1, GlobalObjectOperand()); | 1615 __ ldr(r1, GlobalObjectOperand()); |
| 1614 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 1616 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1615 Builtins::StoreIC_Initialize)); | 1617 Builtins::StoreIC_Initialize)); |
| 1616 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1618 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1617 | 1619 |
| 1618 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) { | 1620 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) { |
| 1619 // Perform the assignment for non-const variables and for initialization | 1621 // Perform the assignment for non-const variables and for initialization |
| 1620 // of const variables. Const assignments are simply skipped. | 1622 // of const variables. Const assignments are simply skipped. |
| 1621 Label done; | 1623 Label done; |
| 1622 Slot* slot = var->AsSlot(); | 1624 Slot* slot = var->AsSlot(); |
| 1623 switch (slot->type()) { | 1625 switch (slot->type()) { |
| 1624 case Slot::PARAMETER: | 1626 case Slot::PARAMETER: |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1694 SetSourcePosition(expr->position()); | 1696 SetSourcePosition(expr->position()); |
| 1695 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 1697 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
| 1696 // Load receiver to r1. Leave a copy in the stack if needed for turning the | 1698 // Load receiver to r1. Leave a copy in the stack if needed for turning the |
| 1697 // receiver into fast case. | 1699 // receiver into fast case. |
| 1698 if (expr->ends_initialization_block()) { | 1700 if (expr->ends_initialization_block()) { |
| 1699 __ ldr(r1, MemOperand(sp)); | 1701 __ ldr(r1, MemOperand(sp)); |
| 1700 } else { | 1702 } else { |
| 1701 __ pop(r1); | 1703 __ pop(r1); |
| 1702 } | 1704 } |
| 1703 | 1705 |
| 1704 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 1706 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1705 Builtins::StoreIC_Initialize)); | 1707 Builtins::StoreIC_Initialize)); |
| 1706 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1708 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1707 | 1709 |
| 1708 // If the assignment ends an initialization block, revert to fast case. | 1710 // If the assignment ends an initialization block, revert to fast case. |
| 1709 if (expr->ends_initialization_block()) { | 1711 if (expr->ends_initialization_block()) { |
| 1710 __ push(r0); // Result of assignment, saved even if not needed. | 1712 __ push(r0); // Result of assignment, saved even if not needed. |
| 1711 // Receiver is under the result value. | 1713 // Receiver is under the result value. |
| 1712 __ ldr(ip, MemOperand(sp, kPointerSize)); | 1714 __ ldr(ip, MemOperand(sp, kPointerSize)); |
| 1713 __ push(ip); | 1715 __ push(ip); |
| 1714 __ CallRuntime(Runtime::kToFastProperties, 1); | 1716 __ CallRuntime(Runtime::kToFastProperties, 1); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1739 SetSourcePosition(expr->position()); | 1741 SetSourcePosition(expr->position()); |
| 1740 __ pop(r1); // Key. | 1742 __ pop(r1); // Key. |
| 1741 // Load receiver to r2. Leave a copy in the stack if needed for turning the | 1743 // Load receiver to r2. Leave a copy in the stack if needed for turning the |
| 1742 // receiver into fast case. | 1744 // receiver into fast case. |
| 1743 if (expr->ends_initialization_block()) { | 1745 if (expr->ends_initialization_block()) { |
| 1744 __ ldr(r2, MemOperand(sp)); | 1746 __ ldr(r2, MemOperand(sp)); |
| 1745 } else { | 1747 } else { |
| 1746 __ pop(r2); | 1748 __ pop(r2); |
| 1747 } | 1749 } |
| 1748 | 1750 |
| 1749 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 1751 Handle<Code> ic(isolate()->builtins()->builtin( |
| 1750 Builtins::KeyedStoreIC_Initialize)); | 1752 Builtins::KeyedStoreIC_Initialize)); |
| 1751 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1753 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1752 | 1754 |
| 1753 // If the assignment ends an initialization block, revert to fast case. | 1755 // If the assignment ends an initialization block, revert to fast case. |
| 1754 if (expr->ends_initialization_block()) { | 1756 if (expr->ends_initialization_block()) { |
| 1755 __ push(r0); // Result of assignment, saved even if not needed. | 1757 __ push(r0); // Result of assignment, saved even if not needed. |
| 1756 // Receiver is under the result value. | 1758 // Receiver is under the result value. |
| 1757 __ ldr(ip, MemOperand(sp, kPointerSize)); | 1759 __ ldr(ip, MemOperand(sp, kPointerSize)); |
| 1758 __ push(ip); | 1760 __ push(ip); |
| 1759 __ CallRuntime(Runtime::kToFastProperties, 1); | 1761 __ CallRuntime(Runtime::kToFastProperties, 1); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1792 for (int i = 0; i < arg_count; i++) { | 1794 for (int i = 0; i < arg_count; i++) { |
| 1793 VisitForStackValue(args->at(i)); | 1795 VisitForStackValue(args->at(i)); |
| 1794 } | 1796 } |
| 1795 __ mov(r2, Operand(name)); | 1797 __ mov(r2, Operand(name)); |
| 1796 } | 1798 } |
| 1797 // Record source position for debugger. | 1799 // Record source position for debugger. |
| 1798 SetSourcePosition(expr->position()); | 1800 SetSourcePosition(expr->position()); |
| 1799 // Call the IC initialization code. | 1801 // Call the IC initialization code. |
| 1800 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 1802 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
| 1801 Handle<Code> ic = | 1803 Handle<Code> ic = |
| 1802 ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop); | 1804 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop); |
| 1803 EmitCallIC(ic, mode); | 1805 EmitCallIC(ic, mode); |
| 1804 RecordJSReturnSite(expr); | 1806 RecordJSReturnSite(expr); |
| 1805 // Restore context register. | 1807 // Restore context register. |
| 1806 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1808 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 1807 context()->Plug(r0); | 1809 context()->Plug(r0); |
| 1808 } | 1810 } |
| 1809 | 1811 |
| 1810 | 1812 |
| 1811 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 1813 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
| 1812 Expression* key, | 1814 Expression* key, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1826 { PreservePositionScope scope(masm()->positions_recorder()); | 1828 { PreservePositionScope scope(masm()->positions_recorder()); |
| 1827 for (int i = 0; i < arg_count; i++) { | 1829 for (int i = 0; i < arg_count; i++) { |
| 1828 VisitForStackValue(args->at(i)); | 1830 VisitForStackValue(args->at(i)); |
| 1829 } | 1831 } |
| 1830 } | 1832 } |
| 1831 // Record source position for debugger. | 1833 // Record source position for debugger. |
| 1832 SetSourcePosition(expr->position()); | 1834 SetSourcePosition(expr->position()); |
| 1833 // Call the IC initialization code. | 1835 // Call the IC initialization code. |
| 1834 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 1836 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
| 1835 Handle<Code> ic = | 1837 Handle<Code> ic = |
| 1836 ISOLATE->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); | 1838 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); |
| 1837 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. | 1839 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. |
| 1838 EmitCallIC(ic, mode); | 1840 EmitCallIC(ic, mode); |
| 1839 RecordJSReturnSite(expr); | 1841 RecordJSReturnSite(expr); |
| 1840 // Restore context register. | 1842 // Restore context register. |
| 1841 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1843 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 1842 context()->DropAndPlug(1, r0); // Drop the key still on the stack. | 1844 context()->DropAndPlug(1, r0); // Drop the key still on the stack. |
| 1843 } | 1845 } |
| 1844 | 1846 |
| 1845 | 1847 |
| 1846 void FullCodeGenerator::EmitCallWithStub(Call* expr) { | 1848 void FullCodeGenerator::EmitCallWithStub(Call* expr) { |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1989 VisitForStackValue(prop->obj()); | 1991 VisitForStackValue(prop->obj()); |
| 1990 } | 1992 } |
| 1991 if (prop->is_synthetic()) { | 1993 if (prop->is_synthetic()) { |
| 1992 { PreservePositionScope scope(masm()->positions_recorder()); | 1994 { PreservePositionScope scope(masm()->positions_recorder()); |
| 1993 VisitForAccumulatorValue(prop->key()); | 1995 VisitForAccumulatorValue(prop->key()); |
| 1994 } | 1996 } |
| 1995 // Record source code position for IC call. | 1997 // Record source code position for IC call. |
| 1996 SetSourcePosition(prop->position()); | 1998 SetSourcePosition(prop->position()); |
| 1997 __ pop(r1); // We do not need to keep the receiver. | 1999 __ pop(r1); // We do not need to keep the receiver. |
| 1998 | 2000 |
| 1999 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 2001 Handle<Code> ic(isolate()->builtins()->builtin( |
| 2000 Builtins::KeyedLoadIC_Initialize)); | 2002 Builtins::KeyedLoadIC_Initialize)); |
| 2001 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 2003 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 2002 __ ldr(r1, GlobalObjectOperand()); | 2004 __ ldr(r1, GlobalObjectOperand()); |
| 2003 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 2005 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
| 2004 __ Push(r0, r1); // Function, receiver. | 2006 __ Push(r0, r1); // Function, receiver. |
| 2005 EmitCallWithStub(expr); | 2007 EmitCallWithStub(expr); |
| 2006 } else { | 2008 } else { |
| 2007 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); | 2009 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); |
| 2008 } | 2010 } |
| 2009 } | 2011 } |
| 2010 } else { | 2012 } else { |
| 2011 // Call to some other expression. If the expression is an anonymous | 2013 // Call to some other expression. If the expression is an anonymous |
| 2012 // function literal not called in a loop, mark it as one that should | 2014 // function literal not called in a loop, mark it as one that should |
| 2013 // also use the fast code generator. | 2015 // also use the fast code generator. |
| 2014 FunctionLiteral* lit = fun->AsFunctionLiteral(); | 2016 FunctionLiteral* lit = fun->AsFunctionLiteral(); |
| 2015 if (lit != NULL && | 2017 if (lit != NULL && |
| 2016 lit->name()->Equals(HEAP->empty_string()) && | 2018 lit->name()->Equals(isolate()->heap()->empty_string()) && |
| 2017 loop_depth() == 0) { | 2019 loop_depth() == 0) { |
| 2018 lit->set_try_full_codegen(true); | 2020 lit->set_try_full_codegen(true); |
| 2019 } | 2021 } |
| 2020 | 2022 |
| 2021 { PreservePositionScope scope(masm()->positions_recorder()); | 2023 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2022 VisitForStackValue(fun); | 2024 VisitForStackValue(fun); |
| 2023 } | 2025 } |
| 2024 // Load global receiver object. | 2026 // Load global receiver object. |
| 2025 __ ldr(r1, GlobalObjectOperand()); | 2027 __ ldr(r1, GlobalObjectOperand()); |
| 2026 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 2028 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2055 } | 2057 } |
| 2056 | 2058 |
| 2057 // Call the construct call builtin that handles allocation and | 2059 // Call the construct call builtin that handles allocation and |
| 2058 // constructor invocation. | 2060 // constructor invocation. |
| 2059 SetSourcePosition(expr->position()); | 2061 SetSourcePosition(expr->position()); |
| 2060 | 2062 |
| 2061 // Load function and argument count into r1 and r0. | 2063 // Load function and argument count into r1 and r0. |
| 2062 __ mov(r0, Operand(arg_count)); | 2064 __ mov(r0, Operand(arg_count)); |
| 2063 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); | 2065 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); |
| 2064 | 2066 |
| 2065 Handle<Code> construct_builtin(Isolate::Current()->builtins()->builtin( | 2067 Handle<Code> construct_builtin(isolate()->builtins()->builtin( |
| 2066 Builtins::JSConstructCall)); | 2068 Builtins::JSConstructCall)); |
| 2067 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); | 2069 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); |
| 2068 context()->Plug(r0); | 2070 context()->Plug(r0); |
| 2069 } | 2071 } |
| 2070 | 2072 |
| 2071 | 2073 |
| 2072 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { | 2074 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { |
| 2073 ASSERT(args->length() == 1); | 2075 ASSERT(args->length() == 1); |
| 2074 | 2076 |
| 2075 VisitForAccumulatorValue(args->at(0)); | 2077 VisitForAccumulatorValue(args->at(0)); |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2451 __ bind(&slow_allocate_heapnumber); | 2453 __ bind(&slow_allocate_heapnumber); |
| 2452 // Allocate a heap number. | 2454 // Allocate a heap number. |
| 2453 __ CallRuntime(Runtime::kNumberAlloc, 0); | 2455 __ CallRuntime(Runtime::kNumberAlloc, 0); |
| 2454 __ mov(r4, Operand(r0)); | 2456 __ mov(r4, Operand(r0)); |
| 2455 | 2457 |
| 2456 __ bind(&heapnumber_allocated); | 2458 __ bind(&heapnumber_allocated); |
| 2457 | 2459 |
| 2458 // Convert 32 random bits in r0 to 0.(32 random bits) in a double | 2460 // Convert 32 random bits in r0 to 0.(32 random bits) in a double |
| 2459 // by computing: | 2461 // by computing: |
| 2460 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). | 2462 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). |
| 2461 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) { | 2463 if (isolate()->cpu_features()->IsSupported(VFP3)) { |
| 2462 __ PrepareCallCFunction(0, r1); | 2464 __ PrepareCallCFunction(0, r1); |
| 2463 __ CallCFunction(ExternalReference::random_uint32_function(), 0); | 2465 __ CallCFunction(ExternalReference::random_uint32_function(), 0); |
| 2464 | 2466 |
| 2465 CpuFeatures::Scope scope(VFP3); | 2467 CpuFeatures::Scope scope(VFP3); |
| 2466 // 0x41300000 is the top half of 1.0 x 2^20 as a double. | 2468 // 0x41300000 is the top half of 1.0 x 2^20 as a double. |
| 2467 // Create this constant using mov/orr to avoid PC relative load. | 2469 // Create this constant using mov/orr to avoid PC relative load. |
| 2468 __ mov(r1, Operand(0x41000000)); | 2470 __ mov(r1, Operand(0x41000000)); |
| 2469 __ orr(r1, r1, Operand(0x300000)); | 2471 __ orr(r1, r1, Operand(0x300000)); |
| 2470 // Move 0x41300000xxxxxxxx (x = random bits) to VFP. | 2472 // Move 0x41300000xxxxxxxx (x = random bits) to VFP. |
| 2471 __ vmov(d7, r0, r1); | 2473 __ vmov(d7, r0, r1); |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2793 } | 2795 } |
| 2794 | 2796 |
| 2795 | 2797 |
| 2796 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) { | 2798 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) { |
| 2797 ASSERT_EQ(2, args->length()); | 2799 ASSERT_EQ(2, args->length()); |
| 2798 | 2800 |
| 2799 ASSERT_NE(NULL, args->at(0)->AsLiteral()); | 2801 ASSERT_NE(NULL, args->at(0)->AsLiteral()); |
| 2800 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); | 2802 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); |
| 2801 | 2803 |
| 2802 Handle<FixedArray> jsfunction_result_caches( | 2804 Handle<FixedArray> jsfunction_result_caches( |
| 2803 Isolate::Current()->global_context()->jsfunction_result_caches()); | 2805 isolate()->global_context()->jsfunction_result_caches()); |
| 2804 if (jsfunction_result_caches->length() <= cache_id) { | 2806 if (jsfunction_result_caches->length() <= cache_id) { |
| 2805 __ Abort("Attempt to use undefined cache."); | 2807 __ Abort("Attempt to use undefined cache."); |
| 2806 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); | 2808 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); |
| 2807 context()->Plug(r0); | 2809 context()->Plug(r0); |
| 2808 return; | 2810 return; |
| 2809 } | 2811 } |
| 2810 | 2812 |
| 2811 VisitForAccumulatorValue(args->at(1)); | 2813 VisitForAccumulatorValue(args->at(1)); |
| 2812 | 2814 |
| 2813 Register key = r0; | 2815 Register key = r0; |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2941 // Push the arguments ("left-to-right"). | 2943 // Push the arguments ("left-to-right"). |
| 2942 int arg_count = args->length(); | 2944 int arg_count = args->length(); |
| 2943 for (int i = 0; i < arg_count; i++) { | 2945 for (int i = 0; i < arg_count; i++) { |
| 2944 VisitForStackValue(args->at(i)); | 2946 VisitForStackValue(args->at(i)); |
| 2945 } | 2947 } |
| 2946 | 2948 |
| 2947 if (expr->is_jsruntime()) { | 2949 if (expr->is_jsruntime()) { |
| 2948 // Call the JS runtime function. | 2950 // Call the JS runtime function. |
| 2949 __ mov(r2, Operand(expr->name())); | 2951 __ mov(r2, Operand(expr->name())); |
| 2950 Handle<Code> ic = | 2952 Handle<Code> ic = |
| 2951 ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, NOT_IN_LOOP); | 2953 isolate()->stub_cache()->ComputeCallInitialize(arg_count, NOT_IN_LOOP); |
| 2952 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 2954 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 2953 // Restore context register. | 2955 // Restore context register. |
| 2954 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2956 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2955 } else { | 2957 } else { |
| 2956 // Call the C runtime function. | 2958 // Call the C runtime function. |
| 2957 __ CallRuntime(expr->function(), arg_count); | 2959 __ CallRuntime(expr->function(), arg_count); |
| 2958 } | 2960 } |
| 2959 context()->Plug(r0); | 2961 context()->Plug(r0); |
| 2960 } | 2962 } |
| 2961 | 2963 |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3225 context()->PlugTOS(); | 3227 context()->PlugTOS(); |
| 3226 } | 3228 } |
| 3227 } else { | 3229 } else { |
| 3228 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3230 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 3229 Token::ASSIGN); | 3231 Token::ASSIGN); |
| 3230 } | 3232 } |
| 3231 break; | 3233 break; |
| 3232 case NAMED_PROPERTY: { | 3234 case NAMED_PROPERTY: { |
| 3233 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 3235 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
| 3234 __ pop(r1); | 3236 __ pop(r1); |
| 3235 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 3237 Handle<Code> ic(isolate()->builtins()->builtin( |
| 3236 Builtins::StoreIC_Initialize)); | 3238 Builtins::StoreIC_Initialize)); |
| 3237 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3239 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3238 if (expr->is_postfix()) { | 3240 if (expr->is_postfix()) { |
| 3239 if (!context()->IsEffect()) { | 3241 if (!context()->IsEffect()) { |
| 3240 context()->PlugTOS(); | 3242 context()->PlugTOS(); |
| 3241 } | 3243 } |
| 3242 } else { | 3244 } else { |
| 3243 context()->Plug(r0); | 3245 context()->Plug(r0); |
| 3244 } | 3246 } |
| 3245 break; | 3247 break; |
| 3246 } | 3248 } |
| 3247 case KEYED_PROPERTY: { | 3249 case KEYED_PROPERTY: { |
| 3248 __ pop(r1); // Key. | 3250 __ pop(r1); // Key. |
| 3249 __ pop(r2); // Receiver. | 3251 __ pop(r2); // Receiver. |
| 3250 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 3252 Handle<Code> ic(isolate()->builtins()->builtin( |
| 3251 Builtins::KeyedStoreIC_Initialize)); | 3253 Builtins::KeyedStoreIC_Initialize)); |
| 3252 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3254 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3253 if (expr->is_postfix()) { | 3255 if (expr->is_postfix()) { |
| 3254 if (!context()->IsEffect()) { | 3256 if (!context()->IsEffect()) { |
| 3255 context()->PlugTOS(); | 3257 context()->PlugTOS(); |
| 3256 } | 3258 } |
| 3257 } else { | 3259 } else { |
| 3258 context()->Plug(r0); | 3260 context()->Plug(r0); |
| 3259 } | 3261 } |
| 3260 break; | 3262 break; |
| 3261 } | 3263 } |
| 3262 } | 3264 } |
| 3263 } | 3265 } |
| 3264 | 3266 |
| 3265 | 3267 |
| 3266 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 3268 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
| 3267 ASSERT(!context()->IsEffect()); | 3269 ASSERT(!context()->IsEffect()); |
| 3268 ASSERT(!context()->IsTest()); | 3270 ASSERT(!context()->IsTest()); |
| 3269 VariableProxy* proxy = expr->AsVariableProxy(); | 3271 VariableProxy* proxy = expr->AsVariableProxy(); |
| 3270 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { | 3272 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { |
| 3271 Comment cmnt(masm_, "Global variable"); | 3273 Comment cmnt(masm_, "Global variable"); |
| 3272 __ ldr(r0, GlobalObjectOperand()); | 3274 __ ldr(r0, GlobalObjectOperand()); |
| 3273 __ mov(r2, Operand(proxy->name())); | 3275 __ mov(r2, Operand(proxy->name())); |
| 3274 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 3276 Handle<Code> ic(isolate()->builtins()->builtin( |
| 3275 Builtins::LoadIC_Initialize)); | 3277 Builtins::LoadIC_Initialize)); |
| 3276 // Use a regular load, not a contextual load, to avoid a reference | 3278 // Use a regular load, not a contextual load, to avoid a reference |
| 3277 // error. | 3279 // error. |
| 3278 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3280 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3279 PrepareForBailout(expr, TOS_REG); | 3281 PrepareForBailout(expr, TOS_REG); |
| 3280 context()->Plug(r0); | 3282 context()->Plug(r0); |
| 3281 } else if (proxy != NULL && | 3283 } else if (proxy != NULL && |
| 3282 proxy->var()->AsSlot() != NULL && | 3284 proxy->var()->AsSlot() != NULL && |
| 3283 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { | 3285 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { |
| 3284 Label done, slow; | 3286 Label done, slow; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3318 if (!right_literal_value->IsString()) return false; | 3320 if (!right_literal_value->IsString()) return false; |
| 3319 UnaryOperation* left_unary = left->AsUnaryOperation(); | 3321 UnaryOperation* left_unary = left->AsUnaryOperation(); |
| 3320 if (left_unary == NULL || left_unary->op() != Token::TYPEOF) return false; | 3322 if (left_unary == NULL || left_unary->op() != Token::TYPEOF) return false; |
| 3321 Handle<String> check = Handle<String>::cast(right_literal_value); | 3323 Handle<String> check = Handle<String>::cast(right_literal_value); |
| 3322 | 3324 |
| 3323 { AccumulatorValueContext context(this); | 3325 { AccumulatorValueContext context(this); |
| 3324 VisitForTypeofValue(left_unary->expression()); | 3326 VisitForTypeofValue(left_unary->expression()); |
| 3325 } | 3327 } |
| 3326 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 3328 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
| 3327 | 3329 |
| 3328 if (check->Equals(HEAP->number_symbol())) { | 3330 if (check->Equals(isolate()->heap()->number_symbol())) { |
| 3329 __ tst(r0, Operand(kSmiTagMask)); | 3331 __ tst(r0, Operand(kSmiTagMask)); |
| 3330 __ b(eq, if_true); | 3332 __ b(eq, if_true); |
| 3331 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); | 3333 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); |
| 3332 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 3334 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); |
| 3333 __ cmp(r0, ip); | 3335 __ cmp(r0, ip); |
| 3334 Split(eq, if_true, if_false, fall_through); | 3336 Split(eq, if_true, if_false, fall_through); |
| 3335 } else if (check->Equals(HEAP->string_symbol())) { | 3337 } else if (check->Equals(isolate()->heap()->string_symbol())) { |
| 3336 __ tst(r0, Operand(kSmiTagMask)); | 3338 __ tst(r0, Operand(kSmiTagMask)); |
| 3337 __ b(eq, if_false); | 3339 __ b(eq, if_false); |
| 3338 // Check for undetectable objects => false. | 3340 // Check for undetectable objects => false. |
| 3339 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); | 3341 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); |
| 3340 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); | 3342 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); |
| 3341 __ and_(r1, r1, Operand(1 << Map::kIsUndetectable)); | 3343 __ and_(r1, r1, Operand(1 << Map::kIsUndetectable)); |
| 3342 __ cmp(r1, Operand(1 << Map::kIsUndetectable)); | 3344 __ cmp(r1, Operand(1 << Map::kIsUndetectable)); |
| 3343 __ b(eq, if_false); | 3345 __ b(eq, if_false); |
| 3344 __ ldrb(r1, FieldMemOperand(r0, Map::kInstanceTypeOffset)); | 3346 __ ldrb(r1, FieldMemOperand(r0, Map::kInstanceTypeOffset)); |
| 3345 __ cmp(r1, Operand(FIRST_NONSTRING_TYPE)); | 3347 __ cmp(r1, Operand(FIRST_NONSTRING_TYPE)); |
| 3346 Split(lt, if_true, if_false, fall_through); | 3348 Split(lt, if_true, if_false, fall_through); |
| 3347 } else if (check->Equals(HEAP->boolean_symbol())) { | 3349 } else if (check->Equals(isolate()->heap()->boolean_symbol())) { |
| 3348 __ LoadRoot(ip, Heap::kTrueValueRootIndex); | 3350 __ LoadRoot(ip, Heap::kTrueValueRootIndex); |
| 3349 __ cmp(r0, ip); | 3351 __ cmp(r0, ip); |
| 3350 __ b(eq, if_true); | 3352 __ b(eq, if_true); |
| 3351 __ LoadRoot(ip, Heap::kFalseValueRootIndex); | 3353 __ LoadRoot(ip, Heap::kFalseValueRootIndex); |
| 3352 __ cmp(r0, ip); | 3354 __ cmp(r0, ip); |
| 3353 Split(eq, if_true, if_false, fall_through); | 3355 Split(eq, if_true, if_false, fall_through); |
| 3354 } else if (check->Equals(HEAP->undefined_symbol())) { | 3356 } else if (check->Equals(isolate()->heap()->undefined_symbol())) { |
| 3355 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 3357 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
| 3356 __ cmp(r0, ip); | 3358 __ cmp(r0, ip); |
| 3357 __ b(eq, if_true); | 3359 __ b(eq, if_true); |
| 3358 __ tst(r0, Operand(kSmiTagMask)); | 3360 __ tst(r0, Operand(kSmiTagMask)); |
| 3359 __ b(eq, if_false); | 3361 __ b(eq, if_false); |
| 3360 // Check for undetectable objects => true. | 3362 // Check for undetectable objects => true. |
| 3361 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); | 3363 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); |
| 3362 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); | 3364 __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset)); |
| 3363 __ and_(r1, r1, Operand(1 << Map::kIsUndetectable)); | 3365 __ and_(r1, r1, Operand(1 << Map::kIsUndetectable)); |
| 3364 __ cmp(r1, Operand(1 << Map::kIsUndetectable)); | 3366 __ cmp(r1, Operand(1 << Map::kIsUndetectable)); |
| 3365 Split(eq, if_true, if_false, fall_through); | 3367 Split(eq, if_true, if_false, fall_through); |
| 3366 } else if (check->Equals(HEAP->function_symbol())) { | 3368 } else if (check->Equals(isolate()->heap()->function_symbol())) { |
| 3367 __ tst(r0, Operand(kSmiTagMask)); | 3369 __ tst(r0, Operand(kSmiTagMask)); |
| 3368 __ b(eq, if_false); | 3370 __ b(eq, if_false); |
| 3369 __ CompareObjectType(r0, r1, r0, JS_FUNCTION_TYPE); | 3371 __ CompareObjectType(r0, r1, r0, JS_FUNCTION_TYPE); |
| 3370 __ b(eq, if_true); | 3372 __ b(eq, if_true); |
| 3371 // Regular expressions => 'function' (they are callable). | 3373 // Regular expressions => 'function' (they are callable). |
| 3372 __ CompareInstanceType(r1, r0, JS_REGEXP_TYPE); | 3374 __ CompareInstanceType(r1, r0, JS_REGEXP_TYPE); |
| 3373 Split(eq, if_true, if_false, fall_through); | 3375 Split(eq, if_true, if_false, fall_through); |
| 3374 } else if (check->Equals(HEAP->object_symbol())) { | 3376 } else if (check->Equals(isolate()->heap()->object_symbol())) { |
| 3375 __ tst(r0, Operand(kSmiTagMask)); | 3377 __ tst(r0, Operand(kSmiTagMask)); |
| 3376 __ b(eq, if_false); | 3378 __ b(eq, if_false); |
| 3377 __ LoadRoot(ip, Heap::kNullValueRootIndex); | 3379 __ LoadRoot(ip, Heap::kNullValueRootIndex); |
| 3378 __ cmp(r0, ip); | 3380 __ cmp(r0, ip); |
| 3379 __ b(eq, if_true); | 3381 __ b(eq, if_true); |
| 3380 // Regular expressions => 'function', not 'object'. | 3382 // Regular expressions => 'function', not 'object'. |
| 3381 __ CompareObjectType(r0, r1, r0, JS_REGEXP_TYPE); | 3383 __ CompareObjectType(r0, r1, r0, JS_REGEXP_TYPE); |
| 3382 __ b(eq, if_false); | 3384 __ b(eq, if_false); |
| 3383 // Check for undetectable objects => false. | 3385 // Check for undetectable objects => false. |
| 3384 __ ldrb(r0, FieldMemOperand(r1, Map::kBitFieldOffset)); | 3386 __ ldrb(r0, FieldMemOperand(r1, Map::kBitFieldOffset)); |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3602 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 3604 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
| 3603 __ add(pc, r1, Operand(masm_->CodeObject())); | 3605 __ add(pc, r1, Operand(masm_->CodeObject())); |
| 3604 } | 3606 } |
| 3605 | 3607 |
| 3606 | 3608 |
| 3607 #undef __ | 3609 #undef __ |
| 3608 | 3610 |
| 3609 } } // namespace v8::internal | 3611 } } // namespace v8::internal |
| 3610 | 3612 |
| 3611 #endif // V8_TARGET_ARCH_ARM | 3613 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |