stage0 新增内存复制指令 重构vm交互
This commit is contained in:
1 parent
0b8f649818
commit
40cffa9cb5
22 files changed
+626
-158
No files matched your search
+58
-33
@@ -615,33 +615,51 @@ static spl_vm_val_t vm_timestamp(spl_vm_t *_vm, int nargs, spl_vm_val_t *args) {
|
||||
* nested-VM syscalls
|
||||
* ================================================================= */
|
||||
|
||||
/* ---- 配置层的“外部函数处理器”:把某个 VM 未解析的 native 交给调用者 VM。
|
||||
* 这是配置策略,不属于 VM 库 API;VM 本身只有通用 foreign 钩子。 ---- */
|
||||
/* 通用双向桥(配置层策略,非 VM 平台 API):
|
||||
* 在子 VM 上安装「未解析 native 处理器」,把子 VM 的未解析调用按名转发到
|
||||
* 宿主(调用者)VM 中由 `entry` 指定的函数。宿主函数收到:
|
||||
* (ctx, name_off, name_len, nested_vm, arg_base, nargs)
|
||||
* 平台/C 侧**纯转发**:不复制实参、不限元数、不了解类型;聚合读写由宿主用
|
||||
* vm_stack_get / vm_mem_read / vm_mem_alloc / vm_mem_write 自行完成。
|
||||
* `entry` 由宿主显式给出,平台不预设任何函数名。 */
|
||||
typedef struct {
|
||||
spl_vm_t *caller;
|
||||
spl_vm_t *host;
|
||||
void *ctx;
|
||||
} spl_foreign_t;
|
||||
char entry[128];
|
||||
} spl_bridge_t;
|
||||
|
||||
static spl_vm_val_t spl_foreign_reenter(spl_vm_t *vm, const spl_vm_call_t *call, void *user) {
|
||||
spl_foreign_t *f = (spl_foreign_t *)user;
|
||||
spl_vm_val_t tmp[20];
|
||||
spl_vm_call_t c2;
|
||||
int i;
|
||||
(void)vm;
|
||||
if (!f || !f->caller || !call || !call->name)
|
||||
static spl_vm_val_t spl_bridge_forward(spl_vm_t *nested, const spl_vm_call_t *call, void *user) {
|
||||
spl_bridge_t *b = (spl_bridge_t *)user;
|
||||
spl_vm_val_t name_off;
|
||||
spl_vm_val_t args[6];
|
||||
spl_vm_call_t back;
|
||||
usize n;
|
||||
usize arg_base;
|
||||
if (!b || !b->host || !call || !call->name || b->entry[0] == '\0')
|
||||
return 0;
|
||||
if (call->nargs + 1 > (usize)(sizeof(tmp) / sizeof(tmp[0])))
|
||||
n = strlen(call->name);
|
||||
/* 名拷进宿主 VM 内存,宿主按偏移读取。 */
|
||||
name_off = spl_vm_mem_alloc(b->host, n + 1);
|
||||
if (!name_off)
|
||||
return 0;
|
||||
tmp[0] = (spl_vm_val_t)(uintptr_t)f->ctx;
|
||||
for (i = 0; i < (int)call->nargs; i++)
|
||||
tmp[1 + i] = call->args ? call->args[i] : 0;
|
||||
c2.name = call->name;
|
||||
c2.args = tmp;
|
||||
c2.nargs = call->nargs + 1;
|
||||
c2.ret = 0;
|
||||
if (spl_vm_invoke(f->caller, &c2) != 0)
|
||||
if (spl_vm_mem_write(b->host, name_off, call->name, n + 1) != 0)
|
||||
return 0;
|
||||
return c2.ret;
|
||||
arg_base = spl_vm_call_arg_base(nested, call);
|
||||
if (arg_base == (usize)-1)
|
||||
return 0;
|
||||
args[0] = (spl_vm_val_t)(uintptr_t)b->ctx;
|
||||
args[1] = name_off;
|
||||
args[2] = (spl_vm_val_t)n;
|
||||
args[3] = (spl_vm_val_t)(uintptr_t)nested;
|
||||
args[4] = (spl_vm_val_t)arg_base;
|
||||
args[5] = (spl_vm_val_t)call->nargs;
|
||||
back.name = b->entry;
|
||||
back.args = args;
|
||||
back.nargs = 6;
|
||||
back.ret = 0;
|
||||
if (spl_vm_invoke(b->host, &back) != 0)
|
||||
return 0;
|
||||
return back.ret;
|
||||
}
|
||||
|
||||
static spl_vm_val_t vm_new(spl_vm_t *_vm, int nargs, spl_vm_val_t *args) {
|
||||
@@ -655,25 +673,32 @@ static spl_vm_val_t vm_new(spl_vm_t *_vm, int nargs, spl_vm_val_t *args) {
|
||||
return (spl_vm_val_t)(uintptr_t)vm;
|
||||
}
|
||||
|
||||
/* 配置入口:vm_set_foreign(vm, handler, ctx)。handler=0:把未解析 native 重入
|
||||
* 当前调用者(_vm),ctx 透传前置。名与语义由配置层定义;VM 库不认识 foreign handler。 */
|
||||
/* vm_set_foreign(vm, entry, ctx):宿主显式指定处理器函数名。 */
|
||||
static spl_vm_val_t sc_vm_set_foreign(spl_vm_t *_vm, int nargs, spl_vm_val_t *args) {
|
||||
spl_vm_t *vm;
|
||||
spl_foreign_t *f;
|
||||
spl_bridge_t *b;
|
||||
const spl_vm_val_t *entry;
|
||||
const char *eptr;
|
||||
usize elen;
|
||||
CHECK_NARGS("vm_set_foreign", 3);
|
||||
vm = (spl_vm_t *)(uintptr_t)args[0];
|
||||
if (!vm || !_vm)
|
||||
return -1;
|
||||
if (args[1] != 0) /* 仅注册 handler 0(重入调用者) */
|
||||
entry = (const spl_vm_val_t *)VM_XN(_vm, args[1], 2 * sizeof(spl_vm_val_t));
|
||||
if (!entry)
|
||||
return -1;
|
||||
if (vm->foreign == spl_foreign_reenter && vm->foreign_ctx)
|
||||
free(vm->foreign_ctx);
|
||||
f = (spl_foreign_t *)malloc(sizeof(*f));
|
||||
if (!f)
|
||||
eptr = (const char *)VM_X(_vm, entry[0]);
|
||||
elen = (usize)entry[1];
|
||||
if (!eptr || elen == 0 || elen >= sizeof(((spl_bridge_t *)0)->entry))
|
||||
return -1;
|
||||
f->caller = _vm;
|
||||
f->ctx = (void *)(uintptr_t)args[2];
|
||||
spl_vm_set_foreign(vm, spl_foreign_reenter, f);
|
||||
b = (spl_bridge_t *)malloc(sizeof(*b));
|
||||
if (!b)
|
||||
return -1;
|
||||
b->host = _vm;
|
||||
b->ctx = (void *)(uintptr_t)args[2];
|
||||
memcpy(b->entry, eptr, elen);
|
||||
b->entry[elen] = '\0';
|
||||
spl_vm_set_foreign(vm, spl_bridge_forward, b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -683,7 +708,7 @@ static spl_vm_val_t vm_drop(spl_vm_t *_vm, int nargs, spl_vm_val_t *args) {
|
||||
spl_vm_t *vm = (spl_vm_t *)(uintptr_t)args[0];
|
||||
if (!vm)
|
||||
return 0;
|
||||
if (vm->foreign == spl_foreign_reenter && vm->foreign_ctx)
|
||||
if (vm->foreign == spl_bridge_forward && vm->foreign_ctx)
|
||||
free(vm->foreign_ctx);
|
||||
if (vm->prog) {
|
||||
spl_prog_drop(vm->prog);
|
||||
|
||||
Reference in new issue
Block a user