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

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

Issue 1523753002: [es6] Correct Function.prototype.apply, Reflect.construct and Reflect.apply. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Mark mjsunit/apply as TIMEOUT (for tsan). Created 5 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 | « src/mips/builtins-mips.cc ('k') | src/objects.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 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 #if V8_TARGET_ARCH_MIPS64 5 #if V8_TARGET_ARCH_MIPS64
6 6
7 #include "src/codegen.h" 7 #include "src/codegen.h"
8 #include "src/debug/debug.h" 8 #include "src/debug/debug.h"
9 #include "src/deoptimizer.h" 9 #include "src/deoptimizer.h"
10 #include "src/full-codegen/full-codegen.h" 10 #include "src/full-codegen/full-codegen.h"
(...skipping 1311 matching lines...) Expand 10 before | Expand all | Expand 10 after
1322 // (which is a copy of the last argument). 1322 // (which is a copy of the last argument).
1323 __ Dsubu(a0, a0, Operand(1)); 1323 __ Dsubu(a0, a0, Operand(1));
1324 __ Pop(); 1324 __ Pop();
1325 } 1325 }
1326 1326
1327 // 4. Call the callable. 1327 // 4. Call the callable.
1328 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 1328 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1329 } 1329 }
1330 1330
1331 1331
1332 static void Generate_PushAppliedArguments(MacroAssembler* masm, 1332 void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
1333 const int vectorOffset, 1333 // ----------- S t a t e -------------
1334 const int argumentsOffset, 1334 // -- a0 : argc
1335 const int indexOffset, 1335 // -- sp[0] : argArray
1336 const int limitOffset) { 1336 // -- sp[4] : thisArg
1337 Label entry, loop; 1337 // -- sp[8] : receiver
1338 Register receiver = LoadDescriptor::ReceiverRegister(); 1338 // -----------------------------------
1339 Register key = LoadDescriptor::NameRegister(); 1339
1340 Register slot = LoadDescriptor::SlotRegister(); 1340 // 1. Load receiver into a1, argArray into a0 (if present), remove all
1341 Register vector = LoadWithVectorDescriptor::VectorRegister(); 1341 // arguments from the stack (including the receiver), and push thisArg (if
1342 1342 // present) instead.
1343 __ ld(key, MemOperand(fp, indexOffset)); 1343 {
1344 __ Branch(&entry); 1344 Label no_arg;
1345 1345 Register scratch = a4;
1346 // Load the current argument from the arguments array.
1347 __ bind(&loop);
1348 __ ld(receiver, MemOperand(fp, argumentsOffset));
1349
1350 // Use inline caching to speed up access to arguments.
1351 int slot_index = TypeFeedbackVector::PushAppliedArgumentsIndex();
1352 __ li(slot, Operand(Smi::FromInt(slot_index)));
1353 __ ld(vector, MemOperand(fp, vectorOffset));
1354 Handle<Code> ic =
1355 KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode();
1356 __ Call(ic, RelocInfo::CODE_TARGET);
1357
1358 __ push(v0);
1359
1360 // Use inline caching to access the arguments.
1361 __ ld(key, MemOperand(fp, indexOffset));
1362 __ Daddu(key, key, Operand(Smi::FromInt(1)));
1363 __ sd(key, MemOperand(fp, indexOffset));
1364
1365 // Test if the copy loop has finished copying all the elements from the
1366 // arguments object.
1367 __ bind(&entry);
1368 __ ld(a1, MemOperand(fp, limitOffset));
1369 __ Branch(&loop, ne, key, Operand(a1));
1370
1371 // On exit, the pushed arguments count is in a0, untagged
1372 __ mov(a0, key);
1373 __ SmiUntag(a0);
1374 }
1375
1376
1377 // Used by FunctionApply and ReflectApply
1378 static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
1379 const int kFormalParameters = targetIsArgument ? 3 : 2;
1380 const int kStackSize = kFormalParameters + 1;
1381
1382 {
1383 FrameScope frame_scope(masm, StackFrame::INTERNAL);
1384 const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize;
1385 const int kReceiverOffset = kArgumentsOffset + kPointerSize;
1386 const int kFunctionOffset = kReceiverOffset + kPointerSize;
1387 const int kVectorOffset =
1388 InternalFrameConstants::kCodeOffset - 1 * kPointerSize;
1389
1390 // Push the vector.
1391 __ ld(a1, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
1392 __ ld(a1, FieldMemOperand(a1, SharedFunctionInfo::kFeedbackVectorOffset));
1393 __ Push(a1);
1394
1395 __ ld(a0, MemOperand(fp, kFunctionOffset)); // Get the function.
1396 __ ld(a1, MemOperand(fp, kArgumentsOffset)); // Get the args array.
1397 __ Push(a0, a1);
1398
1399 // Returns (in v0) number of arguments to copy to stack as Smi.
1400 if (targetIsArgument) {
1401 __ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX,
1402 CALL_FUNCTION);
1403 } else {
1404 __ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION);
1405 }
1406
1407 // Returns the result in v0.
1408 Generate_CheckStackOverflow(masm, v0, kArgcIsSmiTagged);
1409
1410 // Push current limit and index.
1411 const int kIndexOffset = kVectorOffset - (2 * kPointerSize);
1412 const int kLimitOffset = kVectorOffset - (1 * kPointerSize);
1413 __ mov(a1, zero_reg);
1414 __ ld(a2, MemOperand(fp, kReceiverOffset));
1415 __ Push(v0, a1, a2); // limit, initial index and receiver.
1416
1417 // Copy all arguments from the array to the stack.
1418 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset,
1419 kIndexOffset, kLimitOffset);
1420
1421 // Call the callable.
1422 // TODO(bmeurer): This should be a tail call according to ES6.
1423 __ ld(a1, MemOperand(fp, kFunctionOffset));
1424 __ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1425
1426 // Tear down the internal frame and remove function, receiver and args.
1427 }
1428
1429 __ Ret(USE_DELAY_SLOT);
1430 __ Daddu(sp, sp, Operand(kStackSize * kPointerSize)); // In delay slot.
1431 }
1432
1433
1434 static void Generate_ConstructHelper(MacroAssembler* masm) {
1435 const int kFormalParameters = 3;
1436 const int kStackSize = kFormalParameters + 1;
1437
1438 {
1439 FrameScope frame_scope(masm, StackFrame::INTERNAL);
1440 const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize;
1441 const int kArgumentsOffset = kNewTargetOffset + kPointerSize;
1442 const int kFunctionOffset = kArgumentsOffset + kPointerSize;
1443 const int kVectorOffset =
1444 InternalFrameConstants::kCodeOffset - 1 * kPointerSize;
1445
1446 // Push the vector.
1447 __ ld(a1, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
1448 __ ld(a1, FieldMemOperand(a1, SharedFunctionInfo::kFeedbackVectorOffset));
1449 __ Push(a1);
1450
1451 // If newTarget is not supplied, set it to constructor
1452 Label validate_arguments;
1453 __ ld(a0, MemOperand(fp, kNewTargetOffset));
1454 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
1455 __ Branch(&validate_arguments, ne, a0, Operand(at));
1456 __ ld(a0, MemOperand(fp, kFunctionOffset));
1457 __ sd(a0, MemOperand(fp, kNewTargetOffset));
1458
1459 // Validate arguments
1460 __ bind(&validate_arguments);
1461 __ ld(a0, MemOperand(fp, kFunctionOffset)); // get the function
1462 __ push(a0);
1463 __ ld(a0, MemOperand(fp, kArgumentsOffset)); // get the args array
1464 __ push(a0);
1465 __ ld(a0, MemOperand(fp, kNewTargetOffset)); // get the new.target
1466 __ push(a0);
1467 // Returns argument count in v0.
1468 __ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX,
1469 CALL_FUNCTION);
1470
1471 // Returns result in v0.
1472 Generate_CheckStackOverflow(masm, v0, kArgcIsSmiTagged);
1473
1474 // Push current limit and index.
1475 const int kIndexOffset = kVectorOffset - (2 * kPointerSize);
1476 const int kLimitOffset = kVectorOffset - (1 * kPointerSize);
1477 __ push(v0); // limit
1478 __ mov(a1, zero_reg); // initial index
1479 __ push(a1);
1480 // Push the constructor function as callee.
1481 __ ld(a0, MemOperand(fp, kFunctionOffset));
1482 __ push(a0);
1483
1484 // Copy all arguments from the array to the stack.
1485 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset,
1486 kIndexOffset, kLimitOffset);
1487
1488 // Use undefined feedback vector
1489 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); 1346 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
1490 __ ld(a1, MemOperand(fp, kFunctionOffset)); 1347 __ mov(a3, a2);
1491 __ ld(a3, MemOperand(fp, kNewTargetOffset)); 1348 __ dsll(scratch, a0, kPointerSizeLog2);
1492 1349 __ Daddu(a0, sp, Operand(scratch));
1493 // Call the function. 1350 __ ld(a1, MemOperand(a0)); // receiver
1494 __ Call(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 1351 __ Dsubu(a0, a0, Operand(kPointerSize));
1495 1352 __ Branch(&no_arg, lt, a0, Operand(sp));
1496 // Leave internal frame. 1353 __ ld(a2, MemOperand(a0)); // thisArg
1497 } 1354 __ Dsubu(a0, a0, Operand(kPointerSize));
1498 __ jr(ra); 1355 __ Branch(&no_arg, lt, a0, Operand(sp));
1499 __ Daddu(sp, sp, Operand(kStackSize * kPointerSize)); // In delay slot. 1356 __ ld(a3, MemOperand(a0)); // argArray
1500 } 1357 __ bind(&no_arg);
1501 1358 __ Daddu(sp, sp, Operand(scratch));
1502 1359 __ sd(a2, MemOperand(sp));
1503 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { 1360 __ mov(a0, a3);
1504 Generate_ApplyHelper(masm, false); 1361 }
1362
1363 // ----------- S t a t e -------------
1364 // -- a0 : argArray
1365 // -- a1 : receiver
1366 // -- sp[0] : thisArg
1367 // -----------------------------------
1368
1369 // 2. Make sure the receiver is actually callable.
1370 Label receiver_not_callable;
1371 __ JumpIfSmi(a1, &receiver_not_callable);
1372 __ ld(a4, FieldMemOperand(a1, HeapObject::kMapOffset));
1373 __ lbu(a4, FieldMemOperand(a4, Map::kBitFieldOffset));
1374 __ And(a4, a4, Operand(1 << Map::kIsCallable));
1375 __ Branch(&receiver_not_callable, eq, a4, Operand(zero_reg));
1376
1377 // 3. Tail call with no arguments if argArray is null or undefined.
1378 Label no_arguments;
1379 __ JumpIfRoot(a0, Heap::kNullValueRootIndex, &no_arguments);
1380 __ JumpIfRoot(a0, Heap::kUndefinedValueRootIndex, &no_arguments);
1381
1382 // 4a. Apply the receiver to the given argArray (passing undefined for
1383 // new.target).
1384 __ LoadRoot(a3, Heap::kUndefinedValueRootIndex);
1385 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1386
1387 // 4b. The argArray is either null or undefined, so we tail call without any
1388 // arguments to the receiver.
1389 __ bind(&no_arguments);
1390 {
1391 __ mov(a0, zero_reg);
1392 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1393 }
1394
1395 // 4c. The receiver is not callable, throw an appropriate TypeError.
1396 __ bind(&receiver_not_callable);
1397 {
1398 __ sd(a1, MemOperand(sp));
1399 __ TailCallRuntime(Runtime::kThrowApplyNonFunction, 1, 1);
1400 }
1505 } 1401 }
1506 1402
1507 1403
1508 void Builtins::Generate_ReflectApply(MacroAssembler* masm) { 1404 void Builtins::Generate_ReflectApply(MacroAssembler* masm) {
1509 Generate_ApplyHelper(masm, true); 1405 // ----------- S t a t e -------------
1406 // -- a0 : argc
1407 // -- sp[0] : argumentsList
1408 // -- sp[4] : thisArgument
1409 // -- sp[8] : target
1410 // -- sp[12] : receiver
1411 // -----------------------------------
1412
1413 // 1. Load target into a1 (if present), argumentsList into a0 (if present),
1414 // remove all arguments from the stack (including the receiver), and push
1415 // thisArgument (if present) instead.
1416 {
1417 Label no_arg;
1418 Register scratch = a4;
1419 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
1420 __ mov(a2, a1);
1421 __ mov(a3, a1);
1422 __ dsll(scratch, a0, kPointerSizeLog2);
1423 __ mov(a0, scratch);
1424 __ Dsubu(a0, a0, Operand(kPointerSize));
1425 __ Branch(&no_arg, lt, a0, Operand(zero_reg));
1426 __ Daddu(a0, sp, Operand(a0));
1427 __ ld(a1, MemOperand(a0)); // target
1428 __ Dsubu(a0, a0, Operand(kPointerSize));
1429 __ Branch(&no_arg, lt, a0, Operand(sp));
1430 __ ld(a2, MemOperand(a0)); // thisArgument
1431 __ Dsubu(a0, a0, Operand(kPointerSize));
1432 __ Branch(&no_arg, lt, a0, Operand(sp));
1433 __ ld(a3, MemOperand(a0)); // argumentsList
1434 __ bind(&no_arg);
1435 __ Daddu(sp, sp, Operand(scratch));
1436 __ sd(a2, MemOperand(sp));
1437 __ mov(a0, a3);
1438 }
1439
1440 // ----------- S t a t e -------------
1441 // -- a0 : argumentsList
1442 // -- a1 : target
1443 // -- sp[0] : thisArgument
1444 // -----------------------------------
1445
1446 // 2. Make sure the target is actually callable.
1447 Label target_not_callable;
1448 __ JumpIfSmi(a1, &target_not_callable);
1449 __ ld(a4, FieldMemOperand(a1, HeapObject::kMapOffset));
1450 __ lbu(a4, FieldMemOperand(a4, Map::kBitFieldOffset));
1451 __ And(a4, a4, Operand(1 << Map::kIsCallable));
1452 __ Branch(&target_not_callable, eq, a4, Operand(zero_reg));
1453
1454 // 3a. Apply the target to the given argumentsList (passing undefined for
1455 // new.target).
1456 __ LoadRoot(a3, Heap::kUndefinedValueRootIndex);
1457 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1458
1459 // 3b. The target is not callable, throw an appropriate TypeError.
1460 __ bind(&target_not_callable);
1461 {
1462 __ sd(a1, MemOperand(sp));
1463 __ TailCallRuntime(Runtime::kThrowApplyNonFunction, 1, 1);
1464 }
1510 } 1465 }
1511 1466
1512 1467
1513 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) { 1468 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
1514 Generate_ConstructHelper(masm); 1469 // ----------- S t a t e -------------
1515 } 1470 // -- a0 : argc
1516 1471 // -- sp[0] : new.target (optional)
1517 1472 // -- sp[4] : argumentsList
1473 // -- sp[8] : target
1474 // -- sp[12] : receiver
1475 // -----------------------------------
1476
1477 // 1. Load target into a1 (if present), argumentsList into a0 (if present),
1478 // new.target into a3 (if present, otherwise use target), remove all
1479 // arguments from the stack (including the receiver), and push thisArgument
1480 // (if present) instead.
1481 {
1482 Label no_arg;
1483 Register scratch = a4;
1484 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
1485 __ mov(a2, a1);
1486 __ dsll(scratch, a0, kPointerSizeLog2);
1487 __ Daddu(a0, sp, Operand(scratch));
1488 __ sd(a2, MemOperand(a0)); // receiver
1489 __ Dsubu(a0, a0, Operand(kPointerSize));
1490 __ Branch(&no_arg, lt, a0, Operand(sp));
1491 __ ld(a1, MemOperand(a0)); // target
1492 __ mov(a3, a1); // new.target defaults to target
1493 __ Dsubu(a0, a0, Operand(kPointerSize));
1494 __ Branch(&no_arg, lt, a0, Operand(sp));
1495 __ ld(a2, MemOperand(a0)); // argumentsList
1496 __ Dsubu(a0, a0, Operand(kPointerSize));
1497 __ Branch(&no_arg, lt, a0, Operand(sp));
1498 __ ld(a3, MemOperand(a0)); // new.target
1499 __ bind(&no_arg);
1500 __ Daddu(sp, sp, Operand(scratch));
1501 __ mov(a0, a2);
1502 }
1503
1504 // ----------- S t a t e -------------
1505 // -- a0 : argumentsList
1506 // -- a3 : new.target
1507 // -- a1 : target
1508 // -- sp[0] : receiver (undefined)
1509 // -----------------------------------
1510
1511 // 2. Make sure the target is actually a constructor.
1512 Label target_not_constructor;
1513 __ JumpIfSmi(a1, &target_not_constructor);
1514 __ ld(a4, FieldMemOperand(a1, HeapObject::kMapOffset));
1515 __ lbu(a4, FieldMemOperand(a4, Map::kBitFieldOffset));
1516 __ And(a4, a4, Operand(1 << Map::kIsConstructor));
1517 __ Branch(&target_not_constructor, eq, a4, Operand(zero_reg));
1518
1519 // 3. Make sure the target is actually a constructor.
1520 Label new_target_not_constructor;
1521 __ JumpIfSmi(a3, &new_target_not_constructor);
1522 __ ld(a4, FieldMemOperand(a3, HeapObject::kMapOffset));
1523 __ lbu(a4, FieldMemOperand(a4, Map::kBitFieldOffset));
1524 __ And(a4, a4, Operand(1 << Map::kIsConstructor));
1525 __ Branch(&new_target_not_constructor, eq, a4, Operand(zero_reg));
1526
1527 // 4a. Construct the target with the given new.target and argumentsList.
1528 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1529
1530 // 4b. The target is not a constructor, throw an appropriate TypeError.
1531 __ bind(&target_not_constructor);
1532 {
1533 __ sd(a1, MemOperand(sp));
1534 __ TailCallRuntime(Runtime::kThrowCalledNonCallable, 1, 1);
1535 }
1536
1537 // 4c. The new.target is not a constructor, throw an appropriate TypeError.
1538 __ bind(&new_target_not_constructor);
1539 {
1540 __ sd(a3, MemOperand(sp));
1541 __ TailCallRuntime(Runtime::kThrowCalledNonCallable, 1, 1);
1542 }
1543 }
1544
1545
1518 static void ArgumentAdaptorStackCheck(MacroAssembler* masm, 1546 static void ArgumentAdaptorStackCheck(MacroAssembler* masm,
1519 Label* stack_overflow) { 1547 Label* stack_overflow) {
1520 // ----------- S t a t e ------------- 1548 // ----------- S t a t e -------------
1521 // -- a0 : actual number of arguments 1549 // -- a0 : actual number of arguments
1522 // -- a1 : function (passed through to callee) 1550 // -- a1 : function (passed through to callee)
1523 // -- a2 : expected number of arguments 1551 // -- a2 : expected number of arguments
1524 // -- a3 : new target (passed through to callee) 1552 // -- a3 : new target (passed through to callee)
1525 // ----------------------------------- 1553 // -----------------------------------
1526 // Check the stack for overflow. We are not trying to catch 1554 // Check the stack for overflow. We are not trying to catch
1527 // interruptions (e.g. debug break and preemption) here, so the "real stack 1555 // interruptions (e.g. debug break and preemption) here, so the "real stack
(...skipping 30 matching lines...) Expand all
1558 __ mov(sp, fp); 1586 __ mov(sp, fp);
1559 __ MultiPop(fp.bit() | ra.bit()); 1587 __ MultiPop(fp.bit() | ra.bit());
1560 __ SmiScale(a4, a1, kPointerSizeLog2); 1588 __ SmiScale(a4, a1, kPointerSizeLog2);
1561 __ Daddu(sp, sp, a4); 1589 __ Daddu(sp, sp, a4);
1562 // Adjust for the receiver. 1590 // Adjust for the receiver.
1563 __ Daddu(sp, sp, Operand(kPointerSize)); 1591 __ Daddu(sp, sp, Operand(kPointerSize));
1564 } 1592 }
1565 1593
1566 1594
1567 // static 1595 // static
1596 void Builtins::Generate_Apply(MacroAssembler* masm) {
1597 // ----------- S t a t e -------------
1598 // -- a0 : argumentsList
1599 // -- a1 : target
1600 // -- a3 : new.target (checked to be constructor or undefined)
1601 // -- sp[0] : thisArgument
1602 // -----------------------------------
1603
1604 // Create the list of arguments from the array-like argumentsList.
1605 {
1606 Label create_arguments, create_array, create_runtime, done_create;
1607 __ JumpIfSmi(a0, &create_runtime);
1608
1609 // Load the map of argumentsList into a2.
1610 __ ld(a2, FieldMemOperand(a0, HeapObject::kMapOffset));
1611
1612 // Load native context into a4.
1613 __ ld(a4, NativeContextMemOperand());
1614
1615 // Check if argumentsList is an (unmodified) arguments object.
1616 __ ld(at, ContextMemOperand(a4, Context::SLOPPY_ARGUMENTS_MAP_INDEX));
1617 __ Branch(&create_arguments, eq, a2, Operand(at));
1618 __ ld(at, ContextMemOperand(a4, Context::STRICT_ARGUMENTS_MAP_INDEX));
1619 __ Branch(&create_arguments, eq, a2, Operand(at));
1620
1621 // Check if argumentsList is a fast JSArray.
1622 __ ld(v0, FieldMemOperand(a2, HeapObject::kMapOffset));
1623 __ lbu(v0, FieldMemOperand(v0, Map::kInstanceTypeOffset));
1624 __ Branch(&create_array, eq, v0, Operand(JS_ARRAY_TYPE));
1625
1626 // Ask the runtime to create the list (actually a FixedArray).
1627 __ bind(&create_runtime);
1628 {
1629 FrameScope scope(masm, StackFrame::INTERNAL);
1630 __ Push(a1, a3, a0);
1631 __ CallRuntime(Runtime::kCreateListFromArrayLike, 1);
1632 __ mov(a0, v0);
1633 __ Pop(a1, a3);
1634 __ ld(a2, FieldMemOperand(v0, FixedArray::kLengthOffset));
1635 __ SmiUntag(a2);
1636 }
1637 __ Branch(&done_create);
1638
1639 // Try to create the list from an arguments object.
1640 __ bind(&create_arguments);
1641 __ ld(a2,
1642 FieldMemOperand(a0, JSObject::kHeaderSize +
1643 Heap::kArgumentsLengthIndex * kPointerSize));
1644 __ ld(a4, FieldMemOperand(a0, JSObject::kElementsOffset));
1645 __ ld(at, FieldMemOperand(a4, FixedArray::kLengthOffset));
1646 __ Branch(&create_runtime, ne, a2, Operand(at));
1647 __ SmiUntag(a2);
1648 __ mov(a0, a4);
1649 __ Branch(&done_create);
1650
1651 // Try to create the list from a JSArray object.
1652 __ bind(&create_array);
1653 __ ld(a2, FieldMemOperand(a2, Map::kBitField2Offset));
1654 __ DecodeField<Map::ElementsKindBits>(a2);
1655 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
1656 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
1657 STATIC_ASSERT(FAST_ELEMENTS == 2);
1658 __ Branch(&create_runtime, hi, a2, Operand(FAST_ELEMENTS));
1659 __ Branch(&create_runtime, eq, a2, Operand(FAST_HOLEY_SMI_ELEMENTS));
1660 __ ld(a2, FieldMemOperand(a0, JSArray::kLengthOffset));
1661 __ ld(a0, FieldMemOperand(a0, JSArray::kElementsOffset));
1662 __ SmiUntag(a2);
1663
1664 __ bind(&done_create);
1665 }
1666
1667 // Check for stack overflow.
1668 {
1669 // Check the stack for overflow. We are not trying to catch interruptions
1670 // (i.e. debug break and preemption) here, so check the "real stack limit".
1671 Label done;
1672 __ LoadRoot(a4, Heap::kRealStackLimitRootIndex);
1673 // Make ip the space we have left. The stack might already be overflowed
1674 // here which will cause ip to become negative.
1675 __ Dsubu(a4, sp, a4);
1676 // Check if the arguments will overflow the stack.
1677 __ dsll(at, a2, kPointerSizeLog2);
1678 __ Branch(&done, gt, a4, Operand(at)); // Signed comparison.
1679 __ TailCallRuntime(Runtime::kThrowStackOverflow, 1, 1);
1680 __ bind(&done);
1681 }
1682
1683 // ----------- S t a t e -------------
1684 // -- a1 : target
1685 // -- a0 : args (a FixedArray built from argumentsList)
1686 // -- a2 : len (number of elements to push from args)
1687 // -- a3 : new.target (checked to be constructor or undefined)
1688 // -- sp[0] : thisArgument
1689 // -----------------------------------
1690
1691 // Push arguments onto the stack (thisArgument is already on the stack).
1692 {
1693 __ mov(a4, zero_reg);
1694 Label done, loop;
1695 __ bind(&loop);
1696 __ Branch(&done, eq, a4, Operand(a2));
1697 __ dsll(at, a4, kPointerSizeLog2);
1698 __ Daddu(at, a0, at);
1699 __ ld(at, FieldMemOperand(at, FixedArray::kHeaderSize));
1700 __ Push(at);
1701 __ Daddu(a4, a4, Operand(1));
1702 __ Branch(&loop);
1703 __ bind(&done);
1704 __ Move(a0, a4);
1705 }
1706
1707 // Dispatch to Call or Construct depending on whether new.target is undefined.
1708 {
1709 Label construct;
1710 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
1711 __ Branch(&construct, ne, a3, Operand(at));
1712 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1713 __ bind(&construct);
1714 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
1715 }
1716 }
1717
1718
1719 // static
1568 void Builtins::Generate_CallFunction(MacroAssembler* masm, 1720 void Builtins::Generate_CallFunction(MacroAssembler* masm,
1569 ConvertReceiverMode mode) { 1721 ConvertReceiverMode mode) {
1570 // ----------- S t a t e ------------- 1722 // ----------- S t a t e -------------
1571 // -- a0 : the number of arguments (not including the receiver) 1723 // -- a0 : the number of arguments (not including the receiver)
1572 // -- a1 : the function to call (checked to be a JSFunction) 1724 // -- a1 : the function to call (checked to be a JSFunction)
1573 // ----------------------------------- 1725 // -----------------------------------
1574 __ AssertFunction(a1); 1726 __ AssertFunction(a1);
1575 1727
1576 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) 1728 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
1577 // Check that function is not a "classConstructor". 1729 // Check that function is not a "classConstructor".
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
1966 } 2118 }
1967 } 2119 }
1968 2120
1969 2121
1970 #undef __ 2122 #undef __
1971 2123
1972 } // namespace internal 2124 } // namespace internal
1973 } // namespace v8 2125 } // namespace v8
1974 2126
1975 #endif // V8_TARGET_ARCH_MIPS64 2127 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/mips/builtins-mips.cc ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698