From c811a743a1528db1d05970e1aa14162ef7c70b75 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 21 Sep 2019 13:59:39 +0200 Subject: Implement vararg, verify arguments to parameters --- src/bytecode/bytecode.c | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) (limited to 'src/bytecode') diff --git a/src/bytecode/bytecode.c b/src/bytecode/bytecode.c index 7dbc305..a5e3abc 100644 --- a/src/bytecode/bytecode.c +++ b/src/bytecode/bytecode.c @@ -142,9 +142,13 @@ static TypeSize function_signature_get_params_size(FunctionSignature *self) { params_total_size.num_pointers = 0; params_total_size.fixed_size = 0; for(; param != param_end; ++param) { - TypeSize param_size = resolved_type_get_byte_size(¶m->resolve_data.type); - params_total_size.num_pointers += param_size.num_pointers; - params_total_size.fixed_size += param_size.fixed_size; + if(param->type.variable_type_flags & VARIABLE_TYPE_FLAG_BORROW) + params_total_size.num_pointers += 1; + else { + TypeSize param_size = resolved_type_get_byte_size(¶m->resolve_data.type); + params_total_size.num_pointers += param_size.num_pointers; + params_total_size.fixed_size += param_size.fixed_size; + } } return params_total_size; } @@ -228,20 +232,21 @@ static void add_extern_functions(BytecodeCompilerContext *self) { |Type|Field |Description | |----|-------------------------|-----------------------------------------------------------------------------------------------------| |u8 |num_params |The number of parameters. | + |u8 |num_return_types |The number of return values. | + |u8 |name_len |The length of the external function name, in bytes. Excluding the null-terminate character. | + |u8 |flags |The flags for the external function. The values are defined in @amal_func_flag. | |u32 |params_num_pointers |The number of pointers in the parameters. | |u32 |params_fixed_size |The size of all non-pointer type parameters, in bytes. | - |u8 |num_return_types |The number of return values. | |u32 |return_types_num_pointers|The number of pointers in the return types. | |u32 |return_types_fixed_size |The size of all non-pointer type return types, in bytes. | - |u8 |name_len |The length of the external function name, in bytes. Excluding the null-terminate character. | |u8[]|name |The name of the external function, where the size is defined by @name_len. Names are null-terminated.| */ Ssa *ssa = self->parser->ssa; Buffer *instructions = &self->bytecode->data; SsaExternFunc *extern_func = buffer_begin(&ssa->extern_funcs); SsaExternFunc *extern_func_end = buffer_end(&ssa->extern_funcs); - u32 extern_funcs_size = (u32)ssa->extern_func_counter * (sizeof(BytecodeHeaderExternFunction) + sizeof(u8)); - assert(sizeof(BytecodeHeaderExternFunction) == 18); + u32 extern_funcs_size = (u32)ssa->extern_func_counter * sizeof(BytecodeHeaderExternFunction); + assert(sizeof(BytecodeHeaderExternFunction) == 20); for(; extern_func != extern_func_end; ++extern_func) { extern_funcs_size += extern_func->name.size + 1; /* +1 for null-termination of string */ @@ -259,17 +264,26 @@ static void add_extern_functions(BytecodeCompilerContext *self) { BytecodeHeaderExternFunction header_func; header_func.num_params = buffer_get_size(&extern_func->func_sig->parameters, FunctionParameter); + header_func.num_return_types = buffer_get_size(&extern_func->func_sig->return_types, FunctionReturnType); + header_func.name_len = extern_func->name.size; + header_func.flags = 0; + if(header_func.num_params > 0) { + amal_default_type *vararg_type = self->parser->compiler->default_types.c_varargs; + FunctionParameter *last_param = buffer_begin(&extern_func->func_sig->parameters); + last_param += (header_func.num_params - 1); + if(last_param->resolve_data.type.value.data == &vararg_type->lhs_expr) + header_func.flags |= FUNC_FLAG_VARARGS; + } + header_func.params_num_pointers = params_total_size.num_pointers; header_func.params_fixed_size = params_total_size.fixed_size; - header_func.num_return_types = buffer_get_size(&extern_func->func_sig->return_types, FunctionReturnType); header_func.return_types_num_pointers = return_types_total_size.num_pointers; header_func.return_types_fixed_size = return_types_total_size.fixed_size; throw_if_error(buffer_append(instructions, &header_func, sizeof(header_func))); /* TODO: Add namespace to the function name */ /* u8 is fine, because the max length of a variable is 255 */ - throw_if_error(buffer_append(instructions, &extern_func->name.size, sizeof(u8))); throw_if_error(buffer_append(instructions, extern_func->name.data, extern_func->name.size)); throw_if_error(buffer_append(instructions, &null_s, sizeof(char))); } @@ -435,10 +449,10 @@ static void add_ins6(BytecodeCompilerContext *self, AmalOpcode opcode, i8 dst_re static void add_instructions(BytecodeCompilerContext *self) { /*doc(Bytecode instructions) # Instructions layout - |Type |Field |Description | - |-----------|-----------------|---------------------------------------------------------------------------| - |u32 |Instructions size|The size of the instructions section, in bytes. | - |Instruction|Instructions data|The instructions data. Each instructions begins with an opcode, see #Opcode| + |Type |Field |Description | + |-------------|-----------------|---------------------------------------------------------------------------| + |u32 |Instructions size|The size of the instructions section, in bytes. | + |Instruction[]|Instructions data|The instructions data. Each instructions begins with an opcode, see #Opcode| */ SsaInsForm1 ssa_ins_form1; -- cgit v1.2.3