Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(287)

Side by Side Diff: src/codegen-arm.cc

Issue 20533: Experimental: fix a frame-height issue with eval on ARM. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: '' Created 11 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/codegen.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 // (partially) translated into branches, or it may have set the condition 375 // (partially) translated into branches, or it may have set the condition
376 // code register. If force_cc is set, the value is forced to set the 376 // code register. If force_cc is set, the value is forced to set the
377 // condition code register and no value is pushed. If the condition code 377 // condition code register and no value is pushed. If the condition code
378 // register was set, has_cc() is true and cc_reg_ contains the condition to 378 // register was set, has_cc() is true and cc_reg_ contains the condition to
379 // test for 'true'. 379 // test for 'true'.
380 void CodeGenerator::LoadCondition(Expression* x, 380 void CodeGenerator::LoadCondition(Expression* x,
381 TypeofState typeof_state, 381 TypeofState typeof_state,
382 JumpTarget* true_target, 382 JumpTarget* true_target,
383 JumpTarget* false_target, 383 JumpTarget* false_target,
384 bool force_cc) { 384 bool force_cc) {
385 #ifdef DEBUG
386 int original_height = frame_->height();
387 #endif
385 ASSERT(!in_spilled_code()); 388 ASSERT(!in_spilled_code());
386 ASSERT(!has_cc()); 389 ASSERT(!has_cc());
387 390
388 { CodeGenState new_state(this, typeof_state, true_target, false_target); 391 { CodeGenState new_state(this, typeof_state, true_target, false_target);
389 Visit(x); 392 Visit(x);
390 } 393 }
391 if (force_cc && frame_ != NULL && !has_cc()) { 394 if (force_cc && frame_ != NULL && !has_cc()) {
392 // Convert the TOS value to a boolean in the condition code register. 395 // Convert the TOS value to a boolean in the condition code register.
393 ToBoolean(true_target, false_target); 396 ToBoolean(true_target, false_target);
394 } 397 }
395 ASSERT(!force_cc || frame_ == NULL || has_cc()); 398 ASSERT(!force_cc || !has_valid_frame() || has_cc());
399 ASSERT(!has_valid_frame() ||
400 (has_cc() && frame_->height() == original_height) ||
401 (!has_cc() && frame_->height() == original_height + 1));
396 } 402 }
397 403
398 404
399 void CodeGenerator::Load(Expression* x, TypeofState typeof_state) { 405 void CodeGenerator::Load(Expression* x, TypeofState typeof_state) {
406 #ifdef DEBUG
407 int original_height = frame_->height();
408 #endif
400 ASSERT(!in_spilled_code()); 409 ASSERT(!in_spilled_code());
401 JumpTarget true_target(this); 410 JumpTarget true_target(this);
402 JumpTarget false_target(this); 411 JumpTarget false_target(this);
403 LoadCondition(x, typeof_state, &true_target, &false_target, false); 412 LoadCondition(x, typeof_state, &true_target, &false_target, false);
404 413
405 if (has_cc()) { 414 if (has_cc()) {
406 // Convert cc_reg_ into a boolean value. 415 // Convert cc_reg_ into a boolean value.
407 JumpTarget loaded(this); 416 JumpTarget loaded(this);
408 JumpTarget materialize_true(this); 417 JumpTarget materialize_true(this);
409 materialize_true.Branch(cc_reg_); 418 materialize_true.Branch(cc_reg_);
(...skipping 28 matching lines...) Expand all
438 } 447 }
439 // Load "false" if necessary. 448 // Load "false" if necessary.
440 if (false_target.is_linked()) { 449 if (false_target.is_linked()) {
441 false_target.Bind(); 450 false_target.Bind();
442 __ mov(r0, Operand(Factory::false_value())); 451 __ mov(r0, Operand(Factory::false_value()));
443 frame_->EmitPush(r0); 452 frame_->EmitPush(r0);
444 } 453 }
445 // A value is loaded on all paths reaching this point. 454 // A value is loaded on all paths reaching this point.
446 loaded.Bind(); 455 loaded.Bind();
447 } 456 }
448 ASSERT(frame_ != NULL); 457 ASSERT(has_valid_frame());
449 ASSERT(!has_cc()); 458 ASSERT(!has_cc());
459 ASSERT(frame_->height() == original_height + 1);
450 } 460 }
451 461
452 462
453 void CodeGenerator::LoadGlobal() { 463 void CodeGenerator::LoadGlobal() {
454 VirtualFrame::SpilledScope spilled_scope(this); 464 VirtualFrame::SpilledScope spilled_scope(this);
455 __ ldr(r0, GlobalObject()); 465 __ ldr(r0, GlobalObject());
456 frame_->EmitPush(r0); 466 frame_->EmitPush(r0);
457 } 467 }
458 468
459 469
(...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after
1078 VirtualFrame::SpilledScope spilled_scope(this); 1088 VirtualFrame::SpilledScope spilled_scope(this);
1079 if (FLAG_check_stack) { 1089 if (FLAG_check_stack) {
1080 Comment cmnt(masm_, "[ check stack"); 1090 Comment cmnt(masm_, "[ check stack");
1081 StackCheckStub stub; 1091 StackCheckStub stub;
1082 frame_->CallStub(&stub, 0); 1092 frame_->CallStub(&stub, 0);
1083 } 1093 }
1084 } 1094 }
1085 1095
1086 1096
1087 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { 1097 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) {
1098 #ifdef DEBUG
1099 int original_height = frame_->height();
1100 #endif
1088 VirtualFrame::SpilledScope spilled_scope(this); 1101 VirtualFrame::SpilledScope spilled_scope(this);
1089 for (int i = 0; frame_ != NULL && i < statements->length(); i++) { 1102 for (int i = 0; frame_ != NULL && i < statements->length(); i++) {
1090 VisitAndSpill(statements->at(i)); 1103 VisitAndSpill(statements->at(i));
1091 } 1104 }
1105 ASSERT(!has_valid_frame() || frame_->height() == original_height);
1092 } 1106 }
1093 1107
1094 1108
1095 void CodeGenerator::VisitBlock(Block* node) { 1109 void CodeGenerator::VisitBlock(Block* node) {
1110 #ifdef DEBUG
1111 int original_height = frame_->height();
1112 #endif
1096 VirtualFrame::SpilledScope spilled_scope(this); 1113 VirtualFrame::SpilledScope spilled_scope(this);
1097 Comment cmnt(masm_, "[ Block"); 1114 Comment cmnt(masm_, "[ Block");
1098 CodeForStatementPosition(node); 1115 CodeForStatementPosition(node);
1099 node->set_break_stack_height(break_stack_height_); 1116 node->set_break_stack_height(break_stack_height_);
1100 node->break_target()->Initialize(this); 1117 node->break_target()->Initialize(this);
1101 VisitStatementsAndSpill(node->statements()); 1118 VisitStatementsAndSpill(node->statements());
1102 if (node->break_target()->is_linked()) { 1119 if (node->break_target()->is_linked()) {
1103 node->break_target()->Bind(); 1120 node->break_target()->Bind();
1104 } 1121 }
1122 ASSERT(!has_valid_frame() || frame_->height() == original_height);
1105 } 1123 }
1106 1124
1107 1125
1108 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 1126 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
1109 VirtualFrame::SpilledScope spilled_scope(this); 1127 VirtualFrame::SpilledScope spilled_scope(this);
1110 __ mov(r0, Operand(pairs)); 1128 __ mov(r0, Operand(pairs));
1111 frame_->EmitPush(r0); 1129 frame_->EmitPush(r0);
1112 frame_->EmitPush(cp); 1130 frame_->EmitPush(cp);
1113 __ mov(r0, Operand(Smi::FromInt(is_eval() ? 1 : 0))); 1131 __ mov(r0, Operand(Smi::FromInt(is_eval() ? 1 : 0)));
1114 frame_->EmitPush(r0); 1132 frame_->EmitPush(r0);
1115 frame_->CallRuntime(Runtime::kDeclareGlobals, 3); 1133 frame_->CallRuntime(Runtime::kDeclareGlobals, 3);
1116 // The result is discarded. 1134 // The result is discarded.
1117 } 1135 }
1118 1136
1119 1137
1120 void CodeGenerator::VisitDeclaration(Declaration* node) { 1138 void CodeGenerator::VisitDeclaration(Declaration* node) {
1139 #ifdef DEBUG
1140 int original_height = frame_->height();
1141 #endif
1121 VirtualFrame::SpilledScope spilled_scope(this); 1142 VirtualFrame::SpilledScope spilled_scope(this);
1122 Comment cmnt(masm_, "[ Declaration"); 1143 Comment cmnt(masm_, "[ Declaration");
1123 CodeForStatementPosition(node); 1144 CodeForStatementPosition(node);
1124 Variable* var = node->proxy()->var(); 1145 Variable* var = node->proxy()->var();
1125 ASSERT(var != NULL); // must have been resolved 1146 ASSERT(var != NULL); // must have been resolved
1126 Slot* slot = var->slot(); 1147 Slot* slot = var->slot();
1127 1148
1128 // If it was not possible to allocate the variable at compile time, 1149 // If it was not possible to allocate the variable at compile time,
1129 // we need to "declare" it at runtime to make sure it actually 1150 // we need to "declare" it at runtime to make sure it actually
1130 // exists in the local context. 1151 // exists in the local context.
(...skipping 18 matching lines...) Expand all
1149 __ mov(r0, Operand(Factory::the_hole_value())); 1170 __ mov(r0, Operand(Factory::the_hole_value()));
1150 frame_->EmitPush(r0); 1171 frame_->EmitPush(r0);
1151 } else if (node->fun() != NULL) { 1172 } else if (node->fun() != NULL) {
1152 LoadAndSpill(node->fun()); 1173 LoadAndSpill(node->fun());
1153 } else { 1174 } else {
1154 __ mov(r0, Operand(0)); // no initial value! 1175 __ mov(r0, Operand(0)); // no initial value!
1155 frame_->EmitPush(r0); 1176 frame_->EmitPush(r0);
1156 } 1177 }
1157 frame_->CallRuntime(Runtime::kDeclareContextSlot, 4); 1178 frame_->CallRuntime(Runtime::kDeclareContextSlot, 4);
1158 // Ignore the return value (declarations are statements). 1179 // Ignore the return value (declarations are statements).
1180 ASSERT(frame_->height() == original_height);
1159 return; 1181 return;
1160 } 1182 }
1161 1183
1162 ASSERT(!var->is_global()); 1184 ASSERT(!var->is_global());
1163 1185
1164 // If we have a function or a constant, we need to initialize the variable. 1186 // If we have a function or a constant, we need to initialize the variable.
1165 Expression* val = NULL; 1187 Expression* val = NULL;
1166 if (node->mode() == Variable::CONST) { 1188 if (node->mode() == Variable::CONST) {
1167 val = new Literal(Factory::the_hole_value()); 1189 val = new Literal(Factory::the_hole_value());
1168 } else { 1190 } else {
1169 val = node->fun(); // NULL if we don't have a function 1191 val = node->fun(); // NULL if we don't have a function
1170 } 1192 }
1171 1193
1172 if (val != NULL) { 1194 if (val != NULL) {
1173 { 1195 {
1174 // Set initial value. 1196 // Set initial value.
1175 Reference target(this, node->proxy()); 1197 Reference target(this, node->proxy());
1176 LoadAndSpill(val); 1198 LoadAndSpill(val);
1177 target.SetValue(NOT_CONST_INIT); 1199 target.SetValue(NOT_CONST_INIT);
1178 // The reference is removed from the stack (preserving TOS) when 1200 // The reference is removed from the stack (preserving TOS) when
1179 // it goes out of scope. 1201 // it goes out of scope.
1180 } 1202 }
1181 // Get rid of the assigned value (declarations are statements). 1203 // Get rid of the assigned value (declarations are statements).
1182 frame_->Drop(); 1204 frame_->Drop();
1183 } 1205 }
1206 ASSERT(frame_->height() == original_height);
1184 } 1207 }
1185 1208
1186 1209
1187 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) { 1210 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) {
1211 #ifdef DEBUG
1212 int original_height = frame_->height();
1213 #endif
1188 VirtualFrame::SpilledScope spilled_scope(this); 1214 VirtualFrame::SpilledScope spilled_scope(this);
1189 Comment cmnt(masm_, "[ ExpressionStatement"); 1215 Comment cmnt(masm_, "[ ExpressionStatement");
1190 CodeForStatementPosition(node); 1216 CodeForStatementPosition(node);
1191 Expression* expression = node->expression(); 1217 Expression* expression = node->expression();
1192 expression->MarkAsStatement(); 1218 expression->MarkAsStatement();
1193 LoadAndSpill(expression); 1219 LoadAndSpill(expression);
1194 frame_->Drop(); 1220 frame_->Drop();
1221 ASSERT(frame_->height() == original_height);
1195 } 1222 }
1196 1223
1197 1224
1198 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) { 1225 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) {
1226 #ifdef DEBUG
1227 int original_height = frame_->height();
1228 #endif
1199 VirtualFrame::SpilledScope spilled_scope(this); 1229 VirtualFrame::SpilledScope spilled_scope(this);
1200 Comment cmnt(masm_, "// EmptyStatement"); 1230 Comment cmnt(masm_, "// EmptyStatement");
1201 CodeForStatementPosition(node); 1231 CodeForStatementPosition(node);
1202 // nothing to do 1232 // nothing to do
1233 ASSERT(frame_->height() == original_height);
1203 } 1234 }
1204 1235
1205 1236
1206 void CodeGenerator::VisitIfStatement(IfStatement* node) { 1237 void CodeGenerator::VisitIfStatement(IfStatement* node) {
1238 #ifdef DEBUG
1239 int original_height = frame_->height();
1240 #endif
1207 VirtualFrame::SpilledScope spilled_scope(this); 1241 VirtualFrame::SpilledScope spilled_scope(this);
1208 Comment cmnt(masm_, "[ IfStatement"); 1242 Comment cmnt(masm_, "[ IfStatement");
1209 // Generate different code depending on which parts of the if statement 1243 // Generate different code depending on which parts of the if statement
1210 // are present or not. 1244 // are present or not.
1211 bool has_then_stm = node->HasThenStatement(); 1245 bool has_then_stm = node->HasThenStatement();
1212 bool has_else_stm = node->HasElseStatement(); 1246 bool has_else_stm = node->HasElseStatement();
1213 1247
1214 CodeForStatementPosition(node); 1248 CodeForStatementPosition(node);
1215 1249
1216 JumpTarget exit(this); 1250 JumpTarget exit(this);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1282 } else { 1316 } else {
1283 frame_->Drop(); 1317 frame_->Drop();
1284 } 1318 }
1285 } 1319 }
1286 } 1320 }
1287 1321
1288 // end 1322 // end
1289 if (exit.is_linked()) { 1323 if (exit.is_linked()) {
1290 exit.Bind(); 1324 exit.Bind();
1291 } 1325 }
1326 ASSERT(!has_valid_frame() || frame_->height() == original_height);
1292 } 1327 }
1293 1328
1294 1329
1295 void CodeGenerator::CleanStack(int num_bytes) { 1330 void CodeGenerator::CleanStack(int num_bytes) {
1296 VirtualFrame::SpilledScope spilled_scope(this); 1331 VirtualFrame::SpilledScope spilled_scope(this);
1297 ASSERT(num_bytes % kPointerSize == 0); 1332 ASSERT(num_bytes % kPointerSize == 0);
1298 frame_->Drop(num_bytes / kPointerSize); 1333 frame_->Drop(num_bytes / kPointerSize);
1299 } 1334 }
1300 1335
1301 1336
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1335 // returning thus making it easier to merge. 1370 // returning thus making it easier to merge.
1336 frame_->EmitPop(r0); 1371 frame_->EmitPop(r0);
1337 frame_->PrepareForReturn(); 1372 frame_->PrepareForReturn();
1338 1373
1339 function_return_.Jump(); 1374 function_return_.Jump();
1340 } 1375 }
1341 } 1376 }
1342 1377
1343 1378
1344 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) { 1379 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) {
1380 #ifdef DEBUG
1381 int original_height = frame_->height();
1382 #endif
1345 VirtualFrame::SpilledScope spilled_scope(this); 1383 VirtualFrame::SpilledScope spilled_scope(this);
1346 Comment cmnt(masm_, "[ WithEnterStatement"); 1384 Comment cmnt(masm_, "[ WithEnterStatement");
1347 CodeForStatementPosition(node); 1385 CodeForStatementPosition(node);
1348 LoadAndSpill(node->expression()); 1386 LoadAndSpill(node->expression());
1349 if (node->is_catch_block()) { 1387 if (node->is_catch_block()) {
1350 frame_->CallRuntime(Runtime::kPushCatchContext, 1); 1388 frame_->CallRuntime(Runtime::kPushCatchContext, 1);
1351 } else { 1389 } else {
1352 frame_->CallRuntime(Runtime::kPushContext, 1); 1390 frame_->CallRuntime(Runtime::kPushContext, 1);
1353 } 1391 }
1354 if (kDebug) { 1392 if (kDebug) {
1355 JumpTarget verified_true(this); 1393 JumpTarget verified_true(this);
1356 __ cmp(r0, Operand(cp)); 1394 __ cmp(r0, Operand(cp));
1357 verified_true.Branch(eq); 1395 verified_true.Branch(eq);
1358 __ stop("PushContext: r0 is expected to be the same as cp"); 1396 __ stop("PushContext: r0 is expected to be the same as cp");
1359 verified_true.Bind(); 1397 verified_true.Bind();
1360 } 1398 }
1361 // Update context local. 1399 // Update context local.
1362 __ str(cp, frame_->Context()); 1400 __ str(cp, frame_->Context());
1401 ASSERT(frame_->height() == original_height);
1363 } 1402 }
1364 1403
1365 1404
1366 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) { 1405 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) {
1406 #ifdef DEBUG
1407 int original_height = frame_->height();
1408 #endif
1367 VirtualFrame::SpilledScope spilled_scope(this); 1409 VirtualFrame::SpilledScope spilled_scope(this);
1368 Comment cmnt(masm_, "[ WithExitStatement"); 1410 Comment cmnt(masm_, "[ WithExitStatement");
1369 CodeForStatementPosition(node); 1411 CodeForStatementPosition(node);
1370 // Pop context. 1412 // Pop context.
1371 __ ldr(cp, ContextOperand(cp, Context::PREVIOUS_INDEX)); 1413 __ ldr(cp, ContextOperand(cp, Context::PREVIOUS_INDEX));
1372 // Update context local. 1414 // Update context local.
1373 __ str(cp, frame_->Context()); 1415 __ str(cp, frame_->Context());
1416 ASSERT(frame_->height() == original_height);
1374 } 1417 }
1375 1418
1376 1419
1377 int CodeGenerator::FastCaseSwitchMaxOverheadFactor() { 1420 int CodeGenerator::FastCaseSwitchMaxOverheadFactor() {
1378 return kFastSwitchMaxOverheadFactor; 1421 return kFastSwitchMaxOverheadFactor;
1379 } 1422 }
1380 1423
1381 int CodeGenerator::FastCaseSwitchMinCaseCount() { 1424 int CodeGenerator::FastCaseSwitchMinCaseCount() {
1382 return kFastSwitchMinCaseCount; 1425 return kFastSwitchMinCaseCount;
1383 } 1426 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1431 // Table containing branch operations. 1474 // Table containing branch operations.
1432 for (int i = 0; i < range; i++) { 1475 for (int i = 0; i < range; i++) {
1433 __ jmp(case_targets[i]); 1476 __ jmp(case_targets[i]);
1434 } 1477 }
1435 GenerateFastCaseSwitchCases(node, case_labels, start_frame); 1478 GenerateFastCaseSwitchCases(node, case_labels, start_frame);
1436 delete start_frame; 1479 delete start_frame;
1437 } 1480 }
1438 1481
1439 1482
1440 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) { 1483 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) {
1484 #ifdef DEBUG
1485 int original_height = frame_->height();
1486 #endif
1441 VirtualFrame::SpilledScope spilled_scope(this); 1487 VirtualFrame::SpilledScope spilled_scope(this);
1442 Comment cmnt(masm_, "[ SwitchStatement"); 1488 Comment cmnt(masm_, "[ SwitchStatement");
1443 CodeForStatementPosition(node); 1489 CodeForStatementPosition(node);
1444 node->set_break_stack_height(break_stack_height_); 1490 node->set_break_stack_height(break_stack_height_);
1445 node->break_target()->Initialize(this); 1491 node->break_target()->Initialize(this);
1446 1492
1447 LoadAndSpill(node->tag()); 1493 LoadAndSpill(node->tag());
1448 if (TryGenerateFastCaseSwitchStatement(node)) { 1494 if (TryGenerateFastCaseSwitchStatement(node)) {
1495 ASSERT(frame_->height() == original_height);
1449 return; 1496 return;
1450 } 1497 }
1451 1498
1452 JumpTarget next_test(this); 1499 JumpTarget next_test(this);
1453 JumpTarget fall_through(this); 1500 JumpTarget fall_through(this);
1454 JumpTarget default_entry(this); 1501 JumpTarget default_entry(this);
1455 JumpTarget default_exit(this); 1502 JumpTarget default_exit(this);
1456 ZoneList<CaseClause*>* cases = node->cases(); 1503 ZoneList<CaseClause*>* cases = node->cases();
1457 int length = cases->length(); 1504 int length = cases->length();
1458 CaseClause* default_clause = NULL; 1505 CaseClause* default_clause = NULL;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 } 1563 }
1517 } 1564 }
1518 1565
1519 if (fall_through.is_linked()) { 1566 if (fall_through.is_linked()) {
1520 fall_through.Bind(); 1567 fall_through.Bind();
1521 } 1568 }
1522 1569
1523 if (node->break_target()->is_linked()) { 1570 if (node->break_target()->is_linked()) {
1524 node->break_target()->Bind(); 1571 node->break_target()->Bind();
1525 } 1572 }
1573 ASSERT(!has_valid_frame() || frame_->height() == original_height);
William Hesse 2009/02/20 13:06:20 How could there not be a valid frame here, if the
Kevin Millikin (Chromium) 2009/02/20 13:12:48 If the last case we compile returns and none of th
1526 } 1574 }
1527 1575
1528 1576
1529 void CodeGenerator::VisitLoopStatement(LoopStatement* node) { 1577 void CodeGenerator::VisitLoopStatement(LoopStatement* node) {
1578 #ifdef DEBUG
1579 int original_height = frame_->height();
1580 #endif
1530 VirtualFrame::SpilledScope spilled_scope(this); 1581 VirtualFrame::SpilledScope spilled_scope(this);
1531 Comment cmnt(masm_, "[ LoopStatement"); 1582 Comment cmnt(masm_, "[ LoopStatement");
1532 CodeForStatementPosition(node); 1583 CodeForStatementPosition(node);
1533 node->set_break_stack_height(break_stack_height_); 1584 node->set_break_stack_height(break_stack_height_);
1534 node->break_target()->Initialize(this); 1585 node->break_target()->Initialize(this);
1535 1586
1536 // Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a 1587 // Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a
1537 // known result for the test expression, with no side effects. 1588 // known result for the test expression, with no side effects.
1538 enum { ALWAYS_TRUE, ALWAYS_FALSE, DONT_KNOW } info = DONT_KNOW; 1589 enum { ALWAYS_TRUE, ALWAYS_FALSE, DONT_KNOW } info = DONT_KNOW;
1539 if (node->cond() == NULL) { 1590 if (node->cond() == NULL) {
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
1700 } 1751 }
1701 } 1752 }
1702 } 1753 }
1703 break; 1754 break;
1704 } 1755 }
1705 } 1756 }
1706 1757
1707 if (node->break_target()->is_linked()) { 1758 if (node->break_target()->is_linked()) {
1708 node->break_target()->Bind(); 1759 node->break_target()->Bind();
1709 } 1760 }
1761 ASSERT(!has_valid_frame() || frame_->height() == original_height);
1710 } 1762 }
1711 1763
1712 1764
1713 void CodeGenerator::VisitForInStatement(ForInStatement* node) { 1765 void CodeGenerator::VisitForInStatement(ForInStatement* node) {
1766 #ifdef DEBUG
1767 int original_height = frame_->height();
1768 #endif
1714 ASSERT(!in_spilled_code()); 1769 ASSERT(!in_spilled_code());
1715 VirtualFrame::SpilledScope spilled_scope(this); 1770 VirtualFrame::SpilledScope spilled_scope(this);
1716 Comment cmnt(masm_, "[ ForInStatement"); 1771 Comment cmnt(masm_, "[ ForInStatement");
1717 CodeForStatementPosition(node); 1772 CodeForStatementPosition(node);
1718 1773
1719 // We keep stuff on the stack while the body is executing. 1774 // We keep stuff on the stack while the body is executing.
1720 // Record it, so that a break/continue crossing this statement 1775 // Record it, so that a break/continue crossing this statement
1721 // can restore the stack. 1776 // can restore the stack.
1722 const int kForInStackSize = 5 * kPointerSize; 1777 const int kForInStackSize = 5 * kPointerSize;
1723 break_stack_height_ += kForInStackSize; 1778 break_stack_height_ += kForInStackSize;
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
1897 entry.Jump(); 1952 entry.Jump();
1898 1953
1899 // Cleanup. 1954 // Cleanup.
1900 node->break_target()->Bind(); 1955 node->break_target()->Bind();
1901 frame_->Drop(5); 1956 frame_->Drop(5);
1902 1957
1903 // Exit. 1958 // Exit.
1904 exit.Bind(); 1959 exit.Bind();
1905 1960
1906 break_stack_height_ -= kForInStackSize; 1961 break_stack_height_ -= kForInStackSize;
1962 ASSERT(frame_->height() == original_height);
1907 } 1963 }
1908 1964
1909 1965
1910 void CodeGenerator::VisitTryCatch(TryCatch* node) { 1966 void CodeGenerator::VisitTryCatch(TryCatch* node) {
1967 #ifdef DEBUG
1968 int original_height = frame_->height();
1969 #endif
1911 VirtualFrame::SpilledScope spilled_scope(this); 1970 VirtualFrame::SpilledScope spilled_scope(this);
1912 Comment cmnt(masm_, "[ TryCatch"); 1971 Comment cmnt(masm_, "[ TryCatch");
1913 CodeForStatementPosition(node); 1972 CodeForStatementPosition(node);
1914 1973
1915 JumpTarget try_block(this); 1974 JumpTarget try_block(this);
1916 JumpTarget exit(this); 1975 JumpTarget exit(this);
1917 1976
1918 try_block.Call(); 1977 try_block.Call();
1919 // --- Catch block --- 1978 // --- Catch block ---
1920 frame_->EmitPush(r0); 1979 frame_->EmitPush(r0);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
2008 __ str(r1, MemOperand(r3)); 2067 __ str(r1, MemOperand(r3));
2009 ASSERT(StackHandlerConstants::kCodeOffset == 0); // first field is code 2068 ASSERT(StackHandlerConstants::kCodeOffset == 0); // first field is code
2010 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); 2069 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
2011 // Code slot popped. 2070 // Code slot popped.
2012 frame_->Forget(1); 2071 frame_->Forget(1);
2013 shadows[i]->other_target()->Jump(); 2072 shadows[i]->other_target()->Jump();
2014 } 2073 }
2015 } 2074 }
2016 2075
2017 exit.Bind(); 2076 exit.Bind();
2077 ASSERT(!has_valid_frame() || frame_->height() == original_height);
2018 } 2078 }
2019 2079
2020 2080
2021 void CodeGenerator::VisitTryFinally(TryFinally* node) { 2081 void CodeGenerator::VisitTryFinally(TryFinally* node) {
2082 #ifdef DEBUG
2083 int original_height = frame_->height();
2084 #endif
2022 VirtualFrame::SpilledScope spilled_scope(this); 2085 VirtualFrame::SpilledScope spilled_scope(this);
2023 Comment cmnt(masm_, "[ TryFinally"); 2086 Comment cmnt(masm_, "[ TryFinally");
2024 CodeForStatementPosition(node); 2087 CodeForStatementPosition(node);
2025 2088
2026 // State: Used to keep track of reason for entering the finally 2089 // State: Used to keep track of reason for entering the finally
2027 // block. Should probably be extended to hold information for 2090 // block. Should probably be extended to hold information for
2028 // break/continue from within the try block. 2091 // break/continue from within the try block.
2029 enum { FALLING, THROWING, JUMPING }; 2092 enum { FALLING, THROWING, JUMPING };
2030 2093
2031 JumpTarget unlink(this); 2094 JumpTarget unlink(this);
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
2167 __ cmp(r2, Operand(Smi::FromInt(THROWING))); 2230 __ cmp(r2, Operand(Smi::FromInt(THROWING)));
2168 exit.Branch(ne); 2231 exit.Branch(ne);
2169 2232
2170 // Rethrow exception. 2233 // Rethrow exception.
2171 frame_->EmitPush(r0); 2234 frame_->EmitPush(r0);
2172 frame_->CallRuntime(Runtime::kReThrow, 1); 2235 frame_->CallRuntime(Runtime::kReThrow, 1);
2173 2236
2174 // Done. 2237 // Done.
2175 exit.Bind(); 2238 exit.Bind();
2176 } 2239 }
2240 ASSERT(!has_valid_frame() || frame_->height() == original_height);
2177 } 2241 }
2178 2242
2179 2243
2180 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) { 2244 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) {
2245 #ifdef DEBUG
2246 int original_height = frame_->height();
2247 #endif
2181 VirtualFrame::SpilledScope spilled_scope(this); 2248 VirtualFrame::SpilledScope spilled_scope(this);
2182 Comment cmnt(masm_, "[ DebuggerStatament"); 2249 Comment cmnt(masm_, "[ DebuggerStatament");
2183 CodeForStatementPosition(node); 2250 CodeForStatementPosition(node);
2184 frame_->CallRuntime(Runtime::kDebugBreak, 0); 2251 frame_->CallRuntime(Runtime::kDebugBreak, 0);
2185 // Ignore the return value. 2252 // Ignore the return value.
2253 ASSERT(frame_->height() == original_height);
2186 } 2254 }
2187 2255
2188 2256
2189 void CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) { 2257 void CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) {
2190 VirtualFrame::SpilledScope spilled_scope(this); 2258 VirtualFrame::SpilledScope spilled_scope(this);
2191 ASSERT(boilerplate->IsBoilerplate()); 2259 ASSERT(boilerplate->IsBoilerplate());
2192 2260
2193 // Push the boilerplate on the stack. 2261 // Push the boilerplate on the stack.
2194 __ mov(r0, Operand(boilerplate)); 2262 __ mov(r0, Operand(boilerplate));
2195 frame_->EmitPush(r0); 2263 frame_->EmitPush(r0);
2196 2264
2197 // Create a new closure. 2265 // Create a new closure.
2198 frame_->EmitPush(cp); 2266 frame_->EmitPush(cp);
2199 frame_->CallRuntime(Runtime::kNewClosure, 2); 2267 frame_->CallRuntime(Runtime::kNewClosure, 2);
2200 frame_->EmitPush(r0); 2268 frame_->EmitPush(r0);
2201 } 2269 }
2202 2270
2203 2271
2204 void CodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) { 2272 void CodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) {
2273 #ifdef DEBUG
2274 int original_height = frame_->height();
2275 #endif
2205 VirtualFrame::SpilledScope spilled_scope(this); 2276 VirtualFrame::SpilledScope spilled_scope(this);
2206 Comment cmnt(masm_, "[ FunctionLiteral"); 2277 Comment cmnt(masm_, "[ FunctionLiteral");
2207 2278
2208 // Build the function boilerplate and instantiate it. 2279 // Build the function boilerplate and instantiate it.
2209 Handle<JSFunction> boilerplate = BuildBoilerplate(node); 2280 Handle<JSFunction> boilerplate = BuildBoilerplate(node);
2210 // Check for stack-overflow exception. 2281 // Check for stack-overflow exception.
2211 if (HasStackOverflow()) return; 2282 if (HasStackOverflow()) {
2283 ASSERT(frame_->height() == original_height);
2284 return;
2285 }
2212 InstantiateBoilerplate(boilerplate); 2286 InstantiateBoilerplate(boilerplate);
2287 ASSERT(frame_->height() == original_height + 1);
2213 } 2288 }
2214 2289
2215 2290
2216 void CodeGenerator::VisitFunctionBoilerplateLiteral( 2291 void CodeGenerator::VisitFunctionBoilerplateLiteral(
2217 FunctionBoilerplateLiteral* node) { 2292 FunctionBoilerplateLiteral* node) {
2293 #ifdef DEBUG
2294 int original_height = frame_->height();
2295 #endif
2218 VirtualFrame::SpilledScope spilled_scope(this); 2296 VirtualFrame::SpilledScope spilled_scope(this);
2219 Comment cmnt(masm_, "[ FunctionBoilerplateLiteral"); 2297 Comment cmnt(masm_, "[ FunctionBoilerplateLiteral");
2220 InstantiateBoilerplate(node->boilerplate()); 2298 InstantiateBoilerplate(node->boilerplate());
2299 ASSERT(frame_->height() == original_height + 1);
2221 } 2300 }
2222 2301
2223 2302
2224 void CodeGenerator::VisitConditional(Conditional* node) { 2303 void CodeGenerator::VisitConditional(Conditional* node) {
2304 #ifdef DEBUG
2305 int original_height = frame_->height();
2306 #endif
2225 VirtualFrame::SpilledScope spilled_scope(this); 2307 VirtualFrame::SpilledScope spilled_scope(this);
2226 Comment cmnt(masm_, "[ Conditional"); 2308 Comment cmnt(masm_, "[ Conditional");
2227 JumpTarget then(this); 2309 JumpTarget then(this);
2228 JumpTarget else_(this); 2310 JumpTarget else_(this);
2229 JumpTarget exit(this); 2311 JumpTarget exit(this);
2230 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, 2312 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF,
2231 &then, &else_, true); 2313 &then, &else_, true);
2232 Branch(false, &else_); 2314 Branch(false, &else_);
2233 then.Bind(); 2315 then.Bind();
2234 LoadAndSpill(node->then_expression(), typeof_state()); 2316 LoadAndSpill(node->then_expression(), typeof_state());
2235 exit.Jump(); 2317 exit.Jump();
2236 else_.Bind(); 2318 else_.Bind();
2237 LoadAndSpill(node->else_expression(), typeof_state()); 2319 LoadAndSpill(node->else_expression(), typeof_state());
2238 exit.Bind(); 2320 exit.Bind();
2321 ASSERT(frame_->height() == original_height + 1);
2239 } 2322 }
2240 2323
2241 2324
2242 void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) { 2325 void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) {
2243 VirtualFrame::SpilledScope spilled_scope(this); 2326 VirtualFrame::SpilledScope spilled_scope(this);
2244 if (slot->type() == Slot::LOOKUP) { 2327 if (slot->type() == Slot::LOOKUP) {
2245 ASSERT(slot->var()->is_dynamic()); 2328 ASSERT(slot->var()->is_dynamic());
2246 2329
2247 JumpTarget slow(this); 2330 JumpTarget slow(this);
2248 JumpTarget done(this); 2331 JumpTarget done(this);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
2351 } else { 2434 } else {
2352 frame_->CallCodeObject(ic, RelocInfo::CODE_TARGET_CONTEXT, &name, 0); 2435 frame_->CallCodeObject(ic, RelocInfo::CODE_TARGET_CONTEXT, &name, 0);
2353 } 2436 }
2354 2437
2355 // Drop the global object. The result is in r0. 2438 // Drop the global object. The result is in r0.
2356 frame_->Drop(); 2439 frame_->Drop();
2357 } 2440 }
2358 2441
2359 2442
2360 void CodeGenerator::VisitSlot(Slot* node) { 2443 void CodeGenerator::VisitSlot(Slot* node) {
2444 #ifdef DEBUG
2445 int original_height = frame_->height();
2446 #endif
2361 VirtualFrame::SpilledScope spilled_scope(this); 2447 VirtualFrame::SpilledScope spilled_scope(this);
2362 Comment cmnt(masm_, "[ Slot"); 2448 Comment cmnt(masm_, "[ Slot");
2363 LoadFromSlot(node, typeof_state()); 2449 LoadFromSlot(node, typeof_state());
2450 ASSERT(frame_->height() == original_height + 1);
2364 } 2451 }
2365 2452
2366 2453
2367 void CodeGenerator::VisitVariableProxy(VariableProxy* node) { 2454 void CodeGenerator::VisitVariableProxy(VariableProxy* node) {
2455 #ifdef DEBUG
2456 int original_height = frame_->height();
2457 #endif
2368 VirtualFrame::SpilledScope spilled_scope(this); 2458 VirtualFrame::SpilledScope spilled_scope(this);
2369 Comment cmnt(masm_, "[ VariableProxy"); 2459 Comment cmnt(masm_, "[ VariableProxy");
2370 2460
2371 Variable* var = node->var(); 2461 Variable* var = node->var();
2372 Expression* expr = var->rewrite(); 2462 Expression* expr = var->rewrite();
2373 if (expr != NULL) { 2463 if (expr != NULL) {
2374 Visit(expr); 2464 Visit(expr);
2375 } else { 2465 } else {
2376 ASSERT(var->is_global()); 2466 ASSERT(var->is_global());
2377 Reference ref(this, node); 2467 Reference ref(this, node);
2378 ref.GetValueAndSpill(typeof_state()); 2468 ref.GetValueAndSpill(typeof_state());
2379 } 2469 }
2470 ASSERT(frame_->height() == original_height + 1);
2380 } 2471 }
2381 2472
2382 2473
2383 void CodeGenerator::VisitLiteral(Literal* node) { 2474 void CodeGenerator::VisitLiteral(Literal* node) {
2475 #ifdef DEBUG
2476 int original_height = frame_->height();
2477 #endif
2384 VirtualFrame::SpilledScope spilled_scope(this); 2478 VirtualFrame::SpilledScope spilled_scope(this);
2385 Comment cmnt(masm_, "[ Literal"); 2479 Comment cmnt(masm_, "[ Literal");
2386 __ mov(r0, Operand(node->handle())); 2480 __ mov(r0, Operand(node->handle()));
2387 frame_->EmitPush(r0); 2481 frame_->EmitPush(r0);
2482 ASSERT(frame_->height() == original_height + 1);
2388 } 2483 }
2389 2484
2390 2485
2391 void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) { 2486 void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) {
2487 #ifdef DEBUG
2488 int original_height = frame_->height();
2489 #endif
2392 VirtualFrame::SpilledScope spilled_scope(this); 2490 VirtualFrame::SpilledScope spilled_scope(this);
2393 Comment cmnt(masm_, "[ RexExp Literal"); 2491 Comment cmnt(masm_, "[ RexExp Literal");
2394 2492
2395 // Retrieve the literal array and check the allocated entry. 2493 // Retrieve the literal array and check the allocated entry.
2396 2494
2397 // Load the function of this activation. 2495 // Load the function of this activation.
2398 __ ldr(r1, frame_->Function()); 2496 __ ldr(r1, frame_->Function());
2399 2497
2400 // Load the literals array of the function. 2498 // Load the literals array of the function.
2401 __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset)); 2499 __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset));
(...skipping 15 matching lines...) Expand all
2417 __ mov(r0, Operand(node->pattern())); // RegExp pattern (2) 2515 __ mov(r0, Operand(node->pattern())); // RegExp pattern (2)
2418 frame_->EmitPush(r0); 2516 frame_->EmitPush(r0);
2419 __ mov(r0, Operand(node->flags())); // RegExp flags (3) 2517 __ mov(r0, Operand(node->flags())); // RegExp flags (3)
2420 frame_->EmitPush(r0); 2518 frame_->EmitPush(r0);
2421 frame_->CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); 2519 frame_->CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
2422 __ mov(r2, Operand(r0)); 2520 __ mov(r2, Operand(r0));
2423 2521
2424 done.Bind(); 2522 done.Bind();
2425 // Push the literal. 2523 // Push the literal.
2426 frame_->EmitPush(r2); 2524 frame_->EmitPush(r2);
2525 ASSERT(frame_->height() == original_height + 1);
2427 } 2526 }
2428 2527
2429 2528
2430 // This deferred code stub will be used for creating the boilerplate 2529 // This deferred code stub will be used for creating the boilerplate
2431 // by calling Runtime_CreateObjectLiteral. 2530 // by calling Runtime_CreateObjectLiteral.
2432 // Each created boilerplate is stored in the JSFunction and they are 2531 // Each created boilerplate is stored in the JSFunction and they are
2433 // therefore context dependent. 2532 // therefore context dependent.
2434 class DeferredObjectLiteral: public DeferredCode { 2533 class DeferredObjectLiteral: public DeferredCode {
2435 public: 2534 public:
2436 DeferredObjectLiteral(CodeGenerator* generator, ObjectLiteral* node) 2535 DeferredObjectLiteral(CodeGenerator* generator, ObjectLiteral* node)
(...skipping 27 matching lines...) Expand all
2464 frame->EmitPush(r0); 2563 frame->EmitPush(r0);
2465 Result boilerplate = 2564 Result boilerplate =
2466 frame->CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3); 2565 frame->CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3);
2467 __ mov(r2, Operand(boilerplate.reg())); 2566 __ mov(r2, Operand(boilerplate.reg()));
2468 // Result is returned in r2. 2567 // Result is returned in r2.
2469 exit_.Jump(); 2568 exit_.Jump();
2470 } 2569 }
2471 2570
2472 2571
2473 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { 2572 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) {
2573 #ifdef DEBUG
2574 int original_height = frame_->height();
2575 #endif
2474 VirtualFrame::SpilledScope spilled_scope(this); 2576 VirtualFrame::SpilledScope spilled_scope(this);
2475 Comment cmnt(masm_, "[ ObjectLiteral"); 2577 Comment cmnt(masm_, "[ ObjectLiteral");
2476 2578
2477 DeferredObjectLiteral* deferred = new DeferredObjectLiteral(this, node); 2579 DeferredObjectLiteral* deferred = new DeferredObjectLiteral(this, node);
2478 2580
2479 // Retrieve the literal array and check the allocated entry. 2581 // Retrieve the literal array and check the allocated entry.
2480 2582
2481 // Load the function of this activation. 2583 // Load the function of this activation.
2482 __ ldr(r1, frame_->Function()); 2584 __ ldr(r1, frame_->Function());
2483 2585
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2534 LoadAndSpill(key); 2636 LoadAndSpill(key);
2535 __ mov(r0, Operand(Smi::FromInt(0))); 2637 __ mov(r0, Operand(Smi::FromInt(0)));
2536 frame_->EmitPush(r0); 2638 frame_->EmitPush(r0);
2537 LoadAndSpill(value); 2639 LoadAndSpill(value);
2538 frame_->CallRuntime(Runtime::kDefineAccessor, 4); 2640 frame_->CallRuntime(Runtime::kDefineAccessor, 4);
2539 __ ldr(r0, frame_->Top()); 2641 __ ldr(r0, frame_->Top());
2540 break; 2642 break;
2541 } 2643 }
2542 } 2644 }
2543 } 2645 }
2646 ASSERT(frame_->height() == original_height + 1);
2544 } 2647 }
2545 2648
2546 2649
2547 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { 2650 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
2651 #ifdef DEBUG
2652 int original_height = frame_->height();
2653 #endif
2548 VirtualFrame::SpilledScope spilled_scope(this); 2654 VirtualFrame::SpilledScope spilled_scope(this);
2549 Comment cmnt(masm_, "[ ArrayLiteral"); 2655 Comment cmnt(masm_, "[ ArrayLiteral");
2550 2656
2551 // Call runtime to create the array literal. 2657 // Call runtime to create the array literal.
2552 __ mov(r0, Operand(node->literals())); 2658 __ mov(r0, Operand(node->literals()));
2553 frame_->EmitPush(r0); 2659 frame_->EmitPush(r0);
2554 // Load the function of this frame. 2660 // Load the function of this frame.
2555 __ ldr(r0, frame_->Function()); 2661 __ ldr(r0, frame_->Function());
2556 __ ldr(r0, FieldMemOperand(r0, JSFunction::kLiteralsOffset)); 2662 __ ldr(r0, FieldMemOperand(r0, JSFunction::kLiteralsOffset));
2557 frame_->EmitPush(r0); 2663 frame_->EmitPush(r0);
(...skipping 21 matching lines...) Expand all
2579 2685
2580 // Write to the indexed properties array. 2686 // Write to the indexed properties array.
2581 int offset = i * kPointerSize + Array::kHeaderSize; 2687 int offset = i * kPointerSize + Array::kHeaderSize;
2582 __ str(r0, FieldMemOperand(r1, offset)); 2688 __ str(r0, FieldMemOperand(r1, offset));
2583 2689
2584 // Update the write barrier for the array address. 2690 // Update the write barrier for the array address.
2585 __ mov(r3, Operand(offset)); 2691 __ mov(r3, Operand(offset));
2586 __ RecordWrite(r1, r3, r2); 2692 __ RecordWrite(r1, r3, r2);
2587 } 2693 }
2588 } 2694 }
2695 ASSERT(frame_->height() == original_height + 1);
2589 } 2696 }
2590 2697
2591 2698
2592 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) { 2699 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) {
2700 #ifdef DEBUG
2701 int original_height = frame_->height();
2702 #endif
2593 ASSERT(!in_spilled_code()); 2703 ASSERT(!in_spilled_code());
2594 VirtualFrame::SpilledScope spilled_scope(this); 2704 VirtualFrame::SpilledScope spilled_scope(this);
2595 // Call runtime routine to allocate the catch extension object and 2705 // Call runtime routine to allocate the catch extension object and
2596 // assign the exception value to the catch variable. 2706 // assign the exception value to the catch variable.
2597 Comment cmnt(masm_, "[ CatchExtensionObject"); 2707 Comment cmnt(masm_, "[ CatchExtensionObject");
2598 LoadAndSpill(node->key()); 2708 LoadAndSpill(node->key());
2599 LoadAndSpill(node->value()); 2709 LoadAndSpill(node->value());
2600 Result result = 2710 Result result =
2601 frame_->CallRuntime(Runtime::kCreateCatchExtensionObject, 2); 2711 frame_->CallRuntime(Runtime::kCreateCatchExtensionObject, 2);
2602 frame_->EmitPush(result.reg()); 2712 frame_->EmitPush(result.reg());
2713 ASSERT(frame_->height() == original_height + 1);
2603 } 2714 }
2604 2715
2605 2716
2606 void CodeGenerator::VisitAssignment(Assignment* node) { 2717 void CodeGenerator::VisitAssignment(Assignment* node) {
2718 #ifdef DEBUG
2719 int original_height = frame_->height();
2720 #endif
2607 VirtualFrame::SpilledScope spilled_scope(this); 2721 VirtualFrame::SpilledScope spilled_scope(this);
2608 Comment cmnt(masm_, "[ Assignment"); 2722 Comment cmnt(masm_, "[ Assignment");
2609 CodeForStatementPosition(node); 2723 CodeForStatementPosition(node);
2610 2724
2611 Reference target(this, node->target()); 2725 { Reference target(this, node->target());
2612 if (target.is_illegal()) { 2726 if (target.is_illegal()) {
2613 // Fool the virtual frame into thinking that we left the assignment's 2727 // Fool the virtual frame into thinking that we left the assignment's
2614 // value on the frame. 2728 // value on the frame.
2615 __ mov(r0, Operand(Smi::FromInt(0))); 2729 __ mov(r0, Operand(Smi::FromInt(0)));
2616 frame_->EmitPush(r0); 2730 frame_->EmitPush(r0);
2617 return; 2731 ASSERT(frame_->height() == original_height + 1);
2618 } 2732 return;
2733 }
2619 2734
2620 if (node->op() == Token::ASSIGN || 2735 if (node->op() == Token::ASSIGN ||
2621 node->op() == Token::INIT_VAR || 2736 node->op() == Token::INIT_VAR ||
2622 node->op() == Token::INIT_CONST) { 2737 node->op() == Token::INIT_CONST) {
2623 LoadAndSpill(node->value()); 2738 LoadAndSpill(node->value());
2624
2625 } else {
2626 target.GetValueAndSpill(NOT_INSIDE_TYPEOF);
2627 Literal* literal = node->value()->AsLiteral();
2628 if (literal != NULL && literal->handle()->IsSmi()) {
2629 SmiOperation(node->binary_op(), literal->handle(), false);
2630 frame_->EmitPush(r0);
2631 2739
2632 } else { 2740 } else {
2633 LoadAndSpill(node->value()); 2741 target.GetValueAndSpill(NOT_INSIDE_TYPEOF);
2634 GenericBinaryOperation(node->binary_op()); 2742 Literal* literal = node->value()->AsLiteral();
2635 frame_->EmitPush(r0); 2743 if (literal != NULL && literal->handle()->IsSmi()) {
2744 SmiOperation(node->binary_op(), literal->handle(), false);
2745 frame_->EmitPush(r0);
2746
2747 } else {
2748 LoadAndSpill(node->value());
2749 GenericBinaryOperation(node->binary_op());
2750 frame_->EmitPush(r0);
2751 }
2752 }
2753
2754 Variable* var = node->target()->AsVariableProxy()->AsVariable();
2755 if (var != NULL &&
2756 (var->mode() == Variable::CONST) &&
2757 node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) {
2758 // Assignment ignored - leave the value on the stack.
2759
2760 } else {
2761 CodeForSourcePosition(node->position());
2762 if (node->op() == Token::INIT_CONST) {
2763 // Dynamic constant initializations must use the function context
2764 // and initialize the actual constant declared. Dynamic variable
2765 // initializations are simply assignments and use SetValue.
2766 target.SetValue(CONST_INIT);
2767 } else {
2768 target.SetValue(NOT_CONST_INIT);
2769 }
2636 } 2770 }
2637 } 2771 }
2638 2772 ASSERT(frame_->height() == original_height + 1);
2639 Variable* var = node->target()->AsVariableProxy()->AsVariable();
2640 if (var != NULL &&
2641 (var->mode() == Variable::CONST) &&
2642 node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) {
2643 // Assignment ignored - leave the value on the stack.
2644
2645 } else {
2646 CodeForSourcePosition(node->position());
2647 if (node->op() == Token::INIT_CONST) {
2648 // Dynamic constant initializations must use the function context
2649 // and initialize the actual constant declared. Dynamic variable
2650 // initializations are simply assignments and use SetValue.
2651 target.SetValue(CONST_INIT);
2652 } else {
2653 target.SetValue(NOT_CONST_INIT);
2654 }
2655 }
2656 } 2773 }
2657 2774
2658 2775
2659 void CodeGenerator::VisitThrow(Throw* node) { 2776 void CodeGenerator::VisitThrow(Throw* node) {
2777 #ifdef DEBUG
2778 int original_height = frame_->height();
2779 #endif
2660 VirtualFrame::SpilledScope spilled_scope(this); 2780 VirtualFrame::SpilledScope spilled_scope(this);
2661 Comment cmnt(masm_, "[ Throw"); 2781 Comment cmnt(masm_, "[ Throw");
2662 2782
2663 LoadAndSpill(node->exception()); 2783 LoadAndSpill(node->exception());
2664 CodeForSourcePosition(node->position()); 2784 CodeForSourcePosition(node->position());
2665 frame_->CallRuntime(Runtime::kThrow, 1); 2785 frame_->CallRuntime(Runtime::kThrow, 1);
2666 frame_->EmitPush(r0); 2786 frame_->EmitPush(r0);
2787 ASSERT(frame_->height() == original_height + 1);
2667 } 2788 }
2668 2789
2669 2790
2670 void CodeGenerator::VisitProperty(Property* node) { 2791 void CodeGenerator::VisitProperty(Property* node) {
2792 #ifdef DEBUG
2793 int original_height = frame_->height();
2794 #endif
2671 VirtualFrame::SpilledScope spilled_scope(this); 2795 VirtualFrame::SpilledScope spilled_scope(this);
2672 Comment cmnt(masm_, "[ Property"); 2796 Comment cmnt(masm_, "[ Property");
2673 2797
2674 Reference property(this, node); 2798 { Reference property(this, node);
2675 property.GetValueAndSpill(typeof_state()); 2799 property.GetValueAndSpill(typeof_state());
2800 }
2801 ASSERT(frame_->height() == original_height + 1);
2676 } 2802 }
2677 2803
2678 2804
2679 void CodeGenerator::VisitCall(Call* node) { 2805 void CodeGenerator::VisitCall(Call* node) {
2806 #ifdef DEBUG
2807 int original_height = frame_->height();
2808 #endif
2680 VirtualFrame::SpilledScope spilled_scope(this); 2809 VirtualFrame::SpilledScope spilled_scope(this);
2681 Comment cmnt(masm_, "[ Call"); 2810 Comment cmnt(masm_, "[ Call");
2682 2811
2683 ZoneList<Expression*>* args = node->arguments(); 2812 ZoneList<Expression*>* args = node->arguments();
2684 2813
2685 CodeForStatementPosition(node); 2814 CodeForStatementPosition(node);
2686 // Standard function call. 2815 // Standard function call.
2687 2816
2688 // Check if the function is a variable or a property. 2817 // Check if the function is a variable or a property.
2689 Expression* function = node->expression(); 2818 Expression* function = node->expression();
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
2806 // Load the function. 2935 // Load the function.
2807 LoadAndSpill(function); 2936 LoadAndSpill(function);
2808 2937
2809 // Pass the global proxy as the receiver. 2938 // Pass the global proxy as the receiver.
2810 LoadGlobalReceiver(r0); 2939 LoadGlobalReceiver(r0);
2811 2940
2812 // Call the function. 2941 // Call the function.
2813 CallWithArguments(args, node->position()); 2942 CallWithArguments(args, node->position());
2814 frame_->EmitPush(r0); 2943 frame_->EmitPush(r0);
2815 } 2944 }
2945 ASSERT(frame_->height() == original_height + 1);
2816 } 2946 }
2817 2947
2818 2948
2819 void CodeGenerator::VisitCallEval(CallEval* node) { 2949 void CodeGenerator::VisitCallEval(CallEval* node) {
2950 #ifdef DEBUG
2951 int original_height = frame_->height();
2952 #endif
2820 VirtualFrame::SpilledScope spilled_scope(this); 2953 VirtualFrame::SpilledScope spilled_scope(this);
2821 Comment cmnt(masm_, "[ CallEval"); 2954 Comment cmnt(masm_, "[ CallEval");
2822 2955
2823 // In a call to eval, we first call %ResolvePossiblyDirectEval to resolve 2956 // In a call to eval, we first call %ResolvePossiblyDirectEval to resolve
2824 // the function we need to call and the receiver of the call. 2957 // the function we need to call and the receiver of the call.
2825 // Then we call the resolved function using the given arguments. 2958 // Then we call the resolved function using the given arguments.
2826 2959
2827 ZoneList<Expression*>* args = node->arguments(); 2960 ZoneList<Expression*>* args = node->arguments();
2828 Expression* function = node->expression(); 2961 Expression* function = node->expression();
2829 2962
2830 CodeForStatementPosition(node); 2963 CodeForStatementPosition(node);
2831 2964
2832 // Prepare stack for call to resolved function. 2965 // Prepare stack for call to resolved function.
2833 LoadAndSpill(function); 2966 LoadAndSpill(function);
2834 __ mov(r2, Operand(Factory::undefined_value())); 2967 __ mov(r2, Operand(Factory::undefined_value()));
2835 __ push(r2); // Slot for receiver 2968 frame_->EmitPush(r2); // Slot for receiver
2836 for (int i = 0; i < args->length(); i++) { 2969 int arg_count = args->length();
2970 for (int i = 0; i < arg_count; i++) {
2837 LoadAndSpill(args->at(i)); 2971 LoadAndSpill(args->at(i));
2838 } 2972 }
2839 2973
2840 // Prepare stack for call to ResolvePossiblyDirectEval. 2974 // Prepare stack for call to ResolvePossiblyDirectEval.
2841 __ ldr(r1, MemOperand(sp, args->length() * kPointerSize + kPointerSize)); 2975 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize + kPointerSize));
2842 __ push(r1); 2976 frame_->EmitPush(r1);
2843 if (args->length() > 0) { 2977 if (arg_count > 0) {
2844 __ ldr(r1, MemOperand(sp, args->length() * kPointerSize)); 2978 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize));
2845 __ push(r1); 2979 frame_->EmitPush(r1);
2846 } else { 2980 } else {
2847 __ push(r2); 2981 frame_->EmitPush(r2);
2848 } 2982 }
2849 2983
2850 // Resolve the call. 2984 // Resolve the call.
2851 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 2); 2985 frame_->CallRuntime(Runtime::kResolvePossiblyDirectEval, 2);
2852 2986
2853 // Touch up stack with the right values for the function and the receiver. 2987 // Touch up stack with the right values for the function and the receiver.
2854 __ ldr(r1, FieldMemOperand(r0, FixedArray::kHeaderSize)); 2988 __ ldr(r1, FieldMemOperand(r0, FixedArray::kHeaderSize));
2855 __ str(r1, MemOperand(sp, (args->length() + 1) * kPointerSize)); 2989 __ str(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2856 __ ldr(r1, FieldMemOperand(r0, FixedArray::kHeaderSize + kPointerSize)); 2990 __ ldr(r1, FieldMemOperand(r0, FixedArray::kHeaderSize + kPointerSize));
2857 __ str(r1, MemOperand(sp, args->length() * kPointerSize)); 2991 __ str(r1, MemOperand(sp, arg_count * kPointerSize));
2858 2992
2859 // Call the function. 2993 // Call the function.
2860 CodeForSourcePosition(node->position()); 2994 CodeForSourcePosition(node->position());
2861 2995
2862 CallFunctionStub call_function(args->length()); 2996 CallFunctionStub call_function(arg_count);
2863 __ CallStub(&call_function); 2997 frame_->CallStub(&call_function, arg_count + 1);
2864 2998
2865 __ ldr(cp, frame_->Context()); 2999 __ ldr(cp, frame_->Context());
2866 // Remove the function from the stack. 3000 // Remove the function from the stack.
2867 frame_->Drop(); 3001 frame_->Drop();
2868 frame_->EmitPush(r0); 3002 frame_->EmitPush(r0);
3003 ASSERT(frame_->height() == original_height + 1);
2869 } 3004 }
2870 3005
2871 3006
2872 void CodeGenerator::VisitCallNew(CallNew* node) { 3007 void CodeGenerator::VisitCallNew(CallNew* node) {
3008 #ifdef DEBUG
3009 int original_height = frame_->height();
3010 #endif
2873 VirtualFrame::SpilledScope spilled_scope(this); 3011 VirtualFrame::SpilledScope spilled_scope(this);
2874 Comment cmnt(masm_, "[ CallNew"); 3012 Comment cmnt(masm_, "[ CallNew");
2875 CodeForStatementPosition(node); 3013 CodeForStatementPosition(node);
2876 3014
2877 // According to ECMA-262, section 11.2.2, page 44, the function 3015 // According to ECMA-262, section 11.2.2, page 44, the function
2878 // expression in new calls must be evaluated before the 3016 // expression in new calls must be evaluated before the
2879 // arguments. This is different from ordinary calls, where the 3017 // arguments. This is different from ordinary calls, where the
2880 // actual function to call is resolved after the arguments have been 3018 // actual function to call is resolved after the arguments have been
2881 // evaluated. 3019 // evaluated.
2882 3020
(...skipping 25 matching lines...) Expand all
2908 CodeForSourcePosition(node->position()); 3046 CodeForSourcePosition(node->position());
2909 Handle<Code> ic(Builtins::builtin(Builtins::JSConstructCall)); 3047 Handle<Code> ic(Builtins::builtin(Builtins::JSConstructCall));
2910 Result result = frame_->CallCodeObject(ic, 3048 Result result = frame_->CallCodeObject(ic,
2911 RelocInfo::CONSTRUCT_CALL, 3049 RelocInfo::CONSTRUCT_CALL,
2912 &num_args, 3050 &num_args,
2913 &function, 3051 &function,
2914 arg_count + 1); 3052 arg_count + 1);
2915 3053
2916 // Discard old TOS value and push r0 on the stack (same as Pop(), push(r0)). 3054 // Discard old TOS value and push r0 on the stack (same as Pop(), push(r0)).
2917 __ str(r0, frame_->Top()); 3055 __ str(r0, frame_->Top());
3056 ASSERT(frame_->height() == original_height + 1);
2918 } 3057 }
2919 3058
2920 3059
2921 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) { 3060 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) {
2922 VirtualFrame::SpilledScope spilled_scope(this); 3061 VirtualFrame::SpilledScope spilled_scope(this);
2923 ASSERT(args->length() == 1); 3062 ASSERT(args->length() == 1);
2924 JumpTarget leave(this); 3063 JumpTarget leave(this);
2925 LoadAndSpill(args->at(0)); 3064 LoadAndSpill(args->at(0));
2926 frame_->EmitPop(r0); // r0 contains object. 3065 frame_->EmitPop(r0); // r0 contains object.
2927 // if (object->IsSmi()) return the object. 3066 // if (object->IsSmi()) return the object.
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
3077 LoadAndSpill(args->at(0)); 3216 LoadAndSpill(args->at(0));
3078 LoadAndSpill(args->at(1)); 3217 LoadAndSpill(args->at(1));
3079 frame_->EmitPop(r0); 3218 frame_->EmitPop(r0);
3080 frame_->EmitPop(r1); 3219 frame_->EmitPop(r1);
3081 __ cmp(r0, Operand(r1)); 3220 __ cmp(r0, Operand(r1));
3082 cc_reg_ = eq; 3221 cc_reg_ = eq;
3083 } 3222 }
3084 3223
3085 3224
3086 void CodeGenerator::VisitCallRuntime(CallRuntime* node) { 3225 void CodeGenerator::VisitCallRuntime(CallRuntime* node) {
3226 #ifdef DEBUG
3227 int original_height = frame_->height();
3228 #endif
3087 VirtualFrame::SpilledScope spilled_scope(this); 3229 VirtualFrame::SpilledScope spilled_scope(this);
3088 if (CheckForInlineRuntimeCall(node)) { 3230 if (CheckForInlineRuntimeCall(node)) {
3231 ASSERT((has_cc() && frame_->height() == original_height) ||
3232 (!has_cc() && frame_->height() == original_height + 1));
3089 return; 3233 return;
3090 } 3234 }
3091 3235
3092 ZoneList<Expression*>* args = node->arguments(); 3236 ZoneList<Expression*>* args = node->arguments();
3093 Comment cmnt(masm_, "[ CallRuntime"); 3237 Comment cmnt(masm_, "[ CallRuntime");
3094 Runtime::Function* function = node->function(); 3238 Runtime::Function* function = node->function();
3095 3239
3096 if (function != NULL) { 3240 if (function != NULL) {
3097 // Push the arguments ("left-to-right"). 3241 // Push the arguments ("left-to-right").
3098 int arg_count = args->length(); 3242 int arg_count = args->length();
(...skipping 19 matching lines...) Expand all
3118 LoadAndSpill(args->at(i)); 3262 LoadAndSpill(args->at(i));
3119 } 3263 }
3120 3264
3121 // Call the JS runtime function. 3265 // Call the JS runtime function.
3122 Handle<Code> stub = ComputeCallInitialize(args->length()); 3266 Handle<Code> stub = ComputeCallInitialize(args->length());
3123 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET, arg_count + 1); 3267 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET, arg_count + 1);
3124 __ ldr(cp, frame_->Context()); 3268 __ ldr(cp, frame_->Context());
3125 frame_->Drop(); 3269 frame_->Drop();
3126 frame_->EmitPush(r0); 3270 frame_->EmitPush(r0);
3127 } 3271 }
3272 ASSERT(frame_->height() == original_height + 1);
3128 } 3273 }
3129 3274
3130 3275
3131 void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) { 3276 void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
3277 #ifdef DEBUG
3278 int original_height = frame_->height();
3279 #endif
3132 VirtualFrame::SpilledScope spilled_scope(this); 3280 VirtualFrame::SpilledScope spilled_scope(this);
3133 Comment cmnt(masm_, "[ UnaryOperation"); 3281 Comment cmnt(masm_, "[ UnaryOperation");
3134 3282
3135 Token::Value op = node->op(); 3283 Token::Value op = node->op();
3136 3284
3137 if (op == Token::NOT) { 3285 if (op == Token::NOT) {
3138 LoadConditionAndSpill(node->expression(), 3286 LoadConditionAndSpill(node->expression(),
3139 NOT_INSIDE_TYPEOF, 3287 NOT_INSIDE_TYPEOF,
3140 false_target(), 3288 false_target(),
3141 true_target(), 3289 true_target(),
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
3254 __ mov(arg_count.reg(), Operand(0)); // not counting receiver 3402 __ mov(arg_count.reg(), Operand(0)); // not counting receiver
3255 frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, &arg_count, 1); 3403 frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, &arg_count, 1);
3256 continue_label.Bind(); 3404 continue_label.Bind();
3257 break; 3405 break;
3258 } 3406 }
3259 default: 3407 default:
3260 UNREACHABLE(); 3408 UNREACHABLE();
3261 } 3409 }
3262 frame_->EmitPush(r0); // r0 has result 3410 frame_->EmitPush(r0); // r0 has result
3263 } 3411 }
3412 ASSERT((has_cc() && frame_->height() == original_height) ||
3413 (!has_cc() && frame_->height() == original_height + 1));
3264 } 3414 }
3265 3415
3266 3416
3267 void CodeGenerator::VisitCountOperation(CountOperation* node) { 3417 void CodeGenerator::VisitCountOperation(CountOperation* node) {
3418 #ifdef DEBUG
3419 int original_height = frame_->height();
3420 #endif
3268 VirtualFrame::SpilledScope spilled_scope(this); 3421 VirtualFrame::SpilledScope spilled_scope(this);
3269 Comment cmnt(masm_, "[ CountOperation"); 3422 Comment cmnt(masm_, "[ CountOperation");
3270 3423
3271 bool is_postfix = node->is_postfix(); 3424 bool is_postfix = node->is_postfix();
3272 bool is_increment = node->op() == Token::INC; 3425 bool is_increment = node->op() == Token::INC;
3273 3426
3274 Variable* var = node->expression()->AsVariableProxy()->AsVariable(); 3427 Variable* var = node->expression()->AsVariableProxy()->AsVariable();
3275 bool is_const = (var != NULL && var->mode() == Variable::CONST); 3428 bool is_const = (var != NULL && var->mode() == Variable::CONST);
3276 3429
3277 // Postfix: Make room for the result. 3430 // Postfix: Make room for the result.
3278 if (is_postfix) { 3431 if (is_postfix) {
3279 __ mov(r0, Operand(0)); 3432 __ mov(r0, Operand(0));
3280 frame_->EmitPush(r0); 3433 frame_->EmitPush(r0);
3281 } 3434 }
3282 3435
3283 { Reference target(this, node->expression()); 3436 { Reference target(this, node->expression());
3284 if (target.is_illegal()) { 3437 if (target.is_illegal()) {
3285 // Spoof the virtual frame to have the expected height (one higher 3438 // Spoof the virtual frame to have the expected height (one higher
3286 // than on entry). 3439 // than on entry).
3287 if (!is_postfix) { 3440 if (!is_postfix) {
3288 __ mov(r0, Operand(Smi::FromInt(0))); 3441 __ mov(r0, Operand(Smi::FromInt(0)));
3289 frame_->EmitPush(r0); 3442 frame_->EmitPush(r0);
3290 } 3443 }
3444 ASSERT(frame_->height() == original_height + 1);
3291 return; 3445 return;
3292 } 3446 }
3293 target.GetValueAndSpill(NOT_INSIDE_TYPEOF); 3447 target.GetValueAndSpill(NOT_INSIDE_TYPEOF);
3294 frame_->EmitPop(r0); 3448 frame_->EmitPop(r0);
3295 3449
3296 JumpTarget slow(this); 3450 JumpTarget slow(this);
3297 JumpTarget exit(this); 3451 JumpTarget exit(this);
3298 3452
3299 // Load the value (1) into register r1. 3453 // Load the value (1) into register r1.
3300 __ mov(r1, Operand(Smi::FromInt(1))); 3454 __ mov(r1, Operand(Smi::FromInt(1)));
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3346 } 3500 }
3347 3501
3348 // Store the new value in the target if not const. 3502 // Store the new value in the target if not const.
3349 exit.Bind(); 3503 exit.Bind();
3350 frame_->EmitPush(r0); 3504 frame_->EmitPush(r0);
3351 if (!is_const) target.SetValue(NOT_CONST_INIT); 3505 if (!is_const) target.SetValue(NOT_CONST_INIT);
3352 } 3506 }
3353 3507
3354 // Postfix: Discard the new value and use the old. 3508 // Postfix: Discard the new value and use the old.
3355 if (is_postfix) frame_->EmitPop(r0); 3509 if (is_postfix) frame_->EmitPop(r0);
3510 ASSERT(frame_->height() == original_height + 1);
3356 } 3511 }
3357 3512
3358 3513
3359 void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) { 3514 void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) {
3515 #ifdef DEBUG
3516 int original_height = frame_->height();
3517 #endif
3360 VirtualFrame::SpilledScope spilled_scope(this); 3518 VirtualFrame::SpilledScope spilled_scope(this);
3361 Comment cmnt(masm_, "[ BinaryOperation"); 3519 Comment cmnt(masm_, "[ BinaryOperation");
3362 Token::Value op = node->op(); 3520 Token::Value op = node->op();
3363 3521
3364 // According to ECMA-262 section 11.11, page 58, the binary logical 3522 // According to ECMA-262 section 11.11, page 58, the binary logical
3365 // operators must yield the result of one of the two expressions 3523 // operators must yield the result of one of the two expressions
3366 // before any ToBoolean() conversions. This means that the value 3524 // before any ToBoolean() conversions. This means that the value
3367 // produced by a && or || operator is not necessarily a boolean. 3525 // produced by a && or || operator is not necessarily a boolean.
3368 3526
3369 // NOTE: If the left hand side produces a materialized value (not in 3527 // NOTE: If the left hand side produces a materialized value (not in
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
3471 LoadAndSpill(node->right()); 3629 LoadAndSpill(node->right());
3472 SmiOperation(node->op(), lliteral->handle(), true); 3630 SmiOperation(node->op(), lliteral->handle(), true);
3473 3631
3474 } else { 3632 } else {
3475 LoadAndSpill(node->left()); 3633 LoadAndSpill(node->left());
3476 LoadAndSpill(node->right()); 3634 LoadAndSpill(node->right());
3477 GenericBinaryOperation(node->op()); 3635 GenericBinaryOperation(node->op());
3478 } 3636 }
3479 frame_->EmitPush(r0); 3637 frame_->EmitPush(r0);
3480 } 3638 }
3639 ASSERT((has_cc() && frame_->height() == original_height) ||
3640 (!has_cc() && frame_->height() == original_height + 1));
3481 } 3641 }
3482 3642
3483 3643
3484 void CodeGenerator::VisitThisFunction(ThisFunction* node) { 3644 void CodeGenerator::VisitThisFunction(ThisFunction* node) {
3645 #ifdef DEBUG
3646 int original_height = frame_->height();
3647 #endif
3485 VirtualFrame::SpilledScope spilled_scope(this); 3648 VirtualFrame::SpilledScope spilled_scope(this);
3486 __ ldr(r0, frame_->Function()); 3649 __ ldr(r0, frame_->Function());
3487 frame_->EmitPush(r0); 3650 frame_->EmitPush(r0);
3651 ASSERT(frame_->height() == original_height + 1);
3488 } 3652 }
3489 3653
3490 3654
3491 void CodeGenerator::VisitCompareOperation(CompareOperation* node) { 3655 void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
3656 #ifdef DEBUG
3657 int original_height = frame_->height();
3658 #endif
3492 VirtualFrame::SpilledScope spilled_scope(this); 3659 VirtualFrame::SpilledScope spilled_scope(this);
3493 Comment cmnt(masm_, "[ CompareOperation"); 3660 Comment cmnt(masm_, "[ CompareOperation");
3494 3661
3495 // Get the expressions from the node. 3662 // Get the expressions from the node.
3496 Expression* left = node->left(); 3663 Expression* left = node->left();
3497 Expression* right = node->right(); 3664 Expression* right = node->right();
3498 Token::Value op = node->op(); 3665 Token::Value op = node->op();
3499 3666
3500 // To make null checks efficient, we check if either left or right is the 3667 // To make null checks efficient, we check if either left or right is the
3501 // literal 'null'. If so, we optimize the code by inlining a null check 3668 // literal 'null'. If so, we optimize the code by inlining a null check
(...skipping 22 matching lines...) Expand all
3524 false_target()->Branch(eq); 3691 false_target()->Branch(eq);
3525 3692
3526 // It can be an undetectable object. 3693 // It can be an undetectable object.
3527 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); 3694 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset));
3528 __ ldrb(r0, FieldMemOperand(r0, Map::kBitFieldOffset)); 3695 __ ldrb(r0, FieldMemOperand(r0, Map::kBitFieldOffset));
3529 __ and_(r0, r0, Operand(1 << Map::kIsUndetectable)); 3696 __ and_(r0, r0, Operand(1 << Map::kIsUndetectable));
3530 __ cmp(r0, Operand(1 << Map::kIsUndetectable)); 3697 __ cmp(r0, Operand(1 << Map::kIsUndetectable));
3531 } 3698 }
3532 3699
3533 cc_reg_ = eq; 3700 cc_reg_ = eq;
3701 ASSERT(has_cc() && frame_->height() == original_height);
3534 return; 3702 return;
3535 } 3703 }
3536 } 3704 }
3537 3705
3538 // To make typeof testing for natives implemented in JavaScript really 3706 // To make typeof testing for natives implemented in JavaScript really
3539 // efficient, we generate special code for expressions of the form: 3707 // efficient, we generate special code for expressions of the form:
3540 // 'typeof <expression> == <string>'. 3708 // 'typeof <expression> == <string>'.
3541 UnaryOperation* operation = left->AsUnaryOperation(); 3709 UnaryOperation* operation = left->AsUnaryOperation();
3542 if ((op == Token::EQ || op == Token::EQ_STRICT) && 3710 if ((op == Token::EQ || op == Token::EQ_STRICT) &&
3543 (operation != NULL && operation->op() == Token::TYPEOF) && 3711 (operation != NULL && operation->op() == Token::TYPEOF) &&
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
3619 __ cmp(r2, Operand(FIRST_JS_OBJECT_TYPE)); 3787 __ cmp(r2, Operand(FIRST_JS_OBJECT_TYPE));
3620 false_target()->Branch(lt); 3788 false_target()->Branch(lt);
3621 __ cmp(r2, Operand(LAST_JS_OBJECT_TYPE)); 3789 __ cmp(r2, Operand(LAST_JS_OBJECT_TYPE));
3622 cc_reg_ = le; 3790 cc_reg_ = le;
3623 3791
3624 } else { 3792 } else {
3625 // Uncommon case: typeof testing against a string literal that is 3793 // Uncommon case: typeof testing against a string literal that is
3626 // never returned from the typeof operator. 3794 // never returned from the typeof operator.
3627 false_target()->Jump(); 3795 false_target()->Jump();
3628 } 3796 }
3797 ASSERT(!has_valid_frame() ||
3798 (has_cc() && frame_->height() == original_height));
3629 return; 3799 return;
3630 } 3800 }
3631 3801
3632 LoadAndSpill(left); 3802 LoadAndSpill(left);
3633 LoadAndSpill(right); 3803 LoadAndSpill(right);
3634 switch (op) { 3804 switch (op) {
3635 case Token::EQ: 3805 case Token::EQ:
3636 Comparison(eq, false); 3806 Comparison(eq, false);
3637 break; 3807 break;
3638 3808
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
3677 &arg_count, 3847 &arg_count,
3678 2); 3848 2);
3679 __ tst(result.reg(), Operand(result.reg())); 3849 __ tst(result.reg(), Operand(result.reg()));
3680 cc_reg_ = eq; 3850 cc_reg_ = eq;
3681 break; 3851 break;
3682 } 3852 }
3683 3853
3684 default: 3854 default:
3685 UNREACHABLE(); 3855 UNREACHABLE();
3686 } 3856 }
3857 ASSERT((has_cc() && frame_->height() == original_height) ||
3858 (!has_cc() && frame_->height() == original_height + 1));
3687 } 3859 }
3688 3860
3689 3861
3690 #ifdef DEBUG 3862 #ifdef DEBUG
3691 bool CodeGenerator::HasValidEntryRegisters() { return true; } 3863 bool CodeGenerator::HasValidEntryRegisters() { return true; }
3692 #endif 3864 #endif
3693 3865
3694 3866
3695 bool CodeGenerator::IsActualFunctionReturn(JumpTarget* target) { 3867 bool CodeGenerator::IsActualFunctionReturn(JumpTarget* target) {
3696 return (target == &function_return_ && !function_return_is_shadowed_); 3868 return (target == &function_return_ && !function_return_is_shadowed_);
(...skipping 1132 matching lines...) Expand 10 before | Expand all | Expand 10 after
4829 __ mov(r2, Operand(0)); 5001 __ mov(r2, Operand(0));
4830 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); 5002 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
4831 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), 5003 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)),
4832 RelocInfo::CODE_TARGET); 5004 RelocInfo::CODE_TARGET);
4833 } 5005 }
4834 5006
4835 5007
4836 #undef __ 5008 #undef __
4837 5009
4838 } } // namespace v8::internal 5010 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/codegen.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698