OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 955 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
966 // Call the function on the stack with the given arguments. | 966 // Call the function on the stack with the given arguments. |
967 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args, | 967 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args, |
968 int position) { | 968 int position) { |
969 // Push the arguments ("left-to-right") on the stack. | 969 // Push the arguments ("left-to-right") on the stack. |
970 int arg_count = args->length(); | 970 int arg_count = args->length(); |
971 for (int i = 0; i < arg_count; i++) { | 971 for (int i = 0; i < arg_count; i++) { |
972 Load(args->at(i)); | 972 Load(args->at(i)); |
973 } | 973 } |
974 | 974 |
975 // Record the position for debugging purposes. | 975 // Record the position for debugging purposes. |
976 __ RecordPosition(position); | 976 CodeForSourcePosition(position); |
977 | 977 |
978 // Use the shared code stub to call the function. | 978 // Use the shared code stub to call the function. |
979 CallFunctionStub call_function(arg_count); | 979 CallFunctionStub call_function(arg_count); |
980 frame_->CallStub(&call_function, arg_count + 1); | 980 frame_->CallStub(&call_function, arg_count + 1); |
981 | 981 |
982 // Restore context and pop function from the stack. | 982 // Restore context and pop function from the stack. |
983 __ ldr(cp, frame_->Context()); | 983 __ ldr(cp, frame_->Context()); |
984 frame_->Drop(); // discard the TOS | 984 frame_->Drop(); // discard the TOS |
985 } | 985 } |
986 | 986 |
(...skipping 17 matching lines...) Expand all Loading... |
1004 | 1004 |
1005 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { | 1005 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { |
1006 for (int i = 0; frame_ != NULL && i < statements->length(); i++) { | 1006 for (int i = 0; frame_ != NULL && i < statements->length(); i++) { |
1007 Visit(statements->at(i)); | 1007 Visit(statements->at(i)); |
1008 } | 1008 } |
1009 } | 1009 } |
1010 | 1010 |
1011 | 1011 |
1012 void CodeGenerator::VisitBlock(Block* node) { | 1012 void CodeGenerator::VisitBlock(Block* node) { |
1013 Comment cmnt(masm_, "[ Block"); | 1013 Comment cmnt(masm_, "[ Block"); |
1014 if (FLAG_debug_info) RecordStatementPosition(node); | 1014 CodeForStatement(node); |
1015 node->set_break_stack_height(break_stack_height_); | 1015 node->set_break_stack_height(break_stack_height_); |
1016 node->break_target()->set_code_generator(this); | 1016 node->break_target()->set_code_generator(this); |
1017 VisitStatements(node->statements()); | 1017 VisitStatements(node->statements()); |
1018 if (node->break_target()->is_linked()) { | 1018 if (node->break_target()->is_linked()) { |
1019 node->break_target()->Bind(); | 1019 node->break_target()->Bind(); |
1020 } | 1020 } |
1021 } | 1021 } |
1022 | 1022 |
1023 | 1023 |
1024 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 1024 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
1025 __ mov(r0, Operand(pairs)); | 1025 __ mov(r0, Operand(pairs)); |
1026 frame_->EmitPush(r0); | 1026 frame_->EmitPush(r0); |
1027 frame_->EmitPush(cp); | 1027 frame_->EmitPush(cp); |
1028 __ mov(r0, Operand(Smi::FromInt(is_eval() ? 1 : 0))); | 1028 __ mov(r0, Operand(Smi::FromInt(is_eval() ? 1 : 0))); |
1029 frame_->EmitPush(r0); | 1029 frame_->EmitPush(r0); |
1030 frame_->CallRuntime(Runtime::kDeclareGlobals, 3); | 1030 frame_->CallRuntime(Runtime::kDeclareGlobals, 3); |
1031 // The result is discarded. | 1031 // The result is discarded. |
1032 } | 1032 } |
1033 | 1033 |
1034 | 1034 |
1035 void CodeGenerator::VisitDeclaration(Declaration* node) { | 1035 void CodeGenerator::VisitDeclaration(Declaration* node) { |
1036 Comment cmnt(masm_, "[ Declaration"); | 1036 Comment cmnt(masm_, "[ Declaration"); |
| 1037 CodeForStatement(node); |
1037 Variable* var = node->proxy()->var(); | 1038 Variable* var = node->proxy()->var(); |
1038 ASSERT(var != NULL); // must have been resolved | 1039 ASSERT(var != NULL); // must have been resolved |
1039 Slot* slot = var->slot(); | 1040 Slot* slot = var->slot(); |
1040 | 1041 |
1041 // If it was not possible to allocate the variable at compile time, | 1042 // If it was not possible to allocate the variable at compile time, |
1042 // we need to "declare" it at runtime to make sure it actually | 1043 // we need to "declare" it at runtime to make sure it actually |
1043 // exists in the local context. | 1044 // exists in the local context. |
1044 if (slot != NULL && slot->type() == Slot::LOOKUP) { | 1045 if (slot != NULL && slot->type() == Slot::LOOKUP) { |
1045 // Variables with a "LOOKUP" slot were introduced as non-locals | 1046 // Variables with a "LOOKUP" slot were introduced as non-locals |
1046 // during variable resolution and must have mode DYNAMIC. | 1047 // during variable resolution and must have mode DYNAMIC. |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1092 // safe to pop the value lying on top of the reference before unloading | 1093 // safe to pop the value lying on top of the reference before unloading |
1093 // the reference itself (which preserves the top of stack) because we | 1094 // the reference itself (which preserves the top of stack) because we |
1094 // know it is a zero-sized reference. | 1095 // know it is a zero-sized reference. |
1095 frame_->Drop(); | 1096 frame_->Drop(); |
1096 } | 1097 } |
1097 } | 1098 } |
1098 | 1099 |
1099 | 1100 |
1100 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) { | 1101 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) { |
1101 Comment cmnt(masm_, "[ ExpressionStatement"); | 1102 Comment cmnt(masm_, "[ ExpressionStatement"); |
1102 if (FLAG_debug_info) RecordStatementPosition(node); | 1103 CodeForStatement(node); |
1103 Expression* expression = node->expression(); | 1104 Expression* expression = node->expression(); |
1104 expression->MarkAsStatement(); | 1105 expression->MarkAsStatement(); |
1105 Load(expression); | 1106 Load(expression); |
1106 frame_->Drop(); | 1107 frame_->Drop(); |
1107 } | 1108 } |
1108 | 1109 |
1109 | 1110 |
1110 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) { | 1111 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) { |
1111 Comment cmnt(masm_, "// EmptyStatement"); | 1112 Comment cmnt(masm_, "// EmptyStatement"); |
| 1113 CodeForStatement(node); |
1112 // nothing to do | 1114 // nothing to do |
1113 } | 1115 } |
1114 | 1116 |
1115 | 1117 |
1116 void CodeGenerator::VisitIfStatement(IfStatement* node) { | 1118 void CodeGenerator::VisitIfStatement(IfStatement* node) { |
1117 Comment cmnt(masm_, "[ IfStatement"); | 1119 Comment cmnt(masm_, "[ IfStatement"); |
1118 // Generate different code depending on which parts of the if statement | 1120 // Generate different code depending on which parts of the if statement |
1119 // are present or not. | 1121 // are present or not. |
1120 bool has_then_stm = node->HasThenStatement(); | 1122 bool has_then_stm = node->HasThenStatement(); |
1121 bool has_else_stm = node->HasElseStatement(); | 1123 bool has_else_stm = node->HasElseStatement(); |
1122 | 1124 |
1123 if (FLAG_debug_info) RecordStatementPosition(node); | 1125 CodeForStatement(node); |
1124 | 1126 |
1125 JumpTarget exit(this); | 1127 JumpTarget exit(this); |
1126 if (has_then_stm && has_else_stm) { | 1128 if (has_then_stm && has_else_stm) { |
1127 Comment cmnt(masm_, "[ IfThenElse"); | 1129 Comment cmnt(masm_, "[ IfThenElse"); |
1128 JumpTarget then(this); | 1130 JumpTarget then(this); |
1129 JumpTarget else_(this); | 1131 JumpTarget else_(this); |
1130 // if (cond) | 1132 // if (cond) |
1131 LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &then, &else_, true); | 1133 LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &then, &else_, true); |
1132 if (frame_ != NULL) { | 1134 if (frame_ != NULL) { |
1133 Branch(false, &else_); | 1135 Branch(false, &else_); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1198 | 1200 |
1199 | 1201 |
1200 void CodeGenerator::CleanStack(int num_bytes) { | 1202 void CodeGenerator::CleanStack(int num_bytes) { |
1201 ASSERT(num_bytes % kPointerSize == 0); | 1203 ASSERT(num_bytes % kPointerSize == 0); |
1202 frame_->Drop(num_bytes / kPointerSize); | 1204 frame_->Drop(num_bytes / kPointerSize); |
1203 } | 1205 } |
1204 | 1206 |
1205 | 1207 |
1206 void CodeGenerator::VisitContinueStatement(ContinueStatement* node) { | 1208 void CodeGenerator::VisitContinueStatement(ContinueStatement* node) { |
1207 Comment cmnt(masm_, "[ ContinueStatement"); | 1209 Comment cmnt(masm_, "[ ContinueStatement"); |
1208 if (FLAG_debug_info) RecordStatementPosition(node); | 1210 CodeForStatement(node); |
1209 CleanStack(break_stack_height_ - node->target()->break_stack_height()); | 1211 CleanStack(break_stack_height_ - node->target()->break_stack_height()); |
1210 node->target()->continue_target()->Jump(); | 1212 node->target()->continue_target()->Jump(); |
1211 } | 1213 } |
1212 | 1214 |
1213 | 1215 |
1214 void CodeGenerator::VisitBreakStatement(BreakStatement* node) { | 1216 void CodeGenerator::VisitBreakStatement(BreakStatement* node) { |
1215 Comment cmnt(masm_, "[ BreakStatement"); | 1217 Comment cmnt(masm_, "[ BreakStatement"); |
1216 if (FLAG_debug_info) RecordStatementPosition(node); | 1218 CodeForStatement(node); |
1217 CleanStack(break_stack_height_ - node->target()->break_stack_height()); | 1219 CleanStack(break_stack_height_ - node->target()->break_stack_height()); |
1218 node->target()->break_target()->Jump(); | 1220 node->target()->break_target()->Jump(); |
1219 } | 1221 } |
1220 | 1222 |
1221 | 1223 |
1222 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) { | 1224 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) { |
1223 Comment cmnt(masm_, "[ ReturnStatement"); | 1225 Comment cmnt(masm_, "[ ReturnStatement"); |
1224 if (FLAG_debug_info) RecordStatementPosition(node); | 1226 CodeForStatement(node); |
1225 Load(node->expression()); | 1227 Load(node->expression()); |
1226 // Move the function result into r0. | 1228 // Move the function result into r0. |
1227 frame_->Pop(r0); | 1229 frame_->Pop(r0); |
1228 | 1230 |
1229 function_return_.Jump(); | 1231 function_return_.Jump(); |
1230 } | 1232 } |
1231 | 1233 |
1232 | 1234 |
1233 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) { | 1235 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) { |
1234 Comment cmnt(masm_, "[ WithEnterStatement"); | 1236 Comment cmnt(masm_, "[ WithEnterStatement"); |
1235 if (FLAG_debug_info) RecordStatementPosition(node); | 1237 CodeForStatement(node); |
1236 Load(node->expression()); | 1238 Load(node->expression()); |
1237 frame_->CallRuntime(Runtime::kPushContext, 1); | 1239 frame_->CallRuntime(Runtime::kPushContext, 1); |
1238 if (kDebug) { | 1240 if (kDebug) { |
1239 JumpTarget verified_true(this); | 1241 JumpTarget verified_true(this); |
1240 __ cmp(r0, Operand(cp)); | 1242 __ cmp(r0, Operand(cp)); |
1241 verified_true.Branch(eq); | 1243 verified_true.Branch(eq); |
1242 __ stop("PushContext: r0 is expected to be the same as cp"); | 1244 __ stop("PushContext: r0 is expected to be the same as cp"); |
1243 verified_true.Bind(); | 1245 verified_true.Bind(); |
1244 } | 1246 } |
1245 // Update context local. | 1247 // Update context local. |
1246 __ str(cp, frame_->Context()); | 1248 __ str(cp, frame_->Context()); |
1247 } | 1249 } |
1248 | 1250 |
1249 | 1251 |
1250 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) { | 1252 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) { |
1251 Comment cmnt(masm_, "[ WithExitStatement"); | 1253 Comment cmnt(masm_, "[ WithExitStatement"); |
| 1254 CodeForStatement(node); |
1252 // Pop context. | 1255 // Pop context. |
1253 __ ldr(cp, ContextOperand(cp, Context::PREVIOUS_INDEX)); | 1256 __ ldr(cp, ContextOperand(cp, Context::PREVIOUS_INDEX)); |
1254 // Update context local. | 1257 // Update context local. |
1255 __ str(cp, frame_->Context()); | 1258 __ str(cp, frame_->Context()); |
1256 } | 1259 } |
1257 | 1260 |
1258 | 1261 |
1259 int CodeGenerator::FastCaseSwitchMaxOverheadFactor() { | 1262 int CodeGenerator::FastCaseSwitchMaxOverheadFactor() { |
1260 return kFastSwitchMaxOverheadFactor; | 1263 return kFastSwitchMaxOverheadFactor; |
1261 } | 1264 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1315 for (int i = 0; i < range; i++) { | 1318 for (int i = 0; i < range; i++) { |
1316 case_targets[i]->Jump(); | 1319 case_targets[i]->Jump(); |
1317 frame_ = new VirtualFrame(table_start.expected_frame()); | 1320 frame_ = new VirtualFrame(table_start.expected_frame()); |
1318 } | 1321 } |
1319 GenerateFastCaseSwitchCases(node, case_labels, &table_start); | 1322 GenerateFastCaseSwitchCases(node, case_labels, &table_start); |
1320 } | 1323 } |
1321 | 1324 |
1322 | 1325 |
1323 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) { | 1326 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) { |
1324 Comment cmnt(masm_, "[ SwitchStatement"); | 1327 Comment cmnt(masm_, "[ SwitchStatement"); |
1325 if (FLAG_debug_info) RecordStatementPosition(node); | 1328 CodeForStatement(node); |
1326 node->set_break_stack_height(break_stack_height_); | 1329 node->set_break_stack_height(break_stack_height_); |
1327 node->break_target()->set_code_generator(this); | 1330 node->break_target()->set_code_generator(this); |
1328 | 1331 |
1329 Load(node->tag()); | 1332 Load(node->tag()); |
1330 | 1333 |
1331 if (TryGenerateFastCaseSwitchStatement(node)) { | 1334 if (TryGenerateFastCaseSwitchStatement(node)) { |
1332 return; | 1335 return; |
1333 } | 1336 } |
1334 | 1337 |
1335 JumpTarget next_test(this); | 1338 JumpTarget next_test(this); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1404 } | 1407 } |
1405 | 1408 |
1406 if (node->break_target()->is_linked()) { | 1409 if (node->break_target()->is_linked()) { |
1407 node->break_target()->Bind(); | 1410 node->break_target()->Bind(); |
1408 } | 1411 } |
1409 } | 1412 } |
1410 | 1413 |
1411 | 1414 |
1412 void CodeGenerator::VisitLoopStatement(LoopStatement* node) { | 1415 void CodeGenerator::VisitLoopStatement(LoopStatement* node) { |
1413 Comment cmnt(masm_, "[ LoopStatement"); | 1416 Comment cmnt(masm_, "[ LoopStatement"); |
1414 if (FLAG_debug_info) RecordStatementPosition(node); | 1417 CodeForStatement(node); |
1415 node->set_break_stack_height(break_stack_height_); | 1418 node->set_break_stack_height(break_stack_height_); |
1416 node->break_target()->set_code_generator(this); | 1419 node->break_target()->set_code_generator(this); |
1417 node->continue_target()->set_code_generator(this); | 1420 node->continue_target()->set_code_generator(this); |
1418 | 1421 |
1419 // Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a | 1422 // Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a |
1420 // known result for the test expression, with no side effects. | 1423 // known result for the test expression, with no side effects. |
1421 enum { ALWAYS_TRUE, ALWAYS_FALSE, DONT_KNOW } info = DONT_KNOW; | 1424 enum { ALWAYS_TRUE, ALWAYS_FALSE, DONT_KNOW } info = DONT_KNOW; |
1422 if (node->cond() == NULL) { | 1425 if (node->cond() == NULL) { |
1423 ASSERT(node->type() == LoopStatement::FOR_LOOP); | 1426 ASSERT(node->type() == LoopStatement::FOR_LOOP); |
1424 info = ALWAYS_TRUE; | 1427 info = ALWAYS_TRUE; |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1558 } | 1561 } |
1559 } else { | 1562 } else { |
1560 // If there is an update statement and control flow can reach it | 1563 // If there is an update statement and control flow can reach it |
1561 // via falling out of the body of the loop or continuing, we | 1564 // via falling out of the body of the loop or continuing, we |
1562 // compile the update statement. | 1565 // compile the update statement. |
1563 if (frame_ != NULL || node->continue_target()->is_linked()) { | 1566 if (frame_ != NULL || node->continue_target()->is_linked()) { |
1564 node->continue_target()->Bind(); | 1567 node->continue_target()->Bind(); |
1565 // Record source position of the statement as this code which is | 1568 // Record source position of the statement as this code which is |
1566 // after the code for the body actually belongs to the loop | 1569 // after the code for the body actually belongs to the loop |
1567 // statement and not the body. | 1570 // statement and not the body. |
1568 RecordStatementPosition(node); | 1571 CodeForStatement(node); |
1569 __ RecordPosition(node->statement_pos()); | 1572 |
| 1573 |
1570 ASSERT(node->type() == LoopStatement::FOR_LOOP); | 1574 ASSERT(node->type() == LoopStatement::FOR_LOOP); |
1571 Visit(node->next()); | 1575 Visit(node->next()); |
1572 loop.Jump(); | 1576 loop.Jump(); |
1573 } | 1577 } |
1574 } | 1578 } |
1575 } | 1579 } |
1576 break; | 1580 break; |
1577 } | 1581 } |
1578 } | 1582 } |
1579 | 1583 |
1580 if (node->break_target()->is_linked()) { | 1584 if (node->break_target()->is_linked()) { |
1581 node->break_target()->Bind(); | 1585 node->break_target()->Bind(); |
1582 } | 1586 } |
1583 } | 1587 } |
1584 | 1588 |
1585 | 1589 |
1586 void CodeGenerator::VisitForInStatement(ForInStatement* node) { | 1590 void CodeGenerator::VisitForInStatement(ForInStatement* node) { |
1587 Comment cmnt(masm_, "[ ForInStatement"); | 1591 Comment cmnt(masm_, "[ ForInStatement"); |
1588 if (FLAG_debug_info) RecordStatementPosition(node); | 1592 CodeForStatement(node); |
1589 | 1593 |
1590 // We keep stuff on the stack while the body is executing. | 1594 // We keep stuff on the stack while the body is executing. |
1591 // Record it, so that a break/continue crossing this statement | 1595 // Record it, so that a break/continue crossing this statement |
1592 // can restore the stack. | 1596 // can restore the stack. |
1593 const int kForInStackSize = 5 * kPointerSize; | 1597 const int kForInStackSize = 5 * kPointerSize; |
1594 break_stack_height_ += kForInStackSize; | 1598 break_stack_height_ += kForInStackSize; |
1595 node->set_break_stack_height(break_stack_height_); | 1599 node->set_break_stack_height(break_stack_height_); |
1596 node->break_target()->set_code_generator(this); | 1600 node->break_target()->set_code_generator(this); |
1597 node->continue_target()->set_code_generator(this); | 1601 node->continue_target()->set_code_generator(this); |
1598 | 1602 |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1767 | 1771 |
1768 // Exit. | 1772 // Exit. |
1769 exit.Bind(); | 1773 exit.Bind(); |
1770 | 1774 |
1771 break_stack_height_ -= kForInStackSize; | 1775 break_stack_height_ -= kForInStackSize; |
1772 } | 1776 } |
1773 | 1777 |
1774 | 1778 |
1775 void CodeGenerator::VisitTryCatch(TryCatch* node) { | 1779 void CodeGenerator::VisitTryCatch(TryCatch* node) { |
1776 Comment cmnt(masm_, "[ TryCatch"); | 1780 Comment cmnt(masm_, "[ TryCatch"); |
| 1781 CodeForStatement(node); |
1777 | 1782 |
1778 JumpTarget try_block(this); | 1783 JumpTarget try_block(this); |
1779 JumpTarget exit(this); | 1784 JumpTarget exit(this); |
1780 | 1785 |
1781 try_block.Call(); | 1786 try_block.Call(); |
1782 // --- Catch block --- | 1787 // --- Catch block --- |
1783 frame_->EmitPush(r0); | 1788 frame_->EmitPush(r0); |
1784 | 1789 |
1785 // Store the caught exception in the catch variable. | 1790 // Store the caught exception in the catch variable. |
1786 { Reference ref(this, node->catch_var()); | 1791 { Reference ref(this, node->catch_var()); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1876 shadows[i]->original_target()->Jump(); | 1881 shadows[i]->original_target()->Jump(); |
1877 } | 1882 } |
1878 } | 1883 } |
1879 | 1884 |
1880 exit.Bind(); | 1885 exit.Bind(); |
1881 } | 1886 } |
1882 | 1887 |
1883 | 1888 |
1884 void CodeGenerator::VisitTryFinally(TryFinally* node) { | 1889 void CodeGenerator::VisitTryFinally(TryFinally* node) { |
1885 Comment cmnt(masm_, "[ TryFinally"); | 1890 Comment cmnt(masm_, "[ TryFinally"); |
| 1891 CodeForStatement(node); |
1886 | 1892 |
1887 // State: Used to keep track of reason for entering the finally | 1893 // State: Used to keep track of reason for entering the finally |
1888 // block. Should probably be extended to hold information for | 1894 // block. Should probably be extended to hold information for |
1889 // break/continue from within the try block. | 1895 // break/continue from within the try block. |
1890 enum { FALLING, THROWING, JUMPING }; | 1896 enum { FALLING, THROWING, JUMPING }; |
1891 | 1897 |
1892 JumpTarget unlink(this); | 1898 JumpTarget unlink(this); |
1893 JumpTarget try_block(this); | 1899 JumpTarget try_block(this); |
1894 JumpTarget finally_block(this); | 1900 JumpTarget finally_block(this); |
1895 | 1901 |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2033 frame_->CallRuntime(Runtime::kReThrow, 1); | 2039 frame_->CallRuntime(Runtime::kReThrow, 1); |
2034 | 2040 |
2035 // Done. | 2041 // Done. |
2036 exit.Bind(); | 2042 exit.Bind(); |
2037 } | 2043 } |
2038 } | 2044 } |
2039 | 2045 |
2040 | 2046 |
2041 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) { | 2047 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) { |
2042 Comment cmnt(masm_, "[ DebuggerStatament"); | 2048 Comment cmnt(masm_, "[ DebuggerStatament"); |
2043 if (FLAG_debug_info) RecordStatementPosition(node); | 2049 CodeForStatement(node); |
2044 frame_->CallRuntime(Runtime::kDebugBreak, 0); | 2050 frame_->CallRuntime(Runtime::kDebugBreak, 0); |
2045 // Ignore the return value. | 2051 // Ignore the return value. |
2046 } | 2052 } |
2047 | 2053 |
2048 | 2054 |
2049 void CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) { | 2055 void CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) { |
2050 ASSERT(boilerplate->IsBoilerplate()); | 2056 ASSERT(boilerplate->IsBoilerplate()); |
2051 | 2057 |
2052 // Push the boilerplate on the stack. | 2058 // Push the boilerplate on the stack. |
2053 __ mov(r0, Operand(boilerplate)); | 2059 __ mov(r0, Operand(boilerplate)); |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2343 // Update the write barrier for the array address. | 2349 // Update the write barrier for the array address. |
2344 __ mov(r3, Operand(offset)); | 2350 __ mov(r3, Operand(offset)); |
2345 __ RecordWrite(r1, r3, r2); | 2351 __ RecordWrite(r1, r3, r2); |
2346 } | 2352 } |
2347 } | 2353 } |
2348 } | 2354 } |
2349 | 2355 |
2350 | 2356 |
2351 void CodeGenerator::VisitAssignment(Assignment* node) { | 2357 void CodeGenerator::VisitAssignment(Assignment* node) { |
2352 Comment cmnt(masm_, "[ Assignment"); | 2358 Comment cmnt(masm_, "[ Assignment"); |
2353 if (FLAG_debug_info) RecordStatementPosition(node); | 2359 CodeForStatement(node); |
2354 | 2360 |
2355 Reference target(this, node->target()); | 2361 Reference target(this, node->target()); |
2356 if (target.is_illegal()) { | 2362 if (target.is_illegal()) { |
2357 // Fool the virtual frame into thinking that we left the assignment's | 2363 // Fool the virtual frame into thinking that we left the assignment's |
2358 // value on the frame. | 2364 // value on the frame. |
2359 __ mov(r0, Operand(Smi::FromInt(0))); | 2365 __ mov(r0, Operand(Smi::FromInt(0))); |
2360 frame_->EmitPush(r0); | 2366 frame_->EmitPush(r0); |
2361 return; | 2367 return; |
2362 } | 2368 } |
2363 | 2369 |
(...skipping 16 matching lines...) Expand all Loading... |
2380 } | 2386 } |
2381 } | 2387 } |
2382 | 2388 |
2383 Variable* var = node->target()->AsVariableProxy()->AsVariable(); | 2389 Variable* var = node->target()->AsVariableProxy()->AsVariable(); |
2384 if (var != NULL && | 2390 if (var != NULL && |
2385 (var->mode() == Variable::CONST) && | 2391 (var->mode() == Variable::CONST) && |
2386 node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) { | 2392 node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) { |
2387 // Assignment ignored - leave the value on the stack. | 2393 // Assignment ignored - leave the value on the stack. |
2388 | 2394 |
2389 } else { | 2395 } else { |
2390 __ RecordPosition(node->position()); | 2396 CodeForSourcePosition(node->position()); |
2391 if (node->op() == Token::INIT_CONST) { | 2397 if (node->op() == Token::INIT_CONST) { |
2392 // Dynamic constant initializations must use the function context | 2398 // Dynamic constant initializations must use the function context |
2393 // and initialize the actual constant declared. Dynamic variable | 2399 // and initialize the actual constant declared. Dynamic variable |
2394 // initializations are simply assignments and use SetValue. | 2400 // initializations are simply assignments and use SetValue. |
2395 target.SetValue(CONST_INIT); | 2401 target.SetValue(CONST_INIT); |
2396 } else { | 2402 } else { |
2397 target.SetValue(NOT_CONST_INIT); | 2403 target.SetValue(NOT_CONST_INIT); |
2398 } | 2404 } |
2399 } | 2405 } |
2400 } | 2406 } |
2401 | 2407 |
2402 | 2408 |
2403 void CodeGenerator::VisitThrow(Throw* node) { | 2409 void CodeGenerator::VisitThrow(Throw* node) { |
2404 Comment cmnt(masm_, "[ Throw"); | 2410 Comment cmnt(masm_, "[ Throw"); |
2405 | 2411 |
2406 Load(node->exception()); | 2412 Load(node->exception()); |
2407 __ RecordPosition(node->position()); | 2413 CodeForSourcePosition(node->position()); |
2408 frame_->CallRuntime(Runtime::kThrow, 1); | 2414 frame_->CallRuntime(Runtime::kThrow, 1); |
2409 frame_->EmitPush(r0); | 2415 frame_->EmitPush(r0); |
2410 } | 2416 } |
2411 | 2417 |
2412 | 2418 |
2413 void CodeGenerator::VisitProperty(Property* node) { | 2419 void CodeGenerator::VisitProperty(Property* node) { |
2414 Comment cmnt(masm_, "[ Property"); | 2420 Comment cmnt(masm_, "[ Property"); |
2415 | 2421 |
2416 Reference property(this, node); | 2422 Reference property(this, node); |
2417 property.GetValue(typeof_state()); | 2423 property.GetValue(typeof_state()); |
2418 } | 2424 } |
2419 | 2425 |
2420 | 2426 |
2421 void CodeGenerator::VisitCall(Call* node) { | 2427 void CodeGenerator::VisitCall(Call* node) { |
2422 Comment cmnt(masm_, "[ Call"); | 2428 Comment cmnt(masm_, "[ Call"); |
2423 | 2429 |
2424 ZoneList<Expression*>* args = node->arguments(); | 2430 ZoneList<Expression*>* args = node->arguments(); |
2425 | 2431 |
2426 RecordStatementPosition(node); | 2432 CodeForStatement(node); |
2427 // Standard function call. | 2433 // Standard function call. |
2428 | 2434 |
2429 // Check if the function is a variable or a property. | 2435 // Check if the function is a variable or a property. |
2430 Expression* function = node->expression(); | 2436 Expression* function = node->expression(); |
2431 Variable* var = function->AsVariableProxy()->AsVariable(); | 2437 Variable* var = function->AsVariableProxy()->AsVariable(); |
2432 Property* property = function->AsProperty(); | 2438 Property* property = function->AsProperty(); |
2433 | 2439 |
2434 // ------------------------------------------------------------------------ | 2440 // ------------------------------------------------------------------------ |
2435 // Fast-case: Use inline caching. | 2441 // Fast-case: Use inline caching. |
2436 // --- | 2442 // --- |
(...skipping 18 matching lines...) Expand all Loading... |
2455 LoadGlobal(); | 2461 LoadGlobal(); |
2456 | 2462 |
2457 // Load the arguments. | 2463 // Load the arguments. |
2458 int arg_count = args->length(); | 2464 int arg_count = args->length(); |
2459 for (int i = 0; i < arg_count; i++) { | 2465 for (int i = 0; i < arg_count; i++) { |
2460 Load(args->at(i)); | 2466 Load(args->at(i)); |
2461 } | 2467 } |
2462 | 2468 |
2463 // Setup the receiver register and call the IC initialization code. | 2469 // Setup the receiver register and call the IC initialization code. |
2464 Handle<Code> stub = ComputeCallInitialize(arg_count); | 2470 Handle<Code> stub = ComputeCallInitialize(arg_count); |
2465 __ RecordPosition(node->position()); | 2471 CodeForSourcePosition(node->position()); |
2466 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET_CONTEXT, | 2472 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET_CONTEXT, |
2467 arg_count + 1); | 2473 arg_count + 1); |
2468 __ ldr(cp, frame_->Context()); | 2474 __ ldr(cp, frame_->Context()); |
2469 // Remove the function from the stack. | 2475 // Remove the function from the stack. |
2470 frame_->Drop(); | 2476 frame_->Drop(); |
2471 frame_->EmitPush(r0); | 2477 frame_->EmitPush(r0); |
2472 | 2478 |
2473 } else if (var != NULL && var->slot() != NULL && | 2479 } else if (var != NULL && var->slot() != NULL && |
2474 var->slot()->type() == Slot::LOOKUP) { | 2480 var->slot()->type() == Slot::LOOKUP) { |
2475 // ---------------------------------- | 2481 // ---------------------------------- |
(...skipping 30 matching lines...) Expand all Loading... |
2506 Load(property->obj()); | 2512 Load(property->obj()); |
2507 | 2513 |
2508 // Load the arguments. | 2514 // Load the arguments. |
2509 int arg_count = args->length(); | 2515 int arg_count = args->length(); |
2510 for (int i = 0; i < arg_count; i++) { | 2516 for (int i = 0; i < arg_count; i++) { |
2511 Load(args->at(i)); | 2517 Load(args->at(i)); |
2512 } | 2518 } |
2513 | 2519 |
2514 // Set the receiver register and call the IC initialization code. | 2520 // Set the receiver register and call the IC initialization code. |
2515 Handle<Code> stub = ComputeCallInitialize(arg_count); | 2521 Handle<Code> stub = ComputeCallInitialize(arg_count); |
2516 __ RecordPosition(node->position()); | 2522 CodeForSourcePosition(node->position()); |
2517 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET, arg_count + 1); | 2523 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET, arg_count + 1); |
2518 __ ldr(cp, frame_->Context()); | 2524 __ ldr(cp, frame_->Context()); |
2519 | 2525 |
2520 // Remove the function from the stack. | 2526 // Remove the function from the stack. |
2521 frame_->Drop(); | 2527 frame_->Drop(); |
2522 | 2528 |
2523 frame_->EmitPush(r0); // push after get rid of function from the stack | 2529 frame_->EmitPush(r0); // push after get rid of function from the stack |
2524 | 2530 |
2525 } else { | 2531 } else { |
2526 // ------------------------------------------- | 2532 // ------------------------------------------- |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2560 void CodeGenerator::VisitCallEval(CallEval* node) { | 2566 void CodeGenerator::VisitCallEval(CallEval* node) { |
2561 Comment cmnt(masm_, "[ CallEval"); | 2567 Comment cmnt(masm_, "[ CallEval"); |
2562 | 2568 |
2563 // In a call to eval, we first call %ResolvePossiblyDirectEval to resolve | 2569 // In a call to eval, we first call %ResolvePossiblyDirectEval to resolve |
2564 // the function we need to call and the receiver of the call. | 2570 // the function we need to call and the receiver of the call. |
2565 // Then we call the resolved function using the given arguments. | 2571 // Then we call the resolved function using the given arguments. |
2566 | 2572 |
2567 ZoneList<Expression*>* args = node->arguments(); | 2573 ZoneList<Expression*>* args = node->arguments(); |
2568 Expression* function = node->expression(); | 2574 Expression* function = node->expression(); |
2569 | 2575 |
2570 RecordStatementPosition(node); | 2576 CodeForStatement(node); |
2571 | 2577 |
2572 // Prepare stack for call to resolved function. | 2578 // Prepare stack for call to resolved function. |
2573 Load(function); | 2579 Load(function); |
2574 __ mov(r2, Operand(Factory::undefined_value())); | 2580 __ mov(r2, Operand(Factory::undefined_value())); |
2575 __ push(r2); // Slot for receiver | 2581 __ push(r2); // Slot for receiver |
2576 for (int i = 0; i < args->length(); i++) { | 2582 for (int i = 0; i < args->length(); i++) { |
2577 Load(args->at(i)); | 2583 Load(args->at(i)); |
2578 } | 2584 } |
2579 | 2585 |
2580 // Prepare stack for call to ResolvePossiblyDirectEval. | 2586 // Prepare stack for call to ResolvePossiblyDirectEval. |
2581 __ ldr(r1, MemOperand(sp, args->length() * kPointerSize + kPointerSize)); | 2587 __ ldr(r1, MemOperand(sp, args->length() * kPointerSize + kPointerSize)); |
2582 __ push(r1); | 2588 __ push(r1); |
2583 if (args->length() > 0) { | 2589 if (args->length() > 0) { |
2584 __ ldr(r1, MemOperand(sp, args->length() * kPointerSize)); | 2590 __ ldr(r1, MemOperand(sp, args->length() * kPointerSize)); |
2585 __ push(r1); | 2591 __ push(r1); |
2586 } else { | 2592 } else { |
2587 __ push(r2); | 2593 __ push(r2); |
2588 } | 2594 } |
2589 | 2595 |
2590 // Resolve the call. | 2596 // Resolve the call. |
2591 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 2); | 2597 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 2); |
2592 | 2598 |
2593 // Touch up stack with the right values for the function and the receiver. | 2599 // Touch up stack with the right values for the function and the receiver. |
2594 __ ldr(r1, FieldMemOperand(r0, FixedArray::kHeaderSize)); | 2600 __ ldr(r1, FieldMemOperand(r0, FixedArray::kHeaderSize)); |
2595 __ str(r1, MemOperand(sp, (args->length() + 1) * kPointerSize)); | 2601 __ str(r1, MemOperand(sp, (args->length() + 1) * kPointerSize)); |
2596 __ ldr(r1, FieldMemOperand(r0, FixedArray::kHeaderSize + kPointerSize)); | 2602 __ ldr(r1, FieldMemOperand(r0, FixedArray::kHeaderSize + kPointerSize)); |
2597 __ str(r1, MemOperand(sp, args->length() * kPointerSize)); | 2603 __ str(r1, MemOperand(sp, args->length() * kPointerSize)); |
2598 | 2604 |
2599 // Call the function. | 2605 // Call the function. |
2600 __ RecordPosition(node->position()); | 2606 CodeForSourcePosition(node->position()); |
2601 | 2607 |
2602 CallFunctionStub call_function(args->length()); | 2608 CallFunctionStub call_function(args->length()); |
2603 __ CallStub(&call_function); | 2609 __ CallStub(&call_function); |
2604 | 2610 |
2605 __ ldr(cp, frame_->Context()); | 2611 __ ldr(cp, frame_->Context()); |
2606 // Remove the function from the stack. | 2612 // Remove the function from the stack. |
2607 frame_->Pop(); | 2613 frame_->Pop(); |
2608 frame_->Push(r0); | 2614 frame_->Push(r0); |
2609 } | 2615 } |
2610 | 2616 |
2611 | 2617 |
2612 void CodeGenerator::VisitCallNew(CallNew* node) { | 2618 void CodeGenerator::VisitCallNew(CallNew* node) { |
2613 Comment cmnt(masm_, "[ CallNew"); | 2619 Comment cmnt(masm_, "[ CallNew"); |
| 2620 CodeForStatement(node); |
2614 | 2621 |
2615 // According to ECMA-262, section 11.2.2, page 44, the function | 2622 // According to ECMA-262, section 11.2.2, page 44, the function |
2616 // expression in new calls must be evaluated before the | 2623 // expression in new calls must be evaluated before the |
2617 // arguments. This is different from ordinary calls, where the | 2624 // arguments. This is different from ordinary calls, where the |
2618 // actual function to call is resolved after the arguments have been | 2625 // actual function to call is resolved after the arguments have been |
2619 // evaluated. | 2626 // evaluated. |
2620 | 2627 |
2621 // Compute function to call and use the global object as the | 2628 // Compute function to call and use the global object as the |
2622 // receiver. There is no need to use the global proxy here because | 2629 // receiver. There is no need to use the global proxy here because |
2623 // it will always be replaced with a newly allocated object. | 2630 // it will always be replaced with a newly allocated object. |
2624 Load(node->expression()); | 2631 Load(node->expression()); |
2625 LoadGlobal(); | 2632 LoadGlobal(); |
2626 | 2633 |
2627 // Push the arguments ("left-to-right") on the stack. | 2634 // Push the arguments ("left-to-right") on the stack. |
2628 ZoneList<Expression*>* args = node->arguments(); | 2635 ZoneList<Expression*>* args = node->arguments(); |
2629 int arg_count = args->length(); | 2636 int arg_count = args->length(); |
2630 for (int i = 0; i < arg_count; i++) { | 2637 for (int i = 0; i < arg_count; i++) { |
2631 Load(args->at(i)); | 2638 Load(args->at(i)); |
2632 } | 2639 } |
2633 | 2640 |
2634 // r0: the number of arguments. | 2641 // r0: the number of arguments. |
2635 __ mov(r0, Operand(arg_count)); | 2642 __ mov(r0, Operand(arg_count)); |
2636 | 2643 |
2637 // Load the function into r1 as per calling convention. | 2644 // Load the function into r1 as per calling convention. |
2638 __ ldr(r1, frame_->ElementAt(arg_count + 1)); | 2645 __ ldr(r1, frame_->ElementAt(arg_count + 1)); |
2639 | 2646 |
2640 // Call the construct call builtin that handles allocation and | 2647 // Call the construct call builtin that handles allocation and |
2641 // constructor invocation. | 2648 // constructor invocation. |
2642 __ RecordPosition(RelocInfo::POSITION); | 2649 CodeForSourcePosition(node->position()); |
2643 Handle<Code> ic(Builtins::builtin(Builtins::JSConstructCall)); | 2650 Handle<Code> ic(Builtins::builtin(Builtins::JSConstructCall)); |
2644 frame_->CallCodeObject(ic, RelocInfo::CONSTRUCT_CALL, arg_count + 1); | 2651 frame_->CallCodeObject(ic, RelocInfo::CONSTRUCT_CALL, arg_count + 1); |
2645 | 2652 |
2646 // Discard old TOS value and push r0 on the stack (same as Pop(), push(r0)). | 2653 // Discard old TOS value and push r0 on the stack (same as Pop(), push(r0)). |
2647 __ str(r0, frame_->Top()); | 2654 __ str(r0, frame_->Top()); |
2648 } | 2655 } |
2649 | 2656 |
2650 | 2657 |
2651 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) { | 2658 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) { |
2652 ASSERT(args->length() == 1); | 2659 ASSERT(args->length() == 1); |
(...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3357 __ tst(r0, Operand(r0)); | 3364 __ tst(r0, Operand(r0)); |
3358 cc_reg_ = eq; | 3365 cc_reg_ = eq; |
3359 break; | 3366 break; |
3360 | 3367 |
3361 default: | 3368 default: |
3362 UNREACHABLE(); | 3369 UNREACHABLE(); |
3363 } | 3370 } |
3364 } | 3371 } |
3365 | 3372 |
3366 | 3373 |
3367 void CodeGenerator::RecordStatementPosition(Node* node) { | |
3368 if (FLAG_debug_info) { | |
3369 int statement_pos = node->statement_pos(); | |
3370 if (statement_pos == RelocInfo::kNoPosition) return; | |
3371 __ RecordStatementPosition(statement_pos); | |
3372 } | |
3373 } | |
3374 | |
3375 | |
3376 bool CodeGenerator::IsActualFunctionReturn(JumpTarget* target) { | 3374 bool CodeGenerator::IsActualFunctionReturn(JumpTarget* target) { |
3377 return (target == &function_return_ && !function_return_is_shadowed_); | 3375 return (target == &function_return_ && !function_return_is_shadowed_); |
3378 } | 3376 } |
3379 | 3377 |
3380 | 3378 |
3381 #undef __ | 3379 #undef __ |
3382 #define __ masm-> | 3380 #define __ masm-> |
3383 | 3381 |
3384 Handle<String> Reference::GetName() { | 3382 Handle<String> Reference::GetName() { |
3385 ASSERT(type_ == NAMED); | 3383 ASSERT(type_ == NAMED); |
(...skipping 12 matching lines...) Expand all Loading... |
3398 } | 3396 } |
3399 | 3397 |
3400 | 3398 |
3401 void Reference::GetValue(TypeofState typeof_state) { | 3399 void Reference::GetValue(TypeofState typeof_state) { |
3402 ASSERT(!is_illegal()); | 3400 ASSERT(!is_illegal()); |
3403 ASSERT(!cgen_->has_cc()); | 3401 ASSERT(!cgen_->has_cc()); |
3404 MacroAssembler* masm = cgen_->masm(); | 3402 MacroAssembler* masm = cgen_->masm(); |
3405 VirtualFrame* frame = cgen_->frame(); | 3403 VirtualFrame* frame = cgen_->frame(); |
3406 Property* property = expression_->AsProperty(); | 3404 Property* property = expression_->AsProperty(); |
3407 if (property != NULL) { | 3405 if (property != NULL) { |
3408 __ RecordPosition(property->position()); | 3406 cgen_->CodeForSourcePosition(property->position()); |
3409 } | 3407 } |
3410 | 3408 |
3411 switch (type_) { | 3409 switch (type_) { |
3412 case SLOT: { | 3410 case SLOT: { |
3413 Comment cmnt(masm, "[ Load from Slot"); | 3411 Comment cmnt(masm, "[ Load from Slot"); |
3414 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot(); | 3412 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot(); |
3415 ASSERT(slot != NULL); | 3413 ASSERT(slot != NULL); |
3416 cgen_->LoadFromSlot(slot, typeof_state); | 3414 cgen_->LoadFromSlot(slot, typeof_state); |
3417 break; | 3415 break; |
3418 } | 3416 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3464 } | 3462 } |
3465 | 3463 |
3466 | 3464 |
3467 void Reference::SetValue(InitState init_state) { | 3465 void Reference::SetValue(InitState init_state) { |
3468 ASSERT(!is_illegal()); | 3466 ASSERT(!is_illegal()); |
3469 ASSERT(!cgen_->has_cc()); | 3467 ASSERT(!cgen_->has_cc()); |
3470 MacroAssembler* masm = cgen_->masm(); | 3468 MacroAssembler* masm = cgen_->masm(); |
3471 VirtualFrame* frame = cgen_->frame(); | 3469 VirtualFrame* frame = cgen_->frame(); |
3472 Property* property = expression_->AsProperty(); | 3470 Property* property = expression_->AsProperty(); |
3473 if (property != NULL) { | 3471 if (property != NULL) { |
3474 __ RecordPosition(property->position()); | 3472 cgen_->CodeForSourcePosition(property->position()); |
3475 } | 3473 } |
3476 | 3474 |
3477 switch (type_) { | 3475 switch (type_) { |
3478 case SLOT: { | 3476 case SLOT: { |
3479 Comment cmnt(masm, "[ Store to Slot"); | 3477 Comment cmnt(masm, "[ Store to Slot"); |
3480 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot(); | 3478 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot(); |
3481 ASSERT(slot != NULL); | 3479 ASSERT(slot != NULL); |
3482 if (slot->type() == Slot::LOOKUP) { | 3480 if (slot->type() == Slot::LOOKUP) { |
3483 ASSERT(slot->var()->mode() == Variable::DYNAMIC); | 3481 ASSERT(slot->var()->mode() == Variable::DYNAMIC); |
3484 | 3482 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3567 __ mov(r2, Operand(name)); | 3565 __ mov(r2, Operand(name)); |
3568 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0); | 3566 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0); |
3569 frame->EmitPush(r0); | 3567 frame->EmitPush(r0); |
3570 break; | 3568 break; |
3571 } | 3569 } |
3572 | 3570 |
3573 case KEYED: { | 3571 case KEYED: { |
3574 Comment cmnt(masm, "[ Store to keyed Property"); | 3572 Comment cmnt(masm, "[ Store to keyed Property"); |
3575 Property* property = expression_->AsProperty(); | 3573 Property* property = expression_->AsProperty(); |
3576 ASSERT(property != NULL); | 3574 ASSERT(property != NULL); |
3577 __ RecordPosition(property->position()); | 3575 cgen_->CodeForSourcePosition(property->position()); |
3578 | 3576 |
3579 // Call IC code. | 3577 // Call IC code. |
3580 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 3578 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
3581 // TODO(1222589): Make the IC grab the values from the stack. | 3579 // TODO(1222589): Make the IC grab the values from the stack. |
3582 frame->Pop(r0); // value | 3580 frame->Pop(r0); // value |
3583 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0); | 3581 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0); |
3584 frame->EmitPush(r0); | 3582 frame->EmitPush(r0); |
3585 break; | 3583 break; |
3586 } | 3584 } |
3587 | 3585 |
(...skipping 905 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4493 __ mov(r2, Operand(0)); | 4491 __ mov(r2, Operand(0)); |
4494 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); | 4492 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); |
4495 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), | 4493 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), |
4496 RelocInfo::CODE_TARGET); | 4494 RelocInfo::CODE_TARGET); |
4497 } | 4495 } |
4498 | 4496 |
4499 | 4497 |
4500 #undef __ | 4498 #undef __ |
4501 | 4499 |
4502 } } // namespace v8::internal | 4500 } } // namespace v8::internal |
OLD | NEW |