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

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

Issue 338043: Make it more pleasant to work with expression locations in the... (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 | « no previous file | src/fast-codegen.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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 __ RecordJSReturn(); 113 __ RecordJSReturn();
114 __ mov(sp, fp); 114 __ mov(sp, fp);
115 __ ldm(ia_w, sp, fp.bit() | lr.bit()); 115 __ ldm(ia_w, sp, fp.bit() | lr.bit());
116 int num_parameters = function_->scope()->num_parameters(); 116 int num_parameters = function_->scope()->num_parameters();
117 __ add(sp, sp, Operand((num_parameters + 1) * kPointerSize)); 117 __ add(sp, sp, Operand((num_parameters + 1) * kPointerSize));
118 __ Jump(lr); 118 __ Jump(lr);
119 } 119 }
120 } 120 }
121 121
122 122
123 void FastCodeGenerator::Move(Location destination, Slot* source) {
124 switch (destination.type()) {
125 case Location::NOWHERE:
126 break;
127 case Location::TEMP:
128 __ ldr(ip, MemOperand(fp, SlotOffset(source)));
129 __ push(ip);
130 break;
131 }
132 }
133
134
135 void FastCodeGenerator::Move(Location destination, Literal* expr) {
136 switch (destination.type()) {
137 case Location::NOWHERE:
138 break;
139 case Location::TEMP:
140 __ mov(ip, Operand(expr->handle()));
141 __ push(ip);
142 break;
143 }
144 }
145
146
147 void FastCodeGenerator::Move(Slot* destination, Location source) {
148 switch (source.type()) {
149 case Location::NOWHERE:
150 UNREACHABLE();
151 case Location::TEMP:
152 __ pop(ip);
153 __ str(ip, MemOperand(fp, SlotOffset(destination)));
154 break;
155 }
156 }
157
158
123 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 159 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
124 // Call the runtime to declare the globals. 160 // Call the runtime to declare the globals.
125 // The context is the first argument. 161 // The context is the first argument.
126 __ mov(r1, Operand(pairs)); 162 __ mov(r1, Operand(pairs));
127 __ mov(r0, Operand(Smi::FromInt(is_eval_ ? 1 : 0))); 163 __ mov(r0, Operand(Smi::FromInt(is_eval_ ? 1 : 0)));
128 __ stm(db_w, sp, cp.bit() | r1.bit() | r0.bit()); 164 __ stm(db_w, sp, cp.bit() | r1.bit() | r0.bit());
129 __ CallRuntime(Runtime::kDeclareGlobals, 3); 165 __ CallRuntime(Runtime::kDeclareGlobals, 3);
130 // Return value is ignored. 166 // Return value is ignored.
131 } 167 }
132 168
133 169
134 void FastCodeGenerator::VisitBlock(Block* stmt) {
135 Comment cmnt(masm_, "[ Block");
136 SetStatementPosition(stmt);
137 VisitStatements(stmt->statements());
138 }
139
140
141 void FastCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
142 Comment cmnt(masm_, "[ ExpressionStatement");
143 SetStatementPosition(stmt);
144 Visit(stmt->expression());
145 }
146
147
148 void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { 170 void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
149 Comment cmnt(masm_, "[ ReturnStatement"); 171 Comment cmnt(masm_, "[ ReturnStatement");
150 SetStatementPosition(stmt); 172 SetStatementPosition(stmt);
151 Expression* expr = stmt->expression(); 173 Expression* expr = stmt->expression();
152 // Complete the statement based on the type of the subexpression. 174 // Complete the statement based on the type of the subexpression.
153 if (expr->AsLiteral() != NULL) { 175 if (expr->AsLiteral() != NULL) {
154 __ mov(r0, Operand(expr->AsLiteral()->handle())); 176 __ mov(r0, Operand(expr->AsLiteral()->handle()));
155 } else { 177 } else {
156 Visit(expr); 178 Visit(expr);
157 ASSERT(expr->location().is_temporary()); 179 ASSERT(expr->location().is_temporary());
(...skipping 20 matching lines...) Expand all
178 // Build the function boilerplate and instantiate it. 200 // Build the function boilerplate and instantiate it.
179 Handle<JSFunction> boilerplate = BuildBoilerplate(expr); 201 Handle<JSFunction> boilerplate = BuildBoilerplate(expr);
180 if (HasStackOverflow()) return; 202 if (HasStackOverflow()) return;
181 203
182 ASSERT(boilerplate->IsBoilerplate()); 204 ASSERT(boilerplate->IsBoilerplate());
183 205
184 // Create a new closure. 206 // Create a new closure.
185 __ mov(r0, Operand(boilerplate)); 207 __ mov(r0, Operand(boilerplate));
186 __ stm(db_w, sp, cp.bit() | r0.bit()); 208 __ stm(db_w, sp, cp.bit() | r0.bit());
187 __ CallRuntime(Runtime::kNewClosure, 2); 209 __ CallRuntime(Runtime::kNewClosure, 2);
188 210 Move(expr->location(), r0);
189 if (expr->location().is_temporary()) {
190 __ push(r0);
191 } else {
192 ASSERT(expr->location().is_nowhere());
193 }
194 } 211 }
195 212
196 213
197 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { 214 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
198 Comment cmnt(masm_, "[ VariableProxy"); 215 Comment cmnt(masm_, "[ VariableProxy");
199 Expression* rewrite = expr->var()->rewrite(); 216 Expression* rewrite = expr->var()->rewrite();
200 if (rewrite == NULL) { 217 if (rewrite == NULL) {
201 Comment cmnt(masm_, "Global variable"); 218 Comment cmnt(masm_, "Global variable");
202 // Use inline caching. Variable name is passed in r2 and the global 219 // Use inline caching. Variable name is passed in r2 and the global
203 // object on the stack. 220 // object on the stack.
204 __ ldr(ip, CodeGenerator::GlobalObject()); 221 __ ldr(ip, CodeGenerator::GlobalObject());
205 __ push(ip); 222 __ push(ip);
206 __ mov(r2, Operand(expr->name())); 223 __ mov(r2, Operand(expr->name()));
207 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 224 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
208 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); 225 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
209 if (expr->location().is_temporary()) { 226 switch (expr->location().type()) {
210 // Replace the global object with the result. 227 case Location::NOWHERE:
211 __ str(r0, MemOperand(sp)); 228 __ pop();
212 } else { 229 break;
213 ASSERT(expr->location().is_nowhere()); 230 case Location::TEMP:
214 __ pop(); 231 // Replace the global object with the result.
232 __ str(r0, MemOperand(sp));
233 break;
215 } 234 }
216 235
217 } else { 236 } else {
218 Comment cmnt(masm_, "Stack slot"); 237 Comment cmnt(masm_, "Stack slot");
219 Slot* slot = rewrite->AsSlot(); 238 Move(expr->location(), rewrite->AsSlot());
220 ASSERT(slot != NULL);
221 if (expr->location().is_temporary()) {
222 __ ldr(ip, MemOperand(fp, SlotOffset(slot)));
223 __ push(ip);
224 } else {
225 ASSERT(expr->location().is_nowhere());
226 }
227 }
228 }
229
230
231 void FastCodeGenerator::VisitLiteral(Literal* expr) {
232 if (expr->location().is_temporary()) {
233 __ mov(ip, Operand(expr->AsLiteral()->handle()));
234 __ push(ip);
235 } else {
236 ASSERT(expr->location().is_nowhere());
237 } 239 }
238 } 240 }
239 241
240 242
241 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 243 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
242 Comment cmnt(masm_, "[ ObjectLiteral"); 244 Comment cmnt(masm_, "[ ObjectLiteral");
243 Label boilerplate_exists; 245 Label boilerplate_exists;
244 __ ldr(r2, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 246 __ ldr(r2, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
245 // r2 = literal array (0). 247 // r2 = literal array (0).
246 __ ldr(r2, FieldMemOperand(r2, JSFunction::kLiteralsOffset)); 248 __ ldr(r2, FieldMemOperand(r2, JSFunction::kLiteralsOffset));
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 Smi::FromInt(0))); 310 Smi::FromInt(0)));
309 __ push(r1); 311 __ push(r1);
310 Visit(value); 312 Visit(value);
311 ASSERT(value->location().is_temporary()); 313 ASSERT(value->location().is_temporary());
312 __ CallRuntime(Runtime::kDefineAccessor, 4); 314 __ CallRuntime(Runtime::kDefineAccessor, 4);
313 __ ldr(r0, MemOperand(sp)); // Restore result into r0 315 __ ldr(r0, MemOperand(sp)); // Restore result into r0
314 break; 316 break;
315 default: UNREACHABLE(); 317 default: UNREACHABLE();
316 } 318 }
317 } 319 }
318 if (expr->location().is_nowhere() && result_saved) { 320 switch (expr->location().type()) {
319 __ pop(); 321 case Location::NOWHERE:
320 } else if (expr->location().is_temporary() && !result_saved) { 322 if (result_saved) __ pop();
321 ASSERT(expr->location().is_temporary()); 323 break;
322 __ push(r0); 324 case Location::TEMP:
325 if (!result_saved) __ push(r0);
326 break;
323 } 327 }
324 } 328 }
325 329
326 330
327 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 331 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
328 Comment cmnt(masm_, "[ RegExp Literal"); 332 Comment cmnt(masm_, "[ RegExp Literal");
329 Label done; 333 Label done;
330 // Registers will be used as follows: 334 // Registers will be used as follows:
331 // r4 = JS function, literals array 335 // r4 = JS function, literals array
332 // r3 = literal index 336 // r3 = literal index
333 // r2 = RegExp pattern 337 // r2 = RegExp pattern
334 // r1 = RegExp flags 338 // r1 = RegExp flags
335 // r0 = temp + return value (RegExp literal) 339 // r0 = temp + return value (RegExp literal)
336 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 340 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
337 __ ldr(r4, FieldMemOperand(r0, JSFunction::kLiteralsOffset)); 341 __ ldr(r4, FieldMemOperand(r0, JSFunction::kLiteralsOffset));
338 int literal_offset = 342 int literal_offset =
339 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; 343 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
340 __ ldr(r0, FieldMemOperand(r4, literal_offset)); 344 __ ldr(r0, FieldMemOperand(r4, literal_offset));
341 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 345 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
342 __ cmp(r0, ip); 346 __ cmp(r0, ip);
343 __ b(ne, &done); 347 __ b(ne, &done);
344 __ mov(r3, Operand(Smi::FromInt(expr->literal_index()))); 348 __ mov(r3, Operand(Smi::FromInt(expr->literal_index())));
345 __ mov(r2, Operand(expr->pattern())); 349 __ mov(r2, Operand(expr->pattern()));
346 __ mov(r1, Operand(expr->flags())); 350 __ mov(r1, Operand(expr->flags()));
347 __ stm(db_w, sp, r4.bit() | r3.bit() | r2.bit() | r1.bit()); 351 __ stm(db_w, sp, r4.bit() | r3.bit() | r2.bit() | r1.bit());
348 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); 352 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
349 __ bind(&done); 353 __ bind(&done);
350 if (expr->location().is_temporary()) { 354 Move(expr->location(), r0);
351 __ push(r0);
352 } else {
353 ASSERT(expr->location().is_nowhere());
354 }
355 } 355 }
356 356
357 357
358 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 358 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
359 Comment cmnt(masm_, "[ ArrayLiteral"); 359 Comment cmnt(masm_, "[ ArrayLiteral");
360 Label make_clone; 360 Label make_clone;
361 361
362 // Fetch the function's literals array. 362 // Fetch the function's literals array.
363 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 363 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
364 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); 364 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset));
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 __ ldr(r1, FieldMemOperand(r1, JSObject::kElementsOffset)); 412 __ ldr(r1, FieldMemOperand(r1, JSObject::kElementsOffset));
413 int offset = FixedArray::kHeaderSize + (i * kPointerSize); 413 int offset = FixedArray::kHeaderSize + (i * kPointerSize);
414 __ str(r0, FieldMemOperand(r1, offset)); 414 __ str(r0, FieldMemOperand(r1, offset));
415 415
416 // Update the write barrier for the array store with r0 as the scratch 416 // Update the write barrier for the array store with r0 as the scratch
417 // register. 417 // register.
418 __ mov(r2, Operand(offset)); 418 __ mov(r2, Operand(offset));
419 __ RecordWrite(r1, r2, r0); 419 __ RecordWrite(r1, r2, r0);
420 } 420 }
421 421
422 Location destination = expr->location(); 422 switch (expr->location().type()) {
423 if (destination.is_nowhere() && result_saved) { 423 case Location::NOWHERE:
424 __ pop(); 424 if (result_saved) __ pop();
425 } else if (destination.is_temporary() && !result_saved) { 425 break;
426 __ push(r0); 426 case Location::TEMP:
427 if (!result_saved) __ push(r0);
428 break;
427 } 429 }
428 } 430 }
429 431
430 432
431 void FastCodeGenerator::VisitAssignment(Assignment* expr) { 433 void FastCodeGenerator::VisitAssignment(Assignment* expr) {
432 Comment cmnt(masm_, "[ Assignment"); 434 Comment cmnt(masm_, "[ Assignment");
433 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); 435 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR);
434 436
435 // Left-hand side can only be a global or a (parameter or local) slot. 437 // Left-hand side can only be a global or a (parameter or local) slot.
436 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); 438 Variable* var = expr->target()->AsVariableProxy()->AsVariable();
(...skipping 14 matching lines...) Expand all
451 ASSERT(rhs->location().is_temporary()); 453 ASSERT(rhs->location().is_temporary());
452 Visit(rhs); 454 Visit(rhs);
453 __ pop(r0); 455 __ pop(r0);
454 } 456 }
455 __ mov(r2, Operand(var->name())); 457 __ mov(r2, Operand(var->name()));
456 __ ldr(ip, CodeGenerator::GlobalObject()); 458 __ ldr(ip, CodeGenerator::GlobalObject());
457 __ push(ip); 459 __ push(ip);
458 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 460 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
459 __ Call(ic, RelocInfo::CODE_TARGET); 461 __ Call(ic, RelocInfo::CODE_TARGET);
460 // Overwrite the global object on the stack with the result if needed. 462 // Overwrite the global object on the stack with the result if needed.
461 if (destination.is_temporary()) { 463 switch (expr->location().type()) {
462 __ str(r0, MemOperand(sp)); 464 case Location::NOWHERE:
463 } else { 465 __ pop();
464 ASSERT(destination.is_nowhere()); 466 break;
465 __ pop(); 467 case Location::TEMP:
468 __ str(r0, MemOperand(sp));
469 break;
466 } 470 }
467 471
468 } else { 472 } else {
469 // Local or parameter assignment. 473 // Local or parameter assignment.
470 474
471 // Code for the right-hand side expression depends on its type. 475 // Code for the right-hand side expression depends on its type.
472 if (rhs->AsLiteral() != NULL) { 476 if (rhs->AsLiteral() != NULL) {
473 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a 477 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a
474 // discarded result. Always perform the assignment. 478 // discarded result. Always perform the assignment.
475 __ mov(ip, Operand(rhs->AsLiteral()->handle())); 479 __ mov(ip, Operand(rhs->AsLiteral()->handle()));
476 __ str(ip, MemOperand(fp, SlotOffset(var->slot()))); 480 __ str(ip, MemOperand(fp, SlotOffset(var->slot())));
477 if (destination.is_temporary()) { 481 Move(expr->location(), ip);
478 // Case 'temp <- (var = constant)'. Save result.
479 __ push(ip);
480 }
481 } else { 482 } else {
482 ASSERT(rhs->location().is_temporary()); 483 ASSERT(rhs->location().is_temporary());
483 Visit(rhs); 484 Visit(rhs);
484 if (destination.is_temporary()) { 485 // Load right-hand side into ip.
485 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side 486 switch (expr->location().type()) {
486 // temporary on the stack. 487 case Location::NOWHERE:
487 __ ldr(ip, MemOperand(sp)); 488 // Case 'var = temp'. Discard right-hand-side temporary.
488 } else { 489 __ pop(ip);
489 ASSERT(destination.is_nowhere()); 490 break;
490 // Case 'var = temp'. Discard right-hand-side temporary. 491 case Location::TEMP:
491 __ pop(ip); 492 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side
493 // temporary on the stack.
494 __ ldr(ip, MemOperand(sp));
495 break;
492 } 496 }
497 // Do the slot assignment.
493 __ str(ip, MemOperand(fp, SlotOffset(var->slot()))); 498 __ str(ip, MemOperand(fp, SlotOffset(var->slot())));
494 } 499 }
495 } 500 }
496 } 501 }
497 502
498 503
499 void FastCodeGenerator::VisitCall(Call* expr) { 504 void FastCodeGenerator::VisitCall(Call* expr) {
500 Comment cmnt(masm_, "[ Call"); 505 Comment cmnt(masm_, "[ Call");
501 Expression* fun = expr->expression(); 506 Expression* fun = expr->expression();
502 ZoneList<Expression*>* args = expr->arguments(); 507 ZoneList<Expression*>* args = expr->arguments();
(...skipping 11 matching lines...) Expand all
514 ASSERT(args->at(i)->location().is_temporary()); 519 ASSERT(args->at(i)->location().is_temporary());
515 } 520 }
516 // Record source position for debugger 521 // Record source position for debugger
517 SetSourcePosition(expr->position()); 522 SetSourcePosition(expr->position());
518 // Call the IC initialization code. 523 // Call the IC initialization code.
519 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, 524 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
520 NOT_IN_LOOP); 525 NOT_IN_LOOP);
521 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); 526 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
522 // Restore context register. 527 // Restore context register.
523 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 528 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
524 if (expr->location().is_temporary()) { 529 switch (expr->location().type()) {
525 __ str(r0, MemOperand(sp)); 530 case Location::NOWHERE:
526 } else { 531 __ pop();
527 ASSERT(expr->location().is_nowhere()); 532 break;
528 __ pop(); 533 case Location::TEMP:
534 __ str(r0, MemOperand(sp));
535 break;
529 } 536 }
530 } 537 }
531 538
532 539
533 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 540 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
534 Comment cmnt(masm_, "[ CallRuntime"); 541 Comment cmnt(masm_, "[ CallRuntime");
535 ZoneList<Expression*>* args = expr->arguments(); 542 ZoneList<Expression*>* args = expr->arguments();
536 Runtime::Function* function = expr->function(); 543 Runtime::Function* function = expr->function();
537 544
538 ASSERT(function != NULL); 545 ASSERT(function != NULL);
539 546
540 // Push the arguments ("left-to-right"). 547 // Push the arguments ("left-to-right").
541 int arg_count = args->length(); 548 int arg_count = args->length();
542 for (int i = 0; i < arg_count; i++) { 549 for (int i = 0; i < arg_count; i++) {
543 Visit(args->at(i)); 550 Visit(args->at(i));
544 ASSERT(args->at(i)->location().is_temporary()); 551 ASSERT(args->at(i)->location().is_temporary());
545 } 552 }
546 553
547 __ CallRuntime(function, arg_count); 554 __ CallRuntime(function, arg_count);
548 if (expr->location().is_temporary()) { 555 Move(expr->location(), r0);
549 __ push(r0);
550 } else {
551 ASSERT(expr->location().is_nowhere());
552 }
553 } 556 }
554 557
555 558
556 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { 559 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
557 // Compile a short-circuited boolean or operation in a non-test 560 // Compile a short-circuited boolean or operation in a non-test
558 // context. 561 // context.
559 ASSERT(expr->op() == Token::OR); 562 ASSERT(expr->op() == Token::OR);
560 // Compile (e0 || e1) as if it were 563 // Compile (e0 || e1) as if it were
561 // (let (temp = e0) temp ? temp : e1). 564 // (let (temp = e0) temp ? temp : e1).
562 565
(...skipping 21 matching lines...) Expand all
584 // stack iff the destination location is temporary. 587 // stack iff the destination location is temporary.
585 __ CallRuntime(Runtime::kToBool, 1); 588 __ CallRuntime(Runtime::kToBool, 1);
586 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 589 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
587 __ cmp(r0, ip); 590 __ cmp(r0, ip);
588 __ b(eq, &done); 591 __ b(eq, &done);
589 592
590 // Discard the left-hand value if present on the stack. 593 // Discard the left-hand value if present on the stack.
591 if (destination.is_temporary()) __ pop(); 594 if (destination.is_temporary()) __ pop();
592 // Save or discard the right-hand value as needed. 595 // Save or discard the right-hand value as needed.
593 if (right->AsLiteral() != NULL) { 596 if (right->AsLiteral() != NULL) {
594 if (destination.is_temporary()) { 597 Move(destination, right->AsLiteral());
595 __ mov(ip, Operand(right->AsLiteral()->handle()));
596 __ push(ip);
597 } else {
598 ASSERT(destination.is_nowhere());
599 }
600 } else { 598 } else {
601 Visit(right); 599 Visit(right);
602 ASSERT(right->location().is_temporary()); 600 Move(destination, right->location());
603 if (destination.is_nowhere()) {
604 __ pop();
605 } else {
606 ASSERT(destination.is_temporary());
607 }
608 } 601 }
609 602
610 __ bind(&done); 603 __ bind(&done);
611 } 604 }
612 605
613 } } // namespace v8::internal 606 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/fast-codegen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698