mirror of
https://github.com/ProgramSnail/Lama.git
synced 2025-12-06 14:58:50 +00:00
Fix all prints
This commit is contained in:
parent
a91f61dbfa
commit
db9067b748
3 changed files with 174 additions and 44 deletions
115
runtime/printf.s
115
runtime/printf.s
|
|
@ -7,7 +7,10 @@
|
||||||
.extern fprintf
|
.extern fprintf
|
||||||
|
|
||||||
.global Lsprintf
|
.global Lsprintf
|
||||||
.extern sprintf
|
.extern Bsprintf
|
||||||
|
|
||||||
|
.global Lfailure
|
||||||
|
.extern failure
|
||||||
|
|
||||||
.extern cnt_percentage_sign
|
.extern cnt_percentage_sign
|
||||||
|
|
||||||
|
|
@ -21,7 +24,6 @@ Lprintf:
|
||||||
pushq %rdx
|
pushq %rdx
|
||||||
pushq %rsi
|
pushq %rsi
|
||||||
movq %rsp, %rax
|
movq %rsp, %rax
|
||||||
# pushq %rsi
|
|
||||||
# rdi --- format string
|
# rdi --- format string
|
||||||
# r11 --- number of arguments except format string
|
# r11 --- number of arguments except format string
|
||||||
loop:
|
loop:
|
||||||
|
|
@ -49,3 +51,112 @@ continue:
|
||||||
pushq %r14
|
pushq %r14
|
||||||
jmp printf
|
jmp printf
|
||||||
|
|
||||||
|
Lfprintf:
|
||||||
|
# save return address
|
||||||
|
popq %r14
|
||||||
|
|
||||||
|
pushq %r9
|
||||||
|
pushq %r8
|
||||||
|
pushq %rcx
|
||||||
|
pushq %rdx
|
||||||
|
movq %rsp, %rax
|
||||||
|
# rdi --- FILE*
|
||||||
|
# rsi --- format string
|
||||||
|
# r11 --- number of arguments except format string
|
||||||
|
Lfprintf_loop:
|
||||||
|
movq $0, %r12
|
||||||
|
cmpq %r11, %r12
|
||||||
|
jz Lfprintf_continue
|
||||||
|
|
||||||
|
decq %r11
|
||||||
|
movq (%rax), %r10
|
||||||
|
testq $1, %r10
|
||||||
|
jz Lfprintf_loop_end
|
||||||
|
# unbox value
|
||||||
|
sarq %r10
|
||||||
|
movq %r10, (%rax)
|
||||||
|
Lfprintf_loop_end:
|
||||||
|
addq $8, %rax
|
||||||
|
jmp Lfprintf_loop
|
||||||
|
Lfprintf_continue:
|
||||||
|
popq %rdx
|
||||||
|
popq %rcx
|
||||||
|
popq %r8
|
||||||
|
popq %r9
|
||||||
|
# restore return address
|
||||||
|
pushq %r14
|
||||||
|
jmp fprintf
|
||||||
|
|
||||||
|
Lsprintf:
|
||||||
|
# save return address
|
||||||
|
popq %r14
|
||||||
|
|
||||||
|
pushq %r9
|
||||||
|
pushq %r8
|
||||||
|
pushq %rcx
|
||||||
|
pushq %rdx
|
||||||
|
pushq %rsi
|
||||||
|
movq %rsp, %rax
|
||||||
|
# rdi --- format string
|
||||||
|
# r11 --- number of arguments except format string
|
||||||
|
Lsprintf_loop:
|
||||||
|
movq $0, %r12
|
||||||
|
cmpq %r11, %r12
|
||||||
|
jz Lsprintf_continue
|
||||||
|
|
||||||
|
decq %r11
|
||||||
|
movq (%rax), %r10
|
||||||
|
testq $1, %r10
|
||||||
|
jz Lsprintf_loop_end
|
||||||
|
# unbox value
|
||||||
|
sarq %r10
|
||||||
|
movq %r10, (%rax)
|
||||||
|
Lsprintf_loop_end:
|
||||||
|
addq $8, %rax
|
||||||
|
jmp Lsprintf_loop
|
||||||
|
Lsprintf_continue:
|
||||||
|
popq %rsi
|
||||||
|
popq %rdx
|
||||||
|
popq %rcx
|
||||||
|
popq %r8
|
||||||
|
popq %r9
|
||||||
|
# restore return address
|
||||||
|
pushq %r14
|
||||||
|
jmp Bsprintf
|
||||||
|
|
||||||
|
Lfailure:
|
||||||
|
# save return address
|
||||||
|
popq %r14
|
||||||
|
|
||||||
|
pushq %r9
|
||||||
|
pushq %r8
|
||||||
|
pushq %rcx
|
||||||
|
pushq %rdx
|
||||||
|
pushq %rsi
|
||||||
|
movq %rsp, %rax
|
||||||
|
# rdi --- format string
|
||||||
|
# r11 --- number of arguments except format string
|
||||||
|
Lfailure_loop:
|
||||||
|
movq $0, %r12
|
||||||
|
cmpq %r11, %r12
|
||||||
|
jz Lfailure_continue
|
||||||
|
|
||||||
|
decq %r11
|
||||||
|
movq (%rax), %r10
|
||||||
|
testq $1, %r10
|
||||||
|
jz Lfailure_loop_end
|
||||||
|
# unbox value
|
||||||
|
sarq %r10
|
||||||
|
movq %r10, (%rax)
|
||||||
|
Lfailure_loop_end:
|
||||||
|
addq $8, %rax
|
||||||
|
jmp Lfailure_loop
|
||||||
|
Lfailure_continue:
|
||||||
|
popq %rsi
|
||||||
|
popq %rdx
|
||||||
|
popq %rcx
|
||||||
|
popq %r8
|
||||||
|
popq %r9
|
||||||
|
# restore return address
|
||||||
|
pushq %r14
|
||||||
|
jmp failure
|
||||||
|
|
|
||||||
|
|
@ -968,28 +968,6 @@ extern void *Bsta (void *v, aint i, void *x) {
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fix_unboxed (char *s, va_list va) {
|
|
||||||
aint *p = (aint *)va;
|
|
||||||
aint i = 0;
|
|
||||||
|
|
||||||
while (*s) {
|
|
||||||
if (*s == '%') {
|
|
||||||
aint n = p[i];
|
|
||||||
if (UNBOXED(n)) { p[i] = UNBOX(n); }
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern void Lfailure (char *s, ...) {
|
|
||||||
va_list args;
|
|
||||||
|
|
||||||
va_start(args, s);
|
|
||||||
fix_unboxed(s, args);
|
|
||||||
vfailure(s, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern void Bmatch_failure (void *v, char *fname, aint line, aint col) {
|
extern void Bmatch_failure (void *v, char *fname, aint line, aint col) {
|
||||||
createStringBuf();
|
createStringBuf();
|
||||||
printValue(v);
|
printValue(v);
|
||||||
|
|
@ -1046,24 +1024,38 @@ extern void *LgetEnv (char *var) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef X86_64
|
|
||||||
auint cnt_percentage_sign (char *s) {
|
|
||||||
auint cnt = 0;
|
|
||||||
while (*s) {
|
|
||||||
cnt += (*s == '%');
|
|
||||||
++s;
|
|
||||||
if (*s == '%') {
|
|
||||||
++s;
|
|
||||||
--cnt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cnt;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern aint Lsystem (char *cmd) { return BOX(system(cmd)); }
|
extern aint Lsystem (char *cmd) { return BOX(system(cmd)); }
|
||||||
|
|
||||||
|
extern void Lfailure (char *s, ...);
|
||||||
|
extern void Lprintf (char *s, ...);
|
||||||
|
extern void *Lsprintf (char *fmt, ...);
|
||||||
|
extern void Lfprintf (FILE *f, char *s, ...);
|
||||||
|
|
||||||
#ifndef X86_64
|
#ifndef X86_64
|
||||||
|
// In X86_64 we are not able to modify va_arg
|
||||||
|
|
||||||
|
static void fix_unboxed (char *s, va_list va) {
|
||||||
|
aint *p = (aint *)va;
|
||||||
|
aint i = 0;
|
||||||
|
|
||||||
|
while (*s) {
|
||||||
|
if (*s == '%') {
|
||||||
|
aint n = p[i];
|
||||||
|
if (UNBOXED(n)) { p[i] = UNBOX(n); }
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void Lfailure (char *s, ...) {
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, s);
|
||||||
|
fix_unboxed(s, args);
|
||||||
|
vfailure(s, args);
|
||||||
|
}
|
||||||
|
|
||||||
extern void Lprintf (char *s, ...) {
|
extern void Lprintf (char *s, ...) {
|
||||||
va_list args; // = (va_list)BOX(NULL);
|
va_list args; // = (va_list)BOX(NULL);
|
||||||
|
|
||||||
|
|
@ -1076,18 +1068,15 @@ extern void Lprintf (char *s, ...) {
|
||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// TODO: fix
|
|
||||||
extern void *Lsprintf (char *fmt, ...) {
|
extern void *Lsprintf (char *fmt, ...) {
|
||||||
// exit (255);
|
|
||||||
va_list args;
|
va_list args;
|
||||||
void *s;
|
void *s;
|
||||||
|
|
||||||
ASSERT_STRING("sprintf:1", fmt);
|
ASSERT_STRING("sprintf:1", fmt);
|
||||||
|
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
// fix_unboxed(fmt, args);
|
fix_unboxed(fmt, args);
|
||||||
|
|
||||||
createStringBuf();
|
createStringBuf();
|
||||||
|
|
||||||
|
|
@ -1107,7 +1096,6 @@ extern void *Lsprintf (char *fmt, ...) {
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void Lfprintf (FILE *f, char *s, ...) {
|
extern void Lfprintf (FILE *f, char *s, ...) {
|
||||||
exit (255);
|
|
||||||
va_list args; // = (va_list)BOX(NULL);
|
va_list args; // = (va_list)BOX(NULL);
|
||||||
|
|
||||||
ASSERT_BOXED("fprintf:1", f);
|
ASSERT_BOXED("fprintf:1", f);
|
||||||
|
|
@ -1118,6 +1106,34 @@ extern void Lfprintf (FILE *f, char *s, ...) {
|
||||||
|
|
||||||
if (vfprintf(f, s, args) < 0) { failure("fprintf (...): %s\n", strerror(errno)); }
|
if (vfprintf(f, s, args) < 0) { failure("fprintf (...): %s\n", strerror(errno)); }
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
extern void *Bsprintf (char *fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
void *s;
|
||||||
|
|
||||||
|
ASSERT_STRING("sprintf:1", fmt);
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
|
||||||
|
createStringBuf();
|
||||||
|
|
||||||
|
vprintStringBuf(fmt, args);
|
||||||
|
|
||||||
|
PRE_GC();
|
||||||
|
|
||||||
|
push_extra_root((void **)&fmt);
|
||||||
|
s = Bstring(stringBuf.contents);
|
||||||
|
pop_extra_root((void **)&fmt);
|
||||||
|
|
||||||
|
POST_GC();
|
||||||
|
|
||||||
|
deleteStringBuf();
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
extern FILE *Lfopen (char *f, char *m) {
|
extern FILE *Lfopen (char *f, char *m) {
|
||||||
FILE *h;
|
FILE *h;
|
||||||
|
|
|
||||||
|
|
@ -497,6 +497,9 @@ let compile_call env ?fname nargs tail =
|
||||||
let add_printf_count =
|
let add_printf_count =
|
||||||
match fname with
|
match fname with
|
||||||
| Some "Lprintf" -> [ Mov (L (nargs - 1), r11) ]
|
| Some "Lprintf" -> [ Mov (L (nargs - 1), r11) ]
|
||||||
|
| Some "Lsprintf" -> [ Mov (L (nargs - 1), r11) ]
|
||||||
|
| Some "Lfprintf" -> [ Mov (L (nargs - 2), r11) ]
|
||||||
|
| Some "Lfailure" -> [ Mov (L (nargs - 1), r11) ]
|
||||||
| _ -> []
|
| _ -> []
|
||||||
in
|
in
|
||||||
let fname = adjust_builtin_function_name fname in
|
let fname = adjust_builtin_function_name fname in
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue