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 |