stage0 修复部分问题
This commit is contained in:
1 parent
5073c2b3ea
commit
a1e684f6d4
3 files changed
+57
-43
No files matched your search
+5
-4
@@ -19,6 +19,7 @@ void spl_prog_init(spl_prog_t *prog) {
|
||||
vec_init(prog->natives);
|
||||
vec_init(prog->strtab);
|
||||
vec_init(prog->gdata);
|
||||
vec_push(prog->gdata, (spl_vm_gdata_t){0});
|
||||
map_init(prog->symtab, MAP_HASH_STR, MAP_CMP_STR);
|
||||
prog->debug = NULL;
|
||||
}
|
||||
@@ -296,7 +297,7 @@ int spl_prog_store_to_file(const char *fname, spl_prog_t *prog) {
|
||||
ninsns = vec_size(prog->insns);
|
||||
nnatives = vec_size(prog->natives);
|
||||
nstrs = vec_size(prog->strtab);
|
||||
ndata = vec_size(prog->gdata);
|
||||
ndata = vec_size(prog->gdata) - 1; /* jump 0 node */
|
||||
|
||||
/* Calculate total size */
|
||||
total = 8 /* magic */
|
||||
@@ -325,7 +326,7 @@ int spl_prog_store_to_file(const char *fname, spl_prog_t *prog) {
|
||||
}
|
||||
|
||||
/* gdata */
|
||||
for (i = 0; i < ndata; i++) {
|
||||
for (i = 1; i < vec_size(prog->gdata); i++) {
|
||||
usize dsize = vec_at(prog->gdata, i).size;
|
||||
total += 8 + ALIGN8(dsize); /* dsize + data(pad) */
|
||||
}
|
||||
@@ -398,7 +399,7 @@ int spl_prog_store_to_file(const char *fname, spl_prog_t *prog) {
|
||||
}
|
||||
|
||||
/* ---- global data ---- */
|
||||
for (i = 0; i < ndata; i++) {
|
||||
for (i = 1; i <= ndata; i++) {
|
||||
spl_vm_gdata_t *entry = &vec_at(prog->gdata, i);
|
||||
pad = ALIGN8(entry->size) - entry->size;
|
||||
wr64(&p, entry->size);
|
||||
@@ -452,7 +453,7 @@ int spl_prog_add_data(spl_prog_t *prog, void *ptr, usize size) {
|
||||
memcpy(entry.data, ptr, size);
|
||||
entry.size = size;
|
||||
vec_push(prog->gdata, entry);
|
||||
return vec_size(prog->gdata);
|
||||
return (int)(vec_size(prog->gdata) - 1);
|
||||
}
|
||||
|
||||
spl_vm_func_t *spl_prog_get_func(spl_prog_t *prog, const char *name) {
|
||||
|
||||
+44
-37
@@ -168,63 +168,70 @@ SYSCALL_2(vm_strcmp, const char *, const char *, strcmp(a1, a2))
|
||||
SYSCALL_3(vm_memcpy, void *, const void *, size_t, (memcpy(a1, a2, a3), (uintptr_t)a1))
|
||||
|
||||
static spl_vm_val_t vm_printf(int nargs, spl_vm_val_t *args) {
|
||||
(void)args;
|
||||
if (nargs <= 0) {
|
||||
if (nargs <= 0)
|
||||
return 0;
|
||||
|
||||
/* args[0] 是 SPL 的 []u8 format 参数。VM 里 slice 作为参数传递时,
|
||||
栈上压的是"指向 slice 结构体的指针",结构为 {ptr:*u8, len:u64} */
|
||||
const spl_vm_val_t *fmt_slice = (const spl_vm_val_t *)args[0];
|
||||
const char *fmt = (const char *)fmt_slice[0];
|
||||
usize fmt_len = (usize)fmt_slice[1];
|
||||
|
||||
if (nargs <= 1) {
|
||||
fwrite(fmt, 1, fmt_len, stdout);
|
||||
return (spl_vm_val_t)nargs;
|
||||
}
|
||||
const char *fmt = (const char *)args[0];
|
||||
usize fmt_len = strlen(fmt);
|
||||
|
||||
typedef VEC(char) string_builder_t;
|
||||
string_builder_t buffer;
|
||||
vec_init(buffer);
|
||||
if (nargs <= 1) {
|
||||
printf("%s", fmt);
|
||||
return nargs;
|
||||
}
|
||||
int arg_idx = 0;
|
||||
|
||||
int arg_idx = 1; /* 0 是 format */
|
||||
char tmp_buf[32];
|
||||
memset(tmp_buf, 0, sizeof(tmp_buf));
|
||||
|
||||
for (usize i = 0; i < fmt_len; ++i) {
|
||||
if (fmt[i] != '%') {
|
||||
vec_push(buffer, fmt[i]);
|
||||
continue;
|
||||
}
|
||||
arg_idx += 1;
|
||||
if (++i >= fmt_len) {
|
||||
continue;
|
||||
}
|
||||
switch (fmt[i]) {
|
||||
case '.': {
|
||||
Assert(i + 2 < fmt_len && arg_idx + 1 <= nargs && fmt[i + 1] == '*' &&
|
||||
fmt[i + 2] == 's');
|
||||
for (usize j = 0; j < args[arg_idx]; ++j) {
|
||||
vec_push(buffer, ((const char *)args[arg_idx + 1])[j]);
|
||||
}
|
||||
arg_idx += 1; /* %.*s 消耗 2 个实参(len, data),遇 % 已 +1,这里补 1 */
|
||||
i += 2;
|
||||
} break;
|
||||
case 'd':
|
||||
snprintf(tmp_buf, sizeof(tmp_buf), "%zd", args[arg_idx]);
|
||||
for (usize j = 0; j < strlen(tmp_buf); ++j) {
|
||||
vec_push(buffer, tmp_buf[j]);
|
||||
}
|
||||
if (++i >= fmt_len)
|
||||
break;
|
||||
if (arg_idx >= nargs)
|
||||
break;
|
||||
|
||||
switch (fmt[i]) {
|
||||
case 'd': {
|
||||
memset(tmp_buf, 0, sizeof(tmp_buf));
|
||||
snprintf(tmp_buf, sizeof(tmp_buf), "%zd", (isize)args[arg_idx]);
|
||||
for (usize j = 0; tmp_buf[j] != '\0'; ++j)
|
||||
vec_push(buffer, tmp_buf[j]);
|
||||
arg_idx++;
|
||||
break;
|
||||
}
|
||||
case 'c':
|
||||
vec_push(buffer, (char)args[arg_idx]);
|
||||
arg_idx++;
|
||||
break;
|
||||
case 's':
|
||||
for (usize j = 0; j < strlen((const char *)args[arg_idx]); ++j) {
|
||||
vec_push(buffer, ((const char *)args[arg_idx])[j]);
|
||||
}
|
||||
case 's': {
|
||||
const spl_vm_val_t *s = (const spl_vm_val_t *)args[arg_idx];
|
||||
const char *p = (const char *)s[0];
|
||||
usize l = (usize)s[1];
|
||||
for (usize j = 0; j < l; ++j)
|
||||
vec_push(buffer, p[j]);
|
||||
arg_idx++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
continue;
|
||||
vec_push(buffer, '%');
|
||||
vec_push(buffer, fmt[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
vec_push(buffer, '\0');
|
||||
printf("%s", buffer.data);
|
||||
|
||||
if (vec_size(buffer) > 0)
|
||||
fwrite(buffer.data, 1, vec_size(buffer), stdout);
|
||||
vec_free(buffer);
|
||||
return nargs;
|
||||
return (spl_vm_val_t)nargs;
|
||||
}
|
||||
|
||||
/* =================================================================
|
||||
|
||||
+8
-2
@@ -328,6 +328,9 @@ static int spl_type_size(spl_vm_kind_t t) {
|
||||
_r = _da OP _db; \
|
||||
break; \
|
||||
} \
|
||||
case SPL_BOOL: \
|
||||
_r = (uint8_t)_a OP(uint8_t) _b; \
|
||||
break; \
|
||||
default: \
|
||||
_r = 0; \
|
||||
break; \
|
||||
@@ -1018,9 +1021,12 @@ int spl_vm_run_once(spl_vm_t *vm) {
|
||||
|
||||
case SPL_GADDR: {
|
||||
spl_vm_val_t _idx = ins->imm;
|
||||
if (_idx >= vec_size(prog->gdata))
|
||||
if (_idx == 0 || _idx >= vec_size(prog->gdata))
|
||||
VM_ERROR("GADDR: global data index out of range");
|
||||
PUSH((spl_vm_val_t)(uintptr_t)vec_at(prog->gdata, _idx).data);
|
||||
spl_vm_gdata_t *gd = &vec_at(prog->gdata, _idx);
|
||||
if (!gd->data)
|
||||
VM_ERROR("GADDR: null gdata entry");
|
||||
PUSH((spl_vm_val_t)(uintptr_t)gd->data);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user