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 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1036 | 1036 |
1037 // Call the function on the stack with the given arguments. | 1037 // Call the function on the stack with the given arguments. |
1038 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args, | 1038 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args, |
1039 int position) { | 1039 int position) { |
1040 // Push the arguments ("left-to-right") on the stack. | 1040 // Push the arguments ("left-to-right") on the stack. |
1041 for (int i = 0; i < args->length(); i++) { | 1041 for (int i = 0; i < args->length(); i++) { |
1042 Load(args->at(i)); | 1042 Load(args->at(i)); |
1043 } | 1043 } |
1044 | 1044 |
1045 // Record the position for debugging purposes. | 1045 // Record the position for debugging purposes. |
1046 __ RecordPosition(position); | 1046 CodeForSourcePosition(position); |
1047 | 1047 |
1048 // Use the shared code stub to call the function. | 1048 // Use the shared code stub to call the function. |
1049 CallFunctionStub call_function(args->length()); | 1049 CallFunctionStub call_function(args->length()); |
1050 __ CallStub(&call_function); | 1050 __ CallStub(&call_function); |
1051 | 1051 |
1052 // Restore context and pop function from the stack. | 1052 // Restore context and pop function from the stack. |
1053 __ ldr(cp, frame_->Context()); | 1053 __ ldr(cp, frame_->Context()); |
1054 frame_->Pop(); // discard the TOS | 1054 frame_->Pop(); // discard the TOS |
1055 } | 1055 } |
1056 | 1056 |
(...skipping 10 matching lines...) Expand all Loading... |
1067 if (FLAG_check_stack) { | 1067 if (FLAG_check_stack) { |
1068 Comment cmnt(masm_, "[ check stack"); | 1068 Comment cmnt(masm_, "[ check stack"); |
1069 StackCheckStub stub; | 1069 StackCheckStub stub; |
1070 __ CallStub(&stub); | 1070 __ CallStub(&stub); |
1071 } | 1071 } |
1072 } | 1072 } |
1073 | 1073 |
1074 | 1074 |
1075 void CodeGenerator::VisitBlock(Block* node) { | 1075 void CodeGenerator::VisitBlock(Block* node) { |
1076 Comment cmnt(masm_, "[ Block"); | 1076 Comment cmnt(masm_, "[ Block"); |
1077 if (FLAG_debug_info) RecordStatementPosition(node); | 1077 CodeForStatement(node); |
1078 node->set_break_stack_height(break_stack_height_); | 1078 node->set_break_stack_height(break_stack_height_); |
1079 VisitStatements(node->statements()); | 1079 VisitStatements(node->statements()); |
1080 __ bind(node->break_target()); | 1080 __ bind(node->break_target()); |
1081 } | 1081 } |
1082 | 1082 |
1083 | 1083 |
1084 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 1084 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
1085 __ mov(r0, Operand(pairs)); | 1085 __ mov(r0, Operand(pairs)); |
1086 frame_->Push(r0); | 1086 frame_->Push(r0); |
1087 frame_->Push(cp); | 1087 frame_->Push(cp); |
1088 __ mov(r0, Operand(Smi::FromInt(is_eval() ? 1 : 0))); | 1088 __ mov(r0, Operand(Smi::FromInt(is_eval() ? 1 : 0))); |
1089 frame_->Push(r0); | 1089 frame_->Push(r0); |
1090 __ CallRuntime(Runtime::kDeclareGlobals, 3); | 1090 __ CallRuntime(Runtime::kDeclareGlobals, 3); |
1091 // The result is discarded. | 1091 // The result is discarded. |
1092 } | 1092 } |
1093 | 1093 |
1094 | 1094 |
1095 void CodeGenerator::VisitDeclaration(Declaration* node) { | 1095 void CodeGenerator::VisitDeclaration(Declaration* node) { |
1096 Comment cmnt(masm_, "[ Declaration"); | 1096 Comment cmnt(masm_, "[ Declaration"); |
| 1097 CodeForStatement(node); |
1097 Variable* var = node->proxy()->var(); | 1098 Variable* var = node->proxy()->var(); |
1098 ASSERT(var != NULL); // must have been resolved | 1099 ASSERT(var != NULL); // must have been resolved |
1099 Slot* slot = var->slot(); | 1100 Slot* slot = var->slot(); |
1100 | 1101 |
1101 // If it was not possible to allocate the variable at compile time, | 1102 // If it was not possible to allocate the variable at compile time, |
1102 // we need to "declare" it at runtime to make sure it actually | 1103 // we need to "declare" it at runtime to make sure it actually |
1103 // exists in the local context. | 1104 // exists in the local context. |
1104 if (slot != NULL && slot->type() == Slot::LOOKUP) { | 1105 if (slot != NULL && slot->type() == Slot::LOOKUP) { |
1105 // Variables with a "LOOKUP" slot were introduced as non-locals | 1106 // Variables with a "LOOKUP" slot were introduced as non-locals |
1106 // during variable resolution and must have mode DYNAMIC. | 1107 // during variable resolution and must have mode DYNAMIC. |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1152 // safe to pop the value lying on top of the reference before unloading | 1153 // safe to pop the value lying on top of the reference before unloading |
1153 // the reference itself (which preserves the top of stack) because we | 1154 // the reference itself (which preserves the top of stack) because we |
1154 // know it is a zero-sized reference. | 1155 // know it is a zero-sized reference. |
1155 frame_->Pop(); | 1156 frame_->Pop(); |
1156 } | 1157 } |
1157 } | 1158 } |
1158 | 1159 |
1159 | 1160 |
1160 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) { | 1161 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) { |
1161 Comment cmnt(masm_, "[ ExpressionStatement"); | 1162 Comment cmnt(masm_, "[ ExpressionStatement"); |
1162 if (FLAG_debug_info) RecordStatementPosition(node); | 1163 CodeForStatement(node); |
1163 Expression* expression = node->expression(); | 1164 Expression* expression = node->expression(); |
1164 expression->MarkAsStatement(); | 1165 expression->MarkAsStatement(); |
1165 Load(expression); | 1166 Load(expression); |
1166 frame_->Pop(); | 1167 frame_->Pop(); |
1167 } | 1168 } |
1168 | 1169 |
1169 | 1170 |
1170 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) { | 1171 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) { |
1171 Comment cmnt(masm_, "// EmptyStatement"); | 1172 Comment cmnt(masm_, "// EmptyStatement"); |
| 1173 CodeForStatement(node); |
1172 // nothing to do | 1174 // nothing to do |
1173 } | 1175 } |
1174 | 1176 |
1175 | 1177 |
1176 void CodeGenerator::VisitIfStatement(IfStatement* node) { | 1178 void CodeGenerator::VisitIfStatement(IfStatement* node) { |
1177 Comment cmnt(masm_, "[ IfStatement"); | 1179 Comment cmnt(masm_, "[ IfStatement"); |
1178 // Generate different code depending on which | 1180 // Generate different code depending on which |
1179 // parts of the if statement are present or not. | 1181 // parts of the if statement are present or not. |
1180 bool has_then_stm = node->HasThenStatement(); | 1182 bool has_then_stm = node->HasThenStatement(); |
1181 bool has_else_stm = node->HasElseStatement(); | 1183 bool has_else_stm = node->HasElseStatement(); |
1182 | 1184 |
1183 if (FLAG_debug_info) RecordStatementPosition(node); | 1185 CodeForStatement(node); |
1184 | 1186 |
1185 Label exit; | 1187 Label exit; |
1186 if (has_then_stm && has_else_stm) { | 1188 if (has_then_stm && has_else_stm) { |
1187 Comment cmnt(masm_, "[ IfThenElse"); | 1189 Comment cmnt(masm_, "[ IfThenElse"); |
1188 Label then; | 1190 Label then; |
1189 Label else_; | 1191 Label else_; |
1190 // if (cond) | 1192 // if (cond) |
1191 LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &then, &else_, true); | 1193 LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &then, &else_, true); |
1192 Branch(false, &else_); | 1194 Branch(false, &else_); |
1193 // then | 1195 // then |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1238 | 1240 |
1239 | 1241 |
1240 void CodeGenerator::CleanStack(int num_bytes) { | 1242 void CodeGenerator::CleanStack(int num_bytes) { |
1241 ASSERT(num_bytes % kPointerSize == 0); | 1243 ASSERT(num_bytes % kPointerSize == 0); |
1242 frame_->Drop(num_bytes / kPointerSize); | 1244 frame_->Drop(num_bytes / kPointerSize); |
1243 } | 1245 } |
1244 | 1246 |
1245 | 1247 |
1246 void CodeGenerator::VisitContinueStatement(ContinueStatement* node) { | 1248 void CodeGenerator::VisitContinueStatement(ContinueStatement* node) { |
1247 Comment cmnt(masm_, "[ ContinueStatement"); | 1249 Comment cmnt(masm_, "[ ContinueStatement"); |
1248 if (FLAG_debug_info) RecordStatementPosition(node); | 1250 CodeForStatement(node); |
1249 CleanStack(break_stack_height_ - node->target()->break_stack_height()); | 1251 CleanStack(break_stack_height_ - node->target()->break_stack_height()); |
1250 __ b(node->target()->continue_target()); | 1252 __ b(node->target()->continue_target()); |
1251 } | 1253 } |
1252 | 1254 |
1253 | 1255 |
1254 void CodeGenerator::VisitBreakStatement(BreakStatement* node) { | 1256 void CodeGenerator::VisitBreakStatement(BreakStatement* node) { |
1255 Comment cmnt(masm_, "[ BreakStatement"); | 1257 Comment cmnt(masm_, "[ BreakStatement"); |
1256 if (FLAG_debug_info) RecordStatementPosition(node); | 1258 CodeForStatement(node); |
1257 CleanStack(break_stack_height_ - node->target()->break_stack_height()); | 1259 CleanStack(break_stack_height_ - node->target()->break_stack_height()); |
1258 __ b(node->target()->break_target()); | 1260 __ b(node->target()->break_target()); |
1259 } | 1261 } |
1260 | 1262 |
1261 | 1263 |
1262 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) { | 1264 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) { |
1263 Comment cmnt(masm_, "[ ReturnStatement"); | 1265 Comment cmnt(masm_, "[ ReturnStatement"); |
1264 if (FLAG_debug_info) RecordStatementPosition(node); | 1266 CodeForStatement(node); |
1265 Load(node->expression()); | 1267 Load(node->expression()); |
1266 // Move the function result into r0. | 1268 // Move the function result into r0. |
1267 frame_->Pop(r0); | 1269 frame_->Pop(r0); |
1268 | 1270 |
1269 __ b(&function_return_); | 1271 __ b(&function_return_); |
1270 } | 1272 } |
1271 | 1273 |
1272 | 1274 |
1273 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) { | 1275 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) { |
1274 Comment cmnt(masm_, "[ WithEnterStatement"); | 1276 Comment cmnt(masm_, "[ WithEnterStatement"); |
1275 if (FLAG_debug_info) RecordStatementPosition(node); | 1277 CodeForStatement(node); |
1276 Load(node->expression()); | 1278 Load(node->expression()); |
1277 __ CallRuntime(Runtime::kPushContext, 1); | 1279 __ CallRuntime(Runtime::kPushContext, 1); |
1278 if (kDebug) { | 1280 if (kDebug) { |
1279 Label verified_true; | 1281 Label verified_true; |
1280 __ cmp(r0, Operand(cp)); | 1282 __ cmp(r0, Operand(cp)); |
1281 __ b(eq, &verified_true); | 1283 __ b(eq, &verified_true); |
1282 __ stop("PushContext: r0 is expected to be the same as cp"); | 1284 __ stop("PushContext: r0 is expected to be the same as cp"); |
1283 __ bind(&verified_true); | 1285 __ bind(&verified_true); |
1284 } | 1286 } |
1285 // Update context local. | 1287 // Update context local. |
1286 __ str(cp, frame_->Context()); | 1288 __ str(cp, frame_->Context()); |
1287 } | 1289 } |
1288 | 1290 |
1289 | 1291 |
1290 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) { | 1292 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) { |
1291 Comment cmnt(masm_, "[ WithExitStatement"); | 1293 Comment cmnt(masm_, "[ WithExitStatement"); |
| 1294 CodeForStatement(node); |
1292 // Pop context. | 1295 // Pop context. |
1293 __ ldr(cp, ContextOperand(cp, Context::PREVIOUS_INDEX)); | 1296 __ ldr(cp, ContextOperand(cp, Context::PREVIOUS_INDEX)); |
1294 // Update context local. | 1297 // Update context local. |
1295 __ str(cp, frame_->Context()); | 1298 __ str(cp, frame_->Context()); |
1296 } | 1299 } |
1297 | 1300 |
1298 | 1301 |
1299 int CodeGenerator::FastCaseSwitchMaxOverheadFactor() { | 1302 int CodeGenerator::FastCaseSwitchMaxOverheadFactor() { |
1300 return kFastSwitchMaxOverheadFactor; | 1303 return kFastSwitchMaxOverheadFactor; |
1301 } | 1304 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1348 __ cmp(r0, Operand(Smi::FromInt(range))); | 1351 __ cmp(r0, Operand(Smi::FromInt(range))); |
1349 __ b(ge, fail_label); | 1352 __ b(ge, fail_label); |
1350 __ SmiJumpTable(r0, case_targets); | 1353 __ SmiJumpTable(r0, case_targets); |
1351 | 1354 |
1352 GenerateFastCaseSwitchCases(node, case_labels); | 1355 GenerateFastCaseSwitchCases(node, case_labels); |
1353 } | 1356 } |
1354 | 1357 |
1355 | 1358 |
1356 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) { | 1359 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) { |
1357 Comment cmnt(masm_, "[ SwitchStatement"); | 1360 Comment cmnt(masm_, "[ SwitchStatement"); |
1358 if (FLAG_debug_info) RecordStatementPosition(node); | 1361 CodeForStatement(node); |
1359 node->set_break_stack_height(break_stack_height_); | 1362 node->set_break_stack_height(break_stack_height_); |
1360 | 1363 |
1361 Load(node->tag()); | 1364 Load(node->tag()); |
1362 | 1365 |
1363 if (TryGenerateFastCaseSwitchStatement(node)) { | 1366 if (TryGenerateFastCaseSwitchStatement(node)) { |
1364 return; | 1367 return; |
1365 } | 1368 } |
1366 | 1369 |
1367 Label next, fall_through, default_case; | 1370 Label next, fall_through, default_case; |
1368 ZoneList<CaseClause*>* cases = node->cases(); | 1371 ZoneList<CaseClause*>* cases = node->cases(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1416 frame_->Pop(); | 1419 frame_->Pop(); |
1417 } | 1420 } |
1418 | 1421 |
1419 __ bind(&fall_through); | 1422 __ bind(&fall_through); |
1420 __ bind(node->break_target()); | 1423 __ bind(node->break_target()); |
1421 } | 1424 } |
1422 | 1425 |
1423 | 1426 |
1424 void CodeGenerator::VisitLoopStatement(LoopStatement* node) { | 1427 void CodeGenerator::VisitLoopStatement(LoopStatement* node) { |
1425 Comment cmnt(masm_, "[ LoopStatement"); | 1428 Comment cmnt(masm_, "[ LoopStatement"); |
1426 if (FLAG_debug_info) RecordStatementPosition(node); | 1429 CodeForStatement(node); |
1427 node->set_break_stack_height(break_stack_height_); | 1430 node->set_break_stack_height(break_stack_height_); |
1428 | 1431 |
1429 // simple condition analysis | 1432 // simple condition analysis |
1430 enum { ALWAYS_TRUE, ALWAYS_FALSE, DONT_KNOW } info = DONT_KNOW; | 1433 enum { ALWAYS_TRUE, ALWAYS_FALSE, DONT_KNOW } info = DONT_KNOW; |
1431 if (node->cond() == NULL) { | 1434 if (node->cond() == NULL) { |
1432 ASSERT(node->type() == LoopStatement::FOR_LOOP); | 1435 ASSERT(node->type() == LoopStatement::FOR_LOOP); |
1433 info = ALWAYS_TRUE; | 1436 info = ALWAYS_TRUE; |
1434 } else { | 1437 } else { |
1435 Literal* lit = node->cond()->AsLiteral(); | 1438 Literal* lit = node->cond()->AsLiteral(); |
1436 if (lit != NULL) { | 1439 if (lit != NULL) { |
(...skipping 19 matching lines...) Expand all Loading... |
1456 // body | 1459 // body |
1457 __ bind(&loop); | 1460 __ bind(&loop); |
1458 Visit(node->body()); | 1461 Visit(node->body()); |
1459 | 1462 |
1460 // next | 1463 // next |
1461 __ bind(node->continue_target()); | 1464 __ bind(node->continue_target()); |
1462 if (node->next() != NULL) { | 1465 if (node->next() != NULL) { |
1463 // Record source position of the statement as this code which is after the | 1466 // Record source position of the statement as this code which is after the |
1464 // code for the body actually belongs to the loop statement and not the | 1467 // code for the body actually belongs to the loop statement and not the |
1465 // body. | 1468 // body. |
1466 if (FLAG_debug_info) __ RecordPosition(node->statement_pos()); | 1469 CodeForStatement(node); |
1467 ASSERT(node->type() == LoopStatement::FOR_LOOP); | 1470 ASSERT(node->type() == LoopStatement::FOR_LOOP); |
1468 Visit(node->next()); | 1471 Visit(node->next()); |
1469 } | 1472 } |
1470 | 1473 |
1471 // cond | 1474 // cond |
1472 __ bind(&entry); | 1475 __ bind(&entry); |
1473 switch (info) { | 1476 switch (info) { |
1474 case ALWAYS_TRUE: | 1477 case ALWAYS_TRUE: |
1475 CheckStack(); // TODO(1222600): ignore if body contains calls. | 1478 CheckStack(); // TODO(1222600): ignore if body contains calls. |
1476 __ b(&loop); | 1479 __ b(&loop); |
(...skipping 11 matching lines...) Expand all Loading... |
1488 break; | 1491 break; |
1489 } | 1492 } |
1490 | 1493 |
1491 // exit | 1494 // exit |
1492 __ bind(node->break_target()); | 1495 __ bind(node->break_target()); |
1493 } | 1496 } |
1494 | 1497 |
1495 | 1498 |
1496 void CodeGenerator::VisitForInStatement(ForInStatement* node) { | 1499 void CodeGenerator::VisitForInStatement(ForInStatement* node) { |
1497 Comment cmnt(masm_, "[ ForInStatement"); | 1500 Comment cmnt(masm_, "[ ForInStatement"); |
1498 if (FLAG_debug_info) RecordStatementPosition(node); | 1501 CodeForStatement(node); |
1499 | 1502 |
1500 // We keep stuff on the stack while the body is executing. | 1503 // We keep stuff on the stack while the body is executing. |
1501 // Record it, so that a break/continue crossing this statement | 1504 // Record it, so that a break/continue crossing this statement |
1502 // can restore the stack. | 1505 // can restore the stack. |
1503 const int kForInStackSize = 5 * kPointerSize; | 1506 const int kForInStackSize = 5 * kPointerSize; |
1504 break_stack_height_ += kForInStackSize; | 1507 break_stack_height_ += kForInStackSize; |
1505 node->set_break_stack_height(break_stack_height_); | 1508 node->set_break_stack_height(break_stack_height_); |
1506 | 1509 |
1507 Label loop, next, entry, cleanup, exit, primitive, jsobject; | 1510 Label loop, next, entry, cleanup, exit, primitive, jsobject; |
1508 Label filter_key, end_del_check, fixed_array, non_string; | 1511 Label filter_key, end_del_check, fixed_array, non_string; |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1676 | 1679 |
1677 // Exit. | 1680 // Exit. |
1678 __ bind(&exit); | 1681 __ bind(&exit); |
1679 | 1682 |
1680 break_stack_height_ -= kForInStackSize; | 1683 break_stack_height_ -= kForInStackSize; |
1681 } | 1684 } |
1682 | 1685 |
1683 | 1686 |
1684 void CodeGenerator::VisitTryCatch(TryCatch* node) { | 1687 void CodeGenerator::VisitTryCatch(TryCatch* node) { |
1685 Comment cmnt(masm_, "[ TryCatch"); | 1688 Comment cmnt(masm_, "[ TryCatch"); |
| 1689 CodeForStatement(node); |
1686 | 1690 |
1687 Label try_block, exit; | 1691 Label try_block, exit; |
1688 | 1692 |
1689 __ bl(&try_block); | 1693 __ bl(&try_block); |
1690 // --- Catch block --- | 1694 // --- Catch block --- |
1691 frame_->Push(r0); | 1695 frame_->Push(r0); |
1692 | 1696 |
1693 // Store the caught exception in the catch variable. | 1697 // Store the caught exception in the catch variable. |
1694 { Reference ref(this, node->catch_var()); | 1698 { Reference ref(this, node->catch_var()); |
1695 ASSERT(ref.is_slot()); | 1699 ASSERT(ref.is_slot()); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1772 __ b(shadows[i]->original_label()); | 1776 __ b(shadows[i]->original_label()); |
1773 } | 1777 } |
1774 } | 1778 } |
1775 | 1779 |
1776 __ bind(&exit); | 1780 __ bind(&exit); |
1777 } | 1781 } |
1778 | 1782 |
1779 | 1783 |
1780 void CodeGenerator::VisitTryFinally(TryFinally* node) { | 1784 void CodeGenerator::VisitTryFinally(TryFinally* node) { |
1781 Comment cmnt(masm_, "[ TryFinally"); | 1785 Comment cmnt(masm_, "[ TryFinally"); |
| 1786 CodeForStatement(node); |
1782 | 1787 |
1783 // State: Used to keep track of reason for entering the finally | 1788 // State: Used to keep track of reason for entering the finally |
1784 // block. Should probably be extended to hold information for | 1789 // block. Should probably be extended to hold information for |
1785 // break/continue from within the try block. | 1790 // break/continue from within the try block. |
1786 enum { FALLING, THROWING, JUMPING }; | 1791 enum { FALLING, THROWING, JUMPING }; |
1787 | 1792 |
1788 Label exit, unlink, try_block, finally_block; | 1793 Label exit, unlink, try_block, finally_block; |
1789 | 1794 |
1790 __ bl(&try_block); | 1795 __ bl(&try_block); |
1791 | 1796 |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1913 frame_->Push(r0); | 1918 frame_->Push(r0); |
1914 __ CallRuntime(Runtime::kReThrow, 1); | 1919 __ CallRuntime(Runtime::kReThrow, 1); |
1915 | 1920 |
1916 // Done. | 1921 // Done. |
1917 __ bind(&exit); | 1922 __ bind(&exit); |
1918 } | 1923 } |
1919 | 1924 |
1920 | 1925 |
1921 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) { | 1926 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) { |
1922 Comment cmnt(masm_, "[ DebuggerStatament"); | 1927 Comment cmnt(masm_, "[ DebuggerStatament"); |
1923 if (FLAG_debug_info) RecordStatementPosition(node); | 1928 CodeForStatement(node); |
1924 __ CallRuntime(Runtime::kDebugBreak, 0); | 1929 __ CallRuntime(Runtime::kDebugBreak, 0); |
1925 // Ignore the return value. | 1930 // Ignore the return value. |
1926 } | 1931 } |
1927 | 1932 |
1928 | 1933 |
1929 void CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) { | 1934 void CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) { |
1930 ASSERT(boilerplate->IsBoilerplate()); | 1935 ASSERT(boilerplate->IsBoilerplate()); |
1931 | 1936 |
1932 // Push the boilerplate on the stack. | 1937 // Push the boilerplate on the stack. |
1933 __ mov(r0, Operand(boilerplate)); | 1938 __ mov(r0, Operand(boilerplate)); |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2221 // Update the write barrier for the array address. | 2226 // Update the write barrier for the array address. |
2222 __ mov(r3, Operand(offset)); | 2227 __ mov(r3, Operand(offset)); |
2223 __ RecordWrite(r1, r3, r2); | 2228 __ RecordWrite(r1, r3, r2); |
2224 } | 2229 } |
2225 } | 2230 } |
2226 } | 2231 } |
2227 | 2232 |
2228 | 2233 |
2229 void CodeGenerator::VisitAssignment(Assignment* node) { | 2234 void CodeGenerator::VisitAssignment(Assignment* node) { |
2230 Comment cmnt(masm_, "[ Assignment"); | 2235 Comment cmnt(masm_, "[ Assignment"); |
2231 if (FLAG_debug_info) RecordStatementPosition(node); | 2236 CodeForStatement(node); |
2232 | 2237 |
2233 Reference target(this, node->target()); | 2238 Reference target(this, node->target()); |
2234 if (target.is_illegal()) return; | 2239 if (target.is_illegal()) return; |
2235 | 2240 |
2236 if (node->op() == Token::ASSIGN || | 2241 if (node->op() == Token::ASSIGN || |
2237 node->op() == Token::INIT_VAR || | 2242 node->op() == Token::INIT_VAR || |
2238 node->op() == Token::INIT_CONST) { | 2243 node->op() == Token::INIT_CONST) { |
2239 Load(node->value()); | 2244 Load(node->value()); |
2240 | 2245 |
2241 } else { | 2246 } else { |
(...skipping 10 matching lines...) Expand all Loading... |
2252 } | 2257 } |
2253 } | 2258 } |
2254 | 2259 |
2255 Variable* var = node->target()->AsVariableProxy()->AsVariable(); | 2260 Variable* var = node->target()->AsVariableProxy()->AsVariable(); |
2256 if (var != NULL && | 2261 if (var != NULL && |
2257 (var->mode() == Variable::CONST) && | 2262 (var->mode() == Variable::CONST) && |
2258 node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) { | 2263 node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) { |
2259 // Assignment ignored - leave the value on the stack. | 2264 // Assignment ignored - leave the value on the stack. |
2260 | 2265 |
2261 } else { | 2266 } else { |
2262 __ RecordPosition(node->position()); | 2267 CodeForSourcePosition(node->position()); |
2263 if (node->op() == Token::INIT_CONST) { | 2268 if (node->op() == Token::INIT_CONST) { |
2264 // Dynamic constant initializations must use the function context | 2269 // Dynamic constant initializations must use the function context |
2265 // and initialize the actual constant declared. Dynamic variable | 2270 // and initialize the actual constant declared. Dynamic variable |
2266 // initializations are simply assignments and use SetValue. | 2271 // initializations are simply assignments and use SetValue. |
2267 target.SetValue(CONST_INIT); | 2272 target.SetValue(CONST_INIT); |
2268 } else { | 2273 } else { |
2269 target.SetValue(NOT_CONST_INIT); | 2274 target.SetValue(NOT_CONST_INIT); |
2270 } | 2275 } |
2271 } | 2276 } |
2272 } | 2277 } |
2273 | 2278 |
2274 | 2279 |
2275 void CodeGenerator::VisitThrow(Throw* node) { | 2280 void CodeGenerator::VisitThrow(Throw* node) { |
2276 Comment cmnt(masm_, "[ Throw"); | 2281 Comment cmnt(masm_, "[ Throw"); |
2277 | 2282 |
2278 Load(node->exception()); | 2283 Load(node->exception()); |
2279 __ RecordPosition(node->position()); | 2284 CodeForSourcePosition(node->position()); |
2280 __ CallRuntime(Runtime::kThrow, 1); | 2285 __ CallRuntime(Runtime::kThrow, 1); |
2281 frame_->Push(r0); | 2286 frame_->Push(r0); |
2282 } | 2287 } |
2283 | 2288 |
2284 | 2289 |
2285 void CodeGenerator::VisitProperty(Property* node) { | 2290 void CodeGenerator::VisitProperty(Property* node) { |
2286 Comment cmnt(masm_, "[ Property"); | 2291 Comment cmnt(masm_, "[ Property"); |
2287 | 2292 |
2288 Reference property(this, node); | 2293 Reference property(this, node); |
2289 property.GetValue(typeof_state()); | 2294 property.GetValue(typeof_state()); |
2290 } | 2295 } |
2291 | 2296 |
2292 | 2297 |
2293 void CodeGenerator::VisitCall(Call* node) { | 2298 void CodeGenerator::VisitCall(Call* node) { |
2294 Comment cmnt(masm_, "[ Call"); | 2299 Comment cmnt(masm_, "[ Call"); |
2295 | 2300 |
2296 ZoneList<Expression*>* args = node->arguments(); | 2301 ZoneList<Expression*>* args = node->arguments(); |
2297 | 2302 |
2298 RecordStatementPosition(node); | 2303 CodeForStatement(node); |
2299 // Standard function call. | 2304 // Standard function call. |
2300 | 2305 |
2301 // Check if the function is a variable or a property. | 2306 // Check if the function is a variable or a property. |
2302 Expression* function = node->expression(); | 2307 Expression* function = node->expression(); |
2303 Variable* var = function->AsVariableProxy()->AsVariable(); | 2308 Variable* var = function->AsVariableProxy()->AsVariable(); |
2304 Property* property = function->AsProperty(); | 2309 Property* property = function->AsProperty(); |
2305 | 2310 |
2306 // ------------------------------------------------------------------------ | 2311 // ------------------------------------------------------------------------ |
2307 // Fast-case: Use inline caching. | 2312 // Fast-case: Use inline caching. |
2308 // --- | 2313 // --- |
(...skipping 15 matching lines...) Expand all Loading... |
2324 // Pass the global object as the receiver and let the IC stub | 2329 // Pass the global object as the receiver and let the IC stub |
2325 // patch the stack to use the global proxy as 'this' in the | 2330 // patch the stack to use the global proxy as 'this' in the |
2326 // invoked function. | 2331 // invoked function. |
2327 LoadGlobal(); | 2332 LoadGlobal(); |
2328 | 2333 |
2329 // Load the arguments. | 2334 // Load the arguments. |
2330 for (int i = 0; i < args->length(); i++) Load(args->at(i)); | 2335 for (int i = 0; i < args->length(); i++) Load(args->at(i)); |
2331 | 2336 |
2332 // Setup the receiver register and call the IC initialization code. | 2337 // Setup the receiver register and call the IC initialization code. |
2333 Handle<Code> stub = ComputeCallInitialize(args->length()); | 2338 Handle<Code> stub = ComputeCallInitialize(args->length()); |
2334 __ RecordPosition(node->position()); | 2339 CodeForSourcePosition(node->position()); |
2335 __ Call(stub, RelocInfo::CODE_TARGET_CONTEXT); | 2340 __ Call(stub, RelocInfo::CODE_TARGET_CONTEXT); |
2336 __ ldr(cp, frame_->Context()); | 2341 __ ldr(cp, frame_->Context()); |
2337 // Remove the function from the stack. | 2342 // Remove the function from the stack. |
2338 frame_->Pop(); | 2343 frame_->Pop(); |
2339 frame_->Push(r0); | 2344 frame_->Push(r0); |
2340 | 2345 |
2341 } else if (var != NULL && var->slot() != NULL && | 2346 } else if (var != NULL && var->slot() != NULL && |
2342 var->slot()->type() == Slot::LOOKUP) { | 2347 var->slot()->type() == Slot::LOOKUP) { |
2343 // ---------------------------------- | 2348 // ---------------------------------- |
2344 // JavaScript example: 'with (obj) foo(1, 2, 3)' // foo is in obj | 2349 // JavaScript example: 'with (obj) foo(1, 2, 3)' // foo is in obj |
(...skipping 26 matching lines...) Expand all Loading... |
2371 // Push the name of the function and the receiver onto the stack. | 2376 // Push the name of the function and the receiver onto the stack. |
2372 __ mov(r0, Operand(literal->handle())); | 2377 __ mov(r0, Operand(literal->handle())); |
2373 frame_->Push(r0); | 2378 frame_->Push(r0); |
2374 Load(property->obj()); | 2379 Load(property->obj()); |
2375 | 2380 |
2376 // Load the arguments. | 2381 // Load the arguments. |
2377 for (int i = 0; i < args->length(); i++) Load(args->at(i)); | 2382 for (int i = 0; i < args->length(); i++) Load(args->at(i)); |
2378 | 2383 |
2379 // Set the receiver register and call the IC initialization code. | 2384 // Set the receiver register and call the IC initialization code. |
2380 Handle<Code> stub = ComputeCallInitialize(args->length()); | 2385 Handle<Code> stub = ComputeCallInitialize(args->length()); |
2381 __ RecordPosition(node->position()); | 2386 CodeForSourcePosition(node->position()); |
2382 __ Call(stub, RelocInfo::CODE_TARGET); | 2387 __ Call(stub, RelocInfo::CODE_TARGET); |
2383 __ ldr(cp, frame_->Context()); | 2388 __ ldr(cp, frame_->Context()); |
2384 | 2389 |
2385 // Remove the function from the stack. | 2390 // Remove the function from the stack. |
2386 frame_->Pop(); | 2391 frame_->Pop(); |
2387 | 2392 |
2388 frame_->Push(r0); // push after get rid of function from the stack | 2393 frame_->Push(r0); // push after get rid of function from the stack |
2389 | 2394 |
2390 } else { | 2395 } else { |
2391 // ------------------------------------------- | 2396 // ------------------------------------------- |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2425 void CodeGenerator::VisitCallEval(CallEval* node) { | 2430 void CodeGenerator::VisitCallEval(CallEval* node) { |
2426 Comment cmnt(masm_, "[ CallEval"); | 2431 Comment cmnt(masm_, "[ CallEval"); |
2427 | 2432 |
2428 // In a call to eval, we first call %ResolvePossiblyDirectEval to resolve | 2433 // In a call to eval, we first call %ResolvePossiblyDirectEval to resolve |
2429 // the function we need to call and the receiver of the call. | 2434 // the function we need to call and the receiver of the call. |
2430 // Then we call the resolved function using the given arguments. | 2435 // Then we call the resolved function using the given arguments. |
2431 | 2436 |
2432 ZoneList<Expression*>* args = node->arguments(); | 2437 ZoneList<Expression*>* args = node->arguments(); |
2433 Expression* function = node->expression(); | 2438 Expression* function = node->expression(); |
2434 | 2439 |
2435 RecordStatementPosition(node); | 2440 CodeForStatement(node); |
2436 | 2441 |
2437 // Prepare stack for call to resolved function. | 2442 // Prepare stack for call to resolved function. |
2438 Load(function); | 2443 Load(function); |
2439 __ mov(r2, Operand(Factory::undefined_value())); | 2444 __ mov(r2, Operand(Factory::undefined_value())); |
2440 __ push(r2); // Slot for receiver | 2445 __ push(r2); // Slot for receiver |
2441 for (int i = 0; i < args->length(); i++) { | 2446 for (int i = 0; i < args->length(); i++) { |
2442 Load(args->at(i)); | 2447 Load(args->at(i)); |
2443 } | 2448 } |
2444 | 2449 |
2445 // Prepare stack for call to ResolvePossiblyDirectEval. | 2450 // Prepare stack for call to ResolvePossiblyDirectEval. |
2446 __ ldr(r1, MemOperand(sp, args->length() * kPointerSize + kPointerSize)); | 2451 __ ldr(r1, MemOperand(sp, args->length() * kPointerSize + kPointerSize)); |
2447 __ push(r1); | 2452 __ push(r1); |
2448 if (args->length() > 0) { | 2453 if (args->length() > 0) { |
2449 __ ldr(r1, MemOperand(sp, args->length() * kPointerSize)); | 2454 __ ldr(r1, MemOperand(sp, args->length() * kPointerSize)); |
2450 __ push(r1); | 2455 __ push(r1); |
2451 } else { | 2456 } else { |
2452 __ push(r2); | 2457 __ push(r2); |
2453 } | 2458 } |
2454 | 2459 |
2455 // Resolve the call. | 2460 // Resolve the call. |
2456 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 2); | 2461 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 2); |
2457 | 2462 |
2458 // Touch up stack with the right values for the function and the receiver. | 2463 // Touch up stack with the right values for the function and the receiver. |
2459 __ ldr(r1, FieldMemOperand(r0, FixedArray::kHeaderSize)); | 2464 __ ldr(r1, FieldMemOperand(r0, FixedArray::kHeaderSize)); |
2460 __ str(r1, MemOperand(sp, (args->length() + 1) * kPointerSize)); | 2465 __ str(r1, MemOperand(sp, (args->length() + 1) * kPointerSize)); |
2461 __ ldr(r1, FieldMemOperand(r0, FixedArray::kHeaderSize + kPointerSize)); | 2466 __ ldr(r1, FieldMemOperand(r0, FixedArray::kHeaderSize + kPointerSize)); |
2462 __ str(r1, MemOperand(sp, args->length() * kPointerSize)); | 2467 __ str(r1, MemOperand(sp, args->length() * kPointerSize)); |
2463 | 2468 |
2464 // Call the function. | 2469 // Call the function. |
2465 __ RecordPosition(node->position()); | 2470 CodeForSourcePosition(node->position()); |
2466 | 2471 |
2467 CallFunctionStub call_function(args->length()); | 2472 CallFunctionStub call_function(args->length()); |
2468 __ CallStub(&call_function); | 2473 __ CallStub(&call_function); |
2469 | 2474 |
2470 __ ldr(cp, frame_->Context()); | 2475 __ ldr(cp, frame_->Context()); |
2471 // Remove the function from the stack. | 2476 // Remove the function from the stack. |
2472 frame_->Pop(); | 2477 frame_->Pop(); |
2473 frame_->Push(r0); | 2478 frame_->Push(r0); |
2474 } | 2479 } |
2475 | 2480 |
2476 | 2481 |
2477 void CodeGenerator::VisitCallNew(CallNew* node) { | 2482 void CodeGenerator::VisitCallNew(CallNew* node) { |
2478 Comment cmnt(masm_, "[ CallNew"); | 2483 Comment cmnt(masm_, "[ CallNew"); |
| 2484 CodeForStatement(node); |
2479 | 2485 |
2480 // According to ECMA-262, section 11.2.2, page 44, the function | 2486 // According to ECMA-262, section 11.2.2, page 44, the function |
2481 // expression in new calls must be evaluated before the | 2487 // expression in new calls must be evaluated before the |
2482 // arguments. This is different from ordinary calls, where the | 2488 // arguments. This is different from ordinary calls, where the |
2483 // actual function to call is resolved after the arguments have been | 2489 // actual function to call is resolved after the arguments have been |
2484 // evaluated. | 2490 // evaluated. |
2485 | 2491 |
2486 // Compute function to call and use the global object as the | 2492 // Compute function to call and use the global object as the |
2487 // receiver. There is no need to use the global proxy here because | 2493 // receiver. There is no need to use the global proxy here because |
2488 // it will always be replaced with a newly allocated object. | 2494 // it will always be replaced with a newly allocated object. |
2489 Load(node->expression()); | 2495 Load(node->expression()); |
2490 LoadGlobal(); | 2496 LoadGlobal(); |
2491 | 2497 |
2492 // Push the arguments ("left-to-right") on the stack. | 2498 // Push the arguments ("left-to-right") on the stack. |
2493 ZoneList<Expression*>* args = node->arguments(); | 2499 ZoneList<Expression*>* args = node->arguments(); |
2494 for (int i = 0; i < args->length(); i++) Load(args->at(i)); | 2500 for (int i = 0; i < args->length(); i++) Load(args->at(i)); |
2495 | 2501 |
2496 // r0: the number of arguments. | 2502 // r0: the number of arguments. |
2497 __ mov(r0, Operand(args->length())); | 2503 __ mov(r0, Operand(args->length())); |
2498 | 2504 |
2499 // Load the function into r1 as per calling convention. | 2505 // Load the function into r1 as per calling convention. |
2500 __ ldr(r1, frame_->Element(args->length() + 1)); | 2506 __ ldr(r1, frame_->Element(args->length() + 1)); |
2501 | 2507 |
2502 // Call the construct call builtin that handles allocation and | 2508 // Call the construct call builtin that handles allocation and |
2503 // constructor invocation. | 2509 // constructor invocation. |
2504 __ RecordPosition(RelocInfo::POSITION); | 2510 CodeForSourcePosition(node->position()); |
2505 __ Call(Handle<Code>(Builtins::builtin(Builtins::JSConstructCall)), | 2511 __ Call(Handle<Code>(Builtins::builtin(Builtins::JSConstructCall)), |
2506 RelocInfo::CONSTRUCT_CALL); | 2512 RelocInfo::CONSTRUCT_CALL); |
2507 | 2513 |
2508 // Discard old TOS value and push r0 on the stack (same as Pop(), push(r0)). | 2514 // Discard old TOS value and push r0 on the stack (same as Pop(), push(r0)). |
2509 __ str(r0, frame_->Top()); | 2515 __ str(r0, frame_->Top()); |
2510 } | 2516 } |
2511 | 2517 |
2512 | 2518 |
2513 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) { | 2519 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) { |
2514 ASSERT(args->length() == 1); | 2520 ASSERT(args->length() == 1); |
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3200 __ tst(r0, Operand(r0)); | 3206 __ tst(r0, Operand(r0)); |
3201 cc_reg_ = eq; | 3207 cc_reg_ = eq; |
3202 break; | 3208 break; |
3203 | 3209 |
3204 default: | 3210 default: |
3205 UNREACHABLE(); | 3211 UNREACHABLE(); |
3206 } | 3212 } |
3207 } | 3213 } |
3208 | 3214 |
3209 | 3215 |
3210 void CodeGenerator::RecordStatementPosition(Node* node) { | |
3211 if (FLAG_debug_info) { | |
3212 int statement_pos = node->statement_pos(); | |
3213 if (statement_pos == RelocInfo::kNoPosition) return; | |
3214 __ RecordStatementPosition(statement_pos); | |
3215 } | |
3216 } | |
3217 | |
3218 | |
3219 #undef __ | 3216 #undef __ |
3220 #define __ masm-> | 3217 #define __ masm-> |
3221 | 3218 |
3222 Handle<String> Reference::GetName() { | 3219 Handle<String> Reference::GetName() { |
3223 ASSERT(type_ == NAMED); | 3220 ASSERT(type_ == NAMED); |
3224 Property* property = expression_->AsProperty(); | 3221 Property* property = expression_->AsProperty(); |
3225 if (property == NULL) { | 3222 if (property == NULL) { |
3226 // Global variable reference treated as a named property reference. | 3223 // Global variable reference treated as a named property reference. |
3227 VariableProxy* proxy = expression_->AsVariableProxy(); | 3224 VariableProxy* proxy = expression_->AsVariableProxy(); |
3228 ASSERT(proxy->AsVariable() != NULL); | 3225 ASSERT(proxy->AsVariable() != NULL); |
3229 ASSERT(proxy->AsVariable()->is_global()); | 3226 ASSERT(proxy->AsVariable()->is_global()); |
3230 return proxy->name(); | 3227 return proxy->name(); |
3231 } else { | 3228 } else { |
3232 Literal* raw_name = property->key()->AsLiteral(); | 3229 Literal* raw_name = property->key()->AsLiteral(); |
3233 ASSERT(raw_name != NULL); | 3230 ASSERT(raw_name != NULL); |
3234 return Handle<String>(String::cast(*raw_name->handle())); | 3231 return Handle<String>(String::cast(*raw_name->handle())); |
3235 } | 3232 } |
3236 } | 3233 } |
3237 | 3234 |
3238 | 3235 |
3239 void Reference::GetValue(TypeofState typeof_state) { | 3236 void Reference::GetValue(TypeofState typeof_state) { |
3240 ASSERT(!is_illegal()); | 3237 ASSERT(!is_illegal()); |
3241 ASSERT(!cgen_->has_cc()); | 3238 ASSERT(!cgen_->has_cc()); |
3242 MacroAssembler* masm = cgen_->masm(); | 3239 MacroAssembler* masm = cgen_->masm(); |
3243 VirtualFrame* frame = cgen_->frame(); | 3240 VirtualFrame* frame = cgen_->frame(); |
3244 Property* property = expression_->AsProperty(); | 3241 Property* property = expression_->AsProperty(); |
3245 if (property != NULL) { | 3242 if (property != NULL) { |
3246 __ RecordPosition(property->position()); | 3243 cgen_->CodeForSourcePosition(property->position()); |
3247 } | 3244 } |
3248 | 3245 |
3249 switch (type_) { | 3246 switch (type_) { |
3250 case SLOT: { | 3247 case SLOT: { |
3251 Comment cmnt(masm, "[ Load from Slot"); | 3248 Comment cmnt(masm, "[ Load from Slot"); |
3252 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot(); | 3249 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot(); |
3253 ASSERT(slot != NULL); | 3250 ASSERT(slot != NULL); |
3254 cgen_->LoadFromSlot(slot, typeof_state); | 3251 cgen_->LoadFromSlot(slot, typeof_state); |
3255 break; | 3252 break; |
3256 } | 3253 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3302 } | 3299 } |
3303 | 3300 |
3304 | 3301 |
3305 void Reference::SetValue(InitState init_state) { | 3302 void Reference::SetValue(InitState init_state) { |
3306 ASSERT(!is_illegal()); | 3303 ASSERT(!is_illegal()); |
3307 ASSERT(!cgen_->has_cc()); | 3304 ASSERT(!cgen_->has_cc()); |
3308 MacroAssembler* masm = cgen_->masm(); | 3305 MacroAssembler* masm = cgen_->masm(); |
3309 VirtualFrame* frame = cgen_->frame(); | 3306 VirtualFrame* frame = cgen_->frame(); |
3310 Property* property = expression_->AsProperty(); | 3307 Property* property = expression_->AsProperty(); |
3311 if (property != NULL) { | 3308 if (property != NULL) { |
3312 __ RecordPosition(property->position()); | 3309 cgen_->CodeForSourcePosition(property->position()); |
3313 } | 3310 } |
3314 | 3311 |
3315 switch (type_) { | 3312 switch (type_) { |
3316 case SLOT: { | 3313 case SLOT: { |
3317 Comment cmnt(masm, "[ Store to Slot"); | 3314 Comment cmnt(masm, "[ Store to Slot"); |
3318 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot(); | 3315 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot(); |
3319 ASSERT(slot != NULL); | 3316 ASSERT(slot != NULL); |
3320 if (slot->type() == Slot::LOOKUP) { | 3317 if (slot->type() == Slot::LOOKUP) { |
3321 ASSERT(slot->var()->mode() == Variable::DYNAMIC); | 3318 ASSERT(slot->var()->mode() == Variable::DYNAMIC); |
3322 | 3319 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3405 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 3402 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
3406 __ Call(ic, RelocInfo::CODE_TARGET); | 3403 __ Call(ic, RelocInfo::CODE_TARGET); |
3407 frame->Push(r0); | 3404 frame->Push(r0); |
3408 break; | 3405 break; |
3409 } | 3406 } |
3410 | 3407 |
3411 case KEYED: { | 3408 case KEYED: { |
3412 Comment cmnt(masm, "[ Store to keyed Property"); | 3409 Comment cmnt(masm, "[ Store to keyed Property"); |
3413 Property* property = expression_->AsProperty(); | 3410 Property* property = expression_->AsProperty(); |
3414 ASSERT(property != NULL); | 3411 ASSERT(property != NULL); |
3415 __ RecordPosition(property->position()); | 3412 cgen_->CodeForSourcePosition(property->position()); |
3416 | 3413 |
3417 // Call IC code. | 3414 // Call IC code. |
3418 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 3415 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
3419 // TODO(1222589): Make the IC grab the values from the stack. | 3416 // TODO(1222589): Make the IC grab the values from the stack. |
3420 frame->Pop(r0); // value | 3417 frame->Pop(r0); // value |
3421 __ Call(ic, RelocInfo::CODE_TARGET); | 3418 __ Call(ic, RelocInfo::CODE_TARGET); |
3422 frame->Push(r0); | 3419 frame->Push(r0); |
3423 break; | 3420 break; |
3424 } | 3421 } |
3425 | 3422 |
(...skipping 905 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4331 __ mov(r2, Operand(0)); | 4328 __ mov(r2, Operand(0)); |
4332 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); | 4329 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); |
4333 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), | 4330 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), |
4334 RelocInfo::CODE_TARGET); | 4331 RelocInfo::CODE_TARGET); |
4335 } | 4332 } |
4336 | 4333 |
4337 | 4334 |
4338 #undef __ | 4335 #undef __ |
4339 | 4336 |
4340 } } // namespace v8::internal | 4337 } } // namespace v8::internal |
OLD | NEW |