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

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

Issue 7039036: Fix calls of strict mode function with an implicit receiver. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Address comments. Get rid of value check. Created 9 years, 7 months 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
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 __ jmp(Operand(ebx)); 95 __ jmp(Operand(ebx));
96 96
97 // edi: called object 97 // edi: called object
98 // eax: number of arguments 98 // eax: number of arguments
99 __ bind(&non_function_call); 99 __ bind(&non_function_call);
100 // Set expected number of arguments to zero (not changing eax). 100 // Set expected number of arguments to zero (not changing eax).
101 __ Set(ebx, Immediate(0)); 101 __ Set(ebx, Immediate(0));
102 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); 102 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
103 Handle<Code> arguments_adaptor = 103 Handle<Code> arguments_adaptor =
104 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); 104 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
105 __ SetCallKind(ecx, CALL_AS_METHOD);
105 __ jmp(arguments_adaptor, RelocInfo::CODE_TARGET); 106 __ jmp(arguments_adaptor, RelocInfo::CODE_TARGET);
106 } 107 }
107 108
108 109
109 static void Generate_JSConstructStubHelper(MacroAssembler* masm, 110 static void Generate_JSConstructStubHelper(MacroAssembler* masm,
110 bool is_api_function, 111 bool is_api_function,
111 bool count_constructions) { 112 bool count_constructions) {
112 // Should never count constructions for api objects. 113 // Should never count constructions for api objects.
113 ASSERT(!is_api_function || !count_constructions); 114 ASSERT(!is_api_function || !count_constructions);
114 115
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 461
461 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { 462 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
462 Generate_JSEntryTrampolineHelper(masm, true); 463 Generate_JSEntryTrampolineHelper(masm, true);
463 } 464 }
464 465
465 466
466 void Builtins::Generate_LazyCompile(MacroAssembler* masm) { 467 void Builtins::Generate_LazyCompile(MacroAssembler* masm) {
467 // Enter an internal frame. 468 // Enter an internal frame.
468 __ EnterInternalFrame(); 469 __ EnterInternalFrame();
469 470
470 // Push a copy of the function onto the stack. 471 // Push a copy of the function.
471 __ push(edi); 472 __ push(edi);
473 // Push call kind information.
474 __ push(ecx);
472 475
473 __ push(edi); // Function is also the parameter to the runtime call. 476 __ push(edi); // Function is also the parameter to the runtime call.
474 __ CallRuntime(Runtime::kLazyCompile, 1); 477 __ CallRuntime(Runtime::kLazyCompile, 1);
478
479 // Restore call kind information.
480 __ pop(ecx);
481 // Restore receiver.
475 __ pop(edi); 482 __ pop(edi);
476 483
477 // Tear down temporary frame. 484 // Tear down temporary frame.
478 __ LeaveInternalFrame(); 485 __ LeaveInternalFrame();
479 486
480 // Do a tail-call of the compiled function. 487 // Do a tail-call of the compiled function.
481 __ lea(ecx, FieldOperand(eax, Code::kHeaderSize)); 488 __ lea(eax, FieldOperand(eax, Code::kHeaderSize));
482 __ jmp(Operand(ecx)); 489 __ jmp(Operand(eax));
483 } 490 }
484 491
485 492
486 void Builtins::Generate_LazyRecompile(MacroAssembler* masm) { 493 void Builtins::Generate_LazyRecompile(MacroAssembler* masm) {
487 // Enter an internal frame. 494 // Enter an internal frame.
488 __ EnterInternalFrame(); 495 __ EnterInternalFrame();
489 496
490 // Push a copy of the function onto the stack. 497 // Push a copy of the function onto the stack.
491 __ push(edi); 498 __ push(edi);
499 // Push call kind information.
500 __ push(ecx);
492 501
493 __ push(edi); // Function is also the parameter to the runtime call. 502 __ push(edi); // Function is also the parameter to the runtime call.
494 __ CallRuntime(Runtime::kLazyRecompile, 1); 503 __ CallRuntime(Runtime::kLazyRecompile, 1);
495 504
496 // Restore function and tear down temporary frame. 505 // Restore call kind information.
506 __ pop(ecx);
507 // Restore receiver.
497 __ pop(edi); 508 __ pop(edi);
509
510 // Tear down temporary frame.
498 __ LeaveInternalFrame(); 511 __ LeaveInternalFrame();
499 512
500 // Do a tail-call of the compiled function. 513 // Do a tail-call of the compiled function.
501 __ lea(ecx, FieldOperand(eax, Code::kHeaderSize)); 514 __ lea(eax, FieldOperand(eax, Code::kHeaderSize));
502 __ jmp(Operand(ecx)); 515 __ jmp(Operand(eax));
503 } 516 }
504 517
505 518
506 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, 519 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm,
507 Deoptimizer::BailoutType type) { 520 Deoptimizer::BailoutType type) {
508 // Enter an internal frame. 521 // Enter an internal frame.
509 __ EnterInternalFrame(); 522 __ EnterInternalFrame();
510 523
511 // Pass the function and deoptimization type to the runtime system. 524 // Pass the function and deoptimization type to the runtime system.
512 __ push(Immediate(Smi::FromInt(static_cast<int>(type)))); 525 __ push(Immediate(Smi::FromInt(static_cast<int>(type))));
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 __ pop(ebx); // Discard copy of return address. 689 __ pop(ebx); // Discard copy of return address.
677 __ dec(eax); // One fewer argument (first argument is new receiver). 690 __ dec(eax); // One fewer argument (first argument is new receiver).
678 } 691 }
679 692
680 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin. 693 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin.
681 { Label function; 694 { Label function;
682 __ test(edi, Operand(edi)); 695 __ test(edi, Operand(edi));
683 __ j(not_zero, &function); 696 __ j(not_zero, &function);
684 __ Set(ebx, Immediate(0)); 697 __ Set(ebx, Immediate(0));
685 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); 698 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
699 __ SetCallKind(ecx, CALL_AS_METHOD);
686 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 700 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
687 RelocInfo::CODE_TARGET); 701 RelocInfo::CODE_TARGET);
688 __ bind(&function); 702 __ bind(&function);
689 } 703 }
690 704
691 // 5b. Get the code to call from the function and check that the number of 705 // 5b. Get the code to call from the function and check that the number of
692 // expected arguments matches what we're providing. If so, jump 706 // expected arguments matches what we're providing. If so, jump
693 // (tail-call) to the code in register edx without checking arguments. 707 // (tail-call) to the code in register edx without checking arguments.
694 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 708 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
695 __ mov(ebx, 709 __ mov(ebx,
696 FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); 710 FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset));
697 __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset)); 711 __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset));
698 __ SmiUntag(ebx); 712 __ SmiUntag(ebx);
713 __ SetCallKind(ecx, CALL_AS_METHOD);
699 __ cmp(eax, Operand(ebx)); 714 __ cmp(eax, Operand(ebx));
700 __ j(not_equal, 715 __ j(not_equal,
701 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline()); 716 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline());
702 717
703 ParameterCount expected(0); 718 ParameterCount expected(0);
704 __ InvokeCode(Operand(edx), expected, expected, JUMP_FUNCTION); 719 __ InvokeCode(Operand(edx), expected, expected, JUMP_FUNCTION);
705 } 720 }
706 721
707 722
708 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { 723 void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
(...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after
1422 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { 1437 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
1423 __ push(ebp); 1438 __ push(ebp);
1424 __ mov(ebp, Operand(esp)); 1439 __ mov(ebp, Operand(esp));
1425 1440
1426 // Store the arguments adaptor context sentinel. 1441 // Store the arguments adaptor context sentinel.
1427 __ push(Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 1442 __ push(Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
1428 1443
1429 // Push the function on the stack. 1444 // Push the function on the stack.
1430 __ push(edi); 1445 __ push(edi);
1431 1446
1432 // Preserve the number of arguments on the stack. Must preserve both 1447 // Preserve the number of arguments on the stack. Must preserve eax,
1433 // eax and ebx because these registers are used when copying the 1448 // ebx and ecx because these registers are used when copying the
1434 // arguments and the receiver. 1449 // arguments and the receiver.
1435 ASSERT(kSmiTagSize == 1); 1450 ASSERT(kSmiTagSize == 1);
1436 __ lea(ecx, Operand(eax, eax, times_1, kSmiTag)); 1451 __ lea(edi, Operand(eax, eax, times_1, kSmiTag));
1437 __ push(ecx); 1452 __ push(edi);
1438 } 1453 }
1439 1454
1440 1455
1441 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { 1456 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
1442 // Retrieve the number of arguments from the stack. 1457 // Retrieve the number of arguments from the stack.
1443 __ mov(ebx, Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset)); 1458 __ mov(ebx, Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset));
1444 1459
1445 // Leave the frame. 1460 // Leave the frame.
1446 __ leave(); 1461 __ leave();
1447 1462
1448 // Remove caller arguments from the stack. 1463 // Remove caller arguments from the stack.
1449 ASSERT(kSmiTagSize == 1 && kSmiTag == 0); 1464 ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
1450 __ pop(ecx); 1465 __ pop(ecx);
1451 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver 1466 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver
1452 __ push(ecx); 1467 __ push(ecx);
1453 } 1468 }
1454 1469
1455 1470
1456 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { 1471 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
1457 // ----------- S t a t e ------------- 1472 // ----------- S t a t e -------------
1458 // -- eax : actual number of arguments 1473 // -- eax : actual number of arguments
1459 // -- ebx : expected number of arguments 1474 // -- ebx : expected number of arguments
1475 // -- ecx : call kind information
1460 // -- edx : code entry to call 1476 // -- edx : code entry to call
1461 // ----------------------------------- 1477 // -----------------------------------
1462 1478
1463 Label invoke, dont_adapt_arguments; 1479 Label invoke, dont_adapt_arguments;
1464 __ IncrementCounter(masm->isolate()->counters()->arguments_adaptors(), 1); 1480 __ IncrementCounter(masm->isolate()->counters()->arguments_adaptors(), 1);
1465 1481
1466 Label enough, too_few; 1482 Label enough, too_few;
1467 __ cmp(eax, Operand(ebx)); 1483 __ cmp(eax, Operand(ebx));
1468 __ j(less, &too_few); 1484 __ j(less, &too_few);
1469 __ cmp(ebx, SharedFunctionInfo::kDontAdaptArgumentsSentinel); 1485 __ cmp(ebx, SharedFunctionInfo::kDontAdaptArgumentsSentinel);
1470 __ j(equal, &dont_adapt_arguments); 1486 __ j(equal, &dont_adapt_arguments);
1471 1487
1472 { // Enough parameters: Actual >= expected. 1488 { // Enough parameters: Actual >= expected.
1473 __ bind(&enough); 1489 __ bind(&enough);
1474 EnterArgumentsAdaptorFrame(masm); 1490 EnterArgumentsAdaptorFrame(masm);
1475 1491
1476 // Copy receiver and all expected arguments. 1492 // Copy receiver and all expected arguments.
1477 const int offset = StandardFrameConstants::kCallerSPOffset; 1493 const int offset = StandardFrameConstants::kCallerSPOffset;
1478 __ lea(eax, Operand(ebp, eax, times_4, offset)); 1494 __ lea(eax, Operand(ebp, eax, times_4, offset));
1479 __ mov(ecx, -1); // account for receiver 1495 __ mov(edi, -1); // account for receiver
1480 1496
1481 Label copy; 1497 Label copy;
1482 __ bind(&copy); 1498 __ bind(&copy);
1483 __ inc(ecx); 1499 __ inc(edi);
1484 __ push(Operand(eax, 0)); 1500 __ push(Operand(eax, 0));
1485 __ sub(Operand(eax), Immediate(kPointerSize)); 1501 __ sub(Operand(eax), Immediate(kPointerSize));
1486 __ cmp(ecx, Operand(ebx)); 1502 __ cmp(edi, Operand(ebx));
1487 __ j(less, &copy); 1503 __ j(less, &copy);
1488 __ jmp(&invoke); 1504 __ jmp(&invoke);
1489 } 1505 }
1490 1506
1491 { // Too few parameters: Actual < expected. 1507 { // Too few parameters: Actual < expected.
1492 __ bind(&too_few); 1508 __ bind(&too_few);
1493 EnterArgumentsAdaptorFrame(masm); 1509 EnterArgumentsAdaptorFrame(masm);
1494 1510
1495 // Copy receiver and all actual arguments. 1511 // Copy receiver and all actual arguments.
1496 const int offset = StandardFrameConstants::kCallerSPOffset; 1512 const int offset = StandardFrameConstants::kCallerSPOffset;
1497 __ lea(edi, Operand(ebp, eax, times_4, offset)); 1513 __ lea(edi, Operand(ebp, eax, times_4, offset));
1498 __ mov(ecx, -1); // account for receiver 1514 // ebx = expected - actual.
1515 __ sub(ebx, Operand(eax));
1516 // eax = -actual - 1
1517 __ neg(eax);
1518 __ sub(Operand(eax), Immediate(1));
1499 1519
1500 Label copy; 1520 Label copy;
1501 __ bind(&copy); 1521 __ bind(&copy);
1502 __ inc(ecx); 1522 __ inc(eax);
1503 __ push(Operand(edi, 0)); 1523 __ push(Operand(edi, 0));
1504 __ sub(Operand(edi), Immediate(kPointerSize)); 1524 __ sub(Operand(edi), Immediate(kPointerSize));
1505 __ cmp(ecx, Operand(eax)); 1525 __ test(eax, Operand(eax));
1506 __ j(less, &copy); 1526 __ j(not_zero, &copy);
1507 1527
1508 // Fill remaining expected arguments with undefined values. 1528 // Fill remaining expected arguments with undefined values.
1509 Label fill; 1529 Label fill;
1510 __ bind(&fill); 1530 __ bind(&fill);
1511 __ inc(ecx); 1531 __ inc(eax);
1512 __ push(Immediate(masm->isolate()->factory()->undefined_value())); 1532 __ push(Immediate(masm->isolate()->factory()->undefined_value()));
1513 __ cmp(ecx, Operand(ebx)); 1533 __ cmp(eax, Operand(ebx));
1514 __ j(less, &fill); 1534 __ j(less, &fill);
1515
1516 // Restore function pointer.
1517 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
1518 } 1535 }
1519 1536
1520 // Call the entry point. 1537 // Call the entry point.
1521 __ bind(&invoke); 1538 __ bind(&invoke);
1539 // Restore function pointer.
1540 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
1522 __ call(Operand(edx)); 1541 __ call(Operand(edx));
1523 1542
1524 // Leave frame and return. 1543 // Leave frame and return.
1525 LeaveArgumentsAdaptorFrame(masm); 1544 LeaveArgumentsAdaptorFrame(masm);
1526 __ ret(0); 1545 __ ret(0);
1527 1546
1528 // ------------------------------------------- 1547 // -------------------------------------------
1529 // Dont adapt arguments. 1548 // Dont adapt arguments.
1530 // ------------------------------------------- 1549 // -------------------------------------------
1531 __ bind(&dont_adapt_arguments); 1550 __ bind(&dont_adapt_arguments);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1598 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); 1617 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR);
1599 generator.Generate(); 1618 generator.Generate();
1600 } 1619 }
1601 1620
1602 1621
1603 #undef __ 1622 #undef __
1604 } 1623 }
1605 } // namespace v8::internal 1624 } // namespace v8::internal
1606 1625
1607 #endif // V8_TARGET_ARCH_IA32 1626 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698