Skip to content

Commit

Permalink
Allows mounting on a specific path (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
mohanson authored Jan 23, 2025
1 parent e8b889d commit 97dc827
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 19 deletions.
7 changes: 4 additions & 3 deletions docs/syscalls.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,12 @@ and `index`.

Example:
```js
ckb.mount(index, source)
ckb.mount(index, source, mount_point)
```

Arguments: source (the source of the cell to load), index (the index of the cell
to load within all cells with source `source`)
Arguments: source (the source of the cell to load), index (the index of the cellt
to load within all cells with source `source`), mount_point (the file system will
be mounted at this path, usually "/")

Return value(s): None

Expand Down
5 changes: 3 additions & 2 deletions libc/ckb_cell_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ typedef struct CellFileSystemNode {
uint32_t count;
FSEntry *files;
void *start;
const char *prefix;
} CellFileSystemNode;

typedef struct CellFileSystem {
Expand All @@ -36,9 +37,9 @@ int get_file(const CellFileSystem *fs, const char *filename, FSFile **f);

int ckb_get_file(const char *filename, FSFile **file);

int load_fs(CellFileSystem **fs, void *buf, uint64_t buflen);
int load_fs(CellFileSystem **fs, const char *prefix, void *buf, uint64_t buflen);

int ckb_load_fs(void *buf, uint64_t buflen);
int ckb_load_fs(const char *prefix, void *buf, uint64_t buflen);

void ckb_reset_fs();

Expand Down
25 changes: 21 additions & 4 deletions libc/src/ckb_cell_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,21 @@ int get_file(const CellFileSystem *fs, const char *filename, FSFile **f) {
CellFileSystem *cfs = (CellFileSystem *)fs;
CellFileSystemNode *node = cfs->current;
while (node != NULL) {
if (strncmp(node->prefix + 1, filename, strlen(node->prefix) - 1) != 0) {
if (cfs->next == NULL) {
break;
}
cfs = cfs->next;
node = cfs->current;
continue;
}
const char *basename = filename + strlen(node->prefix) - 1;
if (node->prefix[strlen(node->prefix) - 1] != '/') {
basename++;
}
for (uint32_t i = 0; i < node->count; i++) {
FSEntry entry = node->files[i];
if (strcmp(filename, node->start + entry.filename.offset) == 0) {
if (strcmp(basename, node->start + entry.filename.offset) == 0) {
// TODO: check the memory addresses are legal
file->filename = filename;
file->size = entry.content.length;
Expand All @@ -41,7 +53,7 @@ int get_file(const CellFileSystem *fs, const char *filename, FSFile **f) {

int ckb_get_file(const char *filename, FSFile **file) { return get_file(CELL_FILE_SYSTEM, filename, file); }

int load_fs(CellFileSystem **fs, void *buf, uint64_t buflen) {
int load_fs(CellFileSystem **fs, const char *prefix, void *buf, uint64_t buflen) {
if (fs == NULL || buf == NULL) {
return -1;
}
Expand All @@ -57,6 +69,7 @@ int load_fs(CellFileSystem **fs, void *buf, uint64_t buflen) {
return -1;
}

node->prefix = prefix;
node->count = *(uint32_t *)buf;
if (node->count == 0) {
node->files = NULL;
Expand All @@ -79,6 +92,10 @@ int load_fs(CellFileSystem **fs, void *buf, uint64_t buflen) {
for (uint32_t i = 0; i < node->count; i++) {
FSEntry entry = entries[i];
node->files[i] = entry;
char *filename = node->start + entry.filename.offset;
if (filename[0] == '.' || filename[0] == '/' || filename[0] == '\\' || filename[0] == '~') {
return -2;
}
}

newfs->next = *fs;
Expand All @@ -87,8 +104,8 @@ int load_fs(CellFileSystem **fs, void *buf, uint64_t buflen) {
return 0;
}

int ckb_load_fs(void *buf, uint64_t buflen) {
int ret = load_fs(&CELL_FILE_SYSTEM, buf, buflen);
int ckb_load_fs(const char *prefix, void *buf, uint64_t buflen) {
int ret = load_fs(&CELL_FILE_SYSTEM, prefix, buf, buflen);
return ret;
}

Expand Down
22 changes: 17 additions & 5 deletions src/ckb_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -606,16 +606,28 @@ static JSValue syscall_load_block_extension(JSContext *ctx, JSValueConst this_va
}

static JSValue mount(JSContext *ctx, JSValueConst this_value, int argc, JSValueConst *argv) {
JSValue buf = syscall_load_cell_data(ctx, this_value, argc, argv);
JSValue buf = syscall_load_cell_data(ctx, this_value, 2, argv);
if (JS_IsException(buf)) {
return JS_EXCEPTION;
}
const char *prefix = JS_ToCString(ctx, argv[2]);
if (prefix[0] != '/') {
ThrowError(ctx, QJS_ERROR_MOUNT, "ckb.mount mount_point should starts with /");
return JS_EXCEPTION;
}
size_t psize = 0;
uint8_t *addr = JS_GetArrayBuffer(ctx, &psize, buf);
int err = ckb_load_fs(addr, psize);
int err = ckb_load_fs(prefix, addr, psize);
if (err != 0) {
ThrowError(ctx, QJS_ERROR_MOUNT, "ckb.mount failed");
return JS_EXCEPTION;
switch (err) {
case -2:
ThrowError(ctx, QJS_ERROR_MOUNT, "ckb.mount found illegal file name");
return JS_EXCEPTION;
case -1:
default:
ThrowError(ctx, QJS_ERROR_MOUNT, "ckb.mount failed");
return JS_EXCEPTION;
}
} else {
return JS_UNDEFINED;
}
Expand Down Expand Up @@ -793,7 +805,7 @@ static const JSCFunctionListEntry js_ckb_funcs[] = {
JS_CFUNC_DEF("wait", 1, syscall_wait),
JS_CFUNC_DEF("processId", 0, syscall_process_id),
JS_CFUNC_DEF("loadBlockExtension", 3, syscall_load_block_extension),
JS_CFUNC_DEF("mount", 2, mount),
JS_CFUNC_DEF("mount", 3, mount),
JS_CFUNC_DEF("evalJsScript", 2, js_eval_script),
JS_CFUNC_DEF("loadJsScript", 2, js_load_script),
JS_CFUNC_DEF("loadFile", 1, js_load_file),
Expand Down
2 changes: 1 addition & 1 deletion src/qjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ static int eval_buf(JSContext *ctx, const void *buf, int buf_len, const char *fi
}

int run_from_file_system_buf(JSContext *ctx, char *buf, size_t buf_size) {
int err = ckb_load_fs(buf, buf_size);
int err = ckb_load_fs("/", buf, buf_size);
CHECK(err);

FSFile *init_file = NULL;
Expand Down
8 changes: 6 additions & 2 deletions tests/ckb_js_tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ FS_PACKER = node $(ROOT_DIR)/../../tools/fs-packer/dist/index.js

BYTECODE_DIR = $(ROOT_DIR)/../../build/bytecode
JS_SOURCE_DIR = $(ROOT_DIR)/test_data/fs_module_mount
BYTECODE_FILES = $(BYTECODE_DIR)/index.bc $(BYTECODE_DIR)/fib_module.bc
BYTECODE_FILES = index.bc fib_module.bc a/fib_module.bc b/fib_module.bc

define compile_js_to_bc
$(CKB_DEBUGGER) --read-file $(1) --bin $(BIN_PATH) -- -c | \
Expand All @@ -25,14 +25,18 @@ all: out \

out:
@mkdir -p $(ROOT_DIR)/../../build/bytecode
@mkdir -p $(ROOT_DIR)/../../build/bytecode/a
@mkdir -p $(ROOT_DIR)/../../build/bytecode/b

cargo_test:
cargo test

fs_bytecode:
$(call compile_js_to_bc,$(JS_SOURCE_DIR)/index.js,$(BYTECODE_DIR)/index.bc)
$(call compile_js_to_bc,$(JS_SOURCE_DIR)/fib_module.js,$(BYTECODE_DIR)/fib_module.bc)
cd $(BYTECODE_DIR) && $(FS_PACKER) pack fs_modules_bc.fs $(notdir $(BYTECODE_FILES))
cp $(BYTECODE_DIR)/fib_module.bc $(BYTECODE_DIR)/a/fib_module.bc
cp $(BYTECODE_DIR)/fib_module.bc $(BYTECODE_DIR)/b/fib_module.bc
cd $(BYTECODE_DIR) && $(FS_PACKER) pack fs_modules_bc.fs $(BYTECODE_FILES)
$(CKB_DEBUGGER) --max-cycles $(MAX_CYCLES) \
--read-file $(BYTECODE_DIR)/fs_modules_bc.fs \
--bin $(BIN_PATH) -- -f -r 2>&1 | \
Expand Down
4 changes: 4 additions & 0 deletions tests/ckb_js_tests/test_data/fs_module_mount/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
/* example of JS module */
import * as module from './fib_module.js';
import * as module_a from './a/fib_module.js';
import * as module_b from './b/fib_module.js';

console.log(`fib(10)=${module.fib(10)}!`);
console.log(`fib(10)=${module_a.fib(10)}!`);
console.log(`fib(10)=${module_b.fib(10)}!`);
7 changes: 5 additions & 2 deletions tests/ckb_js_tests/test_data/fs_module_mount/init.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import * as ckb from "@ckb-js-std/bindings";
ckb.mount(2, ckb.SOURCE_CELL_DEP)

console.log("init.js");
ckb.mount(2, ckb.SOURCE_CELL_DEP, "/")
ckb.mount(2, ckb.SOURCE_CELL_DEP, "/a")
ckb.mount(2, ckb.SOURCE_CELL_DEP, "/b/")

console.log("init.js");

0 comments on commit 97dc827

Please sign in to comment.