| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 VisitForValue(function, kAccumulator); | 613 VisitForValue(function, kAccumulator); |
| 614 __ pop(r1); // Key. | 614 __ pop(r1); // Key. |
| 615 } else { | 615 } else { |
| 616 VisitForValue(prop->key(), kAccumulator); | 616 VisitForValue(prop->key(), kAccumulator); |
| 617 __ mov(r1, result_register()); // Key. | 617 __ mov(r1, result_register()); // Key. |
| 618 __ LoadRoot(result_register(), Heap::kTheHoleValueRootIndex); | 618 __ LoadRoot(result_register(), Heap::kTheHoleValueRootIndex); |
| 619 } | 619 } |
| 620 __ pop(r2); // Receiver. | 620 __ pop(r2); // Receiver. |
| 621 | 621 |
| 622 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 622 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
| 623 __ Call(ic, RelocInfo::CODE_TARGET); | 623 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 624 // Value in r0 is ignored (declarations are statements). | 624 // Value in r0 is ignored (declarations are statements). |
| 625 } | 625 } |
| 626 } | 626 } |
| 627 } | 627 } |
| 628 | 628 |
| 629 | 629 |
| 630 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { | 630 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { |
| 631 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); | 631 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); |
| 632 } | 632 } |
| 633 | 633 |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 949 obj_proxy->IsArguments() && | 949 obj_proxy->IsArguments() && |
| 950 key_literal->handle()->IsSmi()) { | 950 key_literal->handle()->IsSmi()) { |
| 951 // Load arguments object if there are no eval-introduced | 951 // Load arguments object if there are no eval-introduced |
| 952 // variables. Then load the argument from the arguments | 952 // variables. Then load the argument from the arguments |
| 953 // object using keyed load. | 953 // object using keyed load. |
| 954 __ ldr(r1, | 954 __ ldr(r1, |
| 955 ContextSlotOperandCheckExtensions(obj_proxy->var()->slot(), | 955 ContextSlotOperandCheckExtensions(obj_proxy->var()->slot(), |
| 956 slow)); | 956 slow)); |
| 957 __ mov(r0, Operand(key_literal->handle())); | 957 __ mov(r0, Operand(key_literal->handle())); |
| 958 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 958 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
| 959 __ Call(ic, RelocInfo::CODE_TARGET); | 959 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 960 __ jmp(done); | 960 __ jmp(done); |
| 961 } | 961 } |
| 962 } | 962 } |
| 963 } | 963 } |
| 964 } | 964 } |
| 965 } | 965 } |
| 966 | 966 |
| 967 | 967 |
| 968 void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions( | 968 void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions( |
| 969 Slot* slot, | 969 Slot* slot, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1015 __ b(&loop); | 1015 __ b(&loop); |
| 1016 __ bind(&fast); | 1016 __ bind(&fast); |
| 1017 } | 1017 } |
| 1018 | 1018 |
| 1019 __ ldr(r0, CodeGenerator::GlobalObject()); | 1019 __ ldr(r0, CodeGenerator::GlobalObject()); |
| 1020 __ mov(r2, Operand(slot->var()->name())); | 1020 __ mov(r2, Operand(slot->var()->name())); |
| 1021 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 1021 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) |
| 1022 ? RelocInfo::CODE_TARGET | 1022 ? RelocInfo::CODE_TARGET |
| 1023 : RelocInfo::CODE_TARGET_CONTEXT; | 1023 : RelocInfo::CODE_TARGET_CONTEXT; |
| 1024 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 1024 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
| 1025 __ Call(ic, mode); | 1025 EmitCallIC(ic, mode); |
| 1026 } | 1026 } |
| 1027 | 1027 |
| 1028 | 1028 |
| 1029 void FullCodeGenerator::EmitVariableLoad(Variable* var, | 1029 void FullCodeGenerator::EmitVariableLoad(Variable* var, |
| 1030 Expression::Context context) { | 1030 Expression::Context context) { |
| 1031 // Four cases: non-this global variables, lookup slots, all other | 1031 // Four cases: non-this global variables, lookup slots, all other |
| 1032 // types of slots, and parameters that rewrite to explicit property | 1032 // types of slots, and parameters that rewrite to explicit property |
| 1033 // accesses on the arguments object. | 1033 // accesses on the arguments object. |
| 1034 Slot* slot = var->slot(); | 1034 Slot* slot = var->slot(); |
| 1035 Property* property = var->AsProperty(); | 1035 Property* property = var->AsProperty(); |
| 1036 | 1036 |
| 1037 if (var->is_global() && !var->is_this()) { | 1037 if (var->is_global() && !var->is_this()) { |
| 1038 Comment cmnt(masm_, "Global variable"); | 1038 Comment cmnt(masm_, "Global variable"); |
| 1039 // Use inline caching. Variable name is passed in r2 and the global | 1039 // Use inline caching. Variable name is passed in r2 and the global |
| 1040 // object (receiver) in r0. | 1040 // object (receiver) in r0. |
| 1041 __ ldr(r0, CodeGenerator::GlobalObject()); | 1041 __ ldr(r0, CodeGenerator::GlobalObject()); |
| 1042 __ mov(r2, Operand(var->name())); | 1042 __ mov(r2, Operand(var->name())); |
| 1043 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 1043 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
| 1044 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1044 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 1045 Apply(context, r0); | 1045 Apply(context, r0); |
| 1046 | 1046 |
| 1047 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { | 1047 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
| 1048 Label done, slow; | 1048 Label done, slow; |
| 1049 | 1049 |
| 1050 // Generate code for loading from variables potentially shadowed | 1050 // Generate code for loading from variables potentially shadowed |
| 1051 // by eval-introduced variables. | 1051 // by eval-introduced variables. |
| 1052 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); | 1052 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); |
| 1053 | 1053 |
| 1054 __ bind(&slow); | 1054 __ bind(&slow); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1093 // Assert that the key is a smi. | 1093 // Assert that the key is a smi. |
| 1094 Literal* key_literal = property->key()->AsLiteral(); | 1094 Literal* key_literal = property->key()->AsLiteral(); |
| 1095 ASSERT_NOT_NULL(key_literal); | 1095 ASSERT_NOT_NULL(key_literal); |
| 1096 ASSERT(key_literal->handle()->IsSmi()); | 1096 ASSERT(key_literal->handle()->IsSmi()); |
| 1097 | 1097 |
| 1098 // Load the key. | 1098 // Load the key. |
| 1099 __ mov(r0, Operand(key_literal->handle())); | 1099 __ mov(r0, Operand(key_literal->handle())); |
| 1100 | 1100 |
| 1101 // Call keyed load IC. It has arguments key and receiver in r0 and r1. | 1101 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
| 1102 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1102 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
| 1103 __ Call(ic, RelocInfo::CODE_TARGET); | 1103 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1104 Apply(context, r0); | 1104 Apply(context, r0); |
| 1105 } | 1105 } |
| 1106 } | 1106 } |
| 1107 | 1107 |
| 1108 | 1108 |
| 1109 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 1109 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
| 1110 Comment cmnt(masm_, "[ RegExpLiteral"); | 1110 Comment cmnt(masm_, "[ RegExpLiteral"); |
| 1111 Label materialized; | 1111 Label materialized; |
| 1112 // Registers will be used as follows: | 1112 // Registers will be used as follows: |
| 1113 // r4 = JS function, literals array | 1113 // r4 = JS function, literals array |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1182 UNREACHABLE(); | 1182 UNREACHABLE(); |
| 1183 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1183 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1184 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1184 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); |
| 1185 // Fall through. | 1185 // Fall through. |
| 1186 case ObjectLiteral::Property::COMPUTED: | 1186 case ObjectLiteral::Property::COMPUTED: |
| 1187 if (key->handle()->IsSymbol()) { | 1187 if (key->handle()->IsSymbol()) { |
| 1188 VisitForValue(value, kAccumulator); | 1188 VisitForValue(value, kAccumulator); |
| 1189 __ mov(r2, Operand(key->handle())); | 1189 __ mov(r2, Operand(key->handle())); |
| 1190 __ ldr(r1, MemOperand(sp)); | 1190 __ ldr(r1, MemOperand(sp)); |
| 1191 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1191 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| 1192 __ Call(ic, RelocInfo::CODE_TARGET); | 1192 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1193 break; | 1193 break; |
| 1194 } | 1194 } |
| 1195 // Fall through. | 1195 // Fall through. |
| 1196 case ObjectLiteral::Property::PROTOTYPE: | 1196 case ObjectLiteral::Property::PROTOTYPE: |
| 1197 // Duplicate receiver on stack. | 1197 // Duplicate receiver on stack. |
| 1198 __ ldr(r0, MemOperand(sp)); | 1198 __ ldr(r0, MemOperand(sp)); |
| 1199 __ push(r0); | 1199 __ push(r0); |
| 1200 VisitForValue(key, kStack); | 1200 VisitForValue(key, kStack); |
| 1201 VisitForValue(value, kStack); | 1201 VisitForValue(value, kStack); |
| 1202 __ CallRuntime(Runtime::kSetProperty, 3); | 1202 __ CallRuntime(Runtime::kSetProperty, 3); |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1402 } | 1402 } |
| 1403 } | 1403 } |
| 1404 | 1404 |
| 1405 | 1405 |
| 1406 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1406 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 1407 SetSourcePosition(prop->position()); | 1407 SetSourcePosition(prop->position()); |
| 1408 Literal* key = prop->key()->AsLiteral(); | 1408 Literal* key = prop->key()->AsLiteral(); |
| 1409 __ mov(r2, Operand(key->handle())); | 1409 __ mov(r2, Operand(key->handle())); |
| 1410 // Call load IC. It has arguments receiver and property name r0 and r2. | 1410 // Call load IC. It has arguments receiver and property name r0 and r2. |
| 1411 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 1411 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
| 1412 __ Call(ic, RelocInfo::CODE_TARGET); | 1412 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1413 } | 1413 } |
| 1414 | 1414 |
| 1415 | 1415 |
| 1416 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1416 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 1417 SetSourcePosition(prop->position()); | 1417 SetSourcePosition(prop->position()); |
| 1418 // Call keyed load IC. It has arguments key and receiver in r0 and r1. | 1418 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
| 1419 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1419 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
| 1420 __ Call(ic, RelocInfo::CODE_TARGET); | 1420 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1421 } | 1421 } |
| 1422 | 1422 |
| 1423 | 1423 |
| 1424 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, | 1424 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, |
| 1425 Token::Value op, | 1425 Token::Value op, |
| 1426 Expression::Context context, | 1426 Expression::Context context, |
| 1427 OverwriteMode mode, | 1427 OverwriteMode mode, |
| 1428 Expression* left, | 1428 Expression* left, |
| 1429 Expression* right, | 1429 Expression* right, |
| 1430 ConstantOperand constant) { | 1430 ConstantOperand constant) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1468 EmitVariableAssignment(var, Token::ASSIGN, Expression::kEffect); | 1468 EmitVariableAssignment(var, Token::ASSIGN, Expression::kEffect); |
| 1469 break; | 1469 break; |
| 1470 } | 1470 } |
| 1471 case NAMED_PROPERTY: { | 1471 case NAMED_PROPERTY: { |
| 1472 __ push(r0); // Preserve value. | 1472 __ push(r0); // Preserve value. |
| 1473 VisitForValue(prop->obj(), kAccumulator); | 1473 VisitForValue(prop->obj(), kAccumulator); |
| 1474 __ mov(r1, r0); | 1474 __ mov(r1, r0); |
| 1475 __ pop(r0); // Restore value. | 1475 __ pop(r0); // Restore value. |
| 1476 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 1476 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
| 1477 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1477 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| 1478 __ Call(ic, RelocInfo::CODE_TARGET); | 1478 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1479 break; | 1479 break; |
| 1480 } | 1480 } |
| 1481 case KEYED_PROPERTY: { | 1481 case KEYED_PROPERTY: { |
| 1482 __ push(r0); // Preserve value. | 1482 __ push(r0); // Preserve value. |
| 1483 VisitForValue(prop->obj(), kStack); | 1483 VisitForValue(prop->obj(), kStack); |
| 1484 VisitForValue(prop->key(), kAccumulator); | 1484 VisitForValue(prop->key(), kAccumulator); |
| 1485 __ mov(r1, r0); | 1485 __ mov(r1, r0); |
| 1486 __ pop(r2); | 1486 __ pop(r2); |
| 1487 __ pop(r0); // Restore value. | 1487 __ pop(r0); // Restore value. |
| 1488 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 1488 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
| 1489 __ Call(ic, RelocInfo::CODE_TARGET); | 1489 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1490 break; | 1490 break; |
| 1491 } | 1491 } |
| 1492 } | 1492 } |
| 1493 } | 1493 } |
| 1494 | 1494 |
| 1495 | 1495 |
| 1496 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 1496 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
| 1497 Token::Value op, | 1497 Token::Value op, |
| 1498 Expression::Context context) { | 1498 Expression::Context context) { |
| 1499 // Left-hand sides that rewrite to explicit property accesses do not reach | 1499 // Left-hand sides that rewrite to explicit property accesses do not reach |
| 1500 // here. | 1500 // here. |
| 1501 ASSERT(var != NULL); | 1501 ASSERT(var != NULL); |
| 1502 ASSERT(var->is_global() || var->slot() != NULL); | 1502 ASSERT(var->is_global() || var->slot() != NULL); |
| 1503 | 1503 |
| 1504 if (var->is_global()) { | 1504 if (var->is_global()) { |
| 1505 ASSERT(!var->is_this()); | 1505 ASSERT(!var->is_this()); |
| 1506 // Assignment to a global variable. Use inline caching for the | 1506 // Assignment to a global variable. Use inline caching for the |
| 1507 // assignment. Right-hand-side value is passed in r0, variable name in | 1507 // assignment. Right-hand-side value is passed in r0, variable name in |
| 1508 // r2, and the global object in r1. | 1508 // r2, and the global object in r1. |
| 1509 __ mov(r2, Operand(var->name())); | 1509 __ mov(r2, Operand(var->name())); |
| 1510 __ ldr(r1, CodeGenerator::GlobalObject()); | 1510 __ ldr(r1, CodeGenerator::GlobalObject()); |
| 1511 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1511 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| 1512 __ Call(ic, RelocInfo::CODE_TARGET); | 1512 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1513 | 1513 |
| 1514 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) { | 1514 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) { |
| 1515 // Perform the assignment for non-const variables and for initialization | 1515 // Perform the assignment for non-const variables and for initialization |
| 1516 // of const variables. Const assignments are simply skipped. | 1516 // of const variables. Const assignments are simply skipped. |
| 1517 Label done; | 1517 Label done; |
| 1518 Slot* slot = var->slot(); | 1518 Slot* slot = var->slot(); |
| 1519 switch (slot->type()) { | 1519 switch (slot->type()) { |
| 1520 case Slot::PARAMETER: | 1520 case Slot::PARAMETER: |
| 1521 case Slot::LOCAL: | 1521 case Slot::LOCAL: |
| 1522 if (op == Token::INIT_CONST) { | 1522 if (op == Token::INIT_CONST) { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1591 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 1591 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
| 1592 // Load receiver to r1. Leave a copy in the stack if needed for turning the | 1592 // Load receiver to r1. Leave a copy in the stack if needed for turning the |
| 1593 // receiver into fast case. | 1593 // receiver into fast case. |
| 1594 if (expr->ends_initialization_block()) { | 1594 if (expr->ends_initialization_block()) { |
| 1595 __ ldr(r1, MemOperand(sp)); | 1595 __ ldr(r1, MemOperand(sp)); |
| 1596 } else { | 1596 } else { |
| 1597 __ pop(r1); | 1597 __ pop(r1); |
| 1598 } | 1598 } |
| 1599 | 1599 |
| 1600 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1600 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| 1601 __ Call(ic, RelocInfo::CODE_TARGET); | 1601 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1602 | 1602 |
| 1603 // If the assignment ends an initialization block, revert to fast case. | 1603 // If the assignment ends an initialization block, revert to fast case. |
| 1604 if (expr->ends_initialization_block()) { | 1604 if (expr->ends_initialization_block()) { |
| 1605 __ push(r0); // Result of assignment, saved even if not needed. | 1605 __ push(r0); // Result of assignment, saved even if not needed. |
| 1606 // Receiver is under the result value. | 1606 // Receiver is under the result value. |
| 1607 __ ldr(ip, MemOperand(sp, kPointerSize)); | 1607 __ ldr(ip, MemOperand(sp, kPointerSize)); |
| 1608 __ push(ip); | 1608 __ push(ip); |
| 1609 __ CallRuntime(Runtime::kToFastProperties, 1); | 1609 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1610 __ pop(r0); | 1610 __ pop(r0); |
| 1611 DropAndApply(1, context_, r0); | 1611 DropAndApply(1, context_, r0); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1635 __ pop(r1); // Key. | 1635 __ pop(r1); // Key. |
| 1636 // Load receiver to r2. Leave a copy in the stack if needed for turning the | 1636 // Load receiver to r2. Leave a copy in the stack if needed for turning the |
| 1637 // receiver into fast case. | 1637 // receiver into fast case. |
| 1638 if (expr->ends_initialization_block()) { | 1638 if (expr->ends_initialization_block()) { |
| 1639 __ ldr(r2, MemOperand(sp)); | 1639 __ ldr(r2, MemOperand(sp)); |
| 1640 } else { | 1640 } else { |
| 1641 __ pop(r2); | 1641 __ pop(r2); |
| 1642 } | 1642 } |
| 1643 | 1643 |
| 1644 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 1644 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
| 1645 __ Call(ic, RelocInfo::CODE_TARGET); | 1645 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1646 | 1646 |
| 1647 // If the assignment ends an initialization block, revert to fast case. | 1647 // If the assignment ends an initialization block, revert to fast case. |
| 1648 if (expr->ends_initialization_block()) { | 1648 if (expr->ends_initialization_block()) { |
| 1649 __ push(r0); // Result of assignment, saved even if not needed. | 1649 __ push(r0); // Result of assignment, saved even if not needed. |
| 1650 // Receiver is under the result value. | 1650 // Receiver is under the result value. |
| 1651 __ ldr(ip, MemOperand(sp, kPointerSize)); | 1651 __ ldr(ip, MemOperand(sp, kPointerSize)); |
| 1652 __ push(ip); | 1652 __ push(ip); |
| 1653 __ CallRuntime(Runtime::kToFastProperties, 1); | 1653 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1654 __ pop(r0); | 1654 __ pop(r0); |
| 1655 DropAndApply(1, context_, r0); | 1655 DropAndApply(1, context_, r0); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1684 int arg_count = args->length(); | 1684 int arg_count = args->length(); |
| 1685 for (int i = 0; i < arg_count; i++) { | 1685 for (int i = 0; i < arg_count; i++) { |
| 1686 VisitForValue(args->at(i), kStack); | 1686 VisitForValue(args->at(i), kStack); |
| 1687 } | 1687 } |
| 1688 __ mov(r2, Operand(name)); | 1688 __ mov(r2, Operand(name)); |
| 1689 // Record source position for debugger. | 1689 // Record source position for debugger. |
| 1690 SetSourcePosition(expr->position()); | 1690 SetSourcePosition(expr->position()); |
| 1691 // Call the IC initialization code. | 1691 // Call the IC initialization code. |
| 1692 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 1692 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
| 1693 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop); | 1693 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop); |
| 1694 __ Call(ic, mode); | 1694 EmitCallIC(ic, mode); |
| 1695 // Restore context register. | 1695 // Restore context register. |
| 1696 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1696 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 1697 Apply(context_, r0); | 1697 Apply(context_, r0); |
| 1698 } | 1698 } |
| 1699 | 1699 |
| 1700 | 1700 |
| 1701 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 1701 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
| 1702 Expression* key, | 1702 Expression* key, |
| 1703 RelocInfo::Mode mode) { | 1703 RelocInfo::Mode mode) { |
| 1704 // Code common for calls using the IC. | 1704 // Code common for calls using the IC. |
| 1705 ZoneList<Expression*>* args = expr->arguments(); | 1705 ZoneList<Expression*>* args = expr->arguments(); |
| 1706 int arg_count = args->length(); | 1706 int arg_count = args->length(); |
| 1707 for (int i = 0; i < arg_count; i++) { | 1707 for (int i = 0; i < arg_count; i++) { |
| 1708 VisitForValue(args->at(i), kStack); | 1708 VisitForValue(args->at(i), kStack); |
| 1709 } | 1709 } |
| 1710 VisitForValue(key, kAccumulator); | 1710 VisitForValue(key, kAccumulator); |
| 1711 __ mov(r2, r0); | 1711 __ mov(r2, r0); |
| 1712 // Record source position for debugger. | 1712 // Record source position for debugger. |
| 1713 SetSourcePosition(expr->position()); | 1713 SetSourcePosition(expr->position()); |
| 1714 // Call the IC initialization code. | 1714 // Call the IC initialization code. |
| 1715 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 1715 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
| 1716 Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(arg_count, | 1716 Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(arg_count, |
| 1717 in_loop); | 1717 in_loop); |
| 1718 __ Call(ic, mode); | 1718 EmitCallIC(ic, mode); |
| 1719 // Restore context register. | 1719 // Restore context register. |
| 1720 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1720 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 1721 Apply(context_, r0); | 1721 Apply(context_, r0); |
| 1722 } | 1722 } |
| 1723 | 1723 |
| 1724 | 1724 |
| 1725 void FullCodeGenerator::EmitCallWithStub(Call* expr) { | 1725 void FullCodeGenerator::EmitCallWithStub(Call* expr) { |
| 1726 // Code common for calls using the call stub. | 1726 // Code common for calls using the call stub. |
| 1727 ZoneList<Expression*>* args = expr->arguments(); | 1727 ZoneList<Expression*>* args = expr->arguments(); |
| 1728 int arg_count = args->length(); | 1728 int arg_count = args->length(); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1847 // For a synthetic property use keyed load IC followed by function call, | 1847 // For a synthetic property use keyed load IC followed by function call, |
| 1848 // for a regular property use keyed CallIC. | 1848 // for a regular property use keyed CallIC. |
| 1849 VisitForValue(prop->obj(), kStack); | 1849 VisitForValue(prop->obj(), kStack); |
| 1850 if (prop->is_synthetic()) { | 1850 if (prop->is_synthetic()) { |
| 1851 VisitForValue(prop->key(), kAccumulator); | 1851 VisitForValue(prop->key(), kAccumulator); |
| 1852 // Record source code position for IC call. | 1852 // Record source code position for IC call. |
| 1853 SetSourcePosition(prop->position()); | 1853 SetSourcePosition(prop->position()); |
| 1854 __ pop(r1); // We do not need to keep the receiver. | 1854 __ pop(r1); // We do not need to keep the receiver. |
| 1855 | 1855 |
| 1856 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1856 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
| 1857 __ Call(ic, RelocInfo::CODE_TARGET); | 1857 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1858 __ ldr(r1, CodeGenerator::GlobalObject()); | 1858 __ ldr(r1, CodeGenerator::GlobalObject()); |
| 1859 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 1859 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
| 1860 __ Push(r0, r1); // Function, receiver. | 1860 __ Push(r0, r1); // Function, receiver. |
| 1861 EmitCallWithStub(expr); | 1861 EmitCallWithStub(expr); |
| 1862 } else { | 1862 } else { |
| 1863 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); | 1863 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); |
| 1864 } | 1864 } |
| 1865 } | 1865 } |
| 1866 } else { | 1866 } else { |
| 1867 // Call to some other expression. If the expression is an anonymous | 1867 // Call to some other expression. If the expression is an anonymous |
| (...skipping 894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2762 int arg_count = args->length(); | 2762 int arg_count = args->length(); |
| 2763 for (int i = 0; i < arg_count; i++) { | 2763 for (int i = 0; i < arg_count; i++) { |
| 2764 VisitForValue(args->at(i), kStack); | 2764 VisitForValue(args->at(i), kStack); |
| 2765 } | 2765 } |
| 2766 | 2766 |
| 2767 if (expr->is_jsruntime()) { | 2767 if (expr->is_jsruntime()) { |
| 2768 // Call the JS runtime function. | 2768 // Call the JS runtime function. |
| 2769 __ mov(r2, Operand(expr->name())); | 2769 __ mov(r2, Operand(expr->name())); |
| 2770 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, | 2770 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, |
| 2771 NOT_IN_LOOP); | 2771 NOT_IN_LOOP); |
| 2772 __ Call(ic, RelocInfo::CODE_TARGET); | 2772 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 2773 // Restore context register. | 2773 // Restore context register. |
| 2774 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2774 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2775 } else { | 2775 } else { |
| 2776 // Call the C runtime function. | 2776 // Call the C runtime function. |
| 2777 __ CallRuntime(expr->function(), arg_count); | 2777 __ CallRuntime(expr->function(), arg_count); |
| 2778 } | 2778 } |
| 2779 Apply(context_, r0); | 2779 Apply(context_, r0); |
| 2780 } | 2780 } |
| 2781 | 2781 |
| 2782 | 2782 |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3058 } else { | 3058 } else { |
| 3059 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3059 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 3060 Token::ASSIGN, | 3060 Token::ASSIGN, |
| 3061 context_); | 3061 context_); |
| 3062 } | 3062 } |
| 3063 break; | 3063 break; |
| 3064 case NAMED_PROPERTY: { | 3064 case NAMED_PROPERTY: { |
| 3065 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 3065 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
| 3066 __ pop(r1); | 3066 __ pop(r1); |
| 3067 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 3067 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| 3068 __ Call(ic, RelocInfo::CODE_TARGET); | 3068 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3069 if (expr->is_postfix()) { | 3069 if (expr->is_postfix()) { |
| 3070 if (context_ != Expression::kEffect) { | 3070 if (context_ != Expression::kEffect) { |
| 3071 ApplyTOS(context_); | 3071 ApplyTOS(context_); |
| 3072 } | 3072 } |
| 3073 } else { | 3073 } else { |
| 3074 Apply(context_, r0); | 3074 Apply(context_, r0); |
| 3075 } | 3075 } |
| 3076 break; | 3076 break; |
| 3077 } | 3077 } |
| 3078 case KEYED_PROPERTY: { | 3078 case KEYED_PROPERTY: { |
| 3079 __ pop(r1); // Key. | 3079 __ pop(r1); // Key. |
| 3080 __ pop(r2); // Receiver. | 3080 __ pop(r2); // Receiver. |
| 3081 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 3081 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
| 3082 __ Call(ic, RelocInfo::CODE_TARGET); | 3082 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3083 if (expr->is_postfix()) { | 3083 if (expr->is_postfix()) { |
| 3084 if (context_ != Expression::kEffect) { | 3084 if (context_ != Expression::kEffect) { |
| 3085 ApplyTOS(context_); | 3085 ApplyTOS(context_); |
| 3086 } | 3086 } |
| 3087 } else { | 3087 } else { |
| 3088 Apply(context_, r0); | 3088 Apply(context_, r0); |
| 3089 } | 3089 } |
| 3090 break; | 3090 break; |
| 3091 } | 3091 } |
| 3092 } | 3092 } |
| 3093 } | 3093 } |
| 3094 | 3094 |
| 3095 | 3095 |
| 3096 void FullCodeGenerator::VisitForTypeofValue(Expression* expr, Location where) { | 3096 void FullCodeGenerator::VisitForTypeofValue(Expression* expr, Location where) { |
| 3097 VariableProxy* proxy = expr->AsVariableProxy(); | 3097 VariableProxy* proxy = expr->AsVariableProxy(); |
| 3098 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { | 3098 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { |
| 3099 Comment cmnt(masm_, "Global variable"); | 3099 Comment cmnt(masm_, "Global variable"); |
| 3100 __ ldr(r0, CodeGenerator::GlobalObject()); | 3100 __ ldr(r0, CodeGenerator::GlobalObject()); |
| 3101 __ mov(r2, Operand(proxy->name())); | 3101 __ mov(r2, Operand(proxy->name())); |
| 3102 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 3102 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
| 3103 // Use a regular load, not a contextual load, to avoid a reference | 3103 // Use a regular load, not a contextual load, to avoid a reference |
| 3104 // error. | 3104 // error. |
| 3105 __ Call(ic, RelocInfo::CODE_TARGET); | 3105 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 3106 if (where == kStack) __ push(r0); | 3106 if (where == kStack) __ push(r0); |
| 3107 } else if (proxy != NULL && | 3107 } else if (proxy != NULL && |
| 3108 proxy->var()->slot() != NULL && | 3108 proxy->var()->slot() != NULL && |
| 3109 proxy->var()->slot()->type() == Slot::LOOKUP) { | 3109 proxy->var()->slot()->type() == Slot::LOOKUP) { |
| 3110 Label done, slow; | 3110 Label done, slow; |
| 3111 | 3111 |
| 3112 // Generate code for loading from variables potentially shadowed | 3112 // Generate code for loading from variables potentially shadowed |
| 3113 // by eval-introduced variables. | 3113 // by eval-introduced variables. |
| 3114 Slot* slot = proxy->var()->slot(); | 3114 Slot* slot = proxy->var()->slot(); |
| 3115 EmitDynamicLoadFromSlotFastCase(slot, INSIDE_TYPEOF, &slow, &done); | 3115 EmitDynamicLoadFromSlotFastCase(slot, INSIDE_TYPEOF, &slow, &done); |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3358 Apply(context_, if_true, if_false); | 3358 Apply(context_, if_true, if_false); |
| 3359 } | 3359 } |
| 3360 | 3360 |
| 3361 | 3361 |
| 3362 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { | 3362 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { |
| 3363 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 3363 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 3364 Apply(context_, r0); | 3364 Apply(context_, r0); |
| 3365 } | 3365 } |
| 3366 | 3366 |
| 3367 | 3367 |
| 3368 Register FullCodeGenerator::result_register() { return r0; } | 3368 Register FullCodeGenerator::result_register() { |
| 3369 return r0; |
| 3370 } |
| 3369 | 3371 |
| 3370 | 3372 |
| 3371 Register FullCodeGenerator::context_register() { return cp; } | 3373 Register FullCodeGenerator::context_register() { |
| 3374 return cp; |
| 3375 } |
| 3376 |
| 3377 |
| 3378 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) { |
| 3379 ASSERT(mode == RelocInfo::CODE_TARGET || |
| 3380 mode == RelocInfo::CODE_TARGET_CONTEXT); |
| 3381 __ Call(ic, mode); |
| 3382 } |
| 3372 | 3383 |
| 3373 | 3384 |
| 3374 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { | 3385 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { |
| 3375 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); | 3386 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); |
| 3376 __ str(value, MemOperand(fp, frame_offset)); | 3387 __ str(value, MemOperand(fp, frame_offset)); |
| 3377 } | 3388 } |
| 3378 | 3389 |
| 3379 | 3390 |
| 3380 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { | 3391 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { |
| 3381 __ ldr(dst, ContextOperand(cp, context_index)); | 3392 __ ldr(dst, ContextOperand(cp, context_index)); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 3408 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 3419 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
| 3409 __ add(pc, r1, Operand(masm_->CodeObject())); | 3420 __ add(pc, r1, Operand(masm_->CodeObject())); |
| 3410 } | 3421 } |
| 3411 | 3422 |
| 3412 | 3423 |
| 3413 #undef __ | 3424 #undef __ |
| 3414 | 3425 |
| 3415 } } // namespace v8::internal | 3426 } } // namespace v8::internal |
| 3416 | 3427 |
| 3417 #endif // V8_TARGET_ARCH_ARM | 3428 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |