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

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

Issue 405033: Fast-codegen: Arguments object working on all platforms. (Closed)
Patch Set: Addressed review coments. Created 11 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
« no previous file with comments | « no previous file | src/arm/macro-assembler-arm.h » ('j') | src/ia32/fast-codegen-ia32.cc » ('J')
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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 __ add(fp, sp, Operand(2 * kPointerSize)); 66 __ add(fp, sp, Operand(2 * kPointerSize));
67 67
68 { Comment cmnt(masm_, "[ Allocate locals"); 68 { Comment cmnt(masm_, "[ Allocate locals");
69 for (int i = 0; i < locals_count; i++) { 69 for (int i = 0; i < locals_count; i++) {
70 __ push(ip); 70 __ push(ip);
71 } 71 }
72 } 72 }
73 73
74 bool function_in_register = true; 74 bool function_in_register = true;
75 75
76 // Possibly allocate a local context.
77 if (fun->scope()->num_heap_slots() > 0) {
78 Comment cmnt(masm_, "[ Allocate local context");
79 // Argument to NewContext is the function, which is in r1.
80 __ push(r1);
81 __ CallRuntime(Runtime::kNewContext, 1);
82 function_in_register = false;
83 // Context is returned in both r0 and cp. It replaces the context
84 // passed to us. It's saved in the stack and kept live in cp.
85 __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
86 // Copy any necessary parameters into the context.
87 int num_parameters = fun->scope()->num_parameters();
88 for (int i = 0; i < num_parameters; i++) {
89 Slot* slot = fun->scope()->parameter(i)->slot();
90 if (slot != NULL && slot->type() == Slot::CONTEXT) {
91 int parameter_offset = StandardFrameConstants::kCallerSPOffset +
92 (num_parameters - 1 - i) * kPointerSize;
93 // Load parameter from stack.
94 __ ldr(r0, MemOperand(fp, parameter_offset));
95 // Store it in the context
96 __ str(r0, MemOperand(cp, Context::SlotOffset(slot->index())));
97 }
98 }
99 }
100
76 Variable* arguments = fun->scope()->arguments()->AsVariable(); 101 Variable* arguments = fun->scope()->arguments()->AsVariable();
77 if (arguments != NULL) { 102 if (arguments != NULL) {
78 // Function uses arguments object. 103 // Function uses arguments object.
79 Comment cmnt(masm_, "[ Allocate arguments object"); 104 Comment cmnt(masm_, "[ Allocate arguments object");
80 __ mov(r3, r1); 105 if (!function_in_register) {
106 // Load this again, if it's used by the local context below.
107 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
108 } else {
109 __ mov(r3, r1);
110 }
81 // Receiver is just before the parameters on the caller's stack. 111 // Receiver is just before the parameters on the caller's stack.
82 __ add(r2, fp, Operand(StandardFrameConstants::kCallerSPOffset + 112 __ add(r2, fp, Operand(StandardFrameConstants::kCallerSPOffset +
83 fun->num_parameters() * kPointerSize)); 113 fun->num_parameters() * kPointerSize));
84 __ mov(r1, Operand(Smi::FromInt(fun->num_parameters()))); 114 __ mov(r1, Operand(Smi::FromInt(fun->num_parameters())));
85 __ stm(db_w, sp, r1.bit() | r2.bit() | r3.bit()); 115 __ stm(db_w, sp, r3.bit() | r2.bit() | r1.bit());
86 116
87 // Arguments to ArgumentsAccessStub: 117 // Arguments to ArgumentsAccessStub:
88 // function, receiver address, parameter count. 118 // function, receiver address, parameter count.
89 // The stub will rewrite receiever and parameter count if the previous 119 // The stub will rewrite receiever and parameter count if the previous
90 // stack frame was an arguments adapter frame. 120 // stack frame was an arguments adapter frame.
91 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); 121 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT);
92 __ CallStub(&stub); 122 __ CallStub(&stub);
93 __ str(r0, MemOperand(fp, SlotOffset(arguments->slot()))); 123 // Duplicate the value; move-to-slot operation might clobber registers.
124 __ mov(r3, r0);
125 Move(arguments->slot(), r0, r1, r2);
94 Slot* dot_arguments_slot = 126 Slot* dot_arguments_slot =
95 fun->scope()->arguments_shadow()->AsVariable()->slot(); 127 fun->scope()->arguments_shadow()->AsVariable()->slot();
96 __ str(r0, MemOperand(fp, SlotOffset(dot_arguments_slot))); 128 Move(dot_arguments_slot, r3, r1, r2);
97 function_in_register = false;
98 }
99
100 // Possibly allocate a local context.
101 if (fun->scope()->num_heap_slots() > 0) {
102 Comment cmnt(masm_, "[ Allocate local context");
103 if (!function_in_register) {
104 // Load this again, if it's used by the local context below.
105 __ ldr(r1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
106 }
107 // Argument to NewContext is the function, which is in r1.
108 __ push(r1);
109 __ CallRuntime(Runtime::kNewContext, 1);
110 // Context is returned in both r0 and cp. It replaces the context
111 // passed to us. It's saved in the stack and kept live in cp.
112 __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
113 #ifdef DEBUG
114 // Assert we do not have to copy any parameters into the context.
115 for (int i = 0, len = fun->scope()->num_parameters(); i < len; i++) {
116 Slot* slot = fun->scope()->parameter(i)->slot();
117 ASSERT(slot != NULL && slot->type() != Slot::CONTEXT);
118 }
119 #endif
120 } 129 }
121 130
122 // Check the stack for overflow or break request. 131 // Check the stack for overflow or break request.
123 // Put the lr setup instruction in the delay slot. The kInstrSize is 132 // Put the lr setup instruction in the delay slot. The kInstrSize is
124 // added to the implicit 8 byte offset that always applies to operations 133 // added to the implicit 8 byte offset that always applies to operations
125 // with pc and gives a return address 12 bytes down. 134 // with pc and gives a return address 12 bytes down.
126 { Comment cmnt(masm_, "[ Stack check"); 135 { Comment cmnt(masm_, "[ Stack check");
127 __ LoadRoot(r2, Heap::kStackLimitRootIndex); 136 __ LoadRoot(r2, Heap::kStackLimitRootIndex);
128 __ add(lr, pc, Operand(Assembler::kInstrSize)); 137 __ add(lr, pc, Operand(Assembler::kInstrSize));
129 __ cmp(sp, Operand(r2)); 138 __ cmp(sp, Operand(r2));
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 __ push(source); 240 __ push(source);
232 TestAndBranch(source, &discard, false_label_); 241 TestAndBranch(source, &discard, false_label_);
233 __ bind(&discard); 242 __ bind(&discard);
234 __ pop(); 243 __ pop();
235 __ jmp(true_label_); 244 __ jmp(true_label_);
236 } 245 }
237 } 246 }
238 } 247 }
239 248
240 249
241 void FastCodeGenerator::Move(Expression::Context context, Slot* source) { 250 template <>
251 MemOperand FastCodeGenerator::CreateSlotOperand<MemOperand>(
252 Slot* source,
253 Register scratch) {
254 switch (source->type()) {
255 case Slot::PARAMETER:
256 case Slot::LOCAL:
257 return MemOperand(fp, SlotOffset(source));
258 case Slot::CONTEXT: {
259 int context_chain_length =
260 function_->scope()->ContextChainLength(source->var()->scope());
261 __ LoadContext(scratch, context_chain_length);
262 return CodeGenerator::ContextOperand(scratch, source->index());
263 break;
264 }
265 case Slot::LOOKUP:
266 UNIMPLEMENTED();
267 // Fall-through.
268 default:
269 UNREACHABLE();
270 return MemOperand(r0, 0); // Dead code to make the compiler happy.
271 }
272 }
273
274
275 void FastCodeGenerator::Move(Register dst, Slot* source) {
276 // Use dst as scratch.
277 MemOperand location = CreateSlotOperand<MemOperand>(source, dst);
278 __ ldr(dst, location);
279 }
280
281
282
283 void FastCodeGenerator::Move(Expression::Context context,
284 Slot* source,
285 Register scratch) {
242 switch (context) { 286 switch (context) {
243 case Expression::kUninitialized: 287 case Expression::kUninitialized:
244 UNREACHABLE(); 288 UNREACHABLE();
245 case Expression::kEffect: 289 case Expression::kEffect:
246 break; 290 break;
247 case Expression::kValue: // Fall through. 291 case Expression::kValue: // Fall through.
248 case Expression::kTest: // Fall through. 292 case Expression::kTest: // Fall through.
249 case Expression::kValueTest: // Fall through. 293 case Expression::kValueTest: // Fall through.
250 case Expression::kTestValue: 294 case Expression::kTestValue:
251 __ ldr(ip, MemOperand(fp, SlotOffset(source))); 295 Move(scratch, source);
252 Move(context, ip); 296 Move(context, scratch);
253 break; 297 break;
254 } 298 }
255 } 299 }
256 300
257 301
258 void FastCodeGenerator::Move(Expression::Context context, Literal* expr) { 302 void FastCodeGenerator::Move(Expression::Context context, Literal* expr) {
259 switch (context) { 303 switch (context) {
260 case Expression::kUninitialized: 304 case Expression::kUninitialized:
261 UNREACHABLE(); 305 UNREACHABLE();
262 case Expression::kEffect: 306 case Expression::kEffect:
263 break; 307 break;
264 case Expression::kValue: // Fall through. 308 case Expression::kValue: // Fall through.
265 case Expression::kTest: // Fall through. 309 case Expression::kTest: // Fall through.
266 case Expression::kValueTest: // Fall through. 310 case Expression::kValueTest: // Fall through.
267 case Expression::kTestValue: 311 case Expression::kTestValue:
268 __ mov(ip, Operand(expr->handle())); 312 __ mov(ip, Operand(expr->handle()));
269 Move(context, ip); 313 Move(context, ip);
270 break; 314 break;
271 } 315 }
272 } 316 }
273 317
274 318
319 void FastCodeGenerator::Move(Slot* dst,
320 Register src,
321 Register scratch1,
322 Register scratch2) {
323 switch (dst->type()) {
324 case Slot::PARAMETER:
325 case Slot::LOCAL:
326 __ str(src, MemOperand(fp, SlotOffset(dst)));
327 break;
328 case Slot::CONTEXT: {
329 int context_chain_length =
330 function_->scope()->ContextChainLength(dst->var()->scope());
331 __ LoadContext(scratch1, context_chain_length);
332 int index = Context::SlotOffset(dst->index());
333 __ mov(scratch2, Operand(index));
334 __ str(src, MemOperand(scratch1, index));
335 __ RecordWrite(scratch1, scratch2, src);
336 break;
337 }
338 case Slot::LOOKUP:
339 UNIMPLEMENTED();
340 default:
341 UNREACHABLE();
342 }
343 }
344
345
346
275 void FastCodeGenerator::DropAndMove(Expression::Context context, 347 void FastCodeGenerator::DropAndMove(Expression::Context context,
276 Register source) { 348 Register source,
349 int drop_count) {
350 ASSERT(drop_count > 0);
277 switch (context) { 351 switch (context) {
278 case Expression::kUninitialized: 352 case Expression::kUninitialized:
279 UNREACHABLE(); 353 UNREACHABLE();
280 case Expression::kEffect: 354 case Expression::kEffect:
281 __ pop(); 355 __ add(sp, sp, Operand(drop_count * kPointerSize));
282 break; 356 break;
283 case Expression::kValue: 357 case Expression::kValue:
358 if (drop_count > 1) {
359 __ add(sp, sp, Operand((drop_count - 1) * kPointerSize));
360 }
284 __ str(source, MemOperand(sp)); 361 __ str(source, MemOperand(sp));
285 break; 362 break;
286 case Expression::kTest: 363 case Expression::kTest:
287 ASSERT(!source.is(sp)); 364 ASSERT(!source.is(sp));
288 __ pop(); 365 __ add(sp, sp, Operand(drop_count * kPointerSize));
289 TestAndBranch(source, true_label_, false_label_); 366 TestAndBranch(source, true_label_, false_label_);
290 break; 367 break;
291 case Expression::kValueTest: { 368 case Expression::kValueTest: {
292 Label discard; 369 Label discard;
370 if (drop_count > 1) {
371 __ add(sp, sp, Operand((drop_count - 1) * kPointerSize));
372 }
293 __ str(source, MemOperand(sp)); 373 __ str(source, MemOperand(sp));
294 TestAndBranch(source, true_label_, &discard); 374 TestAndBranch(source, true_label_, &discard);
295 __ bind(&discard); 375 __ bind(&discard);
296 __ pop(); 376 __ pop();
297 __ jmp(false_label_); 377 __ jmp(false_label_);
298 break; 378 break;
299 } 379 }
300 case Expression::kTestValue: { 380 case Expression::kTestValue: {
301 Label discard; 381 Label discard;
382 if (drop_count > 1) {
383 __ add(sp, sp, Operand((drop_count - 1) * kPointerSize));
384 }
302 __ str(source, MemOperand(sp)); 385 __ str(source, MemOperand(sp));
303 TestAndBranch(source, &discard, false_label_); 386 TestAndBranch(source, &discard, false_label_);
304 __ bind(&discard); 387 __ bind(&discard);
305 __ pop(); 388 __ pop();
306 __ jmp(true_label_); 389 __ jmp(true_label_);
307 break; 390 break;
308 } 391 }
309 } 392 }
310 } 393 }
311 394
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 // Use inline caching. Variable name is passed in r2 and the global 543 // Use inline caching. Variable name is passed in r2 and the global
461 // object on the stack. 544 // object on the stack.
462 __ ldr(ip, CodeGenerator::GlobalObject()); 545 __ ldr(ip, CodeGenerator::GlobalObject());
463 __ push(ip); 546 __ push(ip);
464 __ mov(r2, Operand(expr->name())); 547 __ mov(r2, Operand(expr->name()));
465 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 548 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
466 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); 549 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
467 DropAndMove(expr->context(), r0); 550 DropAndMove(expr->context(), r0);
468 } else if (rewrite->AsSlot() != NULL) { 551 } else if (rewrite->AsSlot() != NULL) {
469 Slot* slot = rewrite->AsSlot(); 552 Slot* slot = rewrite->AsSlot();
470 ASSERT_NE(NULL, slot); 553 if (FLAG_debug_code) {
471 switch (slot->type()) { 554 switch (slot->type()) {
472 case Slot::LOCAL: 555 case Slot::LOCAL:
473 case Slot::PARAMETER: { 556 case Slot::PARAMETER: {
474 Comment cmnt(masm_, "Stack slot"); 557 Comment cmnt(masm_, "Stack slot");
475 Move(expr->context(), rewrite->AsSlot()); 558 break;
476 break; 559 }
560 case Slot::CONTEXT: {
561 Comment cmnt(masm_, "Context slot");
562 break;
563 }
564 case Slot::LOOKUP:
565 UNIMPLEMENTED();
566 break;
567 default:
568 UNREACHABLE();
477 } 569 }
478
479 case Slot::CONTEXT: {
480 Comment cmnt(masm_, "Context slot");
481 int chain_length =
482 function_->scope()->ContextChainLength(slot->var()->scope());
483 if (chain_length > 0) {
484 // Move up the chain of contexts to the context containing the slot.
485 __ ldr(r0, CodeGenerator::ContextOperand(cp, Context::CLOSURE_INDEX));
486 // Load the function context (which is the incoming, outer context).
487 __ ldr(r0, FieldMemOperand(r0, JSFunction::kContextOffset));
488 for (int i = 1; i < chain_length; i++) {
489 __ ldr(r0,
490 CodeGenerator::ContextOperand(r0, Context::CLOSURE_INDEX));
491 // Load the function context (which is the incoming, outer context).
492 __ ldr(r0, FieldMemOperand(r0, JSFunction::kContextOffset));
493 }
494 // The context may be an intermediate context, not a function context.
495 __ ldr(r0,
496 CodeGenerator::ContextOperand(r0, Context::FCONTEXT_INDEX));
497 } else { // Slot is in the current context.
498 __ ldr(r0,
499 CodeGenerator::ContextOperand(cp, Context::FCONTEXT_INDEX));
500 }
501 __ ldr(r0, CodeGenerator::ContextOperand(r0, slot->index()));
502 Move(expr->context(), r0);
503 break;
504 }
505
506 case Slot::LOOKUP:
507 UNREACHABLE();
508 break;
509 } 570 }
571 Move(expr->context(), slot, r0);
510 } else { 572 } else {
511 // The parameter variable has been rewritten into an explict access to 573 // A variable has been rewritten into an explicit access to
512 // the arguments object. 574 // an object property.
513 Property* property = rewrite->AsProperty(); 575 Property* property = rewrite->AsProperty();
514 ASSERT_NOT_NULL(property); 576 ASSERT_NOT_NULL(property);
515 ASSERT_EQ(expr->context(), property->context()); 577
516 Visit(property); 578 // Currently the only parameter expressions that can occur are
579 // on the form "slot[literal]".
580
581 // Check that the object is in a slot.
582 Variable* object_var = property->obj()->AsVariableProxy()->AsVariable();
583 ASSERT_NOT_NULL(object_var);
584 Slot* object_slot = object_var->slot();
585 ASSERT_NOT_NULL(object_slot);
586
587 // Load the object.
588 Move(r2, object_slot);
589
590 // Check that the key is a smi.
591 Literal* key_literal = property->key()->AsLiteral();
592 ASSERT_NOT_NULL(key_literal);
593 ASSERT(key_literal->handle()->IsSmi());
594
595 // Load the key.
596 __ mov(r1, Operand(key_literal->handle()));
597
598 // Push both as arguments to ic.
599 __ stm(db_w, sp, r2.bit() | r1.bit());
600
601 // Do a KEYED property load.
602 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
603 __ Call(ic, RelocInfo::CODE_TARGET);
604
605 // Drop key and object left on the stack by IC, and push the result.
606 DropAndMove(expr->context(), r0, 2);
517 } 607 }
518 } 608 }
519 609
520 610
521 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 611 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
522 Comment cmnt(masm_, "[ RegExpLiteral"); 612 Comment cmnt(masm_, "[ RegExpLiteral");
523 Label done; 613 Label done;
524 // Registers will be used as follows: 614 // Registers will be used as follows:
525 // r4 = JS function, literals array 615 // r4 = JS function, literals array
526 // r3 = literal index 616 // r3 = literal index
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 // r2, and the global object on the stack. 868 // r2, and the global object on the stack.
779 __ pop(r0); 869 __ pop(r0);
780 __ mov(r2, Operand(var->name())); 870 __ mov(r2, Operand(var->name()));
781 __ ldr(ip, CodeGenerator::GlobalObject()); 871 __ ldr(ip, CodeGenerator::GlobalObject());
782 __ push(ip); 872 __ push(ip);
783 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 873 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
784 __ Call(ic, RelocInfo::CODE_TARGET); 874 __ Call(ic, RelocInfo::CODE_TARGET);
785 // Overwrite the global object on the stack with the result if needed. 875 // Overwrite the global object on the stack with the result if needed.
786 DropAndMove(expr->context(), r0); 876 DropAndMove(expr->context(), r0);
787 877
788 } else { 878 } else if (var->slot()) {
789 Slot* slot = var->slot(); 879 Slot* slot = var->slot();
790 ASSERT_NOT_NULL(slot); // Variables rewritten as properties not handled. 880 ASSERT_NOT_NULL(slot); // Variables rewritten as properties not handled.
791 switch (slot->type()) { 881 switch (slot->type()) {
792 case Slot::LOCAL: 882 case Slot::LOCAL:
793 case Slot::PARAMETER: { 883 case Slot::PARAMETER: {
794 switch (expr->context()) { 884 switch (expr->context()) {
795 case Expression::kUninitialized: 885 case Expression::kUninitialized:
796 UNREACHABLE(); 886 UNREACHABLE();
797 case Expression::kEffect: 887 case Expression::kEffect:
798 // Perform assignment and discard value. 888 // Perform assignment and discard value.
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
877 expr->context() != Expression::kValue) { 967 expr->context() != Expression::kValue) {
878 Move(expr->context(), r3); 968 Move(expr->context(), r3);
879 } 969 }
880 break; 970 break;
881 } 971 }
882 972
883 case Slot::LOOKUP: 973 case Slot::LOOKUP:
884 UNREACHABLE(); 974 UNREACHABLE();
885 break; 975 break;
886 } 976 }
977 } else {
978 Property* property = var->rewrite()->AsProperty();
979 ASSERT_NOT_NULL(property);
980
981 // Load object and key onto the stack.
982 Slot* object_slot = property->obj()->AsSlot();
983 ASSERT_NOT_NULL(object_slot);
984 Move(Expression::kValue, object_slot, r0);
985
986 Literal* key_literal = property->key()->AsLiteral();
987 ASSERT_NOT_NULL(key_literal);
988 Move(Expression::kValue, key_literal);
989
990 // Value to store was pushed before object and key on the stack.
991 __ ldr(r0, MemOperand(sp, 2 * kPointerSize));
992
993 // Arguments to ic is value in r0, object and key on stack.
994 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
995 __ Call(ic, RelocInfo::CODE_TARGET);
996
997 if (expr->context() == Expression::kEffect) {
998 __ add(sp, sp, Operand(3 * kPointerSize));
999 } else if (expr->context() == Expression::kValue) {
1000 // Value is still on the stack in esp[2 * kPointerSize]
1001 __ add(sp, sp, Operand(2 * kPointerSize));
1002 } else {
1003 __ ldr(r0, MemOperand(sp, 2 * kPointerSize));
1004 DropAndMove(expr->context(), r0, 3);
1005 }
887 } 1006 }
888 } 1007 }
889 1008
890 1009
891 void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 1010 void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
892 // Assignment to a property, using a named store IC. 1011 // Assignment to a property, using a named store IC.
893 Property* prop = expr->target()->AsProperty(); 1012 Property* prop = expr->target()->AsProperty();
894 ASSERT(prop != NULL); 1013 ASSERT(prop != NULL);
895 ASSERT(prop->key()->AsLiteral() != NULL); 1014 ASSERT(prop->key()->AsLiteral() != NULL);
896 1015
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after
1565 true_label_ = saved_true; 1684 true_label_ = saved_true;
1566 false_label_ = saved_false; 1685 false_label_ = saved_false;
1567 // Convert current context to test context: End post-test code. 1686 // Convert current context to test context: End post-test code.
1568 } 1687 }
1569 1688
1570 1689
1571 #undef __ 1690 #undef __
1572 1691
1573 1692
1574 } } // namespace v8::internal 1693 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/arm/macro-assembler-arm.h » ('j') | src/ia32/fast-codegen-ia32.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698