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

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

Issue 1021863002: MIPS: [es6] implement Reflect.apply() & Reflect.construct() (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix comment. Created 5 years, 9 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
« no previous file with comments | « no previous file | src/mips64/builtins-mips64.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 5
6 6
7 #include "src/v8.h" 7 #include "src/v8.h"
8 8
9 #if V8_TARGET_ARCH_MIPS 9 #if V8_TARGET_ARCH_MIPS
10 10
(...skipping 1333 matching lines...) Expand 10 before | Expand all | Expand 10 after
1344 // Check formal and actual parameter counts. 1344 // Check formal and actual parameter counts.
1345 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 1345 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1346 RelocInfo::CODE_TARGET, ne, a2, Operand(a0)); 1346 RelocInfo::CODE_TARGET, ne, a2, Operand(a0));
1347 1347
1348 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); 1348 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
1349 ParameterCount expected(0); 1349 ParameterCount expected(0);
1350 __ InvokeCode(a3, expected, expected, JUMP_FUNCTION, NullCallWrapper()); 1350 __ InvokeCode(a3, expected, expected, JUMP_FUNCTION, NullCallWrapper());
1351 } 1351 }
1352 1352
1353 1353
1354 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { 1354 static void Generate_CheckStackOverflow(MacroAssembler* masm,
1355 const int kIndexOffset = 1355 const int calleeOffset) {
1356 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); 1356 // Check the stack for overflow. We are not trying to catch
1357 const int kLimitOffset = 1357 // interruptions (e.g. debug break and preemption) here, so the "real stack
1358 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); 1358 // limit" is checked.
1359 const int kArgsOffset = 2 * kPointerSize; 1359 Label okay;
1360 const int kRecvOffset = 3 * kPointerSize; 1360 __ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
1361 const int kFunctionOffset = 4 * kPointerSize; 1361 // Make a2 the space we have left. The stack might already be overflowed
1362 // here which will cause a2 to become negative.
1363 __ Subu(a2, sp, a2);
1364 // Check if the arguments will overflow the stack.
1365 __ sll(t3, v0, kPointerSizeLog2 - kSmiTagSize);
1366 // Signed comparison.
1367 __ Branch(&okay, gt, a2, Operand(t3));
1368
1369 // Out of stack space.
1370 __ lw(a1, MemOperand(fp, calleeOffset));
1371 __ Push(a1, v0);
1372 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
1373
1374 __ bind(&okay);
1375 }
1376
1377
1378 static void Generate_PushAppliedArguments(MacroAssembler* masm,
1379 const int argumentsOffset,
1380 const int indexOffset,
1381 const int limitOffset) {
1382 Label entry, loop;
1383 __ lw(a0, MemOperand(fp, indexOffset));
1384 __ Branch(&entry);
1385
1386 // Load the current argument from the arguments array and push it to the
1387 // stack.
1388 // a0: current argument index
1389 __ bind(&loop);
1390 __ lw(a1, MemOperand(fp, argumentsOffset));
1391 __ Push(a1, a0);
1392
1393 // Call the runtime to access the property in the arguments array.
1394 __ CallRuntime(Runtime::kGetProperty, 2);
1395 __ push(v0);
1396
1397 // Use inline caching to access the arguments.
1398 __ lw(a0, MemOperand(fp, indexOffset));
1399 __ Addu(a0, a0, Operand(1 << kSmiTagSize));
1400 __ sw(a0, MemOperand(fp, indexOffset));
1401
1402 // Test if the copy loop has finished copying all the elements from the
1403 // arguments object.
1404 __ bind(&entry);
1405 __ lw(a1, MemOperand(fp, limitOffset));
1406 __ Branch(&loop, ne, a0, Operand(a1));
1407
1408 // On exit, the pushed arguments count is in a0, untagged
1409 __ SmiUntag(a0);
1410 }
1411
1412
1413 // Used by FunctionApply and ReflectApply
1414 static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
1415 const int kFormalParameters = targetIsArgument ? 3 : 2;
1416 const int kStackSize = kFormalParameters + 1;
1362 1417
1363 { 1418 {
1364 FrameScope frame_scope(masm, StackFrame::INTERNAL); 1419 FrameScope frame_scope(masm, StackFrame::INTERNAL);
1420 const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize;
1421 const int kReceiverOffset = kArgumentsOffset + kPointerSize;
1422 const int kFunctionOffset = kReceiverOffset + kPointerSize;
1423
1365 __ lw(a0, MemOperand(fp, kFunctionOffset)); // Get the function. 1424 __ lw(a0, MemOperand(fp, kFunctionOffset)); // Get the function.
1366 __ push(a0); 1425 __ push(a0);
1367 __ lw(a0, MemOperand(fp, kArgsOffset)); // Get the args array. 1426 __ lw(a0, MemOperand(fp, kArgumentsOffset)); // Get the args array.
1368 __ push(a0); 1427 __ push(a0);
1369 // Returns (in v0) number of arguments to copy to stack as Smi. 1428 // Returns (in v0) number of arguments to copy to stack as Smi.
1370 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); 1429 if (targetIsArgument) {
1430 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION);
1431 } else {
1432 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
1433 }
1371 1434
1372 // Check the stack for overflow. We are not trying to catch 1435 Generate_CheckStackOverflow(masm, kFunctionOffset);
1373 // interruptions (e.g. debug break and preemption) here, so the "real stack
1374 // limit" is checked.
1375 Label okay;
1376 __ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
1377 // Make a2 the space we have left. The stack might already be overflowed
1378 // here which will cause a2 to become negative.
1379 __ subu(a2, sp, a2);
1380 // Check if the arguments will overflow the stack.
1381 __ sll(t3, v0, kPointerSizeLog2 - kSmiTagSize);
1382 __ Branch(&okay, gt, a2, Operand(t3)); // Signed comparison.
1383
1384 // Out of stack space.
1385 __ lw(a1, MemOperand(fp, kFunctionOffset));
1386 __ Push(a1, v0);
1387 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
1388 // End of stack check.
1389 1436
1390 // Push current limit and index. 1437 // Push current limit and index.
1391 __ bind(&okay); 1438 const int kIndexOffset =
1439 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize);
1440 const int kLimitOffset =
1441 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
1392 __ mov(a1, zero_reg); 1442 __ mov(a1, zero_reg);
1393 __ Push(v0, a1); // Limit and initial index. 1443 __ Push(v0, a1); // Limit and initial index.
1394 1444
1395 // Get the receiver. 1445 // Get the receiver.
1396 __ lw(a0, MemOperand(fp, kRecvOffset)); 1446 __ lw(a0, MemOperand(fp, kReceiverOffset));
1397 1447
1398 // Check that the function is a JS function (otherwise it must be a proxy). 1448 // Check that the function is a JS function (otherwise it must be a proxy).
1399 Label push_receiver; 1449 Label push_receiver;
1400 __ lw(a1, MemOperand(fp, kFunctionOffset)); 1450 __ lw(a1, MemOperand(fp, kFunctionOffset));
1401 __ GetObjectType(a1, a2, a2); 1451 __ GetObjectType(a1, a2, a2);
1402 __ Branch(&push_receiver, ne, a2, Operand(JS_FUNCTION_TYPE)); 1452 __ Branch(&push_receiver, ne, a2, Operand(JS_FUNCTION_TYPE));
1403 1453
1404 // Change context eagerly to get the right global object if necessary. 1454 // Change context eagerly to get the right global object if necessary.
1405 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); 1455 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
1406 // Load the shared function info while the function is still in a1. 1456 // Load the shared function info while the function is still in a1.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1442 __ bind(&use_global_proxy); 1492 __ bind(&use_global_proxy);
1443 __ lw(a0, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); 1493 __ lw(a0, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
1444 __ lw(a0, FieldMemOperand(a0, GlobalObject::kGlobalProxyOffset)); 1494 __ lw(a0, FieldMemOperand(a0, GlobalObject::kGlobalProxyOffset));
1445 1495
1446 // Push the receiver. 1496 // Push the receiver.
1447 // a0: receiver 1497 // a0: receiver
1448 __ bind(&push_receiver); 1498 __ bind(&push_receiver);
1449 __ push(a0); 1499 __ push(a0);
1450 1500
1451 // Copy all arguments from the array to the stack. 1501 // Copy all arguments from the array to the stack.
1452 Label entry, loop; 1502 Generate_PushAppliedArguments(
1453 __ lw(a0, MemOperand(fp, kIndexOffset)); 1503 masm, kArgumentsOffset, kIndexOffset, kLimitOffset);
1454 __ Branch(&entry);
1455
1456 // Load the current argument from the arguments array and push it to the
1457 // stack.
1458 // a0: current argument index
1459 __ bind(&loop);
1460 __ lw(a1, MemOperand(fp, kArgsOffset));
1461 __ Push(a1, a0);
1462
1463 // Call the runtime to access the property in the arguments array.
1464 __ CallRuntime(Runtime::kGetProperty, 2);
1465 __ push(v0);
1466
1467 // Use inline caching to access the arguments.
1468 __ lw(a0, MemOperand(fp, kIndexOffset));
1469 __ Addu(a0, a0, Operand(1 << kSmiTagSize));
1470 __ sw(a0, MemOperand(fp, kIndexOffset));
1471
1472 // Test if the copy loop has finished copying all the elements from the
1473 // arguments object.
1474 __ bind(&entry);
1475 __ lw(a1, MemOperand(fp, kLimitOffset));
1476 __ Branch(&loop, ne, a0, Operand(a1));
1477 1504
1478 // Call the function. 1505 // Call the function.
1479 Label call_proxy; 1506 Label call_proxy;
1480 ParameterCount actual(a0); 1507 ParameterCount actual(a0);
1481 __ sra(a0, a0, kSmiTagSize);
1482 __ lw(a1, MemOperand(fp, kFunctionOffset)); 1508 __ lw(a1, MemOperand(fp, kFunctionOffset));
1483 __ GetObjectType(a1, a2, a2); 1509 __ GetObjectType(a1, a2, a2);
1484 __ Branch(&call_proxy, ne, a2, Operand(JS_FUNCTION_TYPE)); 1510 __ Branch(&call_proxy, ne, a2, Operand(JS_FUNCTION_TYPE));
1485 1511
1486 __ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper()); 1512 __ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper());
1487 1513
1488 frame_scope.GenerateLeaveFrame(); 1514 frame_scope.GenerateLeaveFrame();
1489 __ Ret(USE_DELAY_SLOT); 1515 __ Ret(USE_DELAY_SLOT);
1490 __ Addu(sp, sp, Operand(3 * kPointerSize)); // In delay slot. 1516 __ Addu(sp, sp, Operand(kStackSize * kPointerSize)); // In delay slot.
1491 1517
1492 // Call the function proxy. 1518 // Call the function proxy.
1493 __ bind(&call_proxy); 1519 __ bind(&call_proxy);
1494 __ push(a1); // Add function proxy as last argument. 1520 __ push(a1); // Add function proxy as last argument.
1495 __ Addu(a0, a0, Operand(1)); 1521 __ Addu(a0, a0, Operand(1));
1496 __ li(a2, Operand(0, RelocInfo::NONE32)); 1522 __ li(a2, Operand(0, RelocInfo::NONE32));
1497 __ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY); 1523 __ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY);
1498 __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 1524 __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1499 RelocInfo::CODE_TARGET); 1525 RelocInfo::CODE_TARGET);
1500 // Tear down the internal frame and remove function, receiver and args. 1526 // Tear down the internal frame and remove function, receiver and args.
1501 } 1527 }
1502 1528
1503 __ Ret(USE_DELAY_SLOT); 1529 __ Ret(USE_DELAY_SLOT);
1504 __ Addu(sp, sp, Operand(3 * kPointerSize)); // In delay slot. 1530 __ Addu(sp, sp, Operand(kStackSize * kPointerSize)); // In delay slot.
1505 } 1531 }
1506 1532
1507 1533
1534 static void Generate_ConstructHelper(MacroAssembler* masm) {
1535 const int kFormalParameters = 3;
1536 const int kStackSize = kFormalParameters + 1;
1537
1538 {
1539 FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL);
1540 const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize;
1541 const int kArgumentsOffset = kNewTargetOffset + kPointerSize;
1542 const int kFunctionOffset = kArgumentsOffset + kPointerSize;
1543
1544 // If newTarget is not supplied, set it to constructor
1545 Label validate_arguments;
1546 __ lw(a0, MemOperand(fp, kNewTargetOffset));
1547 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
1548 __ Branch(&validate_arguments, ne, a0, Operand(at));
1549 __ lw(a0, MemOperand(fp, kFunctionOffset));
1550 __ sw(a0, MemOperand(fp, kNewTargetOffset));
1551
1552 // Validate arguments
1553 __ bind(&validate_arguments);
1554 __ lw(a0, MemOperand(fp, kFunctionOffset)); // get the function
1555 __ push(a0);
1556 __ lw(a0, MemOperand(fp, kArgumentsOffset)); // get the args array
1557 __ push(a0);
1558 __ lw(a0, MemOperand(fp, kNewTargetOffset)); // get the new.target
1559 __ push(a0);
1560 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION);
1561
1562 Generate_CheckStackOverflow(masm, kFunctionOffset);
1563
1564 // Push current limit and index.
1565 const int kIndexOffset =
1566 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize);
1567 const int kLimitOffset =
1568 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
1569 __ push(v0); // limit
1570 __ mov(a1, zero_reg); // initial index
1571 __ push(a1);
1572 // Push newTarget and callee functions
1573 __ lw(a0, MemOperand(fp, kNewTargetOffset));
1574 __ push(a0);
1575 __ lw(a0, MemOperand(fp, kFunctionOffset));
1576 __ push(a0);
1577
1578 // Copy all arguments from the array to the stack.
1579 Generate_PushAppliedArguments(
1580 masm, kArgumentsOffset, kIndexOffset, kLimitOffset);
1581
1582 // Use undefined feedback vector
1583 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
1584 __ lw(a1, MemOperand(fp, kFunctionOffset));
1585
1586 // Call the function.
1587 CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL);
1588 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
1589
1590 __ Drop(1);
1591
1592 // Leave internal frame.
1593 }
1594 __ Addu(sp, sp, Operand(kStackSize * kPointerSize));
1595 __ Jump(ra);
1596 }
1597
1598
1599 void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
1600 Generate_ApplyHelper(masm, false);
1601 }
1602
1603
1604 void Builtins::Generate_ReflectApply(MacroAssembler* masm) {
1605 Generate_ApplyHelper(masm, true);
1606 }
1607
1608
1609 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
1610 Generate_ConstructHelper(masm);
1611 }
1612
1613
1508 static void ArgumentAdaptorStackCheck(MacroAssembler* masm, 1614 static void ArgumentAdaptorStackCheck(MacroAssembler* masm,
1509 Label* stack_overflow) { 1615 Label* stack_overflow) {
1510 // ----------- S t a t e ------------- 1616 // ----------- S t a t e -------------
1511 // -- a0 : actual number of arguments 1617 // -- a0 : actual number of arguments
1512 // -- a1 : function (passed through to callee) 1618 // -- a1 : function (passed through to callee)
1513 // -- a2 : expected number of arguments 1619 // -- a2 : expected number of arguments
1514 // ----------------------------------- 1620 // -----------------------------------
1515 // Check the stack for overflow. We are not trying to catch 1621 // Check the stack for overflow. We are not trying to catch
1516 // interruptions (e.g. debug break and preemption) here, so the "real stack 1622 // interruptions (e.g. debug break and preemption) here, so the "real stack
1517 // limit" is checked. 1623 // limit" is checked.
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
1679 __ break_(0xCC); 1785 __ break_(0xCC);
1680 } 1786 }
1681 } 1787 }
1682 1788
1683 1789
1684 #undef __ 1790 #undef __
1685 1791
1686 } } // namespace v8::internal 1792 } } // namespace v8::internal
1687 1793
1688 #endif // V8_TARGET_ARCH_MIPS 1794 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « no previous file | src/mips64/builtins-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698