line : u32;
column : u32;
}
+
+
+
+Any :: struct {
+ data: rawptr;
+ type: type_expr;
+}
typedef enum VarArgKind {
VA_Kind_Not_VA,
VA_Kind_Typed,
+ VA_Kind_Any,
VA_Kind_Untyped,
} VarArgKind;
extern AstType *builtin_allocator_type;
extern AstType *builtin_iterator_type;
extern AstType *builtin_callsite_type;
+extern AstType *builtin_any_type;
extern AstTyped *type_table_node;
typedef struct BuiltinSymbol {
AstType *builtin_allocator_type;
AstType *builtin_iterator_type;
AstType *builtin_callsite_type;
+AstType *builtin_any_type;
AstTyped *type_table_node = NULL;
return;
}
+ builtin_any_type = (AstType *) symbol_raw_resolve(p->scope, "Any");
+ if (builtin_any_type == NULL) {
+ onyx_report_error((OnyxFilePos) { 0 }, "'Any' struct not found in builtin package.");
+ return;
+ }
+
p = package_lookup("builtin.type_info");
if (p != NULL) {
type_table_node = (AstTyped *) symbol_raw_resolve(p->scope, "type_table");
Type* variadic_type = NULL;
AstParam* variadic_param = NULL;
+ // SPEED CLEANUP: Caching the any type here.
+ Type* any_type = type_build_from_ast(context.ast_alloc, builtin_any_type);
+
ArgState arg_state = AS_Expecting_Exact;
u32 arg_pos = 0;
while (1) {
}
case AS_Expecting_Typed_VA: {
+ if (arg_pos >= (u32) bh_arr_length(arg_arr)) goto type_checking_done;
+
+ if (variadic_type->id == any_type->id) {
+ call->va_kind = VA_Kind_Any;
+
+ resolve_expression_type(arg_arr[arg_pos]->value);
+ arg_arr[arg_pos]->va_kind = VA_Kind_Any;
+ break;
+ }
+
call->va_kind = VA_Kind_Typed;
- if (arg_pos >= (u32) 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 procedure '%s' expects a value of type '%s' for the variadic parameter, '%b', got '%s'.",
u32 vararg_count = 0;
i32 vararg_offset = -1;
+ u32* vararg_any_offsets=NULL;
+ u32* vararg_any_types=NULL;
+ if (call->va_kind == VA_Kind_Any) {
+ vararg_any_offsets = bh_alloc_array(global_scratch_allocator, u32, bh_arr_length(call->args.values));
+ vararg_any_types = bh_alloc_array(global_scratch_allocator, u32, bh_arr_length(call->args.values));
+ }
+
bh_arr_each(AstTyped *, parg, call->args.values) {
AstArgument* arg = (AstArgument *) *parg;
if (arg->is_baked) continue;
WI(WI_PTR_ADD);
}
+ if (arg->va_kind == VA_Kind_Any) {
+ vararg_any_offsets[vararg_count - 1] = reserve_size;
+ vararg_any_types[vararg_count - 1] = arg->value->type->id;
+ }
+
reserve_size += type_size_of(arg->value->type);
}
}
switch (call->va_kind) {
+ case VA_Kind_Any: {
+ vararg_offset = reserve_size;
+
+ i32 any_size = type_size_of(type_build_from_ast(context.ast_alloc, builtin_any_type));
+
+ fori (i, 0, vararg_count) {
+ WIL(WI_LOCAL_GET, stack_top_store_local);
+ WIL(WI_LOCAL_GET, stack_top_store_local);
+ WID(WI_PTR_CONST, vararg_any_offsets[i]);
+ WI(WI_PTR_ADD);
+ emit_store_instruction(mod, &code, &basic_types[Basic_Kind_Rawptr], vararg_offset + i * any_size);
+
+ WIL(WI_LOCAL_GET, stack_top_store_local);
+ WID(WI_I32_CONST, vararg_any_types[i]);
+ emit_store_instruction(mod, &code, &basic_types[Basic_Kind_Type_Index], vararg_offset + i * any_size + 8);
+
+ reserve_size += any_size;
+ }
+
+ // fallthrough
+ }
+
case VA_Kind_Typed: {
WIL(WI_LOCAL_GET, stack_top_store_local);
if (vararg_offset > 0) {