コード例 #1
0
ファイル: cfunc_type.c プロジェクト: asfluido/mruby-cfunc
struct mrb_ffi_type*
mrb_value_to_mrb_ffi_type(mrb_state *mrb, mrb_value val)
{
    if(mrb_nil_p(val)) {
        return rclass_to_mrb_ffi_type(mrb, cfunc_state(mrb, NULL)->pointer_class);
    }
    switch(mrb_type(val)) {
        case MRB_TT_TRUE:
        case MRB_TT_FALSE:
            return rclass_to_mrb_ffi_type(mrb, cfunc_state(mrb, NULL)->sint32_class);
        default:
            return rclass_to_mrb_ffi_type(mrb, mrb_object(val)->c);
    }
}
コード例 #2
0
ファイル: cfunc_rubyvm.c プロジェクト: a-bx/mruby-cfunc
mrb_value
cfunc_rubyvm_class_thread(mrb_state *mrb, mrb_value klass)
{
    // init bindle data with RubyVM object
    struct RClass *c = mrb_class_ptr(klass);
    struct cfunc_rubyvm_data *data = malloc(sizeof(struct cfunc_rubyvm_data));
    data->mrb_state_init = cfunc_state(mrb)->mrb_state_init;
    mrb_value self = mrb_obj_value((struct RObject *)Data_Wrap_Struct(mrb, c, &cfunc_rubyvm_data_type, data));

    // load script
    mrb_value filename, str;
    mrb_get_args(mrb, "S", &filename);
    str = mrb_str_new_cstr(mrb, "mruby_data_");
    mrb_str_concat(mrb, str, mrb_str_new(mrb, RSTRING_PTR(filename), RSTRING_LEN(filename)));

    void *dlh = dlopen(NULL, RTLD_LAZY);
    data->mrb_data = (const char *)dlsym(dlh, RSTRING_PTR(str));

    if (!data->mrb_data) {
        dlclose(dlh);
        mrb_raisef(mrb, E_SCRIPT_ERROR, "file '%s' not found.", RSTRING_PTR(str));
    }

    // initial pthread
    data->queue = create_vector();
    pthread_mutex_init(&data->queue_mutex, NULL);
    pthread_cond_init(&data->queue_cond, NULL);
    pthread_create(&data->thread, NULL, cfunc_rubyvm_open, (void*)data);

    return self;
}
コード例 #3
0
ファイル: cfunc_rubyvm.c プロジェクト: a-bx/mruby-cfunc
mrb_value
cfunc_rubyvm_dispatch(mrb_state *mrb, mrb_value self)
{
    struct cfunc_rubyvm_data *data = mrb_get_datatype(mrb, self, &cfunc_rubyvm_data_type);

    mrb_value name_obj, *args;
    int args_len;
    mrb_get_args(mrb, "o*", &name_obj, &args, &args_len);

    struct queue_task *task = malloc(sizeof(struct queue_task));
    task->refcount = 2;
    task->result = NULL;
    task->status = queue_task_queued;

    pthread_mutex_init(&task->sync_mutex, NULL);
    pthread_cond_init(&task->sync_cond, NULL);

    const char* name = mrb_string_value_ptr(mrb, name_obj);
    int name_len = strlen(name);
    task->name = malloc(name_len+1);
    strncpy(task->name, name, name_len+1);

    task->args_len = args_len;
    task->args = malloc(sizeof(struct task_arg) * task->args_len);
    for(int i=0; i<args_len; ++i) {
        task->args[i] = mrb_value_to_task_arg(mrb, args[i]);
    }

    pthread_mutex_lock(&data->queue_mutex);
    vector_enqueue(data->queue, task);
    pthread_cond_signal(&data->queue_cond);
    pthread_mutex_unlock(&data->queue_mutex);

    return mrb_obj_value((struct RObject *)Data_Wrap_Struct(mrb, cfunc_state(mrb)->rubyvm_task_class, &cfunc_rubyvm_task_data_type, task));
}
コード例 #4
0
void
init_cfunc_pointer(mrb_state *mrb, struct RClass* module)
{
    struct cfunc_state *state = cfunc_state(mrb, module);

    struct RClass *pointer_class = mrb_define_class_under(mrb, module, "Pointer", state->type_class);
    mrb_value ffi_type = mrb_obj_value(Data_Wrap_Struct(mrb, mrb->object_class, &cfunc_pointer_ffi_data_type, &pointer_mrb_ffi_type));
    mrb_obj_iv_set(mrb, (struct RObject*)pointer_class, mrb_intern_cstr(mrb, "@ffi_type"), ffi_type);
    state->pointer_class = pointer_class;

    mrb_define_class_method(mrb, pointer_class, "refer", cfunc_pointer_refer, ARGS_REQ(1));
    mrb_define_class_method(mrb, pointer_class, "malloc", cfunc_pointer_class_malloc, ARGS_REQ(1));

    mrb_define_method(mrb, pointer_class, "initialize", cfunc_pointer_initialize, ARGS_ANY());
    mrb_define_method(mrb, pointer_class, "realloc", cfunc_pointer_realloc, ARGS_REQ(1));
    mrb_define_method(mrb, pointer_class, "free", cfunc_pointer_free, ARGS_NONE());
    mrb_define_method(mrb, pointer_class, "inspect", cfunc_pointer_inspect, ARGS_NONE());
    mrb_define_method(mrb, pointer_class, "is_null?", cfunc_pointer_is_null, ARGS_NONE());
    mrb_define_method(mrb, pointer_class, "autofree", cfunc_pointer_autofree, ARGS_NONE());

    mrb_define_method(mrb, pointer_class, "offset", cfunc_pointer_offset, ARGS_REQ(1));
    mrb_define_method(mrb, pointer_class, "to_s", cfunc_pointer_to_s, ARGS_NONE());
    
    // add method to system classes
    mrb_define_method(mrb, mrb->string_class, "addr", cfunc_string_addr, ARGS_NONE());
    mrb_obj_iv_set(mrb, (struct RObject *)mrb->string_class, mrb_intern_cstr(mrb, "@ffi_type"), ffi_type);
}
コード例 #5
0
ファイル: cfunc_struct.c プロジェクト: asfluido/mruby-cfunc
void
init_cfunc_struct(mrb_state *mrb, struct RClass* module)
{
    struct cfunc_state *state = cfunc_state(mrb, module);
    struct RClass *struct_class = mrb_define_class_under(mrb, module, "Struct", mrb->object_class);
    set_cfunc_state(mrb, struct_class, state);
    state->struct_class = struct_class;
    
    mrb_define_class_method(mrb, struct_class, "define_struct", cfunc_struct_define_struct, ARGS_REQ(1));
}
コード例 #6
0
ファイル: cfunc_closure.c プロジェクト: asfluido/mruby-cfunc
void
init_cfunc_closure(mrb_state *mrb, struct RClass* module)
{
    struct cfunc_state *state = cfunc_state(mrb, module);
    struct RClass *closure_class = mrb_define_class_under(mrb, module, "Closure", state->pointer_class);
    state->closure_class = closure_class;

    mrb_value ffi_type = mrb_obj_value(Data_Wrap_Struct(mrb, mrb->object_class, &cfunc_closure_ffi_type_data_type, &closure_mrb_ffi_type));
    mrb_obj_iv_set(mrb, (struct RObject*)closure_class, mrb_intern_cstr(mrb, "@ffi_type"), ffi_type);

    mrb_define_method(mrb, closure_class, "initialize", cfunc_closure_initialize, ARGS_ANY());
}
コード例 #7
0
mrb_value
cfunc_pointer_new_with_pointer(mrb_state *mrb, void *p, bool autofree)
{
    struct cfunc_type_data *data = mrb_malloc(mrb, sizeof(struct cfunc_type_data));
    data->refer = false;
    data->autofree = autofree;

    set_cfunc_pointer_data(data, p);

    struct cfunc_state *state = cfunc_state(mrb, NULL);
    return mrb_obj_value(Data_Wrap_Struct(mrb, state->pointer_class, &cfunc_pointer_data_type, data));
}
コード例 #8
0
ファイル: cfunc_rubyvm.c プロジェクト: a-bx/mruby-cfunc
void
init_cfunc_rubyvm(mrb_state *mrb, struct RClass* module, void (*mrb_state_init)(mrb_state*))
{
    cfunc_state(mrb)->mrb_state_init = mrb_state_init;

    struct RClass *rubyvm_class = mrb_define_class_under(mrb, module, "RubyVM", mrb->object_class);
    cfunc_state(mrb)->rubyvm_class = rubyvm_class;

    mrb_define_class_method(mrb, rubyvm_class, "thread", cfunc_rubyvm_class_thread, ARGS_REQ(1));
    mrb_define_method(mrb, rubyvm_class, "dispatch", cfunc_rubyvm_dispatch, ARGS_ANY());

    struct RClass *rubyvm_task_class = mrb_define_class_under(mrb, cfunc_state(mrb)->rubyvm_class, "Task", mrb->object_class);
    cfunc_state(mrb)->rubyvm_task_class = rubyvm_task_class;

    mrb_define_method(mrb, rubyvm_task_class, "wait", cfunc_rubyvm_task_wait, ARGS_NONE());
    mrb_define_method(mrb, rubyvm_task_class, "result", cfunc_rubyvm_task_result, ARGS_NONE());
    mrb_define_method(mrb, rubyvm_task_class, "status", cfunc_rubyvm_task_status, ARGS_NONE());

    mrb_define_const(mrb, rubyvm_task_class, "QUEUED", mrb_fixnum_value(queue_task_queued));
    mrb_define_const(mrb, rubyvm_task_class, "RUNNING", mrb_fixnum_value(queue_task_running));
    mrb_define_const(mrb, rubyvm_task_class, "FINISHED", mrb_fixnum_value(queue_task_finished));
}
コード例 #9
0
ファイル: cfunc_type.c プロジェクト: asfluido/mruby-cfunc
void init_cfunc_type(mrb_state *mrb, struct RClass* module)
{
    struct cfunc_state *state = cfunc_state(mrb, module);
    struct RClass *type_class = mrb_define_class_under(mrb, module, "Type", mrb->object_class);
    MRB_SET_INSTANCE_TT(type_class, MRB_TT_DATA);
    state->type_class = type_class;
    set_cfunc_state(mrb, type_class, state);

    int ai = mrb_gc_arena_save(mrb);
    mrb_define_class_method(mrb, type_class, "refer", cfunc_type_class_refer, ARGS_REQ(1));
    mrb_define_class_method(mrb, type_class, "size", cfunc_type_size, ARGS_NONE());
    mrb_define_class_method(mrb, type_class, "align", cfunc_type_align, ARGS_NONE());
    mrb_define_class_method(mrb, type_class, "get", cfunc_type_class_get, ARGS_REQ(1));
    mrb_define_class_method(mrb, type_class, "set", cfunc_type_class_set, ARGS_REQ(2));

    mrb_define_method(mrb, type_class, "initialize", cfunc_type_initialize, ARGS_ANY());
    mrb_define_method(mrb, type_class, "value", cfunc_type_get_value, ARGS_NONE());
    mrb_define_method(mrb, type_class, "value=", cfunc_type_set_value, ARGS_REQ(1));
    mrb_define_method(mrb, type_class, "addr", cfunc_type_addr, ARGS_NONE());
    mrb_define_method(mrb, type_class, "to_ffi_value", cfunc_type_addr, ARGS_NONE());
    DONE;

    int map_size = sizeof(types) / sizeof(struct mrb_ffi_type);
    int i;
    for(i = 0; i < map_size; ++i) {
        struct RClass *new_class = mrb_define_class_under(mrb, module, types[i].name, type_class);
        mrb_value ffi_type = mrb_obj_value(Data_Wrap_Struct(mrb, mrb->object_class, &cfunc_class_ffi_data_type, &types[i]));
        mrb_obj_iv_set(mrb, (struct RObject*)new_class, mrb_intern_cstr(mrb, "@ffi_type"), ffi_type);
    }
    DONE;
    
    mrb_value mod = mrb_obj_value(module);
    state->void_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_cstr(mrb, "Void")));
    state->uint8_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_cstr(mrb, "UInt8")));
    state->sint8_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_cstr(mrb, "SInt8")));
    state->uint16_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_cstr(mrb, "UInt16")));
    state->sint16_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_cstr(mrb, "SInt16")));
    state->uint32_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_cstr(mrb, "UInt32")));
    state->sint32_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_cstr(mrb, "SInt32")));
    state->uint64_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_cstr(mrb, "UInt64")));
    state->sint64_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_cstr(mrb, "SInt64")));
    state->float_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_cstr(mrb, "Float")));
    state->double_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_cstr(mrb, "Double")));
    DONE;

    mrb_define_class_method(mrb, mrb->nil_class, "size", cfunc_nil_size, ARGS_NONE());
    mrb_define_class_method(mrb, mrb->nil_class, "align", cfunc_nil_align, ARGS_NONE());
    DONE;

    // uint64 specific
    struct RClass *uint64_class = state->uint64_class;
    mrb_define_class_method(mrb, uint64_class, "get", cfunc_uint64_class_get, ARGS_REQ(1));
    mrb_define_method(mrb, uint64_class, "value", cfunc_uint64_get_value, ARGS_NONE());
    mrb_define_method(mrb, uint64_class, "low", cfunc_uint64_get_low, ARGS_NONE());
    mrb_define_method(mrb, uint64_class, "low=", cfunc_uint64_set_low, ARGS_REQ(1));
    mrb_define_method(mrb, uint64_class, "high", cfunc_uint64_get_high, ARGS_NONE());
    mrb_define_method(mrb, uint64_class, "high=", cfunc_uint64_set_high, ARGS_REQ(1));
    mrb_define_method(mrb, uint64_class, "to_s", cfunc_uint64_to_s, ARGS_REQ(1));
    mrb_define_method(mrb, uint64_class, "divide", cfunc_uint64_divide, ARGS_REQ(1));
    DONE;
    
    // sint64 specific
    struct RClass *sint64_class = state->sint64_class;
    mrb_define_class_method(mrb, sint64_class, "get", cfunc_sint64_class_get, ARGS_REQ(1));
    mrb_define_method(mrb, sint64_class, "value", cfunc_sint64_get_value, ARGS_NONE());
    mrb_define_method(mrb, sint64_class, "low", cfunc_uint64_get_low, ARGS_NONE());
    mrb_define_method(mrb, sint64_class, "low=", cfunc_uint64_set_low, ARGS_REQ(1));
    mrb_define_method(mrb, sint64_class, "high", cfunc_uint64_get_high, ARGS_NONE());
    mrb_define_method(mrb, sint64_class, "high=", cfunc_uint64_set_high, ARGS_REQ(1));
    mrb_define_method(mrb, sint64_class, "to_s", cfunc_int64_to_s, ARGS_REQ(1));
    DONE;
}