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

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

Issue 339045: Rename the kinds of locations to be consistent with the (codegen)... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 1 month 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/fast-codegen.cc ('k') | src/location.h » ('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 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 // patch with the code required by the debugger. 103 // patch with the code required by the debugger.
104 __ mov(esp, ebp); 104 __ mov(esp, ebp);
105 __ pop(ebp); 105 __ pop(ebp);
106 __ ret((fun->scope()->num_parameters() + 1) * kPointerSize); 106 __ ret((fun->scope()->num_parameters() + 1) * kPointerSize);
107 } 107 }
108 } 108 }
109 109
110 110
111 void FastCodeGenerator::Move(Location destination, Slot* source) { 111 void FastCodeGenerator::Move(Location destination, Slot* source) {
112 switch (destination.type()) { 112 switch (destination.type()) {
113 case Location::NOWHERE: 113 case Location::UNINITIALIZED:
114 UNREACHABLE();
115 case Location::EFFECT:
114 break; 116 break;
115 case Location::TEMP: 117 case Location::VALUE:
116 __ push(Operand(ebp, SlotOffset(source))); 118 __ push(Operand(ebp, SlotOffset(source)));
117 break; 119 break;
118 } 120 }
119 } 121 }
120 122
121 123
122 void FastCodeGenerator::Move(Location destination, Literal* expr) { 124 void FastCodeGenerator::Move(Location destination, Literal* expr) {
123 switch (destination.type()) { 125 switch (destination.type()) {
124 case Location::NOWHERE: 126 case Location::UNINITIALIZED:
127 UNREACHABLE();
128 case Location::EFFECT:
125 break; 129 break;
126 case Location::TEMP: 130 case Location::VALUE:
127 __ push(Immediate(expr->handle())); 131 __ push(Immediate(expr->handle()));
128 break; 132 break;
129 } 133 }
130 } 134 }
131 135
132 136
133 void FastCodeGenerator::Move(Slot* destination, Location source) { 137 void FastCodeGenerator::Move(Slot* destination, Location source) {
134 switch (source.type()) { 138 switch (source.type()) {
135 case Location::NOWHERE: 139 case Location::UNINITIALIZED: // Fall through.
140 case Location::EFFECT:
136 UNREACHABLE(); 141 UNREACHABLE();
137 case Location::TEMP: 142 case Location::VALUE:
138 __ pop(Operand(ebp, SlotOffset(destination))); 143 __ pop(Operand(ebp, SlotOffset(destination)));
139 break; 144 break;
140 } 145 }
141 } 146 }
142 147
143 148
144 void FastCodeGenerator::DropAndMove(Location destination, Register source) { 149 void FastCodeGenerator::DropAndMove(Location destination, Register source) {
145 switch (destination.type()) { 150 switch (destination.type()) {
146 case Location::NOWHERE: 151 case Location::UNINITIALIZED:
152 UNREACHABLE();
153 case Location::EFFECT:
147 __ add(Operand(esp), Immediate(kPointerSize)); 154 __ add(Operand(esp), Immediate(kPointerSize));
148 break; 155 break;
149 case Location::TEMP: 156 case Location::VALUE:
150 __ mov(Operand(esp, 0), source); 157 __ mov(Operand(esp, 0), source);
151 break; 158 break;
152 } 159 }
153 } 160 }
154 161
155 162
156 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 163 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
157 // Call the runtime to declare the globals. 164 // Call the runtime to declare the globals.
158 __ push(esi); // The context is the first argument. 165 __ push(esi); // The context is the first argument.
159 __ push(Immediate(pairs)); 166 __ push(Immediate(pairs));
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 __ nop(); 231 __ nop();
225 232
226 DropAndMove(expr->location(), eax); 233 DropAndMove(expr->location(), eax);
227 } else { 234 } else {
228 Comment cmnt(masm_, "Stack slot"); 235 Comment cmnt(masm_, "Stack slot");
229 Move(expr->location(), rewrite->AsSlot()); 236 Move(expr->location(), rewrite->AsSlot());
230 } 237 }
231 } 238 }
232 239
233 240
241 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
242 Comment cmnt(masm_, "[ RegExp Literal");
243 Label done;
244 // Registers will be used as follows:
245 // edi = JS function.
246 // ebx = literals array.
247 // eax = regexp literal.
248 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
249 __ mov(ebx, FieldOperand(edi, JSFunction::kLiteralsOffset));
250 int literal_offset =
251 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
252 __ mov(eax, FieldOperand(ebx, literal_offset));
253 __ cmp(eax, Factory::undefined_value());
254 __ j(not_equal, &done);
255 // Create regexp literal using runtime function
256 // Result will be in eax.
257 __ push(ebx);
258 __ push(Immediate(Smi::FromInt(expr->literal_index())));
259 __ push(Immediate(expr->pattern()));
260 __ push(Immediate(expr->flags()));
261 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
262 // Label done:
263 __ bind(&done);
264 Move(expr->location(), eax);
265 }
266
267
234 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 268 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
235 Comment cmnt(masm_, "[ ObjectLiteral"); 269 Comment cmnt(masm_, "[ ObjectLiteral");
236 Label exists; 270 Label exists;
237 // Registers will be used as follows: 271 // Registers will be used as follows:
238 // edi = JS function. 272 // edi = JS function.
239 // ebx = literals array. 273 // ebx = literals array.
240 // eax = boilerplate 274 // eax = boilerplate
241 275
242 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 276 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
243 __ mov(ebx, FieldOperand(edi, JSFunction::kLiteralsOffset)); 277 __ mov(ebx, FieldOperand(edi, JSFunction::kLiteralsOffset));
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 __ mov(ecx, Immediate(key->handle())); 322 __ mov(ecx, Immediate(key->handle()));
289 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 323 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
290 __ call(ic, RelocInfo::CODE_TARGET); 324 __ call(ic, RelocInfo::CODE_TARGET);
291 // StoreIC leaves the receiver on the stack. 325 // StoreIC leaves the receiver on the stack.
292 break; 326 break;
293 } 327 }
294 // fall through 328 // fall through
295 case ObjectLiteral::Property::PROTOTYPE: 329 case ObjectLiteral::Property::PROTOTYPE:
296 __ push(eax); 330 __ push(eax);
297 Visit(key); 331 Visit(key);
298 ASSERT(key->location().is_temporary()); 332 ASSERT(key->location().is_value());
299 Visit(value); 333 Visit(value);
300 ASSERT(value->location().is_temporary()); 334 ASSERT(value->location().is_value());
301 __ CallRuntime(Runtime::kSetProperty, 3); 335 __ CallRuntime(Runtime::kSetProperty, 3);
302 __ mov(eax, Operand(esp, 0)); // Restore result into eax. 336 __ mov(eax, Operand(esp, 0)); // Restore result into eax.
303 break; 337 break;
304 case ObjectLiteral::Property::SETTER: // fall through 338 case ObjectLiteral::Property::SETTER: // fall through
305 case ObjectLiteral::Property::GETTER: 339 case ObjectLiteral::Property::GETTER:
306 __ push(eax); 340 __ push(eax);
307 Visit(key); 341 Visit(key);
308 ASSERT(key->location().is_temporary()); 342 ASSERT(key->location().is_value());
309 __ push(Immediate(property->kind() == ObjectLiteral::Property::SETTER ? 343 __ push(Immediate(property->kind() == ObjectLiteral::Property::SETTER ?
310 Smi::FromInt(1) : 344 Smi::FromInt(1) :
311 Smi::FromInt(0))); 345 Smi::FromInt(0)));
312 Visit(value); 346 Visit(value);
313 ASSERT(value->location().is_temporary()); 347 ASSERT(value->location().is_value());
314 __ CallRuntime(Runtime::kDefineAccessor, 4); 348 __ CallRuntime(Runtime::kDefineAccessor, 4);
315 __ mov(eax, Operand(esp, 0)); // Restore result into eax. 349 __ mov(eax, Operand(esp, 0)); // Restore result into eax.
316 break; 350 break;
317 default: UNREACHABLE(); 351 default: UNREACHABLE();
318 } 352 }
319 } 353 }
320 switch (expr->location().type()) { 354 switch (expr->location().type()) {
321 case Location::NOWHERE: 355 case Location::UNINITIALIZED:
356 UNREACHABLE();
357 case Location::EFFECT:
322 if (result_saved) __ add(Operand(esp), Immediate(kPointerSize)); 358 if (result_saved) __ add(Operand(esp), Immediate(kPointerSize));
323 break; 359 break;
324 case Location::TEMP: 360 case Location::VALUE:
325 if (!result_saved) __ push(eax); 361 if (!result_saved) __ push(eax);
326 break; 362 break;
327 } 363 }
328 } 364 }
329 365
330 366
331 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
332 Comment cmnt(masm_, "[ RegExp Literal");
333 Label done;
334 // Registers will be used as follows:
335 // edi = JS function.
336 // ebx = literals array.
337 // eax = regexp literal.
338 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
339 __ mov(ebx, FieldOperand(edi, JSFunction::kLiteralsOffset));
340 int literal_offset =
341 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
342 __ mov(eax, FieldOperand(ebx, literal_offset));
343 __ cmp(eax, Factory::undefined_value());
344 __ j(not_equal, &done);
345 // Create regexp literal using runtime function
346 // Result will be in eax.
347 __ push(ebx);
348 __ push(Immediate(Smi::FromInt(expr->literal_index())));
349 __ push(Immediate(expr->pattern()));
350 __ push(Immediate(expr->flags()));
351 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
352 // Label done:
353 __ bind(&done);
354 Move(expr->location(), eax);
355 }
356
357
358 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 367 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
359 Comment cmnt(masm_, "[ ArrayLiteral"); 368 Comment cmnt(masm_, "[ ArrayLiteral");
360 Label make_clone; 369 Label make_clone;
361 370
362 // Fetch the function's literals array. 371 // Fetch the function's literals array.
363 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 372 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
364 __ mov(ebx, FieldOperand(ebx, JSFunction::kLiteralsOffset)); 373 __ mov(ebx, FieldOperand(ebx, JSFunction::kLiteralsOffset));
365 // Check if the literal's boilerplate has been instantiated. 374 // Check if the literal's boilerplate has been instantiated.
366 int offset = 375 int offset =
367 FixedArray::kHeaderSize + (expr->literal_index() * kPointerSize); 376 FixedArray::kHeaderSize + (expr->literal_index() * kPointerSize);
(...skipping 28 matching lines...) Expand all
396 if (subexpr->AsLiteral() != NULL || 405 if (subexpr->AsLiteral() != NULL ||
397 CompileTimeValue::IsCompileTimeValue(subexpr)) { 406 CompileTimeValue::IsCompileTimeValue(subexpr)) {
398 continue; 407 continue;
399 } 408 }
400 409
401 if (!result_saved) { 410 if (!result_saved) {
402 __ push(eax); 411 __ push(eax);
403 result_saved = true; 412 result_saved = true;
404 } 413 }
405 Visit(subexpr); 414 Visit(subexpr);
406 ASSERT(subexpr->location().is_temporary()); 415 ASSERT(subexpr->location().is_value());
407 416
408 // Store the subexpression value in the array's elements. 417 // Store the subexpression value in the array's elements.
409 __ pop(eax); // Subexpression value. 418 __ pop(eax); // Subexpression value.
410 __ mov(ebx, Operand(esp, 0)); // Copy of array literal. 419 __ mov(ebx, Operand(esp, 0)); // Copy of array literal.
411 __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset)); 420 __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset));
412 int offset = FixedArray::kHeaderSize + (i * kPointerSize); 421 int offset = FixedArray::kHeaderSize + (i * kPointerSize);
413 __ mov(FieldOperand(ebx, offset), eax); 422 __ mov(FieldOperand(ebx, offset), eax);
414 423
415 // Update the write barrier for the array store. 424 // Update the write barrier for the array store.
416 __ RecordWrite(ebx, offset, eax, ecx); 425 __ RecordWrite(ebx, offset, eax, ecx);
417 } 426 }
418 427
419 switch (expr->location().type()) { 428 switch (expr->location().type()) {
420 case Location::NOWHERE: 429 case Location::UNINITIALIZED:
430 UNREACHABLE();
431 case Location::EFFECT:
421 if (result_saved) __ add(Operand(esp), Immediate(kPointerSize)); 432 if (result_saved) __ add(Operand(esp), Immediate(kPointerSize));
422 break; 433 break;
423 case Location::TEMP: 434 case Location::VALUE:
424 if (!result_saved) __ push(eax); 435 if (!result_saved) __ push(eax);
425 break; 436 break;
426 } 437 }
427 } 438 }
428 439
429 440
430 void FastCodeGenerator::VisitAssignment(Assignment* expr) { 441 void FastCodeGenerator::VisitAssignment(Assignment* expr) {
431 Comment cmnt(masm_, "[ Assignment"); 442 Comment cmnt(masm_, "[ Assignment");
432 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); 443 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR);
433 444
434 // Left-hand side can only be a global or a (parameter or local) slot. 445 // Left-hand side can only be a global or a (parameter or local) slot.
435 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); 446 Variable* var = expr->target()->AsVariableProxy()->AsVariable();
436 ASSERT(var != NULL); 447 ASSERT(var != NULL);
437 ASSERT(var->is_global() || var->slot() != NULL); 448 ASSERT(var->is_global() || var->slot() != NULL);
438 449
439 Expression* rhs = expr->value(); 450 Expression* rhs = expr->value();
440 if (var->is_global()) { 451 if (var->is_global()) {
441 // Assignment to a global variable, use inline caching. Right-hand-side 452 // Assignment to a global variable, use inline caching. Right-hand-side
442 // value is passed in eax, variable name in ecx, and the global object 453 // value is passed in eax, variable name in ecx, and the global object
443 // on the stack. 454 // on the stack.
444 455
445 // Code for the right-hand-side expression depends on its type. 456 // Code for the right-hand-side expression depends on its type.
446 if (rhs->AsLiteral() != NULL) { 457 if (rhs->AsLiteral() != NULL) {
447 __ mov(eax, rhs->AsLiteral()->handle()); 458 __ mov(eax, rhs->AsLiteral()->handle());
448 } else { 459 } else {
449 ASSERT(rhs->location().is_temporary()); 460 ASSERT(rhs->location().is_value());
450 Visit(rhs); 461 Visit(rhs);
451 __ pop(eax); 462 __ pop(eax);
452 } 463 }
453 __ mov(ecx, var->name()); 464 __ mov(ecx, var->name());
454 __ push(CodeGenerator::GlobalObject()); 465 __ push(CodeGenerator::GlobalObject());
455 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 466 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
456 __ call(ic, RelocInfo::CODE_TARGET); 467 __ call(ic, RelocInfo::CODE_TARGET);
457 // Overwrite the global object on the stack with the result if needed. 468 // Overwrite the global object on the stack with the result if needed.
458 DropAndMove(expr->location(), eax); 469 DropAndMove(expr->location(), eax);
459 } else { 470 } else {
460 // Local or parameter assignment. 471 // Local or parameter assignment.
461 472
462 // Code for the right-hand side expression depends on its type. 473 // Code for the right-hand side expression depends on its type.
463 if (rhs->AsLiteral() != NULL) { 474 if (rhs->AsLiteral() != NULL) {
464 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a 475 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a
465 // discarded result. Always perform the assignment. 476 // discarded result. Always perform the assignment.
466 __ mov(eax, rhs->AsLiteral()->handle()); 477 __ mov(eax, rhs->AsLiteral()->handle());
467 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); 478 __ mov(Operand(ebp, SlotOffset(var->slot())), eax);
468 Move(expr->location(), eax); 479 Move(expr->location(), eax);
469 } else { 480 } else {
470 ASSERT(rhs->location().is_temporary()); 481 ASSERT(rhs->location().is_value());
471 Visit(rhs); 482 Visit(rhs);
472 switch (expr->location().type()) { 483 switch (expr->location().type()) {
473 case Location::NOWHERE: 484 case Location::UNINITIALIZED:
485 UNREACHABLE();
486 case Location::EFFECT:
474 // Case 'var = temp'. Discard right-hand-side temporary. 487 // Case 'var = temp'. Discard right-hand-side temporary.
475 Move(var->slot(), rhs->location()); 488 Move(var->slot(), rhs->location());
476 break; 489 break;
477 case Location::TEMP: 490 case Location::VALUE:
478 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side 491 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side
479 // temporary on the stack. 492 // temporary on the stack.
480 __ mov(eax, Operand(esp, 0)); 493 __ mov(eax, Operand(esp, 0));
481 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); 494 __ mov(Operand(ebp, SlotOffset(var->slot())), eax);
482 break; 495 break;
483 } 496 }
484 } 497 }
485 } 498 }
486 } 499 }
487 500
(...skipping 24 matching lines...) Expand all
512 Visit(expr->key()); 525 Visit(expr->key());
513 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 526 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
514 __ call(ic, RelocInfo::CODE_TARGET); 527 __ call(ic, RelocInfo::CODE_TARGET);
515 // By emitting a nop we make sure that we do not have a "test eax,..." 528 // By emitting a nop we make sure that we do not have a "test eax,..."
516 // instruction after the call it is treated specially by the LoadIC code. 529 // instruction after the call it is treated specially by the LoadIC code.
517 __ nop(); 530 __ nop();
518 // Drop key left on the stack by IC. 531 // Drop key left on the stack by IC.
519 __ add(Operand(esp), Immediate(kPointerSize)); 532 __ add(Operand(esp), Immediate(kPointerSize));
520 } 533 }
521 switch (expr->location().type()) { 534 switch (expr->location().type()) {
522 case Location::TEMP: 535 case Location::UNINITIALIZED:
536 UNREACHABLE();
537 case Location::VALUE:
523 __ mov(Operand(esp, 0), eax); 538 __ mov(Operand(esp, 0), eax);
524 break; 539 break;
525 case Location::NOWHERE: 540 case Location::EFFECT:
526 __ add(Operand(esp), Immediate(kPointerSize)); 541 __ add(Operand(esp), Immediate(kPointerSize));
527 break; 542 break;
528 } 543 }
529 } 544 }
530 545
531 546
532 void FastCodeGenerator::VisitCall(Call* expr) { 547 void FastCodeGenerator::VisitCall(Call* expr) {
533 Expression* fun = expr->expression(); 548 Expression* fun = expr->expression();
534 ZoneList<Expression*>* args = expr->arguments(); 549 ZoneList<Expression*>* args = expr->arguments();
535 Variable* var = fun->AsVariableProxy()->AsVariable(); 550 Variable* var = fun->AsVariableProxy()->AsVariable();
536 ASSERT(var != NULL && !var->is_this() && var->is_global()); 551 ASSERT(var != NULL && !var->is_this() && var->is_global());
537 ASSERT(!var->is_possibly_eval()); 552 ASSERT(!var->is_possibly_eval());
538 553
539 __ push(Immediate(var->name())); 554 __ push(Immediate(var->name()));
540 // Push global object (receiver). 555 // Push global object (receiver).
541 __ push(CodeGenerator::GlobalObject()); 556 __ push(CodeGenerator::GlobalObject());
542 int arg_count = args->length(); 557 int arg_count = args->length();
543 for (int i = 0; i < arg_count; i++) { 558 for (int i = 0; i < arg_count; i++) {
544 Visit(args->at(i)); 559 Visit(args->at(i));
545 ASSERT(args->at(i)->location().is_temporary()); 560 ASSERT(args->at(i)->location().is_value());
546 } 561 }
547 // Record source position for debugger 562 // Record source position for debugger
548 SetSourcePosition(expr->position()); 563 SetSourcePosition(expr->position());
549 // Call the IC initialization code. 564 // Call the IC initialization code.
550 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, 565 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
551 NOT_IN_LOOP); 566 NOT_IN_LOOP);
552 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); 567 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
553 // Restore context register. 568 // Restore context register.
554 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 569 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
555 // Discard the function left on TOS. 570 // Discard the function left on TOS.
556 DropAndMove(expr->location(), eax); 571 DropAndMove(expr->location(), eax);
557 } 572 }
558 573
559 574
560 void FastCodeGenerator::VisitCallNew(CallNew* node) { 575 void FastCodeGenerator::VisitCallNew(CallNew* node) {
561 Comment cmnt(masm_, "[ CallNew"); 576 Comment cmnt(masm_, "[ CallNew");
562 // According to ECMA-262, section 11.2.2, page 44, the function 577 // According to ECMA-262, section 11.2.2, page 44, the function
563 // expression in new calls must be evaluated before the 578 // expression in new calls must be evaluated before the
564 // arguments. 579 // arguments.
565 // Push function on the stack. 580 // Push function on the stack.
566 Visit(node->expression()); 581 Visit(node->expression());
567 ASSERT(node->expression()->location().is_temporary()); 582 ASSERT(node->expression()->location().is_value());
568 583
569 // Push global object (receiver). 584 // Push global object (receiver).
570 __ push(CodeGenerator::GlobalObject()); 585 __ push(CodeGenerator::GlobalObject());
571 586
572 // Push the arguments ("left-to-right") on the stack. 587 // Push the arguments ("left-to-right") on the stack.
573 ZoneList<Expression*>* args = node->arguments(); 588 ZoneList<Expression*>* args = node->arguments();
574 int arg_count = args->length(); 589 int arg_count = args->length();
575 for (int i = 0; i < arg_count; i++) { 590 for (int i = 0; i < arg_count; i++) {
576 Visit(args->at(i)); 591 Visit(args->at(i));
577 ASSERT(args->at(i)->location().is_temporary()); 592 ASSERT(args->at(i)->location().is_value());
578 // If location is temporary, it is already on the stack, 593 // If location is temporary, it is already on the stack,
579 // so nothing to do here. 594 // so nothing to do here.
580 } 595 }
581 596
582 // Call the construct call builtin that handles allocation and 597 // Call the construct call builtin that handles allocation and
583 // constructor invocation. 598 // constructor invocation.
584 SetSourcePosition(node->position()); 599 SetSourcePosition(node->position());
585 600
586 // Load function, arg_count into edi and eax. 601 // Load function, arg_count into edi and eax.
587 __ Set(eax, Immediate(arg_count)); 602 __ Set(eax, Immediate(arg_count));
(...skipping 12 matching lines...) Expand all
600 Comment cmnt(masm_, "[ CallRuntime"); 615 Comment cmnt(masm_, "[ CallRuntime");
601 ZoneList<Expression*>* args = expr->arguments(); 616 ZoneList<Expression*>* args = expr->arguments();
602 Runtime::Function* function = expr->function(); 617 Runtime::Function* function = expr->function();
603 618
604 ASSERT(function != NULL); 619 ASSERT(function != NULL);
605 620
606 // Push the arguments ("left-to-right"). 621 // Push the arguments ("left-to-right").
607 int arg_count = args->length(); 622 int arg_count = args->length();
608 for (int i = 0; i < arg_count; i++) { 623 for (int i = 0; i < arg_count; i++) {
609 Visit(args->at(i)); 624 Visit(args->at(i));
610 ASSERT(args->at(i)->location().is_temporary()); 625 ASSERT(args->at(i)->location().is_value());
611 } 626 }
612 627
613 __ CallRuntime(function, arg_count); 628 __ CallRuntime(function, arg_count);
614 Move(expr->location(), eax); 629 Move(expr->location(), eax);
615 } 630 }
616 631
617 632
618 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { 633 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
619 // Compile a short-circuited boolean or operation in a non-test 634 // Compile a short-circuited boolean or operation in a non-test
620 // context. 635 // context.
621 ASSERT(expr->op() == Token::OR); 636 ASSERT(expr->op() == Token::OR);
622 // Compile (e0 || e1) as if it were 637 // Compile (e0 || e1) as if it were
623 // (let (temp = e0) temp ? temp : e1). 638 // (let (temp = e0) temp ? temp : e1).
624 639
625 Label eval_right, done; 640 Label eval_right, done;
626 Location destination = expr->location(); 641 Location destination = expr->location();
627 Expression* left = expr->left(); 642 Expression* left = expr->left();
628 Expression* right = expr->right(); 643 Expression* right = expr->right();
629 644
630 // Use the shared ToBoolean stub to find the boolean value of the 645 // Use the shared ToBoolean stub to find the boolean value of the
631 // left-hand subexpression. Load the value into eax to perform some 646 // left-hand subexpression. Load the value into eax to perform some
632 // inlined checks assumed by the stub. 647 // inlined checks assumed by the stub.
633 648
634 // Compile the left-hand value into eax. Put it on the stack if we may 649 // Compile the left-hand value into eax. Put it on the stack if we may
635 // need it as the value of the whole expression. 650 // need it as the value of the whole expression.
636 if (left->AsLiteral() != NULL) { 651 if (left->AsLiteral() != NULL) {
637 __ mov(eax, left->AsLiteral()->handle()); 652 __ mov(eax, left->AsLiteral()->handle());
638 if (destination.is_temporary()) __ push(eax); 653 if (destination.is_value()) __ push(eax);
639 } else { 654 } else {
640 Visit(left); 655 Visit(left);
641 ASSERT(left->location().is_temporary()); 656 ASSERT(left->location().is_value());
642 switch (destination.type()) { 657 switch (destination.type()) {
643 case Location::NOWHERE: 658 case Location::UNINITIALIZED:
659 UNREACHABLE();
660 case Location::EFFECT:
644 // Pop the left-hand value into eax because we will not need it as the 661 // Pop the left-hand value into eax because we will not need it as the
645 // final result. 662 // final result.
646 __ pop(eax); 663 __ pop(eax);
647 break; 664 break;
648 case Location::TEMP: 665 case Location::VALUE:
649 // Copy the left-hand value into eax because we may need it as the 666 // Copy the left-hand value into eax because we may need it as the
650 // final result. 667 // final result.
651 __ mov(eax, Operand(esp, 0)); 668 __ mov(eax, Operand(esp, 0));
652 break; 669 break;
653 } 670 }
654 } 671 }
655 // The left-hand value is in eax. It is also on the stack iff the 672 // The left-hand value is in eax. It is also on the stack iff the
656 // destination location is temporary. 673 // destination location is temporary.
657 674
658 // Perform fast checks assumed by the stub. 675 // Perform fast checks assumed by the stub.
(...skipping 11 matching lines...) Expand all
670 687
671 // Call the stub for all other cases. 688 // Call the stub for all other cases.
672 __ push(eax); 689 __ push(eax);
673 ToBooleanStub stub; 690 ToBooleanStub stub;
674 __ CallStub(&stub); 691 __ CallStub(&stub);
675 __ test(eax, Operand(eax)); // The stub returns nonzero for true. 692 __ test(eax, Operand(eax)); // The stub returns nonzero for true.
676 __ j(not_zero, &done); 693 __ j(not_zero, &done);
677 694
678 __ bind(&eval_right); 695 __ bind(&eval_right);
679 // Discard the left-hand value if present on the stack. 696 // Discard the left-hand value if present on the stack.
680 if (destination.is_temporary()) { 697 if (destination.is_value()) {
681 __ add(Operand(esp), Immediate(kPointerSize)); 698 __ add(Operand(esp), Immediate(kPointerSize));
682 } 699 }
683 // Save or discard the right-hand value as needed. 700 // Save or discard the right-hand value as needed.
684 if (right->AsLiteral() != NULL) { 701 if (right->AsLiteral() != NULL) {
685 Move(destination, right->AsLiteral()); 702 Move(destination, right->AsLiteral());
686 } else { 703 } else {
687 Visit(right); 704 Visit(right);
688 Move(destination, right->location()); 705 Move(destination, right->location());
689 } 706 }
690 707
691 __ bind(&done); 708 __ bind(&done);
692 } 709 }
693 710
694 711
695 } } // namespace v8::internal 712 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/fast-codegen.cc ('k') | src/location.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698