From: Brendan Hansen Date: Sat, 26 Sep 2020 19:54:34 +0000 (-0500) Subject: bugfixes with varargs X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=2ab30b5b354a7651467006bd2edad3e99bca5c7f;p=onyx.git bugfixes with varargs --- diff --git a/onyx b/onyx index 0c8c465e..6c79fded 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/vararg_test.onyx b/progs/vararg_test.onyx index aac4c497..c66dc106 100644 --- a/progs/vararg_test.onyx +++ b/progs/vararg_test.onyx @@ -5,6 +5,7 @@ package main use package core; old_va_test :: proc (prefix: string, va: ..i32) { + println(prefix); for v: va do println(v); } @@ -20,27 +21,14 @@ vararg_get :: proc (va: vararg, ret: ^$T) -> bool { new_va_test :: proc (prefix: string, va: ...) { println(prefix); - for i: 0 .. 2 { + for i: 0 .. va.count { x : i32; vararg_get(va, ^x); println(x); } - - for i: 0 .. 2 { - x : f32; - vararg_get(va, ^x); - println(x); - } } main :: proc (args: [] cstring) { new_va_test("foo", 1, 2, 3.0f, 5.0f); + old_va_test("bar", 1); } - -// Things needed to make the above work" -/* - 1. A RawVarArg type in the type system - 2. Parsing '...' as a rawvararg - 3. Typechecking is disabled for arguments in a rawvararg - 4. RawVarArg is treated as a pointer -*/ diff --git a/src/onyxchecker.c b/src/onyxchecker.c index 9e298475..ebe8cadd 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -430,7 +430,7 @@ b32 check_call(AstCall* call) { ArgState arg_state = AS_Expecting_Exact; i32 arg_pos = 0; - while (arg_pos < bh_arr_length(arg_arr)) { + while (1) { switch (arg_state) { case AS_Expecting_Exact: { if (arg_pos >= callee->type->Function.param_count) goto type_checking_done; @@ -448,6 +448,7 @@ b32 check_call(AstCall* call) { continue; } + if (arg_pos >= bh_arr_length(arg_arr)) goto type_checking_done; if (!type_check_or_auto_cast(arg_arr[arg_pos]->value, formal_params[arg_pos])) { onyx_report_error(arg_arr[arg_pos]->token->pos, "The function '%b' expects a value of type '%s' for %d%s parameter, got '%s'.", @@ -464,6 +465,9 @@ b32 check_call(AstCall* call) { } case AS_Expecting_Typed_VA: { + call->va_kind = VA_Kind_Typed; + + if (arg_pos >= bh_arr_length(arg_arr)) goto type_checking_done; if (!type_check_or_auto_cast(arg_arr[arg_pos]->value, variadic_type)) { onyx_report_error(arg_arr[arg_pos]->token->pos, "The function '%b' expects a value of type '%s' for the variadic parameter, '%b', got '%s'.", @@ -476,13 +480,14 @@ b32 check_call(AstCall* call) { } arg_arr[arg_pos]->va_kind = VA_Kind_Typed; - call->va_kind = VA_Kind_Typed; break; } case AS_Expecting_Untyped_VA: { - arg_arr[arg_pos]->va_kind = VA_Kind_Untyped; call->va_kind = VA_Kind_Untyped; + + if (arg_pos >= bh_arr_length(arg_arr)) goto type_checking_done; + arg_arr[arg_pos]->va_kind = VA_Kind_Untyped; break; } } @@ -492,7 +497,7 @@ b32 check_call(AstCall* call) { type_checking_done: - if (arg_pos < callee->type->Function.param_count) { + if (arg_pos < callee->type->Function.needed_param_count) { onyx_report_error(call->token->pos, "Too few arguments to function call."); return 1; } diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 60d9e95c..3d055bc6 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -1360,7 +1360,9 @@ EMIT_FUNC(call, AstCall* call) { switch (call->va_kind) { case VA_Kind_Typed: { - WID(WI_GLOBAL_GET, vararg_offset); + WID(WI_GLOBAL_GET, stack_top_idx); + WID(WI_I32_CONST, vararg_offset); + WI(WI_I32_ADD); WID(WI_I32_CONST, vararg_count); break; }