diff options
| author | Mike Pall <mike> | 2011-04-05 00:25:31 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2011-04-05 00:25:31 +0200 |
| commit | 314995aebf20ce47f854cdab3722085c944f9e74 (patch) | |
| tree | 58f295ee039768e9529dd90c9ea283a93975bbfb /src | |
| parent | a7874cb29970b72fec106e6a8a4f22c42a15e580 (diff) | |
| download | luajit-314995aebf20ce47f854cdab3722085c944f9e74.tar.gz luajit-314995aebf20ce47f854cdab3722085c944f9e74.tar.bz2 luajit-314995aebf20ce47f854cdab3722085c944f9e74.zip | |
ARM: Finish basic table indexing and add metamethod handlers.
Diffstat (limited to 'src')
| -rw-r--r-- | src/buildvm_arm.dasc | 351 |
1 files changed, 335 insertions, 16 deletions
diff --git a/src/buildvm_arm.dasc b/src/buildvm_arm.dasc index b0b87ebf..e6c66de3 100644 --- a/src/buildvm_arm.dasc +++ b/src/buildvm_arm.dasc | |||
| @@ -53,6 +53,11 @@ | |||
| 53 | |.define SAVE_MULTRES, [sp, #4] | 53 | |.define SAVE_MULTRES, [sp, #4] |
| 54 | |.define ARG5, [sp] | 54 | |.define ARG5, [sp] |
| 55 | | | 55 | | |
| 56 | |.define TMPDhi, [sp, #4] | ||
| 57 | |.define TMPDlo, [sp] | ||
| 58 | |.define TMPD, [sp] | ||
| 59 | |.define TMPDp, sp | ||
| 60 | | | ||
| 56 | |.macro saveregs | 61 | |.macro saveregs |
| 57 | | push {r4, r5, r6, r7, r8, r9, r10, r11, lr} | 62 | | push {r4, r5, r6, r7, r8, r9, r10, r11, lr} |
| 58 | | sub sp, sp, CFRAME_SPACE | 63 | | sub sp, sp, CFRAME_SPACE |
| @@ -189,6 +194,15 @@ | |||
| 189 | |.macro mv_vmstate, reg, st; mvn reg, #LJ_VMST_..st; .endmacro | 194 | |.macro mv_vmstate, reg, st; mvn reg, #LJ_VMST_..st; .endmacro |
| 190 | |.macro st_vmstate, reg; str reg, [DISPATCH, #DISPATCH_GL(vmstate)]; .endmacro | 195 | |.macro st_vmstate, reg; str reg, [DISPATCH, #DISPATCH_GL(vmstate)]; .endmacro |
| 191 | | | 196 | | |
| 197 | |// Move table write barrier back. Overwrites mark and tmp. | ||
| 198 | |.macro barrierback, tab, mark, tmp | ||
| 199 | | ldr tmp, [DISPATCH, #DISPATCH_GL(gc.grayagain)] | ||
| 200 | | bic mark, mark, #LJ_GC_BLACK // black2gray(tab) | ||
| 201 | | str tab, [DISPATCH, #DISPATCH_GL(gc.grayagain)] | ||
| 202 | | strb mark, tab->marked | ||
| 203 | | str tmp, tab->gclist | ||
| 204 | |.endmacro | ||
| 205 | | | ||
| 192 | |//----------------------------------------------------------------------- | 206 | |//----------------------------------------------------------------------- |
| 193 | 207 | ||
| 194 | #if !LJ_DUALNUM | 208 | #if !LJ_DUALNUM |
| @@ -417,25 +431,113 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 417 | | | 431 | | |
| 418 | |//-- Table indexing metamethods ----------------------------------------- | 432 | |//-- Table indexing metamethods ----------------------------------------- |
| 419 | | | 433 | | |
| 434 | |->vmeta_tgets1: | ||
| 435 | | add CARG2, BASE, RB | ||
| 436 | | b >2 | ||
| 437 | | | ||
| 420 | |->vmeta_tgets: | 438 | |->vmeta_tgets: |
| 421 | | NYI | 439 | | sub CARG2, DISPATCH, #-DISPATCH_GL(tmptv) |
| 440 | | mvn CARG4, #~LJ_TTAB | ||
| 441 | | str TAB:RB, [CARG2] | ||
| 442 | | str CARG4, [CARG2, #4] | ||
| 443 | |2: | ||
| 444 | | mvn CARG4, #~LJ_TISNUM | ||
| 445 | | str STR:RC, TMPDlo | ||
| 446 | | str CARG4, TMPDhi | ||
| 447 | | mov CARG3, TMPDp | ||
| 448 | | b >1 | ||
| 422 | | | 449 | | |
| 423 | |->vmeta_tgetb: | 450 | |->vmeta_tgetb: // RC = index |
| 424 | | NYI | 451 | | decode_RB8 RB, INS |
| 452 | | str RC, TMPDlo | ||
| 453 | | mvn CARG4, #~LJ_TISNUM | ||
| 454 | | add CARG2, BASE, RB | ||
| 455 | | str CARG4, TMPDhi | ||
| 456 | | mov CARG3, TMPDp | ||
| 457 | | b >1 | ||
| 425 | | | 458 | | |
| 426 | |->vmeta_tgetv: | 459 | |->vmeta_tgetv: |
| 427 | | NYI | 460 | | add CARG2, BASE, RB |
| 461 | | add CARG3, BASE, RC | ||
| 462 | |1: | ||
| 463 | | str BASE, L->base | ||
| 464 | | mov CARG1, L | ||
| 465 | | str PC, SAVE_PC | ||
| 466 | | bl extern lj_meta_tget // (lua_State *L, TValue *o, TValue *k) | ||
| 467 | | // Returns TValue * (finished) or NULL (metamethod). | ||
| 468 | | cmp CRET1, #0 | ||
| 469 | | beq >3 | ||
| 470 | | ldrd CARG34, [CRET1] | ||
| 471 | | ins_next1 | ||
| 472 | | ins_next2 | ||
| 473 | | strd CARG34, [BASE, RA] | ||
| 474 | | ins_next3 | ||
| 475 | | | ||
| 476 | |3: // Call __index metamethod. | ||
| 477 | | // BASE = base, L->top = new base, stack = cont/func/t/k | ||
| 478 | | rsb CARG1, BASE, #FRAME_CONT | ||
| 479 | | ldr BASE, L->top | ||
| 480 | | mov NARGS8:RC, #16 // 2 args for func(t, k). | ||
| 481 | | str PC, [BASE, #-12] // [cont|PC] | ||
| 482 | | add PC, CARG1, BASE | ||
| 483 | | ldr LFUNC:CARG3, [BASE, FRAME_FUNC] // Guaranteed to be a function here. | ||
| 484 | | b ->vm_call_dispatch_f | ||
| 428 | | | 485 | | |
| 429 | |//----------------------------------------------------------------------- | 486 | |//----------------------------------------------------------------------- |
| 430 | | | 487 | | |
| 488 | |->vmeta_tsets1: | ||
| 489 | | add CARG2, BASE, RB | ||
| 490 | | b >2 | ||
| 491 | | | ||
| 431 | |->vmeta_tsets: | 492 | |->vmeta_tsets: |
| 432 | | NYI | 493 | | sub CARG2, DISPATCH, #-DISPATCH_GL(tmptv) |
| 494 | | mvn CARG4, #~LJ_TTAB | ||
| 495 | | str TAB:RB, [CARG2] | ||
| 496 | | str CARG4, [CARG2, #4] | ||
| 497 | |2: | ||
| 498 | | mvn CARG4, #~LJ_TISNUM | ||
| 499 | | str STR:RC, TMPDlo | ||
| 500 | | str CARG4, TMPDhi | ||
| 501 | | mov CARG3, TMPDp | ||
| 502 | | b >1 | ||
| 433 | | | 503 | | |
| 434 | |->vmeta_tsetb: | 504 | |->vmeta_tsetb: // RC = index |
| 435 | | NYI | 505 | | decode_RB8 RB, INS |
| 506 | | str RC, TMPDlo | ||
| 507 | | mvn CARG4, #~LJ_TISNUM | ||
| 508 | | add CARG2, BASE, RB | ||
| 509 | | str CARG4, TMPDhi | ||
| 510 | | mov CARG3, TMPDp | ||
| 511 | | b >1 | ||
| 436 | | | 512 | | |
| 437 | |->vmeta_tsetv: | 513 | |->vmeta_tsetv: |
| 438 | | NYI | 514 | | add CARG2, BASE, RB |
| 515 | | add CARG3, BASE, RC | ||
| 516 | |1: | ||
| 517 | | str BASE, L->base | ||
| 518 | | mov CARG1, L | ||
| 519 | | str PC, SAVE_PC | ||
| 520 | | bl extern lj_meta_tset // (lua_State *L, TValue *o, TValue *k) | ||
| 521 | | // Returns TValue * (finished) or NULL (metamethod). | ||
| 522 | | cmp CRET1, #0 | ||
| 523 | | ldrd CARG34, [BASE, RA] | ||
| 524 | | beq >3 | ||
| 525 | | ins_next1 | ||
| 526 | | // NOBARRIER: lj_meta_tset ensures the table is not black. | ||
| 527 | | strd CARG34, [CRET1] | ||
| 528 | | ins_next2 | ||
| 529 | | ins_next3 | ||
| 530 | | | ||
| 531 | |3: // Call __newindex metamethod. | ||
| 532 | | // BASE = base, L->top = new base, stack = cont/func/t/k/(v) | ||
| 533 | | rsb CARG1, BASE, #FRAME_CONT | ||
| 534 | | ldr BASE, L->top | ||
| 535 | | mov NARGS8:RC, #24 // 3 args for func(t, k, v). | ||
| 536 | | strd CARG34, [BASE, #16] // Copy value to third argument. | ||
| 537 | | str PC, [BASE, #-12] // [cont|PC] | ||
| 538 | | add PC, CARG1, BASE | ||
| 539 | | ldr LFUNC:CARG3, [BASE, FRAME_FUNC] // Guaranteed to be a function here. | ||
| 540 | | b ->vm_call_dispatch_f | ||
| 439 | | | 541 | | |
| 440 | |//-- Comparison metamethods --------------------------------------------- | 542 | |//-- Comparison metamethods --------------------------------------------- |
| 441 | | | 543 | | |
| @@ -1462,7 +1564,43 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 1462 | break; | 1564 | break; |
| 1463 | 1565 | ||
| 1464 | case BC_TGETV: | 1566 | case BC_TGETV: |
| 1465 | | NYI | 1567 | | decode_RB8 RB, INS |
| 1568 | | decode_RC8 RC, INS | ||
| 1569 | | // RA = dst*8, RB = table*8, RC = key*8 | ||
| 1570 | | ldrd TAB:CARG12, [BASE, RB] | ||
| 1571 | | ldrd CARG34, [BASE, RC] | ||
| 1572 | | checktab CARG2, ->vmeta_tgetv // STALL: load CARG12. | ||
| 1573 | | checktp CARG4, LJ_TISNUM // Integer key? | ||
| 1574 | | ldreq CARG4, TAB:CARG1->array | ||
| 1575 | | ldreq CARG2, TAB:CARG1->asize | ||
| 1576 | | bne >9 | ||
| 1577 | | | ||
| 1578 | | add CARG4, CARG4, CARG3, lsl #3 | ||
| 1579 | | cmp CARG3, CARG2 // In array part? | ||
| 1580 | | ldrdlo CARG34, [CARG4] | ||
| 1581 | | bhs ->vmeta_tgetv | ||
| 1582 | | ins_next1 | ||
| 1583 | | checktp CARG4, LJ_TNIL | ||
| 1584 | | beq >5 | ||
| 1585 | |1: | ||
| 1586 | | ins_next2 | ||
| 1587 | | strd CARG34, [BASE, RA] | ||
| 1588 | | ins_next3 | ||
| 1589 | | | ||
| 1590 | |5: // Check for __index if table value is nil. | ||
| 1591 | | ldr TAB:CARG2, TAB:CARG1->metatable | ||
| 1592 | | cmp TAB:CARG2, #0 | ||
| 1593 | | beq <1 // No metatable: done. | ||
| 1594 | | ldrb CARG2, TAB:CARG2->nomm | ||
| 1595 | | tst CARG2, #1<<MM_index | ||
| 1596 | | bne <1 // 'no __index' flag set: done. | ||
| 1597 | | b ->vmeta_tgetv | ||
| 1598 | | | ||
| 1599 | |9: | ||
| 1600 | | checktp CARG4, LJ_TSTR // String key? | ||
| 1601 | | moveq STR:RC, CARG3 | ||
| 1602 | | beq ->BC_TGETS_Z | ||
| 1603 | | b ->vmeta_tgetv | ||
| 1466 | break; | 1604 | break; |
| 1467 | case BC_TGETS: | 1605 | case BC_TGETS: |
| 1468 | | decode_RB8 RB, INS | 1606 | | decode_RB8 RB, INS |
| @@ -1471,7 +1609,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 1471 | | ldrd CARG12, [BASE, RB] | 1609 | | ldrd CARG12, [BASE, RB] |
| 1472 | | mvn RC, RC | 1610 | | mvn RC, RC |
| 1473 | | ldr STR:RC, [KBASE, RC, lsl #2] // STALL: early RC. | 1611 | | ldr STR:RC, [KBASE, RC, lsl #2] // STALL: early RC. |
| 1474 | | checktab CARG2, ->vmeta_tgets | 1612 | | checktab CARG2, ->vmeta_tgets1 |
| 1475 | |->BC_TGETS_Z: | 1613 | |->BC_TGETS_Z: |
| 1476 | | // (TAB:RB =) TAB:CARG1 = GCtab *, STR:RC = GCstr *, RA = dst*8 | 1614 | | // (TAB:RB =) TAB:CARG1 = GCtab *, STR:RC = GCstr *, RA = dst*8 |
| 1477 | | ldr CARG3, TAB:CARG1->hmask | 1615 | | ldr CARG3, TAB:CARG1->hmask |
| @@ -1506,25 +1644,206 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 1506 | | mov CARG3, #0 // Optional clear of undef. value (during load stall). | 1644 | | mov CARG3, #0 // Optional clear of undef. value (during load stall). |
| 1507 | | mvn CARG4, #~LJ_TNIL | 1645 | | mvn CARG4, #~LJ_TNIL |
| 1508 | | cmp TAB:CARG1, #0 | 1646 | | cmp TAB:CARG1, #0 |
| 1509 | | beq <3 // No metatable: done. | 1647 | | beq <3 // No metatable: done. |
| 1510 | | ldrb CARG2, TAB:CARG1->nomm | 1648 | | ldrb CARG2, TAB:CARG1->nomm |
| 1511 | | tst CARG2, #1<<MM_index | 1649 | | tst CARG2, #1<<MM_index |
| 1512 | | bne <3 // 'no __index' flag set: done. | 1650 | | bne <3 // 'no __index' flag set: done. |
| 1513 | | b ->vmeta_tgets | 1651 | | b ->vmeta_tgets |
| 1514 | break; | 1652 | break; |
| 1515 | case BC_TGETB: | 1653 | case BC_TGETB: |
| 1516 | | NYI | 1654 | | decode_RB8 RB, INS |
| 1655 | | and RC, RC, #255 | ||
| 1656 | | // RA = dst*8, RB = table*8, RC = index | ||
| 1657 | | ldrd CARG12, [BASE, RB] | ||
| 1658 | | checktab CARG2, ->vmeta_tgetb // STALL: load CARG12. | ||
| 1659 | | ldr CARG3, TAB:CARG1->asize | ||
| 1660 | | ldr CARG4, TAB:CARG1->array | ||
| 1661 | | lsl CARG2, RC, #3 | ||
| 1662 | | cmp RC, CARG3 | ||
| 1663 | | ldrdlo CARG34, [CARG4, CARG2] | ||
| 1664 | | bhs ->vmeta_tgetb | ||
| 1665 | | ins_next1 // Overwrites RB! | ||
| 1666 | | checktp CARG4, LJ_TNIL | ||
| 1667 | | beq >5 | ||
| 1668 | |1: | ||
| 1669 | | ins_next2 | ||
| 1670 | | strd CARG34, [BASE, RA] | ||
| 1671 | | ins_next3 | ||
| 1672 | | | ||
| 1673 | |5: // Check for __index if table value is nil. | ||
| 1674 | | ldr TAB:CARG2, TAB:CARG1->metatable | ||
| 1675 | | cmp TAB:CARG2, #0 | ||
| 1676 | | beq <1 // No metatable: done. | ||
| 1677 | | ldrb CARG2, TAB:CARG2->nomm | ||
| 1678 | | tst CARG2, #1<<MM_index | ||
| 1679 | | bne <1 // 'no __index' flag set: done. | ||
| 1680 | | b ->vmeta_tgetb | ||
| 1517 | break; | 1681 | break; |
| 1518 | 1682 | ||
| 1519 | case BC_TSETV: | 1683 | case BC_TSETV: |
| 1520 | | NYI | 1684 | | decode_RB8 RB, INS |
| 1685 | | decode_RC8 RC, INS | ||
| 1686 | | // RA = src*8, RB = table*8, RC = key*8 | ||
| 1687 | | ldrd TAB:CARG12, [BASE, RB] | ||
| 1688 | | ldrd CARG34, [BASE, RC] | ||
| 1689 | | checktab CARG2, ->vmeta_tsetv // STALL: load CARG12. | ||
| 1690 | | checktp CARG4, LJ_TISNUM // Integer key? | ||
| 1691 | | ldreq CARG2, TAB:CARG1->array | ||
| 1692 | | ldreq CARG4, TAB:CARG1->asize | ||
| 1693 | | bne >9 | ||
| 1694 | | | ||
| 1695 | | add CARG2, CARG2, CARG3, lsl #3 | ||
| 1696 | | cmp CARG3, CARG4 // In array part? | ||
| 1697 | | ldrlo INS, [CARG2, #4] | ||
| 1698 | | bhs ->vmeta_tsetv | ||
| 1699 | | ins_next1 // Overwrites RB! | ||
| 1700 | | checktp INS, LJ_TNIL | ||
| 1701 | | ldrb INS, TAB:CARG1->marked | ||
| 1702 | | ldrd CARG34, [BASE, RA] | ||
| 1703 | | beq >5 | ||
| 1704 | |1: | ||
| 1705 | | tst INS, #LJ_GC_BLACK // isblack(table) | ||
| 1706 | | strd CARG34, [CARG2] | ||
| 1707 | | bne >7 | ||
| 1708 | |2: | ||
| 1709 | | ins_next2 | ||
| 1710 | | ins_next3 | ||
| 1711 | | | ||
| 1712 | |5: // Check for __newindex if previous value is nil. | ||
| 1713 | | ldr TAB:RA, TAB:CARG1->metatable | ||
| 1714 | | cmp TAB:RA, #0 | ||
| 1715 | | beq <1 // No metatable: done. | ||
| 1716 | | ldrb RA, TAB:RA->nomm | ||
| 1717 | | tst RA, #1<<MM_newindex | ||
| 1718 | | bne <1 // 'no __newindex' flag set: done. | ||
| 1719 | | ldr INS, [PC, #-4] // Restore RA. | ||
| 1720 | | decode_RA8 RA, INS | ||
| 1721 | | b ->vmeta_tsetv | ||
| 1722 | | | ||
| 1723 | |7: // Possible table write barrier for the value. Skip valiswhite check. | ||
| 1724 | | barrierback TAB:CARG1, INS, CARG3 | ||
| 1725 | | b <2 | ||
| 1726 | | | ||
| 1727 | |9: | ||
| 1728 | | checktp CARG4, LJ_TSTR // String key? | ||
| 1729 | | moveq STR:RC, CARG3 | ||
| 1730 | | beq ->BC_TSETS_Z | ||
| 1731 | | b ->vmeta_tsetv | ||
| 1521 | break; | 1732 | break; |
| 1522 | case BC_TSETS: | 1733 | case BC_TSETS: |
| 1734 | | decode_RB8 RB, INS | ||
| 1735 | | and RC, RC, #255 | ||
| 1736 | | // RA = src*8, RB = table*8, RC = str_const (~) | ||
| 1737 | | ldrd CARG12, [BASE, RB] | ||
| 1738 | | mvn RC, RC | ||
| 1739 | | ldr STR:RC, [KBASE, RC, lsl #2] // STALL: early RC. | ||
| 1740 | | checktab CARG2, ->vmeta_tsets1 | ||
| 1523 | |->BC_TSETS_Z: | 1741 | |->BC_TSETS_Z: |
| 1524 | | NYI | 1742 | | // (TAB:RB =) TAB:CARG1 = GCtab *, STR:RC = GCstr *, RA = dst*8 |
| 1743 | | ldr CARG3, TAB:CARG1->hmask | ||
| 1744 | | ldr CARG4, STR:RC->hash | ||
| 1745 | | ldr NODE:INS, TAB:CARG1->node | ||
| 1746 | | mov TAB:RB, TAB:CARG1 | ||
| 1747 | | and CARG3, CARG3, CARG4 // idx = str->hash & tab->hmask | ||
| 1748 | | add CARG3, CARG3, CARG3, lsl #1 | ||
| 1749 | | add NODE:INS, NODE:INS, CARG3, lsl #3 // node = tab->node + idx*3*8 | ||
| 1750 | |1: | ||
| 1751 | | ldrd CARG12, NODE:INS->key // STALL: early NODE:INS. | ||
| 1752 | | ldr CARG4, NODE:INS->val.it | ||
| 1753 | | ldr NODE:CARG3, NODE:INS->next | ||
| 1754 | | cmp CARG1, STR:RC | ||
| 1755 | | checktpeq CARG2, LJ_TSTR | ||
| 1756 | | bne >5 | ||
| 1757 | | ldrb CARG2, TAB:RB->marked | ||
| 1758 | | checktp CARG4, LJ_TNIL // Key found, but nil value? | ||
| 1759 | | ldrd CARG34, [BASE, RA] | ||
| 1760 | | beq >4 | ||
| 1761 | |2: | ||
| 1762 | | tst CARG2, #LJ_GC_BLACK // isblack(table) | ||
| 1763 | | strd CARG34, NODE:INS->val | ||
| 1764 | | bne >7 | ||
| 1765 | |3: | ||
| 1766 | | ins_next | ||
| 1767 | | | ||
| 1768 | |4: // Check for __newindex if previous value is nil. | ||
| 1769 | | ldr TAB:CARG1, TAB:RB->metatable | ||
| 1770 | | cmp TAB:CARG1, #0 | ||
| 1771 | | beq <2 // No metatable: done. | ||
| 1772 | | ldrb CARG1, TAB:CARG1->nomm | ||
| 1773 | | tst CARG1, #1<<MM_newindex | ||
| 1774 | | bne <2 // 'no __newindex' flag set: done. | ||
| 1775 | | b ->vmeta_tsets | ||
| 1776 | | | ||
| 1777 | |5: // Follow hash chain. | ||
| 1778 | | movs NODE:INS, NODE:CARG3 | ||
| 1779 | | bne <1 | ||
| 1780 | | // End of hash chain: key not found, add a new one. | ||
| 1781 | | | ||
| 1782 | | // But check for __newindex first. | ||
| 1783 | | ldr TAB:CARG1, TAB:RB->metatable | ||
| 1784 | | mov CARG3, TMPDp | ||
| 1785 | | str PC, SAVE_PC | ||
| 1786 | | cmp TAB:CARG1, #0 // No metatable: continue. | ||
| 1787 | | str BASE, L->base | ||
| 1788 | | ldrbne CARG2, TAB:CARG1->nomm | ||
| 1789 | | mov CARG1, L | ||
| 1790 | | beq >6 | ||
| 1791 | | tst CARG2, #1<<MM_newindex | ||
| 1792 | | beq ->vmeta_tsets // 'no __newindex' flag NOT set: check. | ||
| 1793 | |6: | ||
| 1794 | | mvn CARG4, #~LJ_TSTR | ||
| 1795 | | str STR:RC, TMPDlo | ||
| 1796 | | mov CARG2, TAB:RB | ||
| 1797 | | str CARG4, TMPDhi | ||
| 1798 | | bl extern lj_tab_newkey // (lua_State *L, GCtab *t, TValue *k) | ||
| 1799 | | // Returns TValue *. | ||
| 1800 | | ldr BASE, L->base | ||
| 1801 | | ldrd CARG34, [BASE, RA] | ||
| 1802 | | strd CARG34, [CRET1] | ||
| 1803 | | b <3 // No 2nd write barrier needed. | ||
| 1804 | | | ||
| 1805 | |7: // Possible table write barrier for the value. Skip valiswhite check. | ||
| 1806 | | barrierback TAB:CARG1, CARG2, CARG3 | ||
| 1807 | | b <3 | ||
| 1525 | break; | 1808 | break; |
| 1526 | case BC_TSETB: | 1809 | case BC_TSETB: |
| 1527 | | NYI | 1810 | | decode_RB8 RB, INS |
| 1811 | | and RC, RC, #255 | ||
| 1812 | | // RA = src*8, RB = table*8, RC = index | ||
| 1813 | | ldrd CARG12, [BASE, RB] | ||
| 1814 | | checktab CARG2, ->vmeta_tsetb // STALL: load CARG12. | ||
| 1815 | | ldr CARG3, TAB:CARG1->asize | ||
| 1816 | | ldr RB, TAB:CARG1->array | ||
| 1817 | | lsl CARG2, RC, #3 | ||
| 1818 | | cmp RC, CARG3 | ||
| 1819 | | ldrdlo CARG34, [CARG2, RB]! | ||
| 1820 | | bhs ->vmeta_tsetb | ||
| 1821 | | ins_next1 // Overwrites RB! | ||
| 1822 | | checktp CARG4, LJ_TNIL | ||
| 1823 | | ldrb INS, TAB:CARG1->marked | ||
| 1824 | | ldrd CARG34, [BASE, RA] | ||
| 1825 | | beq >5 | ||
| 1826 | |1: | ||
| 1827 | | tst INS, #LJ_GC_BLACK // isblack(table) | ||
| 1828 | | strd CARG34, [CARG2] | ||
| 1829 | | bne >7 | ||
| 1830 | |2: | ||
| 1831 | | ins_next2 | ||
| 1832 | | ins_next3 | ||
| 1833 | | | ||
| 1834 | |5: // Check for __newindex if previous value is nil. | ||
| 1835 | | ldr TAB:RA, TAB:CARG1->metatable | ||
| 1836 | | cmp TAB:RA, #0 | ||
| 1837 | | beq <1 // No metatable: done. | ||
| 1838 | | ldrb RA, TAB:RA->nomm | ||
| 1839 | | tst RA, #1<<MM_newindex | ||
| 1840 | | bne <1 // 'no __newindex' flag set: done. | ||
| 1841 | | ldr INS, [PC, #-4] // Restore INS. | ||
| 1842 | | b ->vmeta_tsetb | ||
| 1843 | | | ||
| 1844 | |7: // Possible table write barrier for the value. Skip valiswhite check. | ||
| 1845 | | barrierback TAB:CARG1, INS, CARG3 | ||
| 1846 | | b <2 | ||
| 1528 | break; | 1847 | break; |
| 1529 | 1848 | ||
| 1530 | case BC_TSETM: | 1849 | case BC_TSETM: |
