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

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

Issue 15077: Merge bleeding-edge change 985, RecordStatementPosition reform, into... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 112
113 113
114 // Calling conventions: 114 // Calling conventions:
115 // ebp: frame pointer 115 // ebp: frame pointer
116 // esp: stack pointer 116 // esp: stack pointer
117 // edi: caller's parameter pointer 117 // edi: caller's parameter pointer
118 // esi: callee's context 118 // esi: callee's context
119 119
120 void CodeGenerator::GenCode(FunctionLiteral* fun) { 120 void CodeGenerator::GenCode(FunctionLiteral* fun) {
121 // Record the position for debugging purposes. 121 // Record the position for debugging purposes.
122 __ RecordPosition(fun->start_position()); 122 CodeForSourcePosition(fun->start_position());
123 123
124 ZoneList<Statement*>* body = fun->body(); 124 ZoneList<Statement*>* body = fun->body();
125 125
126 // Initialize state. 126 // Initialize state.
127 ASSERT(scope_ == NULL); 127 ASSERT(scope_ == NULL);
128 scope_ = fun->scope(); 128 scope_ = fun->scope();
129 ASSERT(allocator_ == NULL); 129 ASSERT(allocator_ == NULL);
130 RegisterAllocator register_allocator(this); 130 RegisterAllocator register_allocator(this);
131 allocator_ = &register_allocator; 131 allocator_ = &register_allocator;
132 ASSERT(frame_ == NULL); 132 ASSERT(frame_ == NULL);
(...skipping 1135 matching lines...) Expand 10 before | Expand all | Expand 10 after
1268 // arguments. The receiver is the TOS. 1268 // arguments. The receiver is the TOS.
1269 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args, 1269 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args,
1270 int position) { 1270 int position) {
1271 // Push the arguments ("left-to-right") on the stack. 1271 // Push the arguments ("left-to-right") on the stack.
1272 int arg_count = args->length(); 1272 int arg_count = args->length();
1273 for (int i = 0; i < arg_count; i++) { 1273 for (int i = 0; i < arg_count; i++) {
1274 LoadAndSpill(args->at(i)); 1274 LoadAndSpill(args->at(i));
1275 } 1275 }
1276 1276
1277 // Record the position for debugging purposes. 1277 // Record the position for debugging purposes.
1278 __ RecordPosition(position); 1278 CodeForSourcePosition(position);
1279 1279
1280 // Use the shared code stub to call the function. 1280 // Use the shared code stub to call the function.
1281 CallFunctionStub call_function(arg_count); 1281 CallFunctionStub call_function(arg_count);
1282 frame_->CallStub(&call_function, arg_count + 1); 1282 frame_->CallStub(&call_function, arg_count + 1);
1283 1283
1284 // Restore context and pop function from the stack. 1284 // Restore context and pop function from the stack.
1285 __ mov(esi, frame_->Context()); 1285 __ mov(esi, frame_->Context());
1286 __ mov(frame_->Top(), eax); 1286 __ mov(frame_->Top(), eax);
1287 } 1287 }
1288 1288
(...skipping 27 matching lines...) Expand all
1316 ASSERT(!in_spilled_code()); 1316 ASSERT(!in_spilled_code());
1317 for (int i = 0; frame_ != NULL && i < statements->length(); i++) { 1317 for (int i = 0; frame_ != NULL && i < statements->length(); i++) {
1318 Visit(statements->at(i)); 1318 Visit(statements->at(i));
1319 } 1319 }
1320 } 1320 }
1321 1321
1322 1322
1323 void CodeGenerator::VisitBlock(Block* node) { 1323 void CodeGenerator::VisitBlock(Block* node) {
1324 ASSERT(!in_spilled_code()); 1324 ASSERT(!in_spilled_code());
1325 Comment cmnt(masm_, "[ Block"); 1325 Comment cmnt(masm_, "[ Block");
1326 RecordStatementPosition(node); 1326 CodeForStatement(node);
1327 node->set_break_stack_height(break_stack_height_); 1327 node->set_break_stack_height(break_stack_height_);
1328 node->break_target()->set_code_generator(this); 1328 node->break_target()->set_code_generator(this);
1329 VisitStatements(node->statements()); 1329 VisitStatements(node->statements());
1330 if (node->break_target()->is_linked()) { 1330 if (node->break_target()->is_linked()) {
1331 node->break_target()->Bind(); 1331 node->break_target()->Bind();
1332 } 1332 }
1333 } 1333 }
1334 1334
1335 1335
1336 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 1336 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
1337 VirtualFrame::SpilledScope spilled_scope(this); 1337 VirtualFrame::SpilledScope spilled_scope(this);
1338 frame_->EmitPush(Immediate(pairs)); 1338 frame_->EmitPush(Immediate(pairs));
1339 frame_->EmitPush(esi); 1339 frame_->EmitPush(esi);
1340 frame_->EmitPush(Immediate(Smi::FromInt(is_eval() ? 1 : 0))); 1340 frame_->EmitPush(Immediate(Smi::FromInt(is_eval() ? 1 : 0)));
1341 frame_->CallRuntime(Runtime::kDeclareGlobals, 3); 1341 frame_->CallRuntime(Runtime::kDeclareGlobals, 3);
1342 // Return value is ignored. 1342 // Return value is ignored.
1343 } 1343 }
1344 1344
1345 1345
1346 void CodeGenerator::VisitDeclaration(Declaration* node) { 1346 void CodeGenerator::VisitDeclaration(Declaration* node) {
1347 Comment cmnt(masm_, "[ Declaration"); 1347 Comment cmnt(masm_, "[ Declaration");
1348 CodeForStatement(node);
1348 Variable* var = node->proxy()->var(); 1349 Variable* var = node->proxy()->var();
1349 ASSERT(var != NULL); // must have been resolved 1350 ASSERT(var != NULL); // must have been resolved
1350 Slot* slot = var->slot(); 1351 Slot* slot = var->slot();
1351 1352
1352 // If it was not possible to allocate the variable at compile time, 1353 // If it was not possible to allocate the variable at compile time,
1353 // we need to "declare" it at runtime to make sure it actually 1354 // we need to "declare" it at runtime to make sure it actually
1354 // exists in the local context. 1355 // exists in the local context.
1355 if (slot != NULL && slot->type() == Slot::LOOKUP) { 1356 if (slot != NULL && slot->type() == Slot::LOOKUP) {
1356 // Variables with a "LOOKUP" slot were introduced as non-locals 1357 // Variables with a "LOOKUP" slot were introduced as non-locals
1357 // during variable resolution and must have mode DYNAMIC. 1358 // during variable resolution and must have mode DYNAMIC.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1402 // the reference itself (which preserves the top of stack) because we 1403 // the reference itself (which preserves the top of stack) because we
1403 // know that it is a zero-sized reference. 1404 // know that it is a zero-sized reference.
1404 frame_->Drop(); 1405 frame_->Drop();
1405 } 1406 }
1406 } 1407 }
1407 1408
1408 1409
1409 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) { 1410 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) {
1410 ASSERT(!in_spilled_code()); 1411 ASSERT(!in_spilled_code());
1411 Comment cmnt(masm_, "[ ExpressionStatement"); 1412 Comment cmnt(masm_, "[ ExpressionStatement");
1412 RecordStatementPosition(node); 1413 CodeForStatement(node);
1413 Expression* expression = node->expression(); 1414 Expression* expression = node->expression();
1414 expression->MarkAsStatement(); 1415 expression->MarkAsStatement();
1415 Load(expression); 1416 Load(expression);
1416 // Remove the lingering expression result from the top of stack. 1417 // Remove the lingering expression result from the top of stack.
1417 frame_->Drop(); 1418 frame_->Drop();
1418 } 1419 }
1419 1420
1420 1421
1421 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) { 1422 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) {
1422 ASSERT(!in_spilled_code()); 1423 ASSERT(!in_spilled_code());
1423 VirtualFrame::SpilledScope spilled_scope(this); 1424 VirtualFrame::SpilledScope spilled_scope(this);
1424 Comment cmnt(masm_, "// EmptyStatement"); 1425 Comment cmnt(masm_, "// EmptyStatement");
1426 CodeForStatement(node);
1425 // nothing to do 1427 // nothing to do
1426 } 1428 }
1427 1429
1428 1430
1429 void CodeGenerator::VisitIfStatement(IfStatement* node) { 1431 void CodeGenerator::VisitIfStatement(IfStatement* node) {
1430 ASSERT(!in_spilled_code()); 1432 ASSERT(!in_spilled_code());
1431 VirtualFrame::SpilledScope spilled_scope(this); 1433 VirtualFrame::SpilledScope spilled_scope(this);
1432 Comment cmnt(masm_, "[ IfStatement"); 1434 Comment cmnt(masm_, "[ IfStatement");
1433 // Generate different code depending on which parts of the if statement 1435 // Generate different code depending on which parts of the if statement
1434 // are present or not. 1436 // are present or not.
1435 bool has_then_stm = node->HasThenStatement(); 1437 bool has_then_stm = node->HasThenStatement();
1436 bool has_else_stm = node->HasElseStatement(); 1438 bool has_else_stm = node->HasElseStatement();
1437 1439
1438 RecordStatementPosition(node); 1440 CodeForStatement(node);
1439 JumpTarget exit(this); 1441 JumpTarget exit(this);
1440 if (has_then_stm && has_else_stm) { 1442 if (has_then_stm && has_else_stm) {
1441 JumpTarget then(this); 1443 JumpTarget then(this);
1442 JumpTarget else_(this); 1444 JumpTarget else_(this);
1443 // if (cond) 1445 // if (cond)
1444 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, 1446 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF,
1445 &then, &else_, true); 1447 &then, &else_, true);
1446 if (frame_ != NULL) { 1448 if (frame_ != NULL) {
1447 // A NULL frame here indicates that the code for the condition cannot 1449 // A NULL frame here indicates that the code for the condition cannot
1448 // fall-through, i.e. it causes unconditional branchs to targets. 1450 // fall-through, i.e. it causes unconditional branchs to targets.
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1526 void CodeGenerator::CleanStack(int num_bytes) { 1528 void CodeGenerator::CleanStack(int num_bytes) {
1527 ASSERT(num_bytes % kPointerSize == 0); 1529 ASSERT(num_bytes % kPointerSize == 0);
1528 frame_->Drop(num_bytes / kPointerSize); 1530 frame_->Drop(num_bytes / kPointerSize);
1529 } 1531 }
1530 1532
1531 1533
1532 void CodeGenerator::VisitContinueStatement(ContinueStatement* node) { 1534 void CodeGenerator::VisitContinueStatement(ContinueStatement* node) {
1533 ASSERT(!in_spilled_code()); 1535 ASSERT(!in_spilled_code());
1534 VirtualFrame::SpilledScope spilled_scope(this); 1536 VirtualFrame::SpilledScope spilled_scope(this);
1535 Comment cmnt(masm_, "[ ContinueStatement"); 1537 Comment cmnt(masm_, "[ ContinueStatement");
1536 RecordStatementPosition(node); 1538 CodeForStatement(node);
1537 CleanStack(break_stack_height_ - node->target()->break_stack_height()); 1539 CleanStack(break_stack_height_ - node->target()->break_stack_height());
1538 node->target()->continue_target()->Jump(); 1540 node->target()->continue_target()->Jump();
1539 } 1541 }
1540 1542
1541 1543
1542 void CodeGenerator::VisitBreakStatement(BreakStatement* node) { 1544 void CodeGenerator::VisitBreakStatement(BreakStatement* node) {
1543 ASSERT(!in_spilled_code()); 1545 ASSERT(!in_spilled_code());
1544 VirtualFrame::SpilledScope spilled_scope(this); 1546 VirtualFrame::SpilledScope spilled_scope(this);
1545 Comment cmnt(masm_, "[ BreakStatement"); 1547 Comment cmnt(masm_, "[ BreakStatement");
1546 RecordStatementPosition(node); 1548 CodeForStatement(node);
1547 CleanStack(break_stack_height_ - node->target()->break_stack_height()); 1549 CleanStack(break_stack_height_ - node->target()->break_stack_height());
1548 node->target()->break_target()->Jump(); 1550 node->target()->break_target()->Jump();
1549 } 1551 }
1550 1552
1551 1553
1552 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) { 1554 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) {
1553 ASSERT(!in_spilled_code()); 1555 ASSERT(!in_spilled_code());
1554 VirtualFrame::SpilledScope spilled_scope(this); 1556 VirtualFrame::SpilledScope spilled_scope(this);
1555 Comment cmnt(masm_, "[ ReturnStatement"); 1557 Comment cmnt(masm_, "[ ReturnStatement");
1556 RecordStatementPosition(node); 1558 CodeForStatement(node);
1557 LoadAndSpill(node->expression()); 1559 LoadAndSpill(node->expression());
1558 1560
1559 // Move the function result into eax 1561 // Move the function result into eax
1560 frame_->EmitPop(eax); 1562 frame_->EmitPop(eax);
1561 1563
1562 // If we're inside a try statement or the return instruction 1564 // If we're inside a try statement or the return instruction
1563 // sequence has been generated, we just jump to that 1565 // sequence has been generated, we just jump to that
1564 // point. Otherwise, we generate the return instruction sequence and 1566 // point. Otherwise, we generate the return instruction sequence and
1565 // bind the function return label. 1567 // bind the function return label.
1566 if (is_inside_try_ || function_return_.is_bound()) { 1568 if (is_inside_try_ || function_return_.is_bound()) {
(...skipping 20 matching lines...) Expand all
1587 ASSERT_EQ(Debug::kIa32JSReturnSequenceLength, 1589 ASSERT_EQ(Debug::kIa32JSReturnSequenceLength,
1588 __ SizeOfCodeGeneratedSince(&check_exit_codesize)); 1590 __ SizeOfCodeGeneratedSince(&check_exit_codesize));
1589 } 1591 }
1590 } 1592 }
1591 1593
1592 1594
1593 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) { 1595 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) {
1594 ASSERT(!in_spilled_code()); 1596 ASSERT(!in_spilled_code());
1595 VirtualFrame::SpilledScope spilled_scope(this); 1597 VirtualFrame::SpilledScope spilled_scope(this);
1596 Comment cmnt(masm_, "[ WithEnterStatement"); 1598 Comment cmnt(masm_, "[ WithEnterStatement");
1597 RecordStatementPosition(node); 1599 CodeForStatement(node);
1598 LoadAndSpill(node->expression()); 1600 LoadAndSpill(node->expression());
1599 frame_->CallRuntime(Runtime::kPushContext, 1); 1601 frame_->CallRuntime(Runtime::kPushContext, 1);
1600 1602
1601 if (kDebug) { 1603 if (kDebug) {
1602 JumpTarget verified_true(this); 1604 JumpTarget verified_true(this);
1603 // Verify eax and esi are the same in debug mode 1605 // Verify eax and esi are the same in debug mode
1604 __ cmp(eax, Operand(esi)); 1606 __ cmp(eax, Operand(esi));
1605 verified_true.Branch(equal); 1607 verified_true.Branch(equal);
1606 __ int3(); 1608 __ int3();
1607 verified_true.Bind(); 1609 verified_true.Bind();
1608 } 1610 }
1609 1611
1610 // Update context local. 1612 // Update context local.
1611 __ mov(frame_->Context(), esi); 1613 __ mov(frame_->Context(), esi);
1612 } 1614 }
1613 1615
1614 1616
1615 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) { 1617 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) {
1616 ASSERT(!in_spilled_code()); 1618 ASSERT(!in_spilled_code());
1617 VirtualFrame::SpilledScope spilled_scope(this); 1619 VirtualFrame::SpilledScope spilled_scope(this);
1618 Comment cmnt(masm_, "[ WithExitStatement"); 1620 Comment cmnt(masm_, "[ WithExitStatement");
1621 CodeForStatement(node);
1619 // Pop context. 1622 // Pop context.
1620 __ mov(esi, ContextOperand(esi, Context::PREVIOUS_INDEX)); 1623 __ mov(esi, ContextOperand(esi, Context::PREVIOUS_INDEX));
1621 // Update context local. 1624 // Update context local.
1622 __ mov(frame_->Context(), esi); 1625 __ mov(frame_->Context(), esi);
1623 } 1626 }
1624 1627
1625 1628
1626 int CodeGenerator::FastCaseSwitchMaxOverheadFactor() { 1629 int CodeGenerator::FastCaseSwitchMaxOverheadFactor() {
1627 return kFastSwitchMaxOverheadFactor; 1630 return kFastSwitchMaxOverheadFactor;
1628 } 1631 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1697 i++, entry_pos += sizeof(uint32_t)) { 1700 i++, entry_pos += sizeof(uint32_t)) {
1698 __ WriteInternalReference(entry_pos, *case_targets[i]->label()); 1701 __ WriteInternalReference(entry_pos, *case_targets[i]->label());
1699 } 1702 }
1700 } 1703 }
1701 1704
1702 1705
1703 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) { 1706 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) {
1704 ASSERT(!in_spilled_code()); 1707 ASSERT(!in_spilled_code());
1705 VirtualFrame::SpilledScope spilled_scope(this); 1708 VirtualFrame::SpilledScope spilled_scope(this);
1706 Comment cmnt(masm_, "[ SwitchStatement"); 1709 Comment cmnt(masm_, "[ SwitchStatement");
1707 RecordStatementPosition(node); 1710 CodeForStatement(node);
1708 node->set_break_stack_height(break_stack_height_); 1711 node->set_break_stack_height(break_stack_height_);
1709 node->break_target()->set_code_generator(this); 1712 node->break_target()->set_code_generator(this);
1710 1713
1711 LoadAndSpill(node->tag()); 1714 LoadAndSpill(node->tag());
1712 1715
1713 if (TryGenerateFastCaseSwitchStatement(node)) { 1716 if (TryGenerateFastCaseSwitchStatement(node)) {
1714 return; 1717 return;
1715 } 1718 }
1716 1719
1717 JumpTarget next_test(this); 1720 JumpTarget next_test(this);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1789 1792
1790 if (node->break_target()->is_linked()) { 1793 if (node->break_target()->is_linked()) {
1791 node->break_target()->Bind(); 1794 node->break_target()->Bind();
1792 } 1795 }
1793 } 1796 }
1794 1797
1795 1798
1796 void CodeGenerator::VisitLoopStatement(LoopStatement* node) { 1799 void CodeGenerator::VisitLoopStatement(LoopStatement* node) {
1797 ASSERT(!in_spilled_code()); 1800 ASSERT(!in_spilled_code());
1798 Comment cmnt(masm_, "[ LoopStatement"); 1801 Comment cmnt(masm_, "[ LoopStatement");
1799 RecordStatementPosition(node); 1802 CodeForStatement(node);
1800 node->set_break_stack_height(break_stack_height_); 1803 node->set_break_stack_height(break_stack_height_);
1801 node->break_target()->set_code_generator(this); 1804 node->break_target()->set_code_generator(this);
1802 node->continue_target()->set_code_generator(this); 1805 node->continue_target()->set_code_generator(this);
1803 1806
1804 // Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a 1807 // Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a
1805 // known result for the test expression, with no side effects. 1808 // known result for the test expression, with no side effects.
1806 enum { ALWAYS_TRUE, ALWAYS_FALSE, DONT_KNOW } info = DONT_KNOW; 1809 enum { ALWAYS_TRUE, ALWAYS_FALSE, DONT_KNOW } info = DONT_KNOW;
1807 if (node->cond() == NULL) { 1810 if (node->cond() == NULL) {
1808 ASSERT(node->type() == LoopStatement::FOR_LOOP); 1811 ASSERT(node->type() == LoopStatement::FOR_LOOP);
1809 info = ALWAYS_TRUE; 1812 info = ALWAYS_TRUE;
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1951 } 1954 }
1952 } else { 1955 } else {
1953 // If there is an update statement and control flow can reach it 1956 // If there is an update statement and control flow can reach it
1954 // via falling out of the body of the loop or continuing, we 1957 // via falling out of the body of the loop or continuing, we
1955 // compile the update statement. 1958 // compile the update statement.
1956 if (frame_ != NULL || node->continue_target()->is_linked()) { 1959 if (frame_ != NULL || node->continue_target()->is_linked()) {
1957 node->continue_target()->Bind(); 1960 node->continue_target()->Bind();
1958 // Record source position of the statement as this code which is 1961 // Record source position of the statement as this code which is
1959 // after the code for the body actually belongs to the loop 1962 // after the code for the body actually belongs to the loop
1960 // statement and not the body. 1963 // statement and not the body.
1961 RecordStatementPosition(node); 1964 CodeForStatement(node);
1962 __ RecordPosition(node->statement_pos());
1963 ASSERT(node->type() == LoopStatement::FOR_LOOP); 1965 ASSERT(node->type() == LoopStatement::FOR_LOOP);
1964 Visit(node->next()); 1966 Visit(node->next());
1965 loop.Jump(); 1967 loop.Jump();
1966 } 1968 }
1967 } 1969 }
1968 } 1970 }
1969 break; 1971 break;
1970 } 1972 }
1971 } 1973 }
1972 1974
1973 DecrementLoopNesting(); 1975 DecrementLoopNesting();
1974 if (node->break_target()->is_linked()) { 1976 if (node->break_target()->is_linked()) {
1975 node->break_target()->Bind(); 1977 node->break_target()->Bind();
1976 } 1978 }
1977 } 1979 }
1978 1980
1979 1981
1980 void CodeGenerator::VisitForInStatement(ForInStatement* node) { 1982 void CodeGenerator::VisitForInStatement(ForInStatement* node) {
1981 ASSERT(!in_spilled_code()); 1983 ASSERT(!in_spilled_code());
1982 VirtualFrame::SpilledScope spilled_scope(this); 1984 VirtualFrame::SpilledScope spilled_scope(this);
1983 Comment cmnt(masm_, "[ ForInStatement"); 1985 Comment cmnt(masm_, "[ ForInStatement");
1984 RecordStatementPosition(node); 1986 CodeForStatement(node);
1985 1987
1986 // We keep stuff on the stack while the body is executing. 1988 // We keep stuff on the stack while the body is executing.
1987 // Record it, so that a break/continue crossing this statement 1989 // Record it, so that a break/continue crossing this statement
1988 // can restore the stack. 1990 // can restore the stack.
1989 const int kForInStackSize = 5 * kPointerSize; 1991 const int kForInStackSize = 5 * kPointerSize;
1990 break_stack_height_ += kForInStackSize; 1992 break_stack_height_ += kForInStackSize;
1991 node->set_break_stack_height(break_stack_height_); 1993 node->set_break_stack_height(break_stack_height_);
1992 node->break_target()->set_code_generator(this); 1994 node->break_target()->set_code_generator(this);
1993 node->continue_target()->set_code_generator(this); 1995 node->continue_target()->set_code_generator(this);
1994 1996
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
2161 exit.Bind(); 2163 exit.Bind();
2162 2164
2163 break_stack_height_ -= kForInStackSize; 2165 break_stack_height_ -= kForInStackSize;
2164 } 2166 }
2165 2167
2166 2168
2167 void CodeGenerator::VisitTryCatch(TryCatch* node) { 2169 void CodeGenerator::VisitTryCatch(TryCatch* node) {
2168 ASSERT(!in_spilled_code()); 2170 ASSERT(!in_spilled_code());
2169 VirtualFrame::SpilledScope spilled_scope(this); 2171 VirtualFrame::SpilledScope spilled_scope(this);
2170 Comment cmnt(masm_, "[ TryCatch"); 2172 Comment cmnt(masm_, "[ TryCatch");
2173 CodeForStatement(node);
2171 2174
2172 JumpTarget try_block(this); 2175 JumpTarget try_block(this);
2173 JumpTarget exit(this); 2176 JumpTarget exit(this);
2174 2177
2175 try_block.Call(); 2178 try_block.Call();
2176 // --- Catch block --- 2179 // --- Catch block ---
2177 frame_->EmitPush(eax); 2180 frame_->EmitPush(eax);
2178 2181
2179 // Store the caught exception in the catch variable. 2182 // Store the caught exception in the catch variable.
2180 { Reference ref(this, node->catch_var()); 2183 { Reference ref(this, node->catch_var());
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
2277 } 2280 }
2278 2281
2279 exit.Bind(); 2282 exit.Bind();
2280 } 2283 }
2281 2284
2282 2285
2283 void CodeGenerator::VisitTryFinally(TryFinally* node) { 2286 void CodeGenerator::VisitTryFinally(TryFinally* node) {
2284 ASSERT(!in_spilled_code()); 2287 ASSERT(!in_spilled_code());
2285 VirtualFrame::SpilledScope spilled_scope(this); 2288 VirtualFrame::SpilledScope spilled_scope(this);
2286 Comment cmnt(masm_, "[ TryFinally"); 2289 Comment cmnt(masm_, "[ TryFinally");
2290 CodeForStatement(node);
2287 2291
2288 // State: Used to keep track of reason for entering the finally 2292 // State: Used to keep track of reason for entering the finally
2289 // block. Should probably be extended to hold information for 2293 // block. Should probably be extended to hold information for
2290 // break/continue from within the try block. 2294 // break/continue from within the try block.
2291 enum { FALLING, THROWING, JUMPING }; 2295 enum { FALLING, THROWING, JUMPING };
2292 2296
2293 JumpTarget unlink(this); 2297 JumpTarget unlink(this);
2294 JumpTarget try_block(this); 2298 JumpTarget try_block(this);
2295 JumpTarget finally_block(this); 2299 JumpTarget finally_block(this);
2296 2300
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
2428 // Done. 2432 // Done.
2429 exit.Bind(); 2433 exit.Bind();
2430 } 2434 }
2431 } 2435 }
2432 2436
2433 2437
2434 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) { 2438 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) {
2435 ASSERT(!in_spilled_code()); 2439 ASSERT(!in_spilled_code());
2436 VirtualFrame::SpilledScope spilled_scope(this); 2440 VirtualFrame::SpilledScope spilled_scope(this);
2437 Comment cmnt(masm_, "[ DebuggerStatement"); 2441 Comment cmnt(masm_, "[ DebuggerStatement");
2438 RecordStatementPosition(node); 2442 CodeForStatement(node);
2439 frame_->CallRuntime(Runtime::kDebugBreak, 0); 2443 frame_->CallRuntime(Runtime::kDebugBreak, 0);
2440 // Ignore the return value. 2444 // Ignore the return value.
2441 } 2445 }
2442 2446
2443 2447
2444 void CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) { 2448 void CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) {
2445 ASSERT(boilerplate->IsBoilerplate()); 2449 ASSERT(boilerplate->IsBoilerplate());
2446 2450
2447 // Push the boilerplate on the stack. 2451 // Push the boilerplate on the stack.
2448 frame_->EmitPush(Immediate(boilerplate)); 2452 frame_->EmitPush(Immediate(boilerplate));
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
2902 2906
2903 bool CodeGenerator::IsInlineSmi(Literal* literal) { 2907 bool CodeGenerator::IsInlineSmi(Literal* literal) {
2904 if (literal == NULL || !literal->handle()->IsSmi()) return false; 2908 if (literal == NULL || !literal->handle()->IsSmi()) return false;
2905 int int_value = Smi::cast(*literal->handle())->value(); 2909 int int_value = Smi::cast(*literal->handle())->value();
2906 return is_intn(int_value, kMaxSmiInlinedBits); 2910 return is_intn(int_value, kMaxSmiInlinedBits);
2907 } 2911 }
2908 2912
2909 2913
2910 void CodeGenerator::VisitAssignment(Assignment* node) { 2914 void CodeGenerator::VisitAssignment(Assignment* node) {
2911 Comment cmnt(masm_, "[ Assignment"); 2915 Comment cmnt(masm_, "[ Assignment");
2916 CodeForStatement(node);
2912 2917
2913 RecordStatementPosition(node);
2914 { Reference target(this, node->target()); 2918 { Reference target(this, node->target());
2915 if (target.is_illegal()) { 2919 if (target.is_illegal()) {
2916 // Fool the virtual frame into thinking that we left the assignment's 2920 // Fool the virtual frame into thinking that we left the assignment's
2917 // value on the frame. 2921 // value on the frame.
2918 frame_->EmitPush(Immediate(Smi::FromInt(0))); 2922 frame_->EmitPush(Immediate(Smi::FromInt(0)));
2919 return; 2923 return;
2920 } 2924 }
2921 2925
2922 if (node->op() == Token::ASSIGN || 2926 if (node->op() == Token::ASSIGN ||
2923 node->op() == Token::INIT_VAR || 2927 node->op() == Token::INIT_VAR ||
(...skipping 12 matching lines...) Expand all
2936 GenericBinaryOperation(node->binary_op(), node->type()); 2940 GenericBinaryOperation(node->binary_op(), node->type());
2937 } 2941 }
2938 } 2942 }
2939 2943
2940 Variable* var = node->target()->AsVariableProxy()->AsVariable(); 2944 Variable* var = node->target()->AsVariableProxy()->AsVariable();
2941 if (var != NULL && 2945 if (var != NULL &&
2942 var->mode() == Variable::CONST && 2946 var->mode() == Variable::CONST &&
2943 node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) { 2947 node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) {
2944 // Assignment ignored - leave the value on the stack. 2948 // Assignment ignored - leave the value on the stack.
2945 } else { 2949 } else {
2946 __ RecordPosition(node->position()); 2950 CodeForSourcePosition(node->position());
2947 if (node->op() == Token::INIT_CONST) { 2951 if (node->op() == Token::INIT_CONST) {
2948 // Dynamic constant initializations must use the function context 2952 // Dynamic constant initializations must use the function context
2949 // and initialize the actual constant declared. Dynamic variable 2953 // and initialize the actual constant declared. Dynamic variable
2950 // initializations are simply assignments and use SetValue. 2954 // initializations are simply assignments and use SetValue.
2951 target.SetValue(CONST_INIT); 2955 target.SetValue(CONST_INIT);
2952 } else { 2956 } else {
2953 target.SetValue(NOT_CONST_INIT); 2957 target.SetValue(NOT_CONST_INIT);
2954 } 2958 }
2955 } 2959 }
2956 } 2960 }
2957 } 2961 }
2958 2962
2959 2963
2960 void CodeGenerator::VisitThrow(Throw* node) { 2964 void CodeGenerator::VisitThrow(Throw* node) {
2961 VirtualFrame::SpilledScope spilled_scope(this); 2965 VirtualFrame::SpilledScope spilled_scope(this);
2962 Comment cmnt(masm_, "[ Throw"); 2966 Comment cmnt(masm_, "[ Throw");
2967 CodeForStatement(node);
2963 2968
2964 LoadAndSpill(node->exception()); 2969 LoadAndSpill(node->exception());
2965 __ RecordPosition(node->position());
2966 frame_->CallRuntime(Runtime::kThrow, 1); 2970 frame_->CallRuntime(Runtime::kThrow, 1);
2967 frame_->EmitPush(eax); 2971 frame_->EmitPush(eax);
2968 } 2972 }
2969 2973
2970 2974
2971 void CodeGenerator::VisitProperty(Property* node) { 2975 void CodeGenerator::VisitProperty(Property* node) {
2972 VirtualFrame::SpilledScope spilled_scope(this); 2976 VirtualFrame::SpilledScope spilled_scope(this);
2973 Comment cmnt(masm_, "[ Property"); 2977 Comment cmnt(masm_, "[ Property");
2974 Reference property(this, node); 2978 Reference property(this, node);
2975 property.GetValueAndSpill(typeof_state()); 2979 property.GetValueAndSpill(typeof_state());
2976 } 2980 }
2977 2981
2978 2982
2979 void CodeGenerator::VisitCall(Call* node) { 2983 void CodeGenerator::VisitCall(Call* node) {
2980 VirtualFrame::SpilledScope spilled_scope(this); 2984 VirtualFrame::SpilledScope spilled_scope(this);
2981 Comment cmnt(masm_, "[ Call"); 2985 Comment cmnt(masm_, "[ Call");
2982 2986
2983 ZoneList<Expression*>* args = node->arguments(); 2987 ZoneList<Expression*>* args = node->arguments();
2984 2988
2985 RecordStatementPosition(node); 2989 CodeForStatement(node);
2986 2990
2987 // Check if the function is a variable or a property. 2991 // Check if the function is a variable or a property.
2988 Expression* function = node->expression(); 2992 Expression* function = node->expression();
2989 Variable* var = function->AsVariableProxy()->AsVariable(); 2993 Variable* var = function->AsVariableProxy()->AsVariable();
2990 Property* property = function->AsProperty(); 2994 Property* property = function->AsProperty();
2991 2995
2992 // ------------------------------------------------------------------------ 2996 // ------------------------------------------------------------------------
2993 // Fast-case: Use inline caching. 2997 // Fast-case: Use inline caching.
2994 // --- 2998 // ---
2995 // According to ECMA-262, section 11.2.3, page 44, the function to call 2999 // According to ECMA-262, section 11.2.3, page 44, the function to call
(...skipping 17 matching lines...) Expand all
3013 // Load the arguments. 3017 // Load the arguments.
3014 int arg_count = args->length(); 3018 int arg_count = args->length();
3015 for (int i = 0; i < arg_count; i++) { 3019 for (int i = 0; i < arg_count; i++) {
3016 LoadAndSpill(args->at(i)); 3020 LoadAndSpill(args->at(i));
3017 } 3021 }
3018 3022
3019 // Setup the receiver register and call the IC initialization code. 3023 // Setup the receiver register and call the IC initialization code.
3020 Handle<Code> stub = (loop_nesting() > 0) 3024 Handle<Code> stub = (loop_nesting() > 0)
3021 ? ComputeCallInitializeInLoop(arg_count) 3025 ? ComputeCallInitializeInLoop(arg_count)
3022 : ComputeCallInitialize(arg_count); 3026 : ComputeCallInitialize(arg_count);
3023 __ RecordPosition(node->position()); 3027 CodeForSourcePosition(node->position());
3024 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET_CONTEXT, 3028 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET_CONTEXT,
3025 arg_count + 1); 3029 arg_count + 1);
3026 __ mov(esi, frame_->Context()); 3030 __ mov(esi, frame_->Context());
3027 3031
3028 // Overwrite the function on the stack with the result. 3032 // Overwrite the function on the stack with the result.
3029 __ mov(frame_->Top(), eax); 3033 __ mov(frame_->Top(), eax);
3030 3034
3031 } else if (var != NULL && var->slot() != NULL && 3035 } else if (var != NULL && var->slot() != NULL &&
3032 var->slot()->type() == Slot::LOOKUP) { 3036 var->slot()->type() == Slot::LOOKUP) {
3033 // ---------------------------------- 3037 // ----------------------------------
(...skipping 29 matching lines...) Expand all
3063 // Load the arguments. 3067 // Load the arguments.
3064 int arg_count = args->length(); 3068 int arg_count = args->length();
3065 for (int i = 0; i < arg_count; i++) { 3069 for (int i = 0; i < arg_count; i++) {
3066 LoadAndSpill(args->at(i)); 3070 LoadAndSpill(args->at(i));
3067 } 3071 }
3068 3072
3069 // Call the IC initialization code. 3073 // Call the IC initialization code.
3070 Handle<Code> stub = (loop_nesting() > 0) 3074 Handle<Code> stub = (loop_nesting() > 0)
3071 ? ComputeCallInitializeInLoop(arg_count) 3075 ? ComputeCallInitializeInLoop(arg_count)
3072 : ComputeCallInitialize(arg_count); 3076 : ComputeCallInitialize(arg_count);
3073 __ RecordPosition(node->position()); 3077 CodeForSourcePosition(node->position());
3074 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET, arg_count + 1); 3078 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET, arg_count + 1);
3075 __ mov(esi, frame_->Context()); 3079 __ mov(esi, frame_->Context());
3076 3080
3077 // Overwrite the function on the stack with the result. 3081 // Overwrite the function on the stack with the result.
3078 __ mov(frame_->Top(), eax); 3082 __ mov(frame_->Top(), eax);
3079 3083
3080 } else { 3084 } else {
3081 // ------------------------------------------- 3085 // -------------------------------------------
3082 // JavaScript example: 'array[index](1, 2, 3)' 3086 // JavaScript example: 'array[index](1, 2, 3)'
3083 // ------------------------------------------- 3087 // -------------------------------------------
(...skipping 23 matching lines...) Expand all
3107 3111
3108 // Call the function. 3112 // Call the function.
3109 CallWithArguments(args, node->position()); 3113 CallWithArguments(args, node->position());
3110 } 3114 }
3111 } 3115 }
3112 3116
3113 3117
3114 void CodeGenerator::VisitCallNew(CallNew* node) { 3118 void CodeGenerator::VisitCallNew(CallNew* node) {
3115 VirtualFrame::SpilledScope spilled_scope(this); 3119 VirtualFrame::SpilledScope spilled_scope(this);
3116 Comment cmnt(masm_, "[ CallNew"); 3120 Comment cmnt(masm_, "[ CallNew");
3121 CodeForStatement(node);
3117 3122
3118 // According to ECMA-262, section 11.2.2, page 44, the function 3123 // According to ECMA-262, section 11.2.2, page 44, the function
3119 // expression in new calls must be evaluated before the 3124 // expression in new calls must be evaluated before the
3120 // arguments. This is different from ordinary calls, where the 3125 // arguments. This is different from ordinary calls, where the
3121 // actual function to call is resolved after the arguments have been 3126 // actual function to call is resolved after the arguments have been
3122 // evaluated. 3127 // evaluated.
3123 3128
3124 // Compute function to call and use the global object as the 3129 // Compute function to call and use the global object as the
3125 // receiver. There is no need to use the global proxy here because 3130 // receiver. There is no need to use the global proxy here because
3126 // it will always be replaced with a newly allocated object. 3131 // it will always be replaced with a newly allocated object.
(...skipping 11 matching lines...) Expand all
3138 // eax for now. Another option would be to have separate construct 3143 // eax for now. Another option would be to have separate construct
3139 // call trampolines per different arguments counts encountered. 3144 // call trampolines per different arguments counts encountered.
3140 __ Set(eax, Immediate(arg_count)); 3145 __ Set(eax, Immediate(arg_count));
3141 3146
3142 // Load the function into temporary function slot as per calling 3147 // Load the function into temporary function slot as per calling
3143 // convention. 3148 // convention.
3144 __ mov(edi, frame_->ElementAt(arg_count + 1)); 3149 __ mov(edi, frame_->ElementAt(arg_count + 1));
3145 3150
3146 // Call the construct call builtin that handles allocation and 3151 // Call the construct call builtin that handles allocation and
3147 // constructor invocation. 3152 // constructor invocation.
3148 __ RecordPosition(node->position()); 3153 CodeForSourcePosition(node->position());
3149 Handle<Code> ic(Builtins::builtin(Builtins::JSConstructCall)); 3154 Handle<Code> ic(Builtins::builtin(Builtins::JSConstructCall));
3150 frame_->CallCodeObject(ic, RelocInfo::CONSTRUCT_CALL, args->length() + 1); 3155 frame_->CallCodeObject(ic, RelocInfo::CONSTRUCT_CALL, args->length() + 1);
3151 // Discard the function and "push" the newly created object. 3156 // Discard the function and "push" the newly created object.
3152 __ mov(frame_->Top(), eax); 3157 __ mov(frame_->Top(), eax);
3153 } 3158 }
3154 3159
3155 3160
3156 void CodeGenerator::VisitCallEval(CallEval* node) { 3161 void CodeGenerator::VisitCallEval(CallEval* node) {
3157 VirtualFrame::SpilledScope spilled_scope(this); 3162 VirtualFrame::SpilledScope spilled_scope(this);
3158 Comment cmnt(masm_, "[ CallEval"); 3163 Comment cmnt(masm_, "[ CallEval");
3159 3164
3160 // In a call to eval, we first call %ResolvePossiblyDirectEval to resolve 3165 // In a call to eval, we first call %ResolvePossiblyDirectEval to resolve
3161 // the function we need to call and the receiver of the call. 3166 // the function we need to call and the receiver of the call.
3162 // Then we call the resolved function using the given arguments. 3167 // Then we call the resolved function using the given arguments.
3163 3168
3164 ZoneList<Expression*>* args = node->arguments(); 3169 ZoneList<Expression*>* args = node->arguments();
3165 Expression* function = node->expression(); 3170 Expression* function = node->expression();
3166 3171
3167 RecordStatementPosition(node); 3172 CodeForStatement(node);
3168 3173
3169 // Prepare stack for call to resolved function. 3174 // Prepare stack for call to resolved function.
3170 LoadAndSpill(function); 3175 LoadAndSpill(function);
3171 // Allocate a frame slot for the receiver. 3176 // Allocate a frame slot for the receiver.
3172 frame_->EmitPush(Immediate(Factory::undefined_value())); 3177 frame_->EmitPush(Immediate(Factory::undefined_value()));
3173 int arg_count = args->length(); 3178 int arg_count = args->length();
3174 for (int i = 0; i < arg_count; i++) { 3179 for (int i = 0; i < arg_count; i++) {
3175 LoadAndSpill(args->at(i)); 3180 LoadAndSpill(args->at(i));
3176 } 3181 }
3177 3182
3178 // Prepare stack for call to ResolvePossiblyDirectEval. 3183 // Prepare stack for call to ResolvePossiblyDirectEval.
3179 frame_->EmitPush(frame_->ElementAt(arg_count + 1)); 3184 frame_->EmitPush(frame_->ElementAt(arg_count + 1));
3180 if (arg_count > 0) { 3185 if (arg_count > 0) {
3181 frame_->EmitPush(frame_->ElementAt(arg_count)); 3186 frame_->EmitPush(frame_->ElementAt(arg_count));
3182 } else { 3187 } else {
3183 frame_->EmitPush(Immediate(Factory::undefined_value())); 3188 frame_->EmitPush(Immediate(Factory::undefined_value()));
3184 } 3189 }
3185 3190
3186 // Resolve the call. 3191 // Resolve the call.
3187 frame_->CallRuntime(Runtime::kResolvePossiblyDirectEval, 2); 3192 frame_->CallRuntime(Runtime::kResolvePossiblyDirectEval, 2);
3188 3193
3189 // Touch up stack with the right values for the function and the receiver. 3194 // Touch up stack with the right values for the function and the receiver.
3190 __ mov(edx, FieldOperand(eax, FixedArray::kHeaderSize)); 3195 __ mov(edx, FieldOperand(eax, FixedArray::kHeaderSize));
3191 __ mov(frame_->ElementAt(arg_count + 1), edx); 3196 __ mov(frame_->ElementAt(arg_count + 1), edx);
3192 __ mov(edx, FieldOperand(eax, FixedArray::kHeaderSize + kPointerSize)); 3197 __ mov(edx, FieldOperand(eax, FixedArray::kHeaderSize + kPointerSize));
3193 __ mov(frame_->ElementAt(arg_count), edx); 3198 __ mov(frame_->ElementAt(arg_count), edx);
3194 3199
3195 // Call the function. 3200 // Call the function.
3196 __ RecordPosition(node->position()); 3201 CodeForSourcePosition(node->position());
3197 3202
3198 CallFunctionStub call_function(arg_count); 3203 CallFunctionStub call_function(arg_count);
3199 frame_->CallStub(&call_function, arg_count + 1); 3204 frame_->CallStub(&call_function, arg_count + 1);
3200 3205
3201 // Restore context and pop function from the stack. 3206 // Restore context and pop function from the stack.
3202 __ mov(esi, frame_->Context()); 3207 __ mov(esi, frame_->Context());
3203 __ mov(frame_->Top(), eax); 3208 __ mov(frame_->Top(), eax);
3204 } 3209 }
3205 3210
3206 3211
(...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after
4127 return; 4132 return;
4128 } 4133 }
4129 4134
4130 VirtualFrame::SpilledScope spilled_scope(this); 4135 VirtualFrame::SpilledScope spilled_scope(this);
4131 LoadAndSpill(left); 4136 LoadAndSpill(left);
4132 LoadAndSpill(right); 4137 LoadAndSpill(right);
4133 Comparison(cc, strict); 4138 Comparison(cc, strict);
4134 } 4139 }
4135 4140
4136 4141
4137 void CodeGenerator::RecordStatementPosition(Node* node) {
4138 if (FLAG_debug_info) {
4139 int pos = node->statement_pos();
4140 if (pos != RelocInfo::kNoPosition) {
4141 __ RecordStatementPosition(pos);
4142 }
4143 }
4144 }
4145
4146
4147 bool CodeGenerator::IsActualFunctionReturn(JumpTarget* target) { 4142 bool CodeGenerator::IsActualFunctionReturn(JumpTarget* target) {
4148 return (target == &function_return_ && !function_return_is_shadowed_); 4143 return (target == &function_return_ && !function_return_is_shadowed_);
4149 } 4144 }
4150 4145
4151 4146
4152 #undef __ 4147 #undef __
4153 #define __ masm-> 4148 #define __ masm->
4154 4149
4155 Handle<String> Reference::GetName() { 4150 Handle<String> Reference::GetName() {
4156 ASSERT(type_ == NAMED); 4151 ASSERT(type_ == NAMED);
4157 Property* property = expression_->AsProperty(); 4152 Property* property = expression_->AsProperty();
4158 if (property == NULL) { 4153 if (property == NULL) {
4159 // Global variable reference treated as a named property reference. 4154 // Global variable reference treated as a named property reference.
4160 VariableProxy* proxy = expression_->AsVariableProxy(); 4155 VariableProxy* proxy = expression_->AsVariableProxy();
4161 ASSERT(proxy->AsVariable() != NULL); 4156 ASSERT(proxy->AsVariable() != NULL);
4162 ASSERT(proxy->AsVariable()->is_global()); 4157 ASSERT(proxy->AsVariable()->is_global());
4163 return proxy->name(); 4158 return proxy->name();
4164 } else { 4159 } else {
4165 MacroAssembler* masm = cgen_->masm();
4166 __ RecordPosition(property->position());
4167 Literal* raw_name = property->key()->AsLiteral(); 4160 Literal* raw_name = property->key()->AsLiteral();
4168 ASSERT(raw_name != NULL); 4161 ASSERT(raw_name != NULL);
4169 return Handle<String>(String::cast(*raw_name->handle())); 4162 return Handle<String>(String::cast(*raw_name->handle()));
4170 } 4163 }
4171 } 4164 }
4172 4165
4173 4166
4174 void Reference::GetValue(TypeofState typeof_state) { 4167 void Reference::GetValue(TypeofState typeof_state) {
4175 ASSERT(!cgen_->in_spilled_code()); 4168 ASSERT(!cgen_->in_spilled_code());
4176 ASSERT(!is_illegal()); 4169 ASSERT(!is_illegal());
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
4210 break; 4203 break;
4211 } 4204 }
4212 4205
4213 case KEYED: { 4206 case KEYED: {
4214 // TODO(1241834): Make sure that this it is safe to ignore the 4207 // TODO(1241834): Make sure that this it is safe to ignore the
4215 // distinction between expressions in a typeof and not in a typeof. 4208 // distinction between expressions in a typeof and not in a typeof.
4216 VirtualFrame::SpilledScope spilled_scope(cgen_); 4209 VirtualFrame::SpilledScope spilled_scope(cgen_);
4217 Comment cmnt(masm, "[ Load from keyed Property"); 4210 Comment cmnt(masm, "[ Load from keyed Property");
4218 Property* property = expression_->AsProperty(); 4211 Property* property = expression_->AsProperty();
4219 ASSERT(property != NULL); 4212 ASSERT(property != NULL);
4220 __ RecordPosition(property->position());
4221 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 4213 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
4222 4214
4223 Variable* var = expression_->AsVariableProxy()->AsVariable(); 4215 Variable* var = expression_->AsVariableProxy()->AsVariable();
4224 if (var != NULL) { 4216 if (var != NULL) {
4225 ASSERT(var->is_global()); 4217 ASSERT(var->is_global());
4226 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET_CONTEXT, 0); 4218 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET_CONTEXT, 0);
4227 } else { 4219 } else {
4228 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0); 4220 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
4229 } 4221 }
4230 frame->EmitPush(eax); // IC call leaves result in eax, push it out 4222 frame->EmitPush(eax); // IC call leaves result in eax, push it out
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
4264 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0); 4256 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
4265 frame->EmitPush(eax); // IC call leaves result in eax, push it out 4257 frame->EmitPush(eax); // IC call leaves result in eax, push it out
4266 break; 4258 break;
4267 } 4259 }
4268 4260
4269 case KEYED: { 4261 case KEYED: {
4270 VirtualFrame::SpilledScope spilled_scope(cgen_); 4262 VirtualFrame::SpilledScope spilled_scope(cgen_);
4271 Comment cmnt(masm, "[ Store to keyed Property"); 4263 Comment cmnt(masm, "[ Store to keyed Property");
4272 Property* property = expression_->AsProperty(); 4264 Property* property = expression_->AsProperty();
4273 ASSERT(property != NULL); 4265 ASSERT(property != NULL);
4274 __ RecordPosition(property->position());
4275 // Call IC code. 4266 // Call IC code.
4276 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 4267 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
4277 // TODO(1222589): Make the IC grab the values from the stack. 4268 // TODO(1222589): Make the IC grab the values from the stack.
4278 frame->EmitPop(eax); 4269 frame->EmitPop(eax);
4279 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0); 4270 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
4280 frame->EmitPush(eax); // IC call leaves result in eax, push it out 4271 frame->EmitPush(eax); // IC call leaves result in eax, push it out
4281 break; 4272 break;
4282 } 4273 }
4283 4274
4284 default: 4275 default:
(...skipping 1376 matching lines...) Expand 10 before | Expand all | Expand 10 after
5661 5652
5662 // Slow-case: Go through the JavaScript implementation. 5653 // Slow-case: Go through the JavaScript implementation.
5663 __ bind(&slow); 5654 __ bind(&slow);
5664 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 5655 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
5665 } 5656 }
5666 5657
5667 5658
5668 #undef __ 5659 #undef __
5669 5660
5670 } } // namespace v8::internal 5661 } } // 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