OLD | NEW |
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_X87 | 5 #if V8_TARGET_ARCH_X87 |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.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 1357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1368 | 1368 |
1369 // Run the native code for the Array function called as a normal function. | 1369 // Run the native code for the Array function called as a normal function. |
1370 // tail call a stub | 1370 // tail call a stub |
1371 __ mov(ebx, masm->isolate()->factory()->undefined_value()); | 1371 __ mov(ebx, masm->isolate()->factory()->undefined_value()); |
1372 ArrayConstructorStub stub(masm->isolate()); | 1372 ArrayConstructorStub stub(masm->isolate()); |
1373 __ TailCallStub(&stub); | 1373 __ TailCallStub(&stub); |
1374 } | 1374 } |
1375 | 1375 |
1376 | 1376 |
1377 // static | 1377 // static |
| 1378 void Builtins::Generate_NumberConstructor(MacroAssembler* masm) { |
| 1379 // ----------- S t a t e ------------- |
| 1380 // -- eax : number of arguments |
| 1381 // -- edi : constructor function |
| 1382 // -- esp[0] : return address |
| 1383 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 1384 // -- esp[(argc + 1) * 4] : receiver |
| 1385 // ----------------------------------- |
| 1386 |
| 1387 // 1. Load the first argument into eax and get rid of the rest (including the |
| 1388 // receiver). |
| 1389 Label no_arguments; |
| 1390 { |
| 1391 __ test(eax, eax); |
| 1392 __ j(zero, &no_arguments, Label::kNear); |
| 1393 __ mov(ebx, Operand(esp, eax, times_pointer_size, 0)); |
| 1394 __ PopReturnAddressTo(ecx); |
| 1395 __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize)); |
| 1396 __ PushReturnAddressFrom(ecx); |
| 1397 __ mov(eax, ebx); |
| 1398 } |
| 1399 |
| 1400 // 2a. Convert the first argument to a number. |
| 1401 ToNumberStub stub(masm->isolate()); |
| 1402 __ TailCallStub(&stub); |
| 1403 |
| 1404 // 2b. No arguments, return +0 (already in eax). |
| 1405 __ bind(&no_arguments); |
| 1406 __ ret(1 * kPointerSize); |
| 1407 } |
| 1408 |
| 1409 |
| 1410 // static |
| 1411 void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) { |
| 1412 // ----------- S t a t e ------------- |
| 1413 // -- eax : number of arguments |
| 1414 // -- edi : constructor function |
| 1415 // -- edx : new target |
| 1416 // -- esp[0] : return address |
| 1417 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 1418 // -- esp[(argc + 1) * 4] : receiver |
| 1419 // ----------------------------------- |
| 1420 |
| 1421 // 1. Make sure we operate in the context of the called function. |
| 1422 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
| 1423 |
| 1424 // 2. Load the first argument into ebx and get rid of the rest (including the |
| 1425 // receiver). |
| 1426 { |
| 1427 Label no_arguments, done; |
| 1428 __ test(eax, eax); |
| 1429 __ j(zero, &no_arguments, Label::kNear); |
| 1430 __ mov(ebx, Operand(esp, eax, times_pointer_size, 0)); |
| 1431 __ jmp(&done, Label::kNear); |
| 1432 __ bind(&no_arguments); |
| 1433 __ Move(ebx, Smi::FromInt(0)); |
| 1434 __ bind(&done); |
| 1435 __ PopReturnAddressTo(ecx); |
| 1436 __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize)); |
| 1437 __ PushReturnAddressFrom(ecx); |
| 1438 } |
| 1439 |
| 1440 // 3. Make sure ebx is a number. |
| 1441 { |
| 1442 Label done_convert; |
| 1443 __ JumpIfSmi(ebx, &done_convert); |
| 1444 __ CompareRoot(FieldOperand(ebx, HeapObject::kMapOffset), |
| 1445 Heap::kHeapNumberMapRootIndex); |
| 1446 __ j(equal, &done_convert); |
| 1447 { |
| 1448 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1449 __ Push(edi); |
| 1450 __ Push(edx); |
| 1451 __ Move(eax, ebx); |
| 1452 ToNumberStub stub(masm->isolate()); |
| 1453 __ CallStub(&stub); |
| 1454 __ Move(ebx, eax); |
| 1455 __ Pop(edx); |
| 1456 __ Pop(edi); |
| 1457 } |
| 1458 __ bind(&done_convert); |
| 1459 } |
| 1460 |
| 1461 // 4. Check if new target and constructor differ. |
| 1462 Label new_object; |
| 1463 __ cmp(edx, edi); |
| 1464 __ j(not_equal, &new_object); |
| 1465 |
| 1466 // 5. Allocate a JSValue wrapper for the number. |
| 1467 __ AllocateJSValue(eax, edi, ebx, ecx, &new_object); |
| 1468 __ Ret(); |
| 1469 |
| 1470 // 6. Fallback to the runtime to create new object. |
| 1471 __ bind(&new_object); |
| 1472 { |
| 1473 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1474 __ Push(ebx); // the first argument |
| 1475 __ Push(edi); // constructor function |
| 1476 __ Push(edx); // new target |
| 1477 __ CallRuntime(Runtime::kNewObject); |
| 1478 __ Pop(FieldOperand(eax, JSValue::kValueOffset)); |
| 1479 } |
| 1480 __ Ret(); |
| 1481 } |
| 1482 |
| 1483 |
| 1484 // static |
1378 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { | 1485 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { |
1379 // ----------- S t a t e ------------- | 1486 // ----------- S t a t e ------------- |
1380 // -- eax : number of arguments | 1487 // -- eax : number of arguments |
1381 // -- edi : constructor function | 1488 // -- edi : constructor function |
1382 // -- esp[0] : return address | 1489 // -- esp[0] : return address |
1383 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1490 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1384 // -- esp[(argc + 1) * 4] : receiver | 1491 // -- esp[(argc + 1) * 4] : receiver |
1385 // ----------------------------------- | 1492 // ----------------------------------- |
1386 | 1493 |
1387 // 1. Load the first argument into eax and get rid of the rest (including the | 1494 // 1. Load the first argument into eax and get rid of the rest (including the |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1438 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { | 1545 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { |
1439 // ----------- S t a t e ------------- | 1546 // ----------- S t a t e ------------- |
1440 // -- eax : number of arguments | 1547 // -- eax : number of arguments |
1441 // -- edi : constructor function | 1548 // -- edi : constructor function |
1442 // -- edx : new target | 1549 // -- edx : new target |
1443 // -- esp[0] : return address | 1550 // -- esp[0] : return address |
1444 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1551 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1445 // -- esp[(argc + 1) * 4] : receiver | 1552 // -- esp[(argc + 1) * 4] : receiver |
1446 // ----------------------------------- | 1553 // ----------------------------------- |
1447 | 1554 |
1448 // 1. Load the first argument into ebx and get rid of the rest (including the | 1555 // 1. Make sure we operate in the context of the called function. |
| 1556 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
| 1557 |
| 1558 // 2. Load the first argument into ebx and get rid of the rest (including the |
1449 // receiver). | 1559 // receiver). |
1450 { | 1560 { |
1451 Label no_arguments, done; | 1561 Label no_arguments, done; |
1452 __ test(eax, eax); | 1562 __ test(eax, eax); |
1453 __ j(zero, &no_arguments, Label::kNear); | 1563 __ j(zero, &no_arguments, Label::kNear); |
1454 __ mov(ebx, Operand(esp, eax, times_pointer_size, 0)); | 1564 __ mov(ebx, Operand(esp, eax, times_pointer_size, 0)); |
1455 __ jmp(&done, Label::kNear); | 1565 __ jmp(&done, Label::kNear); |
1456 __ bind(&no_arguments); | 1566 __ bind(&no_arguments); |
1457 __ LoadRoot(ebx, Heap::kempty_stringRootIndex); | 1567 __ LoadRoot(ebx, Heap::kempty_stringRootIndex); |
1458 __ bind(&done); | 1568 __ bind(&done); |
1459 __ PopReturnAddressTo(ecx); | 1569 __ PopReturnAddressTo(ecx); |
1460 __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize)); | 1570 __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize)); |
1461 __ PushReturnAddressFrom(ecx); | 1571 __ PushReturnAddressFrom(ecx); |
1462 } | 1572 } |
1463 | 1573 |
1464 // 2. Make sure ebx is a string. | 1574 // 3. Make sure ebx is a string. |
1465 { | 1575 { |
1466 Label convert, done_convert; | 1576 Label convert, done_convert; |
1467 __ JumpIfSmi(ebx, &convert, Label::kNear); | 1577 __ JumpIfSmi(ebx, &convert, Label::kNear); |
1468 __ CmpObjectType(ebx, FIRST_NONSTRING_TYPE, ecx); | 1578 __ CmpObjectType(ebx, FIRST_NONSTRING_TYPE, ecx); |
1469 __ j(below, &done_convert); | 1579 __ j(below, &done_convert); |
1470 __ bind(&convert); | 1580 __ bind(&convert); |
1471 { | 1581 { |
1472 FrameScope scope(masm, StackFrame::INTERNAL); | 1582 FrameScope scope(masm, StackFrame::INTERNAL); |
1473 ToStringStub stub(masm->isolate()); | 1583 ToStringStub stub(masm->isolate()); |
1474 __ Push(edi); | 1584 __ Push(edi); |
1475 __ Push(edx); | 1585 __ Push(edx); |
1476 __ Move(eax, ebx); | 1586 __ Move(eax, ebx); |
1477 __ CallStub(&stub); | 1587 __ CallStub(&stub); |
1478 __ Move(ebx, eax); | 1588 __ Move(ebx, eax); |
1479 __ Pop(edx); | 1589 __ Pop(edx); |
1480 __ Pop(edi); | 1590 __ Pop(edi); |
1481 } | 1591 } |
1482 __ bind(&done_convert); | 1592 __ bind(&done_convert); |
1483 } | 1593 } |
1484 | 1594 |
1485 // 3. Check if new target and constructor differ. | 1595 // 4. Check if new target and constructor differ. |
1486 Label new_object; | 1596 Label new_object; |
1487 __ cmp(edx, edi); | 1597 __ cmp(edx, edi); |
1488 __ j(not_equal, &new_object); | 1598 __ j(not_equal, &new_object); |
1489 | 1599 |
1490 // 4. Allocate a JSValue wrapper for the string. | 1600 // 5. Allocate a JSValue wrapper for the string. |
1491 { | 1601 __ AllocateJSValue(eax, edi, ebx, ecx, &new_object); |
1492 // ----------- S t a t e ------------- | 1602 __ Ret(); |
1493 // -- ebx : the first argument | |
1494 // -- edi : constructor function | |
1495 // -- edx : new target | |
1496 // ----------------------------------- | |
1497 __ Allocate(JSValue::kSize, eax, ecx, no_reg, &new_object, TAG_OBJECT); | |
1498 | 1603 |
1499 // Initialize the JSValue in eax. | 1604 // 6. Fallback to the runtime to create new object. |
1500 __ LoadGlobalFunctionInitialMap(edi, ecx); | |
1501 __ mov(FieldOperand(eax, HeapObject::kMapOffset), ecx); | |
1502 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), | |
1503 masm->isolate()->factory()->empty_fixed_array()); | |
1504 __ mov(FieldOperand(eax, JSObject::kElementsOffset), | |
1505 masm->isolate()->factory()->empty_fixed_array()); | |
1506 __ mov(FieldOperand(eax, JSValue::kValueOffset), ebx); | |
1507 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); | |
1508 __ Ret(); | |
1509 } | |
1510 | |
1511 // 5. Fallback to the runtime to create new object. | |
1512 __ bind(&new_object); | 1605 __ bind(&new_object); |
1513 { | 1606 { |
1514 FrameScope scope(masm, StackFrame::INTERNAL); | 1607 FrameScope scope(masm, StackFrame::INTERNAL); |
1515 __ Push(ebx); // the first argument | 1608 __ Push(ebx); // the first argument |
1516 __ Push(edi); // constructor function | 1609 __ Push(edi); // constructor function |
1517 __ Push(edx); // new target | 1610 __ Push(edx); // new target |
1518 __ CallRuntime(Runtime::kNewObject); | 1611 __ CallRuntime(Runtime::kNewObject); |
1519 __ Pop(FieldOperand(eax, JSValue::kValueOffset)); | 1612 __ Pop(FieldOperand(eax, JSValue::kValueOffset)); |
1520 } | 1613 } |
1521 __ Ret(); | 1614 __ Ret(); |
(...skipping 909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2431 | 2524 |
2432 __ bind(&ok); | 2525 __ bind(&ok); |
2433 __ ret(0); | 2526 __ ret(0); |
2434 } | 2527 } |
2435 | 2528 |
2436 #undef __ | 2529 #undef __ |
2437 } // namespace internal | 2530 } // namespace internal |
2438 } // namespace v8 | 2531 } // namespace v8 |
2439 | 2532 |
2440 #endif // V8_TARGET_ARCH_X87 | 2533 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |