Skip to content

Commit

Permalink
fix: table supported circular dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
X3ZvaWQ committed Jan 22, 2024
1 parent fa77464 commit 9ee4260
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 85 deletions.
1 change: 1 addition & 0 deletions src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import LuaGlobal from './global';
const getContextProxy = (global: LuaGlobal): LuaContext => {
return new Proxy(global, {
get: (target: LuaGlobal, key) => {
// TODO: implement iterator for all global variables
if (key === Symbol.iterator) {
return {
next: () => {
Expand Down
4 changes: 2 additions & 2 deletions src/thread.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ export default class LuaThread {
// lua的table太奔放了 甚至键可以是自身 js里可以匹配的数据结构只有Map
public getTable(index: number, options: GetValueOptions = {}): Record<string | number, any> {
const table = new Map();
const needTransform = !options.refs;
if (!options.refs) {
options.refs = new Map<number, any>();
}
Expand All @@ -342,8 +343,7 @@ export default class LuaThread {
this.pop();
}

// Map to object/array
return mapTransform(table);
return needTransform ? mapTransform(table) : table;
}

public call(name: string, ...args: any[]): MultiReturn {
Expand Down
40 changes: 15 additions & 25 deletions test/debug.mjs
Original file line number Diff line number Diff line change
@@ -1,29 +1,19 @@
import { Lua } from '../dist/index.js';

// This file was created as a sandbox to test and debug on vscode
const lua = await Lua.create({ openStandardLibraries: true });
lua.global.loadLibrary();
lua.ctx.t = { test: 1 };
lua.ctx.tet = () => {
return lua.ctx.t;
};
await lua.doString('return tet(2)');
const value = await lua.doString('return tet(2)');
console.log(value);
// await lua.doString('print(getmetatable(p))');
// await lua.doString('print(getmetatable(p).__index)');
// await lua.doString('print(getmetatable(p).__index(x))');
// await lua.doString('print(p.x)');
// lua.ctx.test = () => {
// return {
// aaaa: 1,
// bbb: 'hey',
// test() {
// return 22;
// },
// };
// };
const lua = await Lua.create();

// await lua.doString('print(test)');
// await lua.doString('print(test())');
// await lua.doString('print(test().test())');
const a = { name: 'a' };
const b = { name: 'b' };
b.a = a;
a.b = b;

lua.global.pushValue(a);
// lua.global.luaApi.lua_setglobal(lua.global.address, 'x');
// lua.doStringSync(`
// print(x.b.a.b.a)
// `);
const res = lua.global.getValue(-1);

//console.log(res.b.a);
console.log(res);
118 changes: 60 additions & 58 deletions test/engine.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -354,76 +354,78 @@ describe('Engine', () => {
expect(finalValue).to.be.equal(20);
});

// it('get memory with allocation tracing should succeeds', async () => {
// const engine = await getEngine({ traceAllocations: true });
// expect(engine.global.getMemoryUsed()).to.be.greaterThan(0);
// });
it('get memory with allocation tracing should succeeds', async () => {
const lua = await Lua.create({ traceAllocations: true });
expect(lua.global.getMemoryUsed()).to.be.greaterThan(0);
});

// it('get memory should return correct', async () => {
// const engine = await getEngine({ traceAllocations: true });
it('get memory should return correct', async () => {
const lua = await Lua.create({ traceAllocations: true });

// const totalMemory = await engine.doString(`
// collectgarbage()
// local x = 10
// local batata = { dawdwa = 1 }
// return collectgarbage('count') * 1024
// `);

// expect(engine.global.getMemoryUsed()).to.be.equal(totalMemory);
// });
const totalMemory = await lua.doString(`
collectgarbage()
local x = 10
local batata = { dawdwa = 1 }
return collectgarbage('count') * 1024
`);

// it('get memory without tracing should throw', async () => {
// const engine = await getEngine({ traceAllocations: false });
expect(lua.global.getMemoryUsed()).to.be.equal(totalMemory);
});

// expect(() => engine.global.getMemoryUsed()).to.throw();
// });
it('get memory without tracing should throw', async () => {
const lua = await Lua.create({ traceAllocations: false });

// it('limit memory use causes program loading failure succeeds', async () => {
// const engine = await getEngine({ traceAllocations: true });
// engine.global.setMemoryMax(engine.global.getMemoryUsed());
// expect(() => {
// engine.global.loadString(`
// local a = 10
// local b = 20
// return a + b
// `);
// }).to.throw('not enough memory');
expect(() => lua.global.getMemoryUsed()).to.throw();
});

// // Remove the limit and retry
// engine.global.setMemoryMax(undefined);
// engine.global.loadString(`
// local a = 10
// local b = 20
// return a + b
// `);
// });
it('limit memory use causes program loading failure succeeds', async () => {
const lua = await Lua.create({ traceAllocations: true });
lua.global.setMemoryMax(lua.global.getMemoryUsed());
expect(() => {
lua.global.loadString(`
local a = 10
local b = 20
return a + b
`);
}).to.throw('not enough memory');

// Remove the limit and retry
lua.global.setMemoryMax(undefined);
lua.global.loadString(`
local a = 10
local b = 20
return a + b
`);
});

// it('limit memory use causes program runtime failure succeeds', async () => {
// const engine = await getEngine({ traceAllocations: true });
// engine.global.loadString(`
// local tab = {}
// for i = 1, 50, 1 do
// tab[i] = i
// end
// `);
// engine.global.setMemoryMax(engine.global.getMemoryUsed());
it('limit memory use causes program runtime failure succeeds', async () => {
const lua = await Lua.create({ traceAllocations: true });
lua.global.loadString(`
local tab = {}
for i = 1, 50, 1 do
tab[i] = i
end
`);
lua.global.setMemoryMax(lua.global.getMemoryUsed());

// await expect(engine.global.run()).to.eventually.be.rejectedWith('not enough memory');
// });
await expect(lua.global.run()).to.eventually.be.rejectedWith('not enough memory');
});

// it('table supported circular dependencies', async () => {
// const engine = await getEngine();
it('table supported circular dependencies', async () => {
const lua = await Lua.create();

// const a = { name: 'a' };
// const b = { name: 'b' };
// b.a = a;
// a.b = b;
const a = { name: 'a' };
const b = { name: 'b' };
b.a = a;
a.b = b;

// engine.global.pushValue(a);
// const res = engine.global.getValue(-1);
lua.global.pushValue(a);
const res = lua.global.getValue(-1);
console.log(res.b.a);
console.log(res);

// expect(res.b.a).to.be.eql(res);
// });
expect(res.b.a).to.be.eql(res);
});

// it('wrap a js object (with metatable)', async () => {
// const engine = await getEngine();
Expand Down

0 comments on commit 9ee4260

Please sign in to comment.