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

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. 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
« no previous file with comments | « src/hydrogen-instructions.h ('k') | src/ia32/code-stubs-ia32.cc » ('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 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 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 __ pop(ebx); // Discard copy of return address. 688 __ pop(ebx); // Discard copy of return address.
676 __ dec(eax); // One fewer argument (first argument is new receiver). 689 __ dec(eax); // One fewer argument (first argument is new receiver).
677 } 690 }
678 691
679 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin. 692 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin.
680 { Label function; 693 { Label function;
681 __ test(edi, Operand(edi)); 694 __ test(edi, Operand(edi));
682 __ j(not_zero, &function); 695 __ j(not_zero, &function);
683 __ Set(ebx, Immediate(0)); 696 __ Set(ebx, Immediate(0));
684 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); 697 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
698 __ SetCallKind(ecx, CALL_AS_METHOD);
685 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 699 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
686 RelocInfo::CODE_TARGET); 700 RelocInfo::CODE_TARGET);
687 __ bind(&function); 701 __ bind(&function);
688 } 702 }
689 703
690 // 5b. Get the code to call from the function and check that the number of 704 // 5b. Get the code to call from the function and check that the number of
691 // expected arguments matches what we're providing. If so, jump 705 // expected arguments matches what we're providing. If so, jump
692 // (tail-call) to the code in register edx without checking arguments. 706 // (tail-call) to the code in register edx without checking arguments.
693 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 707 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
694 __ mov(ebx, 708 __ mov(ebx,
695 FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); 709 FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset));
696 __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset)); 710 __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset));
697 __ SmiUntag(ebx); 711 __ SmiUntag(ebx);
712 __ SetCallKind(ecx, CALL_AS_METHOD);
698 __ cmp(eax, Operand(ebx)); 713 __ cmp(eax, Operand(ebx));
699 __ j(not_equal, 714 __ j(not_equal,
700 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline()); 715 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline());
701 716
702 ParameterCount expected(0); 717 ParameterCount expected(0);
703 __ InvokeCode(Operand(edx), expected, expected, JUMP_FUNCTION); 718 __ InvokeCode(Operand(edx), expected, expected, JUMP_FUNCTION);
704 } 719 }
705 720
706 721
707 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { 722 void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after
1417 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { 1432 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
1418 __ push(ebp); 1433 __ push(ebp);
1419 __ mov(ebp, Operand(esp)); 1434 __ mov(ebp, Operand(esp));
1420 1435
1421 // Store the arguments adaptor context sentinel. 1436 // Store the arguments adaptor context sentinel.
1422 __ push(Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 1437 __ push(Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
1423 1438
1424 // Push the function on the stack. 1439 // Push the function on the stack.
1425 __ push(edi); 1440 __ push(edi);
1426 1441
1427 // Preserve the number of arguments on the stack. Must preserve both 1442 // Preserve the number of arguments on the stack. Must preserve eax,
1428 // eax and ebx because these registers are used when copying the 1443 // ebx and ecx because these registers are used when copying the
1429 // arguments and the receiver. 1444 // arguments and the receiver.
1430 ASSERT(kSmiTagSize == 1); 1445 ASSERT(kSmiTagSize == 1);
1431 __ lea(ecx, Operand(eax, eax, times_1, kSmiTag)); 1446 __ lea(edi, Operand(eax, eax, times_1, kSmiTag));
1432 __ push(ecx); 1447 __ push(edi);
1433 } 1448 }
1434 1449
1435 1450
1436 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { 1451 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
1437 // Retrieve the number of arguments from the stack. 1452 // Retrieve the number of arguments from the stack.
1438 __ mov(ebx, Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset)); 1453 __ mov(ebx, Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset));
1439 1454
1440 // Leave the frame. 1455 // Leave the frame.
1441 __ leave(); 1456 __ leave();
1442 1457
1443 // Remove caller arguments from the stack. 1458 // Remove caller arguments from the stack.
1444 ASSERT(kSmiTagSize == 1 && kSmiTag == 0); 1459 ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
1445 __ pop(ecx); 1460 __ pop(ecx);
1446 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver 1461 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver
1447 __ push(ecx); 1462 __ push(ecx);
1448 } 1463 }
1449 1464
1450 1465
1451 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { 1466 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
1452 // ----------- S t a t e ------------- 1467 // ----------- S t a t e -------------
1453 // -- eax : actual number of arguments 1468 // -- eax : actual number of arguments
1454 // -- ebx : expected number of arguments 1469 // -- ebx : expected number of arguments
1470 // -- ecx : call kind information
1455 // -- edx : code entry to call 1471 // -- edx : code entry to call
1456 // ----------------------------------- 1472 // -----------------------------------
1457 1473
1458 Label invoke, dont_adapt_arguments; 1474 Label invoke, dont_adapt_arguments;
1459 __ IncrementCounter(masm->isolate()->counters()->arguments_adaptors(), 1); 1475 __ IncrementCounter(masm->isolate()->counters()->arguments_adaptors(), 1);
1460 1476
1461 Label enough, too_few; 1477 Label enough, too_few;
1462 __ cmp(eax, Operand(ebx)); 1478 __ cmp(eax, Operand(ebx));
1463 __ j(less, &too_few); 1479 __ j(less, &too_few);
1464 __ cmp(ebx, SharedFunctionInfo::kDontAdaptArgumentsSentinel); 1480 __ cmp(ebx, SharedFunctionInfo::kDontAdaptArgumentsSentinel);
1465 __ j(equal, &dont_adapt_arguments); 1481 __ j(equal, &dont_adapt_arguments);
1466 1482
1467 { // Enough parameters: Actual >= expected. 1483 { // Enough parameters: Actual >= expected.
1468 __ bind(&enough); 1484 __ bind(&enough);
1469 EnterArgumentsAdaptorFrame(masm); 1485 EnterArgumentsAdaptorFrame(masm);
1470 1486
1471 // Copy receiver and all expected arguments. 1487 // Copy receiver and all expected arguments.
1472 const int offset = StandardFrameConstants::kCallerSPOffset; 1488 const int offset = StandardFrameConstants::kCallerSPOffset;
1473 __ lea(eax, Operand(ebp, eax, times_4, offset)); 1489 __ lea(eax, Operand(ebp, eax, times_4, offset));
1474 __ mov(ecx, -1); // account for receiver 1490 __ mov(edi, -1); // account for receiver
1475 1491
1476 Label copy; 1492 Label copy;
1477 __ bind(&copy); 1493 __ bind(&copy);
1478 __ inc(ecx); 1494 __ inc(edi);
1479 __ push(Operand(eax, 0)); 1495 __ push(Operand(eax, 0));
1480 __ sub(Operand(eax), Immediate(kPointerSize)); 1496 __ sub(Operand(eax), Immediate(kPointerSize));
1481 __ cmp(ecx, Operand(ebx)); 1497 __ cmp(edi, Operand(ebx));
1482 __ j(less, &copy); 1498 __ j(less, &copy);
1483 __ jmp(&invoke); 1499 __ jmp(&invoke);
1484 } 1500 }
1485 1501
1486 { // Too few parameters: Actual < expected. 1502 { // Too few parameters: Actual < expected.
1487 __ bind(&too_few); 1503 __ bind(&too_few);
1488 EnterArgumentsAdaptorFrame(masm); 1504 EnterArgumentsAdaptorFrame(masm);
1489 1505
1490 // Copy receiver and all actual arguments. 1506 // Copy receiver and all actual arguments.
1491 const int offset = StandardFrameConstants::kCallerSPOffset; 1507 const int offset = StandardFrameConstants::kCallerSPOffset;
1492 __ lea(edi, Operand(ebp, eax, times_4, offset)); 1508 __ lea(edi, Operand(ebp, eax, times_4, offset));
1493 __ mov(ecx, -1); // account for receiver 1509 // ebx = expected - actual.
1510 __ sub(ebx, Operand(eax));
1511 // eax = -actual - 1
1512 __ neg(eax);
1513 __ sub(Operand(eax), Immediate(1));
1494 1514
1495 Label copy; 1515 Label copy;
1496 __ bind(&copy); 1516 __ bind(&copy);
1497 __ inc(ecx); 1517 __ inc(eax);
1498 __ push(Operand(edi, 0)); 1518 __ push(Operand(edi, 0));
1499 __ sub(Operand(edi), Immediate(kPointerSize)); 1519 __ sub(Operand(edi), Immediate(kPointerSize));
1500 __ cmp(ecx, Operand(eax)); 1520 __ test(eax, Operand(eax));
1501 __ j(less, &copy); 1521 __ j(not_zero, &copy);
1502 1522
1503 // Fill remaining expected arguments with undefined values. 1523 // Fill remaining expected arguments with undefined values.
1504 Label fill; 1524 Label fill;
1505 __ bind(&fill); 1525 __ bind(&fill);
1506 __ inc(ecx); 1526 __ inc(eax);
1507 __ push(Immediate(masm->isolate()->factory()->undefined_value())); 1527 __ push(Immediate(masm->isolate()->factory()->undefined_value()));
1508 __ cmp(ecx, Operand(ebx)); 1528 __ cmp(eax, Operand(ebx));
1509 __ j(less, &fill); 1529 __ j(less, &fill);
1510
1511 // Restore function pointer.
1512 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
1513 } 1530 }
1514 1531
1515 // Call the entry point. 1532 // Call the entry point.
1516 __ bind(&invoke); 1533 __ bind(&invoke);
1534 // Restore function pointer.
1535 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
1517 __ call(Operand(edx)); 1536 __ call(Operand(edx));
1518 1537
1519 // Leave frame and return. 1538 // Leave frame and return.
1520 LeaveArgumentsAdaptorFrame(masm); 1539 LeaveArgumentsAdaptorFrame(masm);
1521 __ ret(0); 1540 __ ret(0);
1522 1541
1523 // ------------------------------------------- 1542 // -------------------------------------------
1524 // Dont adapt arguments. 1543 // Dont adapt arguments.
1525 // ------------------------------------------- 1544 // -------------------------------------------
1526 __ bind(&dont_adapt_arguments); 1545 __ bind(&dont_adapt_arguments);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1593 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); 1612 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR);
1594 generator.Generate(); 1613 generator.Generate();
1595 } 1614 }
1596 1615
1597 1616
1598 #undef __ 1617 #undef __
1599 } 1618 }
1600 } // namespace v8::internal 1619 } // namespace v8::internal
1601 1620
1602 #endif // V8_TARGET_ARCH_IA32 1621 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/hydrogen-instructions.h ('k') | src/ia32/code-stubs-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698