diff --git a/quickjs/ckb_module.c b/quickjs/ckb_module.c index a05aa9d..9301c8f 100644 --- a/quickjs/ckb_module.c +++ b/quickjs/ckb_module.c @@ -5,6 +5,7 @@ #include "ckb_syscalls.h" #include "molecule/blockchain.h" #include "molecule/molecule_reader.h" +#include "ckb_cell_fs.h" // For syscalls supporting partial loading, the arguments are described as: // argument 1: index @@ -460,6 +461,18 @@ static JSValue syscall_current_memory(JSContext *ctx, JSValueConst this_value, i return JS_NewUint32(ctx, (uint32_t)size); } +static JSValue mount(JSContext *ctx, JSValueConst this_value, int argc, JSValueConst *argv) { + JSValue buf = syscall_load_cell_data(ctx, this_value, argc, argv); + size_t psize = 0; + uint8_t *addr = JS_GetArrayBuffer(ctx, &psize, buf); + int err = ckb_load_fs(addr, psize); + if (err != 0) { + return JS_EXCEPTION; + } else { + return JS_UNDEFINED; + } +} + /* TODO: // who allocated the memory indicated by aligned_addr? @@ -501,6 +514,8 @@ int js_init_module_ckb(JSContext *ctx) { JS_NewCFunction(ctx, syscall_get_memory_limit, "get_memory_limit", 0)); JS_SetPropertyStr(ctx, ckb, "current_memory", JS_NewCFunction(ctx, syscall_current_memory, "current_memory", 0)); + JS_SetPropertyStr(ctx, ckb, "mount", + JS_NewCFunction(ctx, mount, "mount", 3)); JS_SetPropertyStr(ctx, ckb, "SOURCE_INPUT", JS_NewInt64(ctx, CKB_SOURCE_INPUT)); JS_SetPropertyStr(ctx, ckb, "SOURCE_OUTPUT", JS_NewInt64(ctx, CKB_SOURCE_OUTPUT)); JS_SetPropertyStr(ctx, ckb, "SOURCE_CELL_DEP", JS_NewInt64(ctx, CKB_SOURCE_CELL_DEP)); diff --git a/quickjs/qjs.c b/quickjs/qjs.c index 65bcd6b..f8af4ea 100644 --- a/quickjs/qjs.c +++ b/quickjs/qjs.c @@ -123,6 +123,20 @@ void js_std_dump_error(JSContext *ctx) { JS_FreeValue(ctx, exception_val); } +void js_std_loop(JSContext *ctx) { + JSContext *ctx1; + int err; + for(;;) { + err = JS_ExecutePendingJob(JS_GetRuntime(ctx), &ctx1); + if (err <= 0) { + if (err < 0) { + js_std_dump_error(ctx1); + } + break; + } + } +} + int compile_from_file(JSContext *ctx) { enable_local_access(1); char buf[1024 * 512]; @@ -304,18 +318,23 @@ int main(int argc, const char **argv) { switch (type) { case RunJsWithCode: err = eval_buf(ctx, argv[1], strlen(argv[1]), "", 0); + js_std_loop(ctx); break; case RunJsWithFile: err = run_from_cell_data(ctx, false); + js_std_loop(ctx); break; case RunJsWithFileSystem: err = run_from_cell_data(ctx, true); + js_std_loop(ctx); break; case RunJsWithDbgFile: err = run_from_local_file(ctx, false); + js_std_loop(ctx); break; case RunJsWithDbgFileSystem: err = run_from_local_file(ctx, true); + js_std_loop(ctx); break; case CompileWithFile: JS_SetModuleLoaderFunc(rt, NULL, js_module_dummy_loader, NULL); diff --git a/tests/ckb_js_tests/Makefile b/tests/ckb_js_tests/Makefile index 26f605e..09927c9 100644 --- a/tests/ckb_js_tests/Makefile +++ b/tests/ckb_js_tests/Makefile @@ -36,6 +36,10 @@ file_system: build/testdata_fs_modules.bin syscall: cargo run --bin syscall | $(CKB_DEBUGGER) --tx-file=- -s lock +fs_mount: + cd test_data/fs_module_mount && lua ../../../../tools/fs.lua pack ../../../../build/fib_module.bin fib_module.js + cargo run --bin module_mount | ${CKB_DEBUGGER} --tx-file=- -s lock + install-lua: sudo apt install lua5.4 diff --git a/tests/ckb_js_tests/src/bin/module_mount.rs b/tests/ckb_js_tests/src/bin/module_mount.rs new file mode 100644 index 0000000..c76844b --- /dev/null +++ b/tests/ckb_js_tests/src/bin/module_mount.rs @@ -0,0 +1,9 @@ +use ckb_js_tests::read_tx_template; + +pub fn main() -> Result<(), Box> { + let tx = read_tx_template("templates/fs_module_mount.json")?; + + let json = serde_json::to_string_pretty(&tx).unwrap(); + println!("{}", json); + Ok(()) +} diff --git a/tests/ckb_js_tests/templates/fs_module_mount.json b/tests/ckb_js_tests/templates/fs_module_mount.json new file mode 100644 index 0000000..28d015e --- /dev/null +++ b/tests/ckb_js_tests/templates/fs_module_mount.json @@ -0,0 +1,75 @@ +{ + "mock_info": { + "inputs": [ + { + "output": { + "capacity": "0x10000000", + "lock": { + "args": "0x0000{{ ref_type js-code-file }}01", + "code_hash": "0x{{ ref_type ckb-js-vm }}", + "hash_type": "type" + }, + "type": null + }, + "data": "0x" + } + ], + "cell_deps": [ + { + "output": { + "capacity": "0x10000000", + "lock": { + "args": "0x00AE9DF3447C404A645BC48BEA4B7643B95AC5C3AE", + "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "hash_type": "data1" + }, + "type": "{{ def_type ckb-js-vm }}" + }, + "data": "0x{{ data ../../../build/ckb-js-vm }}" + }, + { + "output": { + "capacity": "0x10000000", + "lock": { + "args": "0x00AE9DF3447C404A645BC48BEA4B7643B95AC5C3AE", + "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "hash_type": "data1" + }, + "type": "{{ def_type js-code-file }}" + }, + "data": "0x{{ data ../test_data/fs_module_mount/main.js }}" + }, + { + "output": { + "capacity": "0x10000000", + "lock": { + "args": "0x00AE9DF3447C404A645BC48BEA4B7643B95AC5C3AE", + "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "hash_type": "data1" + }, + "type": "{{ def_type fib_module }}" + }, + "data": "0x{{ data ../../../build/fib_module.bin }}" + } + ], + "header_deps": [] + }, + "tx": { + "outputs": [ + { + "capacity": "0x0", + "lock": { + "args": "0x00AE9DF3447C404A645BC48BEA4B7643B95AC5C3AE", + "code_hash": "0x{{ ref_type ckb-js-vm }}", + "hash_type": "type" + } + } + ], + "witnesses": [ + "0x55000000100000005500000055000000410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ], + "outputs_data": [ + "0x" + ] + } + } diff --git a/tests/ckb_js_tests/test_data/fs_module_mount/fib_module.js b/tests/ckb_js_tests/test_data/fs_module_mount/fib_module.js new file mode 100644 index 0000000..6a81071 --- /dev/null +++ b/tests/ckb_js_tests/test_data/fs_module_mount/fib_module.js @@ -0,0 +1,10 @@ +/* fib module */ +export function fib(n) +{ + if (n <= 0) + return 0; + else if (n == 1) + return 1; + else + return fib(n - 1) + fib(n - 2); +} diff --git a/tests/ckb_js_tests/test_data/fs_module_mount/main.js b/tests/ckb_js_tests/test_data/fs_module_mount/main.js new file mode 100644 index 0000000..a9cfe1b --- /dev/null +++ b/tests/ckb_js_tests/test_data/fs_module_mount/main.js @@ -0,0 +1,11 @@ +/* example of JS module */ + +ckb.mount(2, 3) + +import('./fib_module.js') + .then((module) => { + console.log("fib(10)=", module.fib(10)) + }) + .catch((err) => { + console.log(err) + });