Skip to content

Commit cb05ed7

Browse files
committed
chore: quickjs PoC
1 parent 4ee509c commit cb05ed7

File tree

3 files changed

+85
-0
lines changed

3 files changed

+85
-0
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@
116116
"json-schema-to-typescript": "^11.0.1",
117117
"node-stdlib-browser": "^1.2.0",
118118
"prettier": "^2.3.2",
119+
"quickjs-emscripten": "^0.23.0",
119120
"rimraf": "^3.0.2",
120121
"smartweave": "0.4.48",
121122
"ts-jest": "^28.0.7",

tools/quickjs.mjs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { getQuickJS, newQuickJSAsyncWASMModule } from "quickjs-emscripten";
2+
3+
// the example smart contract code loaded from Arweave blockchain
4+
const code = `
5+
function handle(state, action) {
6+
console.log('handle before timeout');
7+
const timeoutResult = timeout(100); // no 'await' here, because fuck logic
8+
console.log('handle after timeout:', timeoutResult);
9+
10+
const someShit = {};
11+
12+
for (i = 0; i < 100000; i++) {
13+
someShit[""+i] = i*i;
14+
}
15+
16+
return 1;
17+
}
18+
`.trim();
19+
20+
async function main() {
21+
22+
// 1. creating the QJS context
23+
const QuickJS = await newQuickJSAsyncWASMModule();
24+
const runtime = QuickJS.newRuntime();
25+
// "Should be enough for everyone" -- attributed to B. Gates
26+
// runtime.setMemoryLimit(1024 * 640);
27+
// Limit stack size
28+
runtime.setMaxStackSize(1024 * 320);
29+
let interruptCycles = 0
30+
runtime.setInterruptHandler((runtime) => { interruptCycles++ });
31+
32+
const vm = runtime.newContext();
33+
34+
// 2. registering APIs
35+
const logHandle = vm.newFunction("log", (...args) => {
36+
const nativeArgs = args.map(vm.dump)
37+
console.log("QuickJS:", ...nativeArgs)
38+
});
39+
40+
const consoleHandle = vm.newObject();
41+
vm.setProp(consoleHandle, "log", logHandle);
42+
vm.setProp(vm.global, "console", consoleHandle);
43+
consoleHandle.dispose();
44+
logHandle.dispose();
45+
46+
const timeoutHandle = vm.newAsyncifiedFunction("timeout", async (msHandle) => {
47+
const ms = vm.getNumber(msHandle);
48+
console.log("omg, that's an async shit!");
49+
await timeout(1000);
50+
return vm.newString("check your head!");
51+
})
52+
timeoutHandle.consume((fn) => vm.setProp(vm.global, "timeout", fn))
53+
54+
// 4. calling the "handle" function
55+
const result = await vm.evalCodeAsync(`(() => {
56+
${code}
57+
return handle();
58+
})()`);
59+
60+
if (result.error) {
61+
console.log('Execution failed:', vm.dump(result.error));
62+
result.error.dispose();
63+
} else {
64+
const parsedResult = vm.unwrapResult(result).consume(vm.getNumber);
65+
console.log("result", parsedResult);
66+
console.log("Cycles", interruptCycles);
67+
}
68+
69+
vm.dispose();
70+
runtime.dispose();
71+
}
72+
73+
main().finally();
74+
75+
function timeout(delay) {
76+
return new Promise(function (resolve) {
77+
setTimeout(resolve, delay);
78+
});
79+
}

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6623,6 +6623,11 @@ quick-lru@^5.1.1:
66236623
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932"
66246624
integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==
66256625

6626+
quickjs-emscripten@^0.23.0:
6627+
version "0.23.0"
6628+
resolved "https://registry.yarnpkg.com/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz#94f412d0ee5f3021fc12ddf6c0b00bd8ce0d28b9"
6629+
integrity sha512-CIP+NDRYDDqbT3cTiN8Bon1wsZ7IgISVYCJHYsPc86oxszpepVMPXFfttyQgn1u1okg1HPnCnM7Xv1LrCO/VmQ==
6630+
66266631
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0:
66276632
version "2.1.0"
66286633
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"

0 commit comments

Comments
 (0)