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 | |
parent | a7874cb29970b72fec106e6a8a4f22c42a15e580 (diff) | |
download | luajit-314995aebf20ce47f854cdab3722085c944f9e74.tar.gz luajit-314995aebf20ce47f854cdab3722085c944f9e74.tar.bz2 luajit-314995aebf20ce47f854cdab3722085c944f9e74.zip |
ARM: Finish basic table indexing and add metamethod handlers.
-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: |