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

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

Powered by Google App Engine
This is Rietveld 408576698