-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
128 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,110 @@ | ||
#include "compiler.h" | ||
#include "helpers/vector.h" | ||
|
||
void native_test_function(struct generator *generator, | ||
struct native_function *func, struct vector *args) { | ||
generator->asm_push("; test"); | ||
struct datatype dtype; | ||
dtype.type = DATA_TYPE_INT; | ||
dtype.size = sizeof(int); | ||
generator->ret(&dtype, "42"); | ||
// va_start(va_list, last_arg) | ||
void native_va_start(struct generator *generator, struct native_function *func, | ||
struct vector *args) { | ||
struct compile_process *compiler = generator->compiler; | ||
if (vector_count(args) != 2) { | ||
compiler_error(compiler, "va_start expects 2 arguments, %d given", | ||
vector_count(args)); | ||
} | ||
|
||
struct node *list_arg = vector_peek_ptr(args); | ||
struct node *stack_arg = vector_peek_ptr(args); | ||
if (stack_arg->type != NODE_TYPE_IDENTIFIER) { | ||
compiler_error(compiler, | ||
"va_start expects an identifier as the second argument"); | ||
} | ||
|
||
generator->asm_push("; va_start on %s", stack_arg->sval); | ||
vector_set_peek_pointer(args, 0); | ||
generator->generate_expression(generator, stack_arg, EXPRESSION_GET_ADDRESS); | ||
|
||
struct resolver_result *result = | ||
resolver_follow(compiler->resolver, list_arg); | ||
assert(resolver_result_ok(result)); | ||
|
||
struct resolver_entity *list_arg_entity = resolver_result_entity_root(result); | ||
struct generator_entity_address address_out; | ||
generator->entity_address(generator, list_arg_entity, &address_out); | ||
generator->asm_push("mov dword [%s], ebx", address_out.address); | ||
generator->asm_push("; va_start end for %s", stack_arg->sval); | ||
|
||
struct datatype void_datatype; | ||
datatype_set_void(&void_datatype); | ||
generator->ret(&void_datatype, "0"); | ||
} | ||
|
||
// va_arg(va_list, type) | ||
void native_builtin_va_arg(struct generator *generator, | ||
struct native_function *func, struct vector *args) { | ||
struct compile_process *compiler = generator->compiler; | ||
if (vector_count(args) != 2) { | ||
compiler_error(compiler, "va_arg expects 2 arguments, %d given", | ||
vector_count(args)); | ||
} | ||
|
||
generator->asm_push("; native __builtin_va_arg start"); | ||
vector_set_peek_pointer(args, 0); | ||
struct node *list_arg = vector_peek_ptr(args); | ||
generator->generate_expression(generator, list_arg, EXPRESSION_GET_ADDRESS); | ||
|
||
struct node *size_arg = vector_peek_ptr(args); | ||
if (size_arg->type != NODE_TYPE_NUMBER) { | ||
compiler_error(compiler, "va_arg expects a number as the second argument"); | ||
} | ||
|
||
generator->asm_push("add dword [ebx], %d", size_arg->llnum); | ||
generator->asm_push("mov dword eax, [ebx]"); | ||
struct datatype void_dtype; | ||
datatype_set_void(&void_dtype); | ||
void_dtype.pointer_depth++; | ||
void_dtype.flags |= DATATYPE_FLAG_IS_POINTER; | ||
generator->ret(&void_dtype, "dword [eax]"); | ||
generator->asm_push("; native __builtin_va_arg end"); | ||
} | ||
|
||
// va_end(va_list) | ||
void native_va_end(struct generator *generator, struct native_function *func, | ||
struct vector *args) { | ||
struct compile_process *compiler = generator->compiler; | ||
if (vector_count(args) != 1) { | ||
compiler_error(compiler, "va_end expects 1 argument, %d given", | ||
vector_count(args)); | ||
} | ||
|
||
struct node *list_arg = vector_peek_ptr(args); | ||
if (list_arg->type != NODE_TYPE_IDENTIFIER) { | ||
compiler_error(compiler, "va_end expects an identifier as the argument"); | ||
} | ||
|
||
generator->asm_push("; va_end start for %s", list_arg->sval); | ||
vector_set_peek_pointer(args, 0); | ||
generator->generate_expression(generator, list_arg, EXPRESSION_GET_ADDRESS); | ||
generator->asm_push("mov dword [ebx], 0"); | ||
generator->asm_push("; va_end end for %s", list_arg->sval); | ||
|
||
struct datatype void_datatype; | ||
datatype_set_void(&void_datatype); | ||
generator->ret(&void_datatype, "0"); | ||
} | ||
|
||
void preprocessor_stdarg_include( | ||
struct preprocessor *preprocessor, | ||
struct preprocessor_included_file *included_file) { | ||
#warning "create va_list" | ||
native_create_function( | ||
preprocessor->compiler, "test", | ||
&(struct native_function_callbacks){.call = native_test_function}); | ||
native_create_function(preprocessor->compiler, "va_start", | ||
&(struct native_function_callbacks){ | ||
.call = native_va_start, | ||
}); | ||
|
||
native_create_function(preprocessor->compiler, "__builtin_va_arg", | ||
&(struct native_function_callbacks){ | ||
.call = native_builtin_va_arg, | ||
}); | ||
|
||
native_create_function(preprocessor->compiler, "va_end", | ||
&(struct native_function_callbacks){ | ||
.call = native_va_end, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#ifndef STDARG_H | ||
#define STDARG_H | ||
|
||
#include <stdarg_internal.h> | ||
|
||
typedef int __builtin_va_list; | ||
typedef __builtin_va_list va_list; | ||
|
||
#define va_arg(ap, type) __builtin_va_arg(ap, sizeof(type)) | ||
|
||
#endif // STDARG_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,15 @@ | ||
#include <stdarg_internal.h> | ||
#include <stdarg.h> | ||
|
||
int main() { test(); } | ||
int sum(int num, ...) { | ||
int res = 0; | ||
va_list args; | ||
va_start(args, num); | ||
int i; | ||
for (i = 0; i < num; i++) { | ||
res += va_arg(args, int); | ||
} | ||
va_end(args); | ||
return res; | ||
} | ||
|
||
int main() { return sum(10, 20, 30); } |