-
-
Save bdw/189cfec71ec13012687c6872b0682f5e to your computer and use it in GitHub Desktop.
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
#include "moar.h" | |
static MVMint32 function_const_ptr(MVMThreadContext *tc, MVMJitExprTree *tree, const void * function_ptr) { | |
MVMint32 function_constant = MVM_jit_expr_add_const_ptr(tc, tree, function_ptr); | |
return MVM_jit_expr_apply_template_adhoc(tc, tree, "ns.", MVM_JIT_CONST_PTR, 0, function_constant); | |
} | |
static MVMint32 tc_arg(MVMThreadContext *tc, MVMJitExprTree *tree) { | |
return MVM_jit_expr_apply_template_adhoc(tc, tree, "nsnsl.", MVM_JIT_TC, 0, MVM_JIT_CARG, 1, 0, MVM_JIT_PTR_SZ); | |
} | |
static MVMint32 nullary_void_function(MVMThreadContext *tc, MVMJitExprTree *tree, const void *function_ptr) { | |
MVMint32 function = function_const_ptr(tc, tree, function_ptr); | |
return MVM_jit_expr_apply_template_adhoc(tc, tree, "ns.ns.l", | |
MVM_JIT_ARGLIST, 1, tc_arg(tc, tree), | |
MVM_JIT_CALLV, 2, function, 0); | |
} | |
static MVMint32 box_function(MVMThreadContext *tc, MVMJitExprTree *tree, const void *function_ptr, MVMint32 boxee, MVMint32 type) { | |
MVMint32 function = function_const_ptr(tc, tree, function_ptr); | |
MVMint32 type_arg = MVM_jit_expr_apply_template_adhoc(tc, tree, "ns..", MVM_JIT_CARG, 1, type, MVM_JIT_PTR_SZ); | |
MVMint32 boxee_arg = MVM_jit_expr_apply_template_adhoc(tc, tree, "ns..", MVM_JIT_CARG, 1, boxee, MVM_JIT_PTR_SZ); | |
MVMint32 arglist = MVM_jit_expr_apply_template_adhoc( | |
tc, tree, "ns...", | |
MVM_JIT_ARGLIST, 3, tc_arg(tc, tree), type_arg, boxee_arg | |
); | |
return MVM_jit_expr_apply_template_adhoc(tc, tree, "ns...", MVM_JIT_CALL, 2, function, arglist, MVM_JIT_PTR_SZ); | |
} | |
MVMint32 MVM_nativecall_build_expr_tree(MVMThreadContext *tc, MVMJitExprTree *tree, MVMNativeCallBody *body, MVMint16 restype) { | |
/* Nodes for arguments */ | |
MVMint32 *arglist = alloca(sizeof(MVMint32) * body->num_args); | |
/* nodes that we have allocated and need to be freed */ | |
MVMint32 *to_free = alloca(sizeof(MVMint32) * body->num_args), num_free = 0; | |
/* maximum number of roots: | |
* - 1 for mark_blocked | |
* - 1 for the CALL | |
* - 1 for mark unblocked | |
* - 1 for the COPY or box operation | |
* - 1 for each node that may be freed (maximum: body->num_args) | |
* The nodes for unbox fit into args */ | |
MVMint32 *roots = alloca(sizeof(MVMint32) * (body->num_args * 2 + 2)); | |
for (int i = 0; i < body->num_args; i++) { | |
MVMint32 size = MVM_JIT_PTR_SZ; | |
MVMint32 arg; | |
switch (body->arg_types[i] & MVM_NATIVECALL_ARG_TYPE_MASK) { | |
case MVM_NATIVECALL_ARG_CHAR: | |
case MVM_NATIVECALL_ARG_UCHAR: | |
case MVM_NATIVECALL_ARG_SHORT: | |
case MVM_NATIVECALL_ARG_USHORT: | |
case MVM_NATIVECALL_ARG_INT: | |
case MVM_NATIVECALL_ARG_UINT: | |
case MVM_NATIVECALL_ARG_LONG: | |
case MVM_NATIVECALL_ARG_ULONG: | |
case MVM_NATIVECALL_ARG_LONGLONG: | |
case MVM_NATIVECALL_ARG_ULONGLONG: | |
} | |
if (must_free) { | |
to_free[num_free++] = arg; | |
} | |
args[i] = MVM_jit_expr_apply_template_adhoc(tc, tree, "ns..", MVM_JIT_CARG, 1, arg, size); | |
} | |
roots[0] = nullary_void_function(tc, tree, MVM_gc_mark_thread_blocked); | |
{ | |
MVMint32 native_function = const_function_ptr(tc, tree, body->entry_point); | |
MVMint32 arglist = MVM_jit_expr_add_variadic(tc, tree, MVM_JIT_ARGLIST, body->num_args, args); | |
roots[1] = MVM_jit_expr_apply_template_adhoc(tc, tree, "ns...", MVM_JIT_CALL, 2, native_function, arglist); | |
} | |
roots[2] = nullary_void_function(tc, tree, MVM_gc_mark_thread_unblocked); | |
{ | |
MVMint32 free_function = = const_function_ptr(tc, tree, MVM_free); | |
for (i = 0; i < num_free; i++) { | |
roots[3+i] = MVM_jit_expr_apply_template_adhoc( | |
tc, tree, "ns.." /* (carg $arg ptr_sz) */ "nsl" /* (arglist (carg)) */ "ns.l" /* (callv (const_ptr) (arglist)) */ | |
MVM_JIT_CARG, 1, to_free[i], MVM_JIT_PTR_SZ, MVM_JIT_ARGLIST, 1, 0, MVM_JIT_CALLV, 2, free_function, 4 | |
); | |
} | |
} | |
{ | |
MVMint32 box; | |
switch (body->ret_type) { | |
case MVM_NATIVECALL_ARG_CHAR: | |
case MVM_NATIVECALL_ARG_UCHAR: | |
case MVM_NATIVECALL_ARG_SHORT: | |
case MVM_NATIVECALL_ARG_USHORT: | |
case MVM_NATIVECALL_ARG_INT: | |
case MVM_NATIVECALL_ARG_UINT: | |
case MVM_NATIVECALL_ARG_LONG: | |
case MVM_NATIVECALL_ARG_ULONG: | |
case MVM_NATIVECALL_ARG_LONGLONG: | |
case MVM_NATIVECALL_ARG_ULONGLONG: | |
box = box_function(tc, tree, MVM_nativecall_make_int, restype); | |
break; | |
case MVM_NATIVECALL_ARG_CPOINTER: | |
box = box_function(tc, tree, MVM_nativecall_make_cpointer, restype); | |
break; | |
case MVM_NATIVECALL_ARG_UTF8STR: | |
assert(0); | |
break; | |
case MVM_NATIVECALL_ARG_VOID: | |
box = 0; | |
} | |
if (box_node) { | |
roots[3+num_free] = box_function(tc, tree, MVM_nativecall_make_int, roots[1], type_operand); | |
} else if (returns_result) { | |
roots[3+num_free] = MVM_jit_expr_apply_template_adhoc(tc, tree, "ns.", MVM_JIT_COPY, 1, roots[1]); | |
} | |
return MVM_jit_expr_add_variadic(tc, tree, returns_result ? MVM_JIT_DO : MVM_JIT_DOV, num_roots, roots); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment