Alien-LibJIT
view release on metacpan or search on metacpan
libjit/jitruby/ext/jit.c view on Meta::CPAN
* Context.build { |context| ... }
*
* Create a context and acquire a lock on it, then yield the context to
* the block.
*/
static VALUE context_s_build(VALUE klass)
{
return context_build(context_s_new(klass));
}
/* ---------------------------------------------------------------------------
* Closure
* ---------------------------------------------------------------------------
*/
static void mark_closure(struct Closure * closure)
{
rb_gc_mark(closure->function);
}
VALUE closure_to_int(VALUE self)
{
struct Closure * closure;
Data_Get_Struct(self, struct Closure, closure);
VALUE v = ULONG2NUM((unsigned long)closure->function_ptr);
return v;
}
VALUE closure_to_s(VALUE self)
{
struct Closure * closure;
VALUE args[4];
Data_Get_Struct(self, struct Closure, closure);
args[0] = rb_str_new2("#<JIT::Closure:0x%x function=%s function_ptr=0x%x>");
args[1] = ULONG2NUM((unsigned long)self);
args[2] = rb_any_to_s(closure->function);
args[3] = ULONG2NUM((unsigned long)closure->function_ptr);
return rb_f_sprintf(sizeof(args)/sizeof(args[0]), args);
}
VALUE closure_inspect(VALUE self)
{
return closure_to_s(self);
}
/* ---------------------------------------------------------------------------
* Function
* ---------------------------------------------------------------------------
*/
static void mark_function(jit_function_t function)
{
rb_gc_mark((VALUE)jit_function_get_meta(function, RJT_VALUE_OBJECTS));
rb_gc_mark((VALUE)jit_function_get_meta(function, RJT_CONTEXT));
}
static VALUE create_function(int argc, VALUE * argv, VALUE klass)
{
VALUE context_v;
VALUE signature_v;
VALUE parent_function_v;
jit_function_t function;
jit_function_t parent_function;
jit_context_t context;
jit_type_t signature;
jit_type_t untagged_signature;
VALUE function_v;
VALUE functions;
int signature_tag;
rb_scan_args(argc, argv, "21", &context_v, &signature_v, &parent_function_v);
Data_Get_Struct(context_v, struct _jit_context, context);
Data_Get_Struct(signature_v, struct _jit_type, signature);
signature_tag = jit_type_get_kind(signature);
/* If this signature was tagged, get the untagged type */
if((untagged_signature = jit_type_get_tagged_type(signature)))
{
signature = untagged_signature;
}
if(RTEST(parent_function_v))
{
/* If this function has a parent, then it is a nested function */
Data_Get_Struct(parent_function_v, struct _jit_function, parent_function);
function = jit_function_create_nested(context, signature, parent_function);
}
else
{
/* Otherwise, it's a standalone function */
function = jit_function_create(context, signature);
}
/* Make sure the function is around as long as the context is */
if(!jit_function_set_meta(function, RJT_VALUE_OBJECTS, (void *)rb_ary_new(), 0, 0))
{
rb_raise(rb_eNoMemError, "Out of memory");
}
/* Remember the signature's tag for later */
if(!jit_function_set_meta(function, RJT_TAG_FOR_SIGNATURE, (void *)signature_tag, 0, 0))
{
rb_raise(rb_eNoMemError, "Out of memory");
}
/* And remember the function's context for later */
if(!jit_function_set_meta(function, RJT_CONTEXT, (void *)context_v, 0, 0))
{
rb_raise(rb_eNoMemError, "Out of memory");
}
function_v = Data_Wrap_Struct(rb_cFunction, mark_function, 0, function);
/* Add this function to the context's list of functions */
functions = (VALUE)jit_context_get_meta(context, RJT_FUNCTIONS);
rb_ary_push(functions, function_v);
return function_v;
}
/*
* call-seq:
* function.compile()
*
* Begin compiling a function.
*/
static VALUE function_compile(VALUE self)
{
jit_function_t function;
Data_Get_Struct(self, struct _jit_function, function);
if(!jit_function_compile(function))
{
rb_raise(rb_eRuntimeError, "Unable to compile function");
}
return self;
}
/*
* call-seq:
* function = Function.new(context, signature, [parent])
*
* Create a new function.
*/
static VALUE function_s_new(int argc, VALUE * argv, VALUE klass)
{
if(rb_block_given_p())
{
rb_raise(rb_eArgError, "Function.new does not take a block");
}
return create_function(argc, argv, klass);
}
static VALUE function_abandon_if_exception(VALUE function_v)
{
if(ruby_errinfo)
{
jit_function_t function;
Data_Get_Struct(function_v, struct _jit_function, function);
jit_function_abandon(function);
}
return Qnil;
}
/*
* call-seq:
* function = Function.new(context, signature, [parent]) { |function| ... }
*
* Create a new function, begin compiling it, and pass the function to
* the block.
*/
static VALUE function_s_compile(int argc, VALUE * argv, VALUE klass)
{
VALUE function = create_function(argc, argv, klass);
rb_yield(function);
function_compile(function);
#ifdef HAVE_RB_ENSURE
rb_ensure(
function_compile,
function,
function_abandon_if_exception,
function);
#else
/* Rubinius does not yet have rb_ensure */
function_compile(function);
function_abandon_if_exception(function);
#endif
return function;
}
/*
* Get the value that corresponds to a specified function parameter.
*
* call-seq:
* value = function.get_param(index)
*/
static VALUE function_get_param(VALUE self, VALUE idx)
{
jit_function_t function;
jit_value_t value;
Data_Get_Struct(self, struct _jit_function, function);
value = jit_value_get_param(function, NUM2INT(idx));
raise_memory_error_if_zero(value);
return Data_Wrap_Struct(rb_cValue, 0, 0, value);
}
#include "insns.inc"
static VALUE function_value_klass(VALUE self, VALUE type_v, VALUE klass)
{
jit_function_t function;
jit_type_t type;
jit_value_t value;
Data_Get_Struct(self, struct _jit_function, function);
type_v = lookup_const(rb_cType, type_v);
check_type("type", rb_cType, type_v);
Data_Get_Struct(type_v, struct _jit_type, type);
/* TODO: When we wrap a value, we should inject a reference to the
* function in the object, so the function stays around as long as the
* value does */
value = jit_value_create(function, type);
return Data_Wrap_Struct(klass, 0, 0, value);
}
( run in 1.273 second using v1.01-cache-2.11-cpan-4991d5b9bd9 )