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

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

Issue 14170: Refactored the recording of source position in the generated code. The code g... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 12 years 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-ia32.h ('k') | src/parser.cc » ('j') | 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 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 179
180 180
181 // Calling conventions: 181 // Calling conventions:
182 // ebp: frame pointer 182 // ebp: frame pointer
183 // esp: stack pointer 183 // esp: stack pointer
184 // edi: caller's parameter pointer 184 // edi: caller's parameter pointer
185 // esi: callee's context 185 // esi: callee's context
186 186
187 void CodeGenerator::GenCode(FunctionLiteral* fun) { 187 void CodeGenerator::GenCode(FunctionLiteral* fun) {
188 // Record the position for debugging purposes. 188 // Record the position for debugging purposes.
189 __ RecordPosition(fun->start_position()); 189 CodeForSourcePosition(fun->start_position());
190 190
191 ZoneList<Statement*>* body = fun->body(); 191 ZoneList<Statement*>* body = fun->body();
192 192
193 // Initialize state. 193 // Initialize state.
194 ASSERT(scope_ == NULL); 194 ASSERT(scope_ == NULL);
195 scope_ = fun->scope(); 195 scope_ = fun->scope();
196 ASSERT(frame_ == NULL); 196 ASSERT(frame_ == NULL);
197 VirtualFrame virtual_frame(this); 197 VirtualFrame virtual_frame(this);
198 frame_ = &virtual_frame; 198 frame_ = &virtual_frame;
199 cc_reg_ = no_condition; 199 cc_reg_ = no_condition;
(...skipping 1115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1315 #endif 1315 #endif
1316 1316
1317 Major MajorKey() { return CallFunction; } 1317 Major MajorKey() { return CallFunction; }
1318 int MinorKey() { return argc_; } 1318 int MinorKey() { return argc_; }
1319 }; 1319 };
1320 1320
1321 1321
1322 // Call the function just below TOS on the stack with the given 1322 // Call the function just below TOS on the stack with the given
1323 // arguments. The receiver is the TOS. 1323 // arguments. The receiver is the TOS.
1324 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args, 1324 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args,
1325 int position) { 1325 int position) {
1326 // Push the arguments ("left-to-right") on the stack. 1326 // Push the arguments ("left-to-right") on the stack.
1327 for (int i = 0; i < args->length(); i++) { 1327 for (int i = 0; i < args->length(); i++) {
1328 Load(args->at(i)); 1328 Load(args->at(i));
1329 } 1329 }
1330 1330
1331 // Record the position for debugging purposes. 1331 // Record the position for debugging purposes.
1332 __ RecordPosition(position); 1332 CodeForSourcePosition(position);
1333 1333
1334 // Use the shared code stub to call the function. 1334 // Use the shared code stub to call the function.
1335 CallFunctionStub call_function(args->length()); 1335 CallFunctionStub call_function(args->length());
1336 __ CallStub(&call_function); 1336 __ CallStub(&call_function);
1337 1337
1338 // Restore context and pop function from the stack. 1338 // Restore context and pop function from the stack.
1339 __ mov(esi, frame_->Context()); 1339 __ mov(esi, frame_->Context());
1340 __ mov(frame_->Top(), eax); 1340 __ mov(frame_->Top(), eax);
1341 } 1341 }
1342 1342
(...skipping 15 matching lines...) Expand all
1358 __ cmp(esp, Operand::StaticVariable(stack_guard_limit)); 1358 __ cmp(esp, Operand::StaticVariable(stack_guard_limit));
1359 __ j(above_equal, &stack_is_ok, taken); 1359 __ j(above_equal, &stack_is_ok, taken);
1360 __ CallStub(&stub); 1360 __ CallStub(&stub);
1361 __ bind(&stack_is_ok); 1361 __ bind(&stack_is_ok);
1362 } 1362 }
1363 } 1363 }
1364 1364
1365 1365
1366 void CodeGenerator::VisitBlock(Block* node) { 1366 void CodeGenerator::VisitBlock(Block* node) {
1367 Comment cmnt(masm_, "[ Block"); 1367 Comment cmnt(masm_, "[ Block");
1368 RecordStatementPosition(node); 1368 CodeForStatement(node);
1369 node->set_break_stack_height(break_stack_height_); 1369 node->set_break_stack_height(break_stack_height_);
1370 VisitStatements(node->statements()); 1370 VisitStatements(node->statements());
1371 __ bind(node->break_target()); 1371 __ bind(node->break_target());
1372 } 1372 }
1373 1373
1374 1374
1375 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 1375 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
1376 frame_->Push(Immediate(pairs)); 1376 frame_->Push(Immediate(pairs));
1377 frame_->Push(esi); 1377 frame_->Push(esi);
1378 frame_->Push(Immediate(Smi::FromInt(is_eval() ? 1 : 0))); 1378 frame_->Push(Immediate(Smi::FromInt(is_eval() ? 1 : 0)));
1379 __ CallRuntime(Runtime::kDeclareGlobals, 3); 1379 __ CallRuntime(Runtime::kDeclareGlobals, 3);
1380 // Return value is ignored. 1380 // Return value is ignored.
1381 } 1381 }
1382 1382
1383 1383
1384 void CodeGenerator::VisitDeclaration(Declaration* node) { 1384 void CodeGenerator::VisitDeclaration(Declaration* node) {
1385 Comment cmnt(masm_, "[ Declaration"); 1385 Comment cmnt(masm_, "[ Declaration");
1386 CodeForStatement(node);
1386 Variable* var = node->proxy()->var(); 1387 Variable* var = node->proxy()->var();
1387 ASSERT(var != NULL); // must have been resolved 1388 ASSERT(var != NULL); // must have been resolved
1388 Slot* slot = var->slot(); 1389 Slot* slot = var->slot();
1389 1390
1390 // If it was not possible to allocate the variable at compile time, 1391 // If it was not possible to allocate the variable at compile time,
1391 // we need to "declare" it at runtime to make sure it actually 1392 // we need to "declare" it at runtime to make sure it actually
1392 // exists in the local context. 1393 // exists in the local context.
1393 if (slot != NULL && slot->type() == Slot::LOOKUP) { 1394 if (slot != NULL && slot->type() == Slot::LOOKUP) {
1394 // Variables with a "LOOKUP" slot were introduced as non-locals 1395 // Variables with a "LOOKUP" slot were introduced as non-locals
1395 // during variable resolution and must have mode DYNAMIC. 1396 // during variable resolution and must have mode DYNAMIC.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1437 // safe to pop the value lying on top of the reference before unloading 1438 // safe to pop the value lying on top of the reference before unloading
1438 // the reference itself (which preserves the top of stack) because we 1439 // the reference itself (which preserves the top of stack) because we
1439 // know that it is a zero-sized reference. 1440 // know that it is a zero-sized reference.
1440 frame_->Pop(); 1441 frame_->Pop();
1441 } 1442 }
1442 } 1443 }
1443 1444
1444 1445
1445 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) { 1446 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) {
1446 Comment cmnt(masm_, "[ ExpressionStatement"); 1447 Comment cmnt(masm_, "[ ExpressionStatement");
1447 RecordStatementPosition(node); 1448 CodeForStatement(node);
1448 Expression* expression = node->expression(); 1449 Expression* expression = node->expression();
1449 expression->MarkAsStatement(); 1450 expression->MarkAsStatement();
1450 Load(expression); 1451 Load(expression);
1451 // Remove the lingering expression result from the top of stack. 1452 // Remove the lingering expression result from the top of stack.
1452 frame_->Pop(); 1453 frame_->Pop();
1453 } 1454 }
1454 1455
1455 1456
1456 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) { 1457 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) {
1457 Comment cmnt(masm_, "// EmptyStatement"); 1458 Comment cmnt(masm_, "// EmptyStatement");
1459 CodeForStatement(node);
1458 // nothing to do 1460 // nothing to do
1459 } 1461 }
1460 1462
1461 1463
1462 void CodeGenerator::VisitIfStatement(IfStatement* node) { 1464 void CodeGenerator::VisitIfStatement(IfStatement* node) {
1463 Comment cmnt(masm_, "[ IfStatement"); 1465 Comment cmnt(masm_, "[ IfStatement");
1464 // Generate different code depending on which 1466 // Generate different code depending on which
1465 // parts of the if statement are present or not. 1467 // parts of the if statement are present or not.
1466 bool has_then_stm = node->HasThenStatement(); 1468 bool has_then_stm = node->HasThenStatement();
1467 bool has_else_stm = node->HasElseStatement(); 1469 bool has_else_stm = node->HasElseStatement();
1468 1470
1469 RecordStatementPosition(node); 1471 CodeForStatement(node);
1470 Label exit; 1472 Label exit;
1471 if (has_then_stm && has_else_stm) { 1473 if (has_then_stm && has_else_stm) {
1472 Label then; 1474 Label then;
1473 Label else_; 1475 Label else_;
1474 // if (cond) 1476 // if (cond)
1475 LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &then, &else_, true); 1477 LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &then, &else_, true);
1476 Branch(false, &else_); 1478 Branch(false, &else_);
1477 // then 1479 // then
1478 __ bind(&then); 1480 __ bind(&then);
1479 Visit(node->then_statement()); 1481 Visit(node->then_statement());
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1521 1523
1522 1524
1523 void CodeGenerator::CleanStack(int num_bytes) { 1525 void CodeGenerator::CleanStack(int num_bytes) {
1524 ASSERT(num_bytes % kPointerSize == 0); 1526 ASSERT(num_bytes % kPointerSize == 0);
1525 frame_->Drop(num_bytes / kPointerSize); 1527 frame_->Drop(num_bytes / kPointerSize);
1526 } 1528 }
1527 1529
1528 1530
1529 void CodeGenerator::VisitContinueStatement(ContinueStatement* node) { 1531 void CodeGenerator::VisitContinueStatement(ContinueStatement* node) {
1530 Comment cmnt(masm_, "[ ContinueStatement"); 1532 Comment cmnt(masm_, "[ ContinueStatement");
1531 RecordStatementPosition(node); 1533 CodeForStatement(node);
1532 CleanStack(break_stack_height_ - node->target()->break_stack_height()); 1534 CleanStack(break_stack_height_ - node->target()->break_stack_height());
1533 __ jmp(node->target()->continue_target()); 1535 __ jmp(node->target()->continue_target());
1534 } 1536 }
1535 1537
1536 1538
1537 void CodeGenerator::VisitBreakStatement(BreakStatement* node) { 1539 void CodeGenerator::VisitBreakStatement(BreakStatement* node) {
1538 Comment cmnt(masm_, "[ BreakStatement"); 1540 Comment cmnt(masm_, "[ BreakStatement");
1539 RecordStatementPosition(node); 1541 CodeForStatement(node);
1540 CleanStack(break_stack_height_ - node->target()->break_stack_height()); 1542 CleanStack(break_stack_height_ - node->target()->break_stack_height());
1541 __ jmp(node->target()->break_target()); 1543 __ jmp(node->target()->break_target());
1542 } 1544 }
1543 1545
1544 1546
1545 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) { 1547 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) {
1546 Comment cmnt(masm_, "[ ReturnStatement"); 1548 Comment cmnt(masm_, "[ ReturnStatement");
1547 RecordStatementPosition(node); 1549 CodeForStatement(node);
1548 Load(node->expression()); 1550 Load(node->expression());
1549 1551
1550 // Move the function result into eax 1552 // Move the function result into eax
1551 frame_->Pop(eax); 1553 frame_->Pop(eax);
1552 1554
1553 // If we're inside a try statement or the return instruction 1555 // If we're inside a try statement or the return instruction
1554 // sequence has been generated, we just jump to that 1556 // sequence has been generated, we just jump to that
1555 // point. Otherwise, we generate the return instruction sequence and 1557 // point. Otherwise, we generate the return instruction sequence and
1556 // bind the function return label. 1558 // bind the function return label.
1557 if (is_inside_try_ || function_return_.is_bound()) { 1559 if (is_inside_try_ || function_return_.is_bound()) {
(...skipping 17 matching lines...) Expand all
1575 // Check that the size of the code used for returning matches what is 1577 // Check that the size of the code used for returning matches what is
1576 // expected by the debugger. 1578 // expected by the debugger.
1577 ASSERT_EQ(Debug::kIa32JSReturnSequenceLength, 1579 ASSERT_EQ(Debug::kIa32JSReturnSequenceLength,
1578 __ SizeOfCodeGeneratedSince(&check_exit_codesize)); 1580 __ SizeOfCodeGeneratedSince(&check_exit_codesize));
1579 } 1581 }
1580 } 1582 }
1581 1583
1582 1584
1583 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) { 1585 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) {
1584 Comment cmnt(masm_, "[ WithEnterStatement"); 1586 Comment cmnt(masm_, "[ WithEnterStatement");
1585 RecordStatementPosition(node); 1587 CodeForStatement(node);
1586 Load(node->expression()); 1588 Load(node->expression());
1587 __ CallRuntime(Runtime::kPushContext, 1); 1589 __ CallRuntime(Runtime::kPushContext, 1);
1588 1590
1589 if (kDebug) { 1591 if (kDebug) {
1590 Label verified_true; 1592 Label verified_true;
1591 // Verify eax and esi are the same in debug mode 1593 // Verify eax and esi are the same in debug mode
1592 __ cmp(eax, Operand(esi)); 1594 __ cmp(eax, Operand(esi));
1593 __ j(equal, &verified_true); 1595 __ j(equal, &verified_true);
1594 __ int3(); 1596 __ int3();
1595 __ bind(&verified_true); 1597 __ bind(&verified_true);
1596 } 1598 }
1597 1599
1598 // Update context local. 1600 // Update context local.
1599 __ mov(frame_->Context(), esi); 1601 __ mov(frame_->Context(), esi);
1600 } 1602 }
1601 1603
1602 1604
1603 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) { 1605 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) {
1604 Comment cmnt(masm_, "[ WithExitStatement"); 1606 Comment cmnt(masm_, "[ WithExitStatement");
1607 CodeForStatement(node);
1605 // Pop context. 1608 // Pop context.
1606 __ mov(esi, ContextOperand(esi, Context::PREVIOUS_INDEX)); 1609 __ mov(esi, ContextOperand(esi, Context::PREVIOUS_INDEX));
1607 // Update context local. 1610 // Update context local.
1608 __ mov(frame_->Context(), esi); 1611 __ mov(frame_->Context(), esi);
1609 } 1612 }
1610 1613
1611 int CodeGenerator::FastCaseSwitchMaxOverheadFactor() { 1614 int CodeGenerator::FastCaseSwitchMaxOverheadFactor() {
1612 return kFastSwitchMaxOverheadFactor; 1615 return kFastSwitchMaxOverheadFactor;
1613 } 1616 }
1614 1617
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1677 1680
1678 for (int i = 0, entry_pos = table_start.pos(); 1681 for (int i = 0, entry_pos = table_start.pos();
1679 i < range; i++, entry_pos += sizeof(uint32_t)) { 1682 i < range; i++, entry_pos += sizeof(uint32_t)) {
1680 __ WriteInternalReference(entry_pos, *case_targets[i]); 1683 __ WriteInternalReference(entry_pos, *case_targets[i]);
1681 } 1684 }
1682 } 1685 }
1683 1686
1684 1687
1685 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) { 1688 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) {
1686 Comment cmnt(masm_, "[ SwitchStatement"); 1689 Comment cmnt(masm_, "[ SwitchStatement");
1687 RecordStatementPosition(node); 1690 CodeForStatement(node);
1688 node->set_break_stack_height(break_stack_height_); 1691 node->set_break_stack_height(break_stack_height_);
1689 1692
1690 Load(node->tag()); 1693 Load(node->tag());
1691 1694
1692 if (TryGenerateFastCaseSwitchStatement(node)) { 1695 if (TryGenerateFastCaseSwitchStatement(node)) {
1693 return; 1696 return;
1694 } 1697 }
1695 1698
1696 Label next, fall_through, default_case; 1699 Label next, fall_through, default_case;
1697 ZoneList<CaseClause*>* cases = node->cases(); 1700 ZoneList<CaseClause*>* cases = node->cases();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1744 frame_->Pop(); 1747 frame_->Pop();
1745 } 1748 }
1746 1749
1747 __ bind(&fall_through); 1750 __ bind(&fall_through);
1748 __ bind(node->break_target()); 1751 __ bind(node->break_target());
1749 } 1752 }
1750 1753
1751 1754
1752 void CodeGenerator::VisitLoopStatement(LoopStatement* node) { 1755 void CodeGenerator::VisitLoopStatement(LoopStatement* node) {
1753 Comment cmnt(masm_, "[ LoopStatement"); 1756 Comment cmnt(masm_, "[ LoopStatement");
1754 RecordStatementPosition(node); 1757 CodeForStatement(node);
1755 node->set_break_stack_height(break_stack_height_); 1758 node->set_break_stack_height(break_stack_height_);
1756 1759
1757 // simple condition analysis 1760 // simple condition analysis
1758 enum { ALWAYS_TRUE, ALWAYS_FALSE, DONT_KNOW } info = DONT_KNOW; 1761 enum { ALWAYS_TRUE, ALWAYS_FALSE, DONT_KNOW } info = DONT_KNOW;
1759 if (node->cond() == NULL) { 1762 if (node->cond() == NULL) {
1760 ASSERT(node->type() == LoopStatement::FOR_LOOP); 1763 ASSERT(node->type() == LoopStatement::FOR_LOOP);
1761 info = ALWAYS_TRUE; 1764 info = ALWAYS_TRUE;
1762 } else { 1765 } else {
1763 Literal* lit = node->cond()->AsLiteral(); 1766 Literal* lit = node->cond()->AsLiteral();
1764 if (lit != NULL) { 1767 if (lit != NULL) {
(...skipping 22 matching lines...) Expand all
1787 __ bind(&loop); 1790 __ bind(&loop);
1788 CheckStack(); // TODO(1222600): ignore if body contains calls. 1791 CheckStack(); // TODO(1222600): ignore if body contains calls.
1789 Visit(node->body()); 1792 Visit(node->body());
1790 1793
1791 // next 1794 // next
1792 __ bind(node->continue_target()); 1795 __ bind(node->continue_target());
1793 if (node->next() != NULL) { 1796 if (node->next() != NULL) {
1794 // Record source position of the statement as this code which is after the 1797 // Record source position of the statement as this code which is after the
1795 // code for the body actually belongs to the loop statement and not the 1798 // code for the body actually belongs to the loop statement and not the
1796 // body. 1799 // body.
1797 RecordStatementPosition(node); 1800 CodeForStatement(node);
1798 __ RecordPosition(node->statement_pos());
1799 ASSERT(node->type() == LoopStatement::FOR_LOOP); 1801 ASSERT(node->type() == LoopStatement::FOR_LOOP);
1800 Visit(node->next()); 1802 Visit(node->next());
1801 } 1803 }
1802 1804
1803 // cond 1805 // cond
1804 __ bind(&entry); 1806 __ bind(&entry);
1805 switch (info) { 1807 switch (info) {
1806 case ALWAYS_TRUE: 1808 case ALWAYS_TRUE:
1807 __ jmp(&loop); 1809 __ jmp(&loop);
1808 break; 1810 break;
1809 case ALWAYS_FALSE: 1811 case ALWAYS_FALSE:
1810 break; 1812 break;
1811 case DONT_KNOW: 1813 case DONT_KNOW:
1812 LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &loop, 1814 LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &loop,
1813 node->break_target(), true); 1815 node->break_target(), true);
1814 Branch(true, &loop); 1816 Branch(true, &loop);
1815 break; 1817 break;
1816 } 1818 }
1817 1819
1818 DecrementLoopNesting(); 1820 DecrementLoopNesting();
1819 1821
1820 // exit 1822 // exit
1821 __ bind(node->break_target()); 1823 __ bind(node->break_target());
1822 } 1824 }
1823 1825
1824 1826
1825 void CodeGenerator::VisitForInStatement(ForInStatement* node) { 1827 void CodeGenerator::VisitForInStatement(ForInStatement* node) {
1826 Comment cmnt(masm_, "[ ForInStatement"); 1828 Comment cmnt(masm_, "[ ForInStatement");
1827 RecordStatementPosition(node); 1829 CodeForStatement(node);
1828 1830
1829 // We keep stuff on the stack while the body is executing. 1831 // We keep stuff on the stack while the body is executing.
1830 // Record it, so that a break/continue crossing this statement 1832 // Record it, so that a break/continue crossing this statement
1831 // can restore the stack. 1833 // can restore the stack.
1832 const int kForInStackSize = 5 * kPointerSize; 1834 const int kForInStackSize = 5 * kPointerSize;
1833 break_stack_height_ += kForInStackSize; 1835 break_stack_height_ += kForInStackSize;
1834 node->set_break_stack_height(break_stack_height_); 1836 node->set_break_stack_height(break_stack_height_);
1835 1837
1836 Label loop, next, entry, cleanup, exit, primitive, jsobject; 1838 Label loop, next, entry, cleanup, exit, primitive, jsobject;
1837 Label end_del_check, fixed_array; 1839 Label end_del_check, fixed_array;
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
2005 2007
2006 // Exit. 2008 // Exit.
2007 __ bind(&exit); 2009 __ bind(&exit);
2008 2010
2009 break_stack_height_ -= kForInStackSize; 2011 break_stack_height_ -= kForInStackSize;
2010 } 2012 }
2011 2013
2012 2014
2013 void CodeGenerator::VisitTryCatch(TryCatch* node) { 2015 void CodeGenerator::VisitTryCatch(TryCatch* node) {
2014 Comment cmnt(masm_, "[ TryCatch"); 2016 Comment cmnt(masm_, "[ TryCatch");
2017 CodeForStatement(node);
2015 2018
2016 Label try_block, exit; 2019 Label try_block, exit;
2017 2020
2018 __ call(&try_block); 2021 __ call(&try_block);
2019 // --- Catch block --- 2022 // --- Catch block ---
2020 frame_->Push(eax); 2023 frame_->Push(eax);
2021 2024
2022 // Store the caught exception in the catch variable. 2025 // Store the caught exception in the catch variable.
2023 { Reference ref(this, node->catch_var()); 2026 { Reference ref(this, node->catch_var());
2024 ASSERT(ref.is_slot()); 2027 ASSERT(ref.is_slot());
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
2110 __ jmp(shadows[i]->original_label()); 2113 __ jmp(shadows[i]->original_label());
2111 } 2114 }
2112 } 2115 }
2113 2116
2114 __ bind(&exit); 2117 __ bind(&exit);
2115 } 2118 }
2116 2119
2117 2120
2118 void CodeGenerator::VisitTryFinally(TryFinally* node) { 2121 void CodeGenerator::VisitTryFinally(TryFinally* node) {
2119 Comment cmnt(masm_, "[ TryFinally"); 2122 Comment cmnt(masm_, "[ TryFinally");
2123 CodeForStatement(node);
2120 2124
2121 // State: Used to keep track of reason for entering the finally 2125 // State: Used to keep track of reason for entering the finally
2122 // block. Should probably be extended to hold information for 2126 // block. Should probably be extended to hold information for
2123 // break/continue from within the try block. 2127 // break/continue from within the try block.
2124 enum { FALLING, THROWING, JUMPING }; 2128 enum { FALLING, THROWING, JUMPING };
2125 2129
2126 Label exit, unlink, try_block, finally_block; 2130 Label exit, unlink, try_block, finally_block;
2127 2131
2128 __ call(&try_block); 2132 __ call(&try_block);
2129 2133
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
2247 frame_->Push(eax); // undo pop from above 2251 frame_->Push(eax); // undo pop from above
2248 __ CallRuntime(Runtime::kReThrow, 1); 2252 __ CallRuntime(Runtime::kReThrow, 1);
2249 2253
2250 // Done. 2254 // Done.
2251 __ bind(&exit); 2255 __ bind(&exit);
2252 } 2256 }
2253 2257
2254 2258
2255 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) { 2259 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) {
2256 Comment cmnt(masm_, "[ DebuggerStatement"); 2260 Comment cmnt(masm_, "[ DebuggerStatement");
2257 RecordStatementPosition(node); 2261 CodeForStatement(node);
2258 __ CallRuntime(Runtime::kDebugBreak, 0); 2262 __ CallRuntime(Runtime::kDebugBreak, 0);
2259 // Ignore the return value. 2263 // Ignore the return value.
2260 } 2264 }
2261 2265
2262 2266
2263 void CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) { 2267 void CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) {
2264 ASSERT(boilerplate->IsBoilerplate()); 2268 ASSERT(boilerplate->IsBoilerplate());
2265 2269
2266 // Push the boilerplate on the stack. 2270 // Push the boilerplate on the stack.
2267 frame_->Push(Immediate(boilerplate)); 2271 frame_->Push(Immediate(boilerplate));
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
2603 2607
2604 bool CodeGenerator::IsInlineSmi(Literal* literal) { 2608 bool CodeGenerator::IsInlineSmi(Literal* literal) {
2605 if (literal == NULL || !literal->handle()->IsSmi()) return false; 2609 if (literal == NULL || !literal->handle()->IsSmi()) return false;
2606 int int_value = Smi::cast(*literal->handle())->value(); 2610 int int_value = Smi::cast(*literal->handle())->value();
2607 return is_intn(int_value, kMaxSmiInlinedBits); 2611 return is_intn(int_value, kMaxSmiInlinedBits);
2608 } 2612 }
2609 2613
2610 2614
2611 void CodeGenerator::VisitAssignment(Assignment* node) { 2615 void CodeGenerator::VisitAssignment(Assignment* node) {
2612 Comment cmnt(masm_, "[ Assignment"); 2616 Comment cmnt(masm_, "[ Assignment");
2617 CodeForStatement(node);
2613 2618
2614 RecordStatementPosition(node);
2615 Reference target(this, node->target()); 2619 Reference target(this, node->target());
2616 if (target.is_illegal()) return; 2620 if (target.is_illegal()) return;
2617 2621
2618 if (node->op() == Token::ASSIGN || 2622 if (node->op() == Token::ASSIGN ||
2619 node->op() == Token::INIT_VAR || 2623 node->op() == Token::INIT_VAR ||
2620 node->op() == Token::INIT_CONST) { 2624 node->op() == Token::INIT_CONST) {
2621 Load(node->value()); 2625 Load(node->value());
2622 2626
2623 } else { 2627 } else {
2624 target.GetValue(NOT_INSIDE_TYPEOF); 2628 target.GetValue(NOT_INSIDE_TYPEOF);
2625 Literal* literal = node->value()->AsLiteral(); 2629 Literal* literal = node->value()->AsLiteral();
2626 if (IsInlineSmi(literal)) { 2630 if (IsInlineSmi(literal)) {
2627 SmiOperation(node->binary_op(), node->type(), literal->handle(), false, 2631 SmiOperation(node->binary_op(), node->type(), literal->handle(), false,
2628 NO_OVERWRITE); 2632 NO_OVERWRITE);
2629 } else { 2633 } else {
2630 Load(node->value()); 2634 Load(node->value());
2631 GenericBinaryOperation(node->binary_op(), node->type()); 2635 GenericBinaryOperation(node->binary_op(), node->type());
2632 } 2636 }
2633 } 2637 }
2634 2638
2635 Variable* var = node->target()->AsVariableProxy()->AsVariable(); 2639 Variable* var = node->target()->AsVariableProxy()->AsVariable();
2636 if (var != NULL && 2640 if (var != NULL &&
2637 var->mode() == Variable::CONST && 2641 var->mode() == Variable::CONST &&
2638 node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) { 2642 node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) {
2639 // Assignment ignored - leave the value on the stack. 2643 // Assignment ignored - leave the value on the stack.
2640 } else { 2644 } else {
2641 __ RecordPosition(node->position()); 2645 CodeForSourcePosition(node->position());
2642 if (node->op() == Token::INIT_CONST) { 2646 if (node->op() == Token::INIT_CONST) {
2643 // Dynamic constant initializations must use the function context 2647 // Dynamic constant initializations must use the function context
2644 // and initialize the actual constant declared. Dynamic variable 2648 // and initialize the actual constant declared. Dynamic variable
2645 // initializations are simply assignments and use SetValue. 2649 // initializations are simply assignments and use SetValue.
2646 target.SetValue(CONST_INIT); 2650 target.SetValue(CONST_INIT);
2647 } else { 2651 } else {
2648 target.SetValue(NOT_CONST_INIT); 2652 target.SetValue(NOT_CONST_INIT);
2649 } 2653 }
2650 } 2654 }
2651 } 2655 }
2652 2656
2653 2657
2654 void CodeGenerator::VisitThrow(Throw* node) { 2658 void CodeGenerator::VisitThrow(Throw* node) {
2655 Comment cmnt(masm_, "[ Throw"); 2659 Comment cmnt(masm_, "[ Throw");
2660 CodeForStatement(node);
2656 2661
2657 Load(node->exception()); 2662 Load(node->exception());
2658 __ RecordPosition(node->position());
2659 __ CallRuntime(Runtime::kThrow, 1); 2663 __ CallRuntime(Runtime::kThrow, 1);
2660 frame_->Push(eax); 2664 frame_->Push(eax);
2661 } 2665 }
2662 2666
2663 2667
2664 void CodeGenerator::VisitProperty(Property* node) { 2668 void CodeGenerator::VisitProperty(Property* node) {
2665 Comment cmnt(masm_, "[ Property"); 2669 Comment cmnt(masm_, "[ Property");
2666 2670
2667 Reference property(this, node); 2671 Reference property(this, node);
2668 property.GetValue(typeof_state()); 2672 property.GetValue(typeof_state());
2669 } 2673 }
2670 2674
2671 2675
2672 void CodeGenerator::VisitCall(Call* node) { 2676 void CodeGenerator::VisitCall(Call* node) {
2673 Comment cmnt(masm_, "[ Call"); 2677 Comment cmnt(masm_, "[ Call");
2674 2678
2675 ZoneList<Expression*>* args = node->arguments(); 2679 ZoneList<Expression*>* args = node->arguments();
2676 2680
2677 RecordStatementPosition(node); 2681 CodeForStatement(node);
2678 2682
2679 // Check if the function is a variable or a property. 2683 // Check if the function is a variable or a property.
2680 Expression* function = node->expression(); 2684 Expression* function = node->expression();
2681 Variable* var = function->AsVariableProxy()->AsVariable(); 2685 Variable* var = function->AsVariableProxy()->AsVariable();
2682 Property* property = function->AsProperty(); 2686 Property* property = function->AsProperty();
2683 2687
2684 // ------------------------------------------------------------------------ 2688 // ------------------------------------------------------------------------
2685 // Fast-case: Use inline caching. 2689 // Fast-case: Use inline caching.
2686 // --- 2690 // ---
2687 // According to ECMA-262, section 11.2.3, page 44, the function to call 2691 // According to ECMA-262, section 11.2.3, page 44, the function to call
(...skipping 16 matching lines...) Expand all
2704 LoadGlobal(); 2708 LoadGlobal();
2705 // Load the arguments. 2709 // Load the arguments.
2706 for (int i = 0; i < args->length(); i++) { 2710 for (int i = 0; i < args->length(); i++) {
2707 Load(args->at(i)); 2711 Load(args->at(i));
2708 } 2712 }
2709 2713
2710 // Setup the receiver register and call the IC initialization code. 2714 // Setup the receiver register and call the IC initialization code.
2711 Handle<Code> stub = (loop_nesting() > 0) 2715 Handle<Code> stub = (loop_nesting() > 0)
2712 ? ComputeCallInitializeInLoop(args->length()) 2716 ? ComputeCallInitializeInLoop(args->length())
2713 : ComputeCallInitialize(args->length()); 2717 : ComputeCallInitialize(args->length());
2714 __ RecordPosition(node->position()); 2718 CodeForSourcePosition(node->position());
2715 __ call(stub, RelocInfo::CODE_TARGET_CONTEXT); 2719 __ call(stub, RelocInfo::CODE_TARGET_CONTEXT);
2716 __ mov(esi, frame_->Context()); 2720 __ mov(esi, frame_->Context());
2717 2721
2718 // Overwrite the function on the stack with the result. 2722 // Overwrite the function on the stack with the result.
2719 __ mov(frame_->Top(), eax); 2723 __ mov(frame_->Top(), eax);
2720 2724
2721 } else if (var != NULL && var->slot() != NULL && 2725 } else if (var != NULL && var->slot() != NULL &&
2722 var->slot()->type() == Slot::LOOKUP) { 2726 var->slot()->type() == Slot::LOOKUP) {
2723 // ---------------------------------- 2727 // ----------------------------------
2724 // JavaScript example: 'with (obj) foo(1, 2, 3)' // foo is in obj 2728 // JavaScript example: 'with (obj) foo(1, 2, 3)' // foo is in obj
(...skipping 25 matching lines...) Expand all
2750 frame_->Push(Immediate(literal->handle())); 2754 frame_->Push(Immediate(literal->handle()));
2751 Load(property->obj()); 2755 Load(property->obj());
2752 2756
2753 // Load the arguments. 2757 // Load the arguments.
2754 for (int i = 0; i < args->length(); i++) Load(args->at(i)); 2758 for (int i = 0; i < args->length(); i++) Load(args->at(i));
2755 2759
2756 // Call the IC initialization code. 2760 // Call the IC initialization code.
2757 Handle<Code> stub = (loop_nesting() > 0) 2761 Handle<Code> stub = (loop_nesting() > 0)
2758 ? ComputeCallInitializeInLoop(args->length()) 2762 ? ComputeCallInitializeInLoop(args->length())
2759 : ComputeCallInitialize(args->length()); 2763 : ComputeCallInitialize(args->length());
2760 __ RecordPosition(node->position()); 2764 CodeForSourcePosition(node->position());
2761 __ call(stub, RelocInfo::CODE_TARGET); 2765 __ call(stub, RelocInfo::CODE_TARGET);
2762 __ mov(esi, frame_->Context()); 2766 __ mov(esi, frame_->Context());
2763 2767
2764 // Overwrite the function on the stack with the result. 2768 // Overwrite the function on the stack with the result.
2765 __ mov(frame_->Top(), eax); 2769 __ mov(frame_->Top(), eax);
2766 2770
2767 } else { 2771 } else {
2768 // ------------------------------------------- 2772 // -------------------------------------------
2769 // JavaScript example: 'array[index](1, 2, 3)' 2773 // JavaScript example: 'array[index](1, 2, 3)'
2770 // ------------------------------------------- 2774 // -------------------------------------------
(...skipping 22 matching lines...) Expand all
2793 LoadGlobalReceiver(eax); 2797 LoadGlobalReceiver(eax);
2794 2798
2795 // Call the function. 2799 // Call the function.
2796 CallWithArguments(args, node->position()); 2800 CallWithArguments(args, node->position());
2797 } 2801 }
2798 } 2802 }
2799 2803
2800 2804
2801 void CodeGenerator::VisitCallNew(CallNew* node) { 2805 void CodeGenerator::VisitCallNew(CallNew* node) {
2802 Comment cmnt(masm_, "[ CallNew"); 2806 Comment cmnt(masm_, "[ CallNew");
2807 CodeForStatement(node);
2803 2808
2804 // According to ECMA-262, section 11.2.2, page 44, the function 2809 // According to ECMA-262, section 11.2.2, page 44, the function
2805 // expression in new calls must be evaluated before the 2810 // expression in new calls must be evaluated before the
2806 // arguments. This is different from ordinary calls, where the 2811 // arguments. This is different from ordinary calls, where the
2807 // actual function to call is resolved after the arguments have been 2812 // actual function to call is resolved after the arguments have been
2808 // evaluated. 2813 // evaluated.
2809 2814
2810 // Compute function to call and use the global object as the 2815 // Compute function to call and use the global object as the
2811 // receiver. There is no need to use the global proxy here because 2816 // receiver. There is no need to use the global proxy here because
2812 // it will always be replaced with a newly allocated object. 2817 // it will always be replaced with a newly allocated object.
2813 Load(node->expression()); 2818 Load(node->expression());
2814 LoadGlobal(); 2819 LoadGlobal();
2815 2820
2816 // Push the arguments ("left-to-right") on the stack. 2821 // Push the arguments ("left-to-right") on the stack.
2817 ZoneList<Expression*>* args = node->arguments(); 2822 ZoneList<Expression*>* args = node->arguments();
2818 for (int i = 0; i < args->length(); i++) Load(args->at(i)); 2823 for (int i = 0; i < args->length(); i++) Load(args->at(i));
2819 2824
2820 // Constructors are called with the number of arguments in register 2825 // Constructors are called with the number of arguments in register
2821 // eax for now. Another option would be to have separate construct 2826 // eax for now. Another option would be to have separate construct
2822 // call trampolines per different arguments counts encountered. 2827 // call trampolines per different arguments counts encountered.
2823 __ Set(eax, Immediate(args->length())); 2828 __ Set(eax, Immediate(args->length()));
2824 2829
2825 // Load the function into temporary function slot as per calling 2830 // Load the function into temporary function slot as per calling
2826 // convention. 2831 // convention.
2827 __ mov(edi, frame_->Element(args->length() + 1)); 2832 __ mov(edi, frame_->Element(args->length() + 1));
2828 2833
2829 // Call the construct call builtin that handles allocation and 2834 // Call the construct call builtin that handles allocation and
2830 // constructor invocation. 2835 // constructor invocation.
2831 __ RecordPosition(node->position()); 2836 CodeForSourcePosition(node->position());
2832 __ call(Handle<Code>(Builtins::builtin(Builtins::JSConstructCall)), 2837 __ call(Handle<Code>(Builtins::builtin(Builtins::JSConstructCall)),
2833 RelocInfo::CONSTRUCT_CALL); 2838 RelocInfo::CONSTRUCT_CALL);
2834 // Discard the function and "push" the newly created object. 2839 // Discard the function and "push" the newly created object.
2835 __ mov(frame_->Top(), eax); 2840 __ mov(frame_->Top(), eax);
2836 } 2841 }
2837 2842
2838 2843
2839 void CodeGenerator::VisitCallEval(CallEval* node) { 2844 void CodeGenerator::VisitCallEval(CallEval* node) {
2840 Comment cmnt(masm_, "[ CallEval"); 2845 Comment cmnt(masm_, "[ CallEval");
2841 2846
2842 // In a call to eval, we first call %ResolvePossiblyDirectEval to resolve 2847 // In a call to eval, we first call %ResolvePossiblyDirectEval to resolve
2843 // the function we need to call and the receiver of the call. 2848 // the function we need to call and the receiver of the call.
2844 // Then we call the resolved function using the given arguments. 2849 // Then we call the resolved function using the given arguments.
2845 2850
2846 ZoneList<Expression*>* args = node->arguments(); 2851 ZoneList<Expression*>* args = node->arguments();
2847 Expression* function = node->expression(); 2852 Expression* function = node->expression();
2848 2853
2849 RecordStatementPosition(node); 2854 CodeForStatement(node);
2850 2855
2851 // Prepare stack for call to resolved function. 2856 // Prepare stack for call to resolved function.
2852 Load(function); 2857 Load(function);
2853 __ push(Immediate(Factory::undefined_value())); // Slot for receiver 2858 __ push(Immediate(Factory::undefined_value())); // Slot for receiver
2854 for (int i = 0; i < args->length(); i++) { 2859 for (int i = 0; i < args->length(); i++) {
2855 Load(args->at(i)); 2860 Load(args->at(i));
2856 } 2861 }
2857 2862
2858 // Prepare stack for call to ResolvePossiblyDirectEval. 2863 // Prepare stack for call to ResolvePossiblyDirectEval.
2859 __ push(Operand(esp, args->length() * kPointerSize + kPointerSize)); 2864 __ push(Operand(esp, args->length() * kPointerSize + kPointerSize));
2860 if (args->length() > 0) { 2865 if (args->length() > 0) {
2861 __ push(Operand(esp, args->length() * kPointerSize)); 2866 __ push(Operand(esp, args->length() * kPointerSize));
2862 } else { 2867 } else {
2863 __ push(Immediate(Factory::undefined_value())); 2868 __ push(Immediate(Factory::undefined_value()));
2864 } 2869 }
2865 2870
2866 // Resolve the call. 2871 // Resolve the call.
2867 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 2); 2872 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 2);
2868 2873
2869 // Touch up stack with the right values for the function and the receiver. 2874 // Touch up stack with the right values for the function and the receiver.
2870 __ mov(edx, FieldOperand(eax, FixedArray::kHeaderSize)); 2875 __ mov(edx, FieldOperand(eax, FixedArray::kHeaderSize));
2871 __ mov(Operand(esp, (args->length() + 1) * kPointerSize), edx); 2876 __ mov(Operand(esp, (args->length() + 1) * kPointerSize), edx);
2872 __ mov(edx, FieldOperand(eax, FixedArray::kHeaderSize + kPointerSize)); 2877 __ mov(edx, FieldOperand(eax, FixedArray::kHeaderSize + kPointerSize));
2873 __ mov(Operand(esp, args->length() * kPointerSize), edx); 2878 __ mov(Operand(esp, args->length() * kPointerSize), edx);
2874 2879
2875 // Call the function. 2880 // Call the function.
2876 __ RecordPosition(node->position()); 2881 CodeForSourcePosition(node->position());
2877 2882
2878 CallFunctionStub call_function(args->length()); 2883 CallFunctionStub call_function(args->length());
2879 __ CallStub(&call_function); 2884 __ CallStub(&call_function);
2880 2885
2881 // Restore context and pop function from the stack. 2886 // Restore context and pop function from the stack.
2882 __ mov(esi, frame_->Context()); 2887 __ mov(esi, frame_->Context());
2883 __ mov(frame_->Top(), eax); 2888 __ mov(frame_->Top(), eax);
2884 } 2889 }
2885 2890
2886 2891
(...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after
3764 SmiComparison(cc, right->AsLiteral()->handle(), strict); 3769 SmiComparison(cc, right->AsLiteral()->handle(), strict);
3765 return; 3770 return;
3766 } 3771 }
3767 3772
3768 Load(left); 3773 Load(left);
3769 Load(right); 3774 Load(right);
3770 Comparison(cc, strict); 3775 Comparison(cc, strict);
3771 } 3776 }
3772 3777
3773 3778
3774 void CodeGenerator::RecordStatementPosition(Node* node) {
3775 if (FLAG_debug_info) {
3776 int pos = node->statement_pos();
3777 if (pos != RelocInfo::kNoPosition) {
3778 __ RecordStatementPosition(pos);
3779 }
3780 }
3781 }
3782
3783
3784 #undef __ 3779 #undef __
3785 #define __ masm-> 3780 #define __ masm->
3786 3781
3787 Handle<String> Reference::GetName() { 3782 Handle<String> Reference::GetName() {
3788 ASSERT(type_ == NAMED); 3783 ASSERT(type_ == NAMED);
3789 Property* property = expression_->AsProperty(); 3784 Property* property = expression_->AsProperty();
3790 if (property == NULL) { 3785 if (property == NULL) {
3791 // Global variable reference treated as a named property reference. 3786 // Global variable reference treated as a named property reference.
3792 VariableProxy* proxy = expression_->AsVariableProxy(); 3787 VariableProxy* proxy = expression_->AsVariableProxy();
3793 ASSERT(proxy->AsVariable() != NULL); 3788 ASSERT(proxy->AsVariable() != NULL);
3794 ASSERT(proxy->AsVariable()->is_global()); 3789 ASSERT(proxy->AsVariable()->is_global());
3795 return proxy->name(); 3790 return proxy->name();
3796 } else { 3791 } else {
3797 MacroAssembler* masm = cgen_->masm();
3798 __ RecordPosition(property->position());
3799 Literal* raw_name = property->key()->AsLiteral(); 3792 Literal* raw_name = property->key()->AsLiteral();
3800 ASSERT(raw_name != NULL); 3793 ASSERT(raw_name != NULL);
3801 return Handle<String>(String::cast(*raw_name->handle())); 3794 return Handle<String>(String::cast(*raw_name->handle()));
3802 } 3795 }
3803 } 3796 }
3804 3797
3805 3798
3806 void Reference::GetValue(TypeofState typeof_state) { 3799 void Reference::GetValue(TypeofState typeof_state) {
3807 ASSERT(!is_illegal()); 3800 ASSERT(!is_illegal());
3808 ASSERT(!cgen_->has_cc()); 3801 ASSERT(!cgen_->has_cc());
(...skipping 30 matching lines...) Expand all
3839 frame->Push(eax); // IC call leaves result in eax, push it out 3832 frame->Push(eax); // IC call leaves result in eax, push it out
3840 break; 3833 break;
3841 } 3834 }
3842 3835
3843 case KEYED: { 3836 case KEYED: {
3844 // TODO(1241834): Make sure that this it is safe to ignore the 3837 // TODO(1241834): Make sure that this it is safe to ignore the
3845 // distinction between expressions in a typeof and not in a typeof. 3838 // distinction between expressions in a typeof and not in a typeof.
3846 Comment cmnt(masm, "[ Load from keyed Property"); 3839 Comment cmnt(masm, "[ Load from keyed Property");
3847 Property* property = expression_->AsProperty(); 3840 Property* property = expression_->AsProperty();
3848 ASSERT(property != NULL); 3841 ASSERT(property != NULL);
3849 __ RecordPosition(property->position());
3850 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 3842 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
3851 3843
3852 Variable* var = expression_->AsVariableProxy()->AsVariable(); 3844 Variable* var = expression_->AsVariableProxy()->AsVariable();
3853 if (var != NULL) { 3845 if (var != NULL) {
3854 ASSERT(var->is_global()); 3846 ASSERT(var->is_global());
3855 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); 3847 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
3856 } else { 3848 } else {
3857 __ call(ic, RelocInfo::CODE_TARGET); 3849 __ call(ic, RelocInfo::CODE_TARGET);
3858 } 3850 }
3859 frame->Push(eax); // IC call leaves result in eax, push it out 3851 frame->Push(eax); // IC call leaves result in eax, push it out
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
3958 __ mov(ecx, name); 3950 __ mov(ecx, name);
3959 __ call(ic, RelocInfo::CODE_TARGET); 3951 __ call(ic, RelocInfo::CODE_TARGET);
3960 frame->Push(eax); // IC call leaves result in eax, push it out 3952 frame->Push(eax); // IC call leaves result in eax, push it out
3961 break; 3953 break;
3962 } 3954 }
3963 3955
3964 case KEYED: { 3956 case KEYED: {
3965 Comment cmnt(masm, "[ Store to keyed Property"); 3957 Comment cmnt(masm, "[ Store to keyed Property");
3966 Property* property = expression_->AsProperty(); 3958 Property* property = expression_->AsProperty();
3967 ASSERT(property != NULL); 3959 ASSERT(property != NULL);
3968 __ RecordPosition(property->position());
3969 // Call IC code. 3960 // Call IC code.
3970 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 3961 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
3971 // TODO(1222589): Make the IC grab the values from the stack. 3962 // TODO(1222589): Make the IC grab the values from the stack.
3972 frame->Pop(eax); 3963 frame->Pop(eax);
3973 __ call(ic, RelocInfo::CODE_TARGET); 3964 __ call(ic, RelocInfo::CODE_TARGET);
3974 frame->Push(eax); // IC call leaves result in eax, push it out 3965 frame->Push(eax); // IC call leaves result in eax, push it out
3975 break; 3966 break;
3976 } 3967 }
3977 3968
3978 default: 3969 default:
(...skipping 1220 matching lines...) Expand 10 before | Expand all | Expand 10 after
5199 5190
5200 // Slow-case: Go through the JavaScript implementation. 5191 // Slow-case: Go through the JavaScript implementation.
5201 __ bind(&slow); 5192 __ bind(&slow);
5202 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 5193 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
5203 } 5194 }
5204 5195
5205 5196
5206 #undef __ 5197 #undef __
5207 5198
5208 } } // namespace v8::internal 5199 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/codegen-ia32.h ('k') | src/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698