fix variadic foreign functions with more than 4 params

This commit is contained in:
Alex Shinn 2019-12-19 23:58:51 +08:00
parent d5b5a079f4
commit d79f557d46
3 changed files with 38 additions and 1 deletions

View file

@ -92,6 +92,12 @@ static sexp disasm (sexp ctx, sexp self, sexp bc, sexp out, int depth) {
if (off >= 0 && off < (int)sexp_bytecode_length(bc) && labels[off] == 0) if (off >= 0 && off < (int)sexp_bytecode_length(bc) && labels[off] == 0)
labels[off] = label++; labels[off] = label++;
case SEXP_OP_CALL: case SEXP_OP_CALL:
case SEXP_OP_FCALL0:
case SEXP_OP_FCALL1:
case SEXP_OP_FCALL2:
case SEXP_OP_FCALL3:
case SEXP_OP_FCALL4:
case SEXP_OP_FCALLN:
case SEXP_OP_CLOSURE_REF: case SEXP_OP_CLOSURE_REF:
case SEXP_OP_GLOBAL_KNOWN_REF: case SEXP_OP_GLOBAL_KNOWN_REF:
case SEXP_OP_GLOBAL_REF: case SEXP_OP_GLOBAL_REF:
@ -178,6 +184,7 @@ static sexp disasm (sexp ctx, sexp self, sexp bc, sexp out, int depth) {
case SEXP_OP_FCALL2: case SEXP_OP_FCALL2:
case SEXP_OP_FCALL3: case SEXP_OP_FCALL3:
case SEXP_OP_FCALL4: case SEXP_OP_FCALL4:
case SEXP_OP_FCALLN:
sexp_write_pointer(ctx, ((sexp*)ip)[0], out); sexp_write_pointer(ctx, ((sexp*)ip)[0], out);
sexp_write_char(ctx, ' ', out); sexp_write_char(ctx, ' ', out);
sexp_write(ctx, sexp_opcode_name(((sexp*)ip)[0]), out); sexp_write(ctx, sexp_opcode_name(((sexp*)ip)[0]), out);

View file

@ -72,6 +72,36 @@ int sub(int x, int y) {
(test -27 (cube -3)) (test -27 (cube -3))
(test -3 (sub (zero) 3))) (test -3 (sub (zero) 3)))
(test-ffi
"params"
(begin
(c-declare "
int add4(int a, int b, int c, int d) {
return a+b+c+d;
}
int add5(int a, int b, int c, int d, int e) {
return a+b+c+d+e;
}
int add6(int a, int b, int c, int d, int e, int f) {
return a+b+c+d+e+f;
}
")
(define-c int add4 (int int int int))
(define-c int add5 (int int int int int))
(define-c int add6 (int int int int int int))
(define-c int (add3or4 "add4") (int int int (default 0 int)))
(define-c int (add4or5 "add5") (int int int int (default 0 int)))
(define-c int (add5or6 "add6") (int int int int int (default 0 int))))
(test 4321 (add4 1 20 300 4000))
(test 54321 (add5 1 20 300 4000 50000))
(test 654321 (add6 1 20 300 4000 50000 600000))
(test 321 (add3or4 1 20 300))
(test 4321 (add3or4 1 20 300 4000))
(test 4321 (add4or5 1 20 300 4000))
(test 54321 (add4or5 1 20 300 4000 50000))
(test 54321 (add5or6 1 20 300 4000 50000))
(test 654321 (add5or6 1 20 300 4000 50000 600000)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; More detailed tests on integer conversions and overflow. ;; More detailed tests on integer conversions and overflow.

2
vm.c
View file

@ -1300,7 +1300,7 @@ sexp sexp_apply (sexp ctx, sexp proc, sexp args) {
_ALIGN_IP(); _ALIGN_IP();
sexp_context_top(ctx) = top; sexp_context_top(ctx) = top;
sexp_context_last_fp(ctx) = fp; sexp_context_last_fp(ctx) = fp;
i = sexp_opcode_num_args(_WORD0); i = sexp_opcode_num_args(_WORD0) + sexp_opcode_variadic_p(_WORD0);
tmp1 = sexp_fcall(ctx, self, i, _WORD0); tmp1 = sexp_fcall(ctx, self, i, _WORD0);
sexp_fcall_return(tmp1, i-1) sexp_fcall_return(tmp1, i-1)
break; break;