diff options
-rw-r--r-- | README.md | 12 | ||||
-rw-r--r-- | src/lvm.js | 4 | ||||
-rw-r--r-- | tests/ltm.js | 59 |
3 files changed, 67 insertions, 8 deletions
@@ -8,20 +8,17 @@ - [ ] Basic types representation: - [x] nil - [x] boolean + - [x] table + - [x] function + - [ ] string (8-bit clean) - [ ] number (32-bit ?) - [ ] integer - [ ] float - - [ ] string (8-bit clean) - - [ ] table - - [ ] function - [ ] userdata - [ ] thread - [ ] Tag Methods - [x] `__index` - [x] `__newindex` - - [x] `__gc` (unavailable) - - [x] `__mode` (unavailable) - - [ ] `__len` - [x] `__add` - [x] `__sub` - [x] `__mul` @@ -39,6 +36,9 @@ - [x] `__eq` - [x] `__lt` - [x] `__le` + - [x] `__gc` (unavailable) + - [x] `__mode` (unavailable) + - [x] `__len` - [ ] `__concat` - [ ] `__call` - [ ] `__tostring` @@ -854,8 +854,8 @@ const luaV_objlen = function(L, ra, rb) { let tm; switch(rb.ttype()) { case CT.LUA_TTABLE: { - tm = rb.value.metatable; - if (tm) break; + tm = ltm.luaT_gettmbyobj(L, rb, TMS.TM_LEN); + if (!tm.ttisnil()) break; L.stack[ra] = rb.luaH_getn(); return; } diff --git a/tests/ltm.js b/tests/ltm.js index 8a20f67..00ea0e6 100644 --- a/tests/ltm.js +++ b/tests/ltm.js @@ -1137,4 +1137,63 @@ test('__unm, __bnot', function (t) { "hello", "Program output is correct" ); +}); + + +test('__len', function (t) { + let luaCode = ` + local mt = { + __len = function (a) + return "hello" + end + } + + local t = {} + + -- setmetatable(t, mt) + + return #t + `, L; + + t.plan(4); + + t.comment("Running following code: \n" + luaCode); + + // main <hello.lua:0,0> (7 instructions at 0x7f91f0600ac0) + // 0+ params, 3 slots, 1 upvalue, 2 locals, 1 constant, 1 function + // 1 [1] NEWTABLE 0 0 1 + // 2 [4] CLOSURE 1 0 ; 0x7f91f0600d10 + // 3 [4] SETTABLE 0 -1 1 ; "__len" - + // 4 [7] NEWTABLE 1 0 0 + // 5 [11] LEN 2 1 <=== We stop here + // 6 [11] RETURN 2 2 + // 7 [11] RETURN 0 1 + // + // ... + + t.doesNotThrow(function () { + L = getState(luaCode); + }, "Bytecode parsed without errors"); + + L.stack[0].p.code[4].breakpoint = true; + + t.doesNotThrow(function () { + ldo.luaD_call(L, 0, -1); + }, "First part of the program executed without errors"); + + L.ci.pcOff--; + L.stack[0].p.code[4].breakpoint = false; + + t.comment("We manually set t's metatable to mt"); + L.stack[2].metatable = L.stack[1]; + + t.doesNotThrow(function () { + VM.luaV_execute(L); + }, "Second part of the program executed without errors"); + + t.strictEqual( + L.stack[L.top - 1].value, + "hello", + "Program output is correct" + ); });
\ No newline at end of file |