Skip to content

Commit

Permalink
Full implemention
Browse files Browse the repository at this point in the history
  • Loading branch information
mohanson committed Sep 10, 2024
1 parent 48d10ea commit f664e2f
Showing 1 changed file with 179 additions and 23 deletions.
202 changes: 179 additions & 23 deletions quickjs/ckb_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,18 @@ static int get_property(JSContext *ctx, JSValueConst *obj, const char *prop, int
return err;
}

int ckb_spawn_cell(const uint8_t* code_hash, uint8_t hash_type, uint32_t offset,
uint32_t length, spawn_args_t* spawn_args) {
size_t index = SIZE_MAX;
int ret = ckb_look_for_dep_with_hash2(code_hash, hash_type, &index);
if (ret != CKB_SUCCESS) {
return ret;
}
size_t bounds = ((size_t)offset << 32) | length;
return syscall(SYS_ckb_spawn, index, CKB_SOURCE_CELL_DEP, 0, bounds,
spawn_args, 0);
}

static JSValue syscall_spawn_cell(JSContext *ctx, JSValueConst this_value, int argc, JSValueConst *argv) {
int err = 0;
size_t code_hash_len = 0;
Expand All @@ -374,8 +386,8 @@ static JSValue syscall_spawn_cell(JSContext *ctx, JSValueConst this_value, int a
uint32_t length = 0;
uint32_t spgs_argc = 0;
const char* spgs_argv[32] = {};
// uint64_t spgs_process_id = 0;
// uint64_t* spgs_inherited_fds = {};
uint64_t spgs_pid = 0;
uint64_t spgs_fds[32] = {0};

JSValue buffer = JS_GetTypedArrayBuffer(ctx, argv[0], NULL, NULL, NULL);
CHECK2(!JS_IsException(buffer), SyscallErrorArgument);
Expand Down Expand Up @@ -412,19 +424,129 @@ static JSValue syscall_spawn_cell(JSContext *ctx, JSValueConst this_value, int a
}
JS_FreeValue(ctx, val);

// err = get_property(ctx, &argv[2], "memory_limit", &memory_limit);
// CHECK(err);
// err = get_property(ctx, &argv[2], "offset", &offset);
// CHECK(err);
// err = get_property(ctx, &argv[2], "length", &length);
// CHECK(err);

// spawn_args_t spgs = {
// .argc = 2,
// .argv = argv,
// .process_id = &pid,
// .inherited_fds = inherited_fds,
// };
val = JS_GetPropertyStr(ctx, argv[4], "inherited_fds");
CHECK2(!JS_IsException(val), SyscallErrorArgument);
if (!JS_IsUndefined(val)) {
JSValue buffer = JS_GetTypedArrayBuffer(ctx, val, NULL, NULL, NULL);
CHECK2(!JS_IsException(buffer), SyscallErrorArgument);
uint32_t temp;
for (int i = 0; i < 32; i++) {
const JSValue elem = JS_GetPropertyUint32(ctx, buffer, i);
err = JS_ToUint32(ctx, &temp, elem);
CHECK(err);
spgs_fds[i] = temp;
if (temp == 0) {
break;
}
}
}
JS_FreeValue(ctx, val);

spawn_args_t spgs = {
.argc = spgs_argc,
.argv = spgs_argv,
.process_id = &spgs_pid,
.inherited_fds = &spgs_fds[0],
};

err = ckb_spawn_cell(code_hash, hash_type, offset, length, &spgs);
CHECK(err);
exit:
if (err != 0) {
return JS_EXCEPTION;
} else {
return JS_NewInt64(ctx, spgs_pid);
}
}

static JSValue syscall_pipe(JSContext *ctx, JSValueConst this_value, int argc, JSValueConst *argv) {
int err = 0;
uint64_t fds[2];
err = ckb_pipe(fds);
CHECK(err);
JSValue obj = JS_NewArray(ctx);
CHECK2(!JS_IsException(obj), SyscallErrorArgument);
JS_SetPropertyUint32(ctx, obj, 0, JS_NewUint32(ctx, fds[0]));
JS_SetPropertyUint32(ctx, obj, 1, JS_NewUint32(ctx, fds[1]));
exit:
if (err != 0) {
return JS_EXCEPTION;
} else {
return obj;
}
}

static JSValue syscall_inherited_file_descriptors(JSContext *ctx, JSValueConst this_value, int argc, JSValueConst *argv) {
int err = 0;
uint64_t fds[2];
uint64_t length;
err = ckb_inherited_file_descriptors(fds, &length);
CHECK(err);
JSValue obj = JS_NewArray(ctx);
CHECK2(!JS_IsException(obj), SyscallErrorArgument);
for (int i = 0; i < length; i++) {
JS_SetPropertyUint32(ctx, obj, i, JS_NewUint32(ctx, (uint32_t)fds[i]));
}
exit:
if (err != 0) {
return JS_EXCEPTION;
} else {
return obj;
}
}

static JSValue syscall_read(JSContext *ctx, JSValueConst this_value, int argc, JSValueConst *argv) {
int err = 0;
uint64_t fd = 0;
void* buffer = {};
size_t length = 0;
uint32_t u32 = 0;
err = JS_ToUint32(ctx, &u32, argv[0]);
CHECK(err);
fd = u32;
err = JS_ToUint32(ctx, &u32, argv[1]);
CHECK(err);
length = u32;
CHECK2(length <= 1024, SyscallErrorArgument);
err = ckb_read(fd, buffer, &length);
CHECK(err);
exit:
if (err != 0) {
return JS_EXCEPTION;
} else {
return JS_NewArrayBuffer(ctx, buffer, length, my_free, buffer, false);
}
}

static JSValue syscall_write(JSContext *ctx, JSValueConst this_value, int argc, JSValueConst *argv) {
int err = 0;
uint64_t fd = 0;
uint32_t u32 = 0;
err = JS_ToUint32(ctx, &u32, argv[0]);
CHECK(err);
fd = (uint64_t)u32;
size_t length = 0;
JSValue buffer = JS_GetTypedArrayBuffer(ctx, argv[1], NULL, NULL, NULL);
CHECK2(!JS_IsException(buffer), SyscallErrorArgument);
uint8_t *content = JS_GetArrayBuffer(ctx, &length, buffer);
CHECK2(content != NULL, SyscallErrorUnknown);
err = ckb_write(fd, content, &length);
CHECK(err);
exit:
if (err != 0) {
return JS_EXCEPTION;
} else {
return JS_UNDEFINED;
}
}

static JSValue syscall_close(JSContext *ctx, JSValueConst this_value, int argc, JSValueConst *argv) {
int err = 0;
uint32_t fd = 0;
err = JS_ToUint32(ctx, &fd, argv[0]);
CHECK(err);
err = ckb_close((uint64_t)fd);
CHECK(err);
exit:
if (err != 0) {
return JS_EXCEPTION;
Expand All @@ -433,14 +555,39 @@ static JSValue syscall_spawn_cell(JSContext *ctx, JSValueConst this_value, int a
}
}

// - [Pipe]
// - [Inherited File Descriptors]
// - [Read]
// - [Write]
// - [Close]
// - [Wait]
// - [Process ID]
// - [Load Block Extension]
static JSValue syscall_wait(JSContext *ctx, JSValueConst this_value, int argc, JSValueConst *argv) {
int err = 0;
uint32_t fd = 0;
int8_t exit = 0;
err = JS_ToUint32(ctx, &fd, argv[0]);
CHECK(err);
err = ckb_wait((uint64_t)fd, &exit);
CHECK(err);
exit:
if (err != 0) {
return JS_EXCEPTION;
} else {
return JS_NewInt32(ctx, exit);
}
}

static JSValue syscall_process_id(JSContext *ctx, JSValueConst this_value, int argc, JSValueConst *argv) {
uint64_t pid = ckb_process_id();
return JS_NewUint32(ctx, (uint32_t)pid);
}

static int _load_block_extension(void *addr, uint64_t *len, LoadData *data) {
return ckb_load_block_extension(addr, len, data->offset, data->index, data->source);
}

static JSValue syscall_load_block_extension(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
LoadData data = {0};
JSValue ret = parse_args(ctx, &data, false, argc, argv, _load_block_extension);
if (JS_IsException(ret)) {
return ret;
}
return syscall_load(ctx, &data);
}

static JSValue mount(JSContext *ctx, JSValueConst this_value, int argc, JSValueConst *argv) {
JSValue buf = syscall_load_cell_data(ctx, this_value, argc, argv);
Expand Down Expand Up @@ -493,6 +640,15 @@ int js_init_module_ckb(JSContext *ctx) {
JS_SetPropertyStr(ctx, ckb, "vm_version", JS_NewCFunction(ctx, syscall_vm_version, "vm_version", 0));
JS_SetPropertyStr(ctx, ckb, "current_cycles", JS_NewCFunction(ctx, syscall_current_cycles, "current_cycles", 0));
JS_SetPropertyStr(ctx, ckb, "exec_cell", JS_NewCFunction(ctx, syscall_exec_cell, "exec_cell", 4));
JS_SetPropertyStr(ctx, ckb, "spawn_cell", JS_NewCFunction(ctx, syscall_spawn_cell, "spawn_cell", 5));
JS_SetPropertyStr(ctx, ckb, "pipe", JS_NewCFunction(ctx, syscall_pipe, "pipe", 0));
JS_SetPropertyStr(ctx, ckb, "inherited_file_descriptors", JS_NewCFunction(ctx, syscall_inherited_file_descriptors, "inherited_file_descriptors", 0));
JS_SetPropertyStr(ctx, ckb, "read", JS_NewCFunction(ctx, syscall_read, "read", 2));
JS_SetPropertyStr(ctx, ckb, "write", JS_NewCFunction(ctx, syscall_write, "write", 2));
JS_SetPropertyStr(ctx, ckb, "close", JS_NewCFunction(ctx, syscall_close, "close", 1));
JS_SetPropertyStr(ctx, ckb, "wait", JS_NewCFunction(ctx, syscall_wait, "wait", 1));
JS_SetPropertyStr(ctx, ckb, "process_id", JS_NewCFunction(ctx, syscall_process_id, "process_id", 0));
JS_SetPropertyStr(ctx, ckb, "load_block_extension", JS_NewCFunction(ctx, syscall_load_block_extension, "load_block_extension", 3));
JS_SetPropertyStr(ctx, ckb, "mount", JS_NewCFunction(ctx, mount, "mount", 2));
JS_SetPropertyStr(ctx, ckb, "SOURCE_INPUT", JS_NewInt64(ctx, CKB_SOURCE_INPUT));
JS_SetPropertyStr(ctx, ckb, "SOURCE_OUTPUT", JS_NewInt64(ctx, CKB_SOURCE_OUTPUT));
Expand Down

0 comments on commit f664e2f

Please sign in to comment.