Skip to content

Instantly share code, notes, and snippets.

@bdw
Created October 9, 2018 10:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bdw/189cfec71ec13012687c6872b0682f5e to your computer and use it in GitHub Desktop.
Save bdw/189cfec71ec13012687c6872b0682f5e to your computer and use it in GitHub Desktop.
#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