stage0 修复部分问题
This commit is contained in:
1 parent
5073c2b3ea
commit
a1e684f6d4
3 files changed
+58
-44
No files matched your search
+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;
|
||||
}
|
||||
|
||||
/* =================================================================
|
||||
|
||||
Reference in new issue
Block a user