aboutsummaryrefslogtreecommitdiff
path: root/src/bytecode
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2019-09-21 13:59:39 +0200
committerdec05eba <dec05eba@protonmail.com>2020-07-25 14:36:46 +0200
commitc811a743a1528db1d05970e1aa14162ef7c70b75 (patch)
tree4560ab5d9084c385946415e9fc2dbf187e26c844 /src/bytecode
parent142a13ad3f77c0ad1bd321d1a1f864a5117896d1 (diff)
Implement vararg, verify arguments to parameters
Diffstat (limited to 'src/bytecode')
-rw-r--r--src/bytecode/bytecode.c40
1 files changed, 27 insertions, 13 deletions
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(&param->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(&param->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;