Ejemplo n.º 1
0
mrb_value
cfunc_type_class_get(mrb_state *mrb, mrb_value klass)
{
    mrb_value pointer;
    mrb_get_args(mrb, "o", &pointer);

    struct mrb_ffi_type *mft = rclass_to_mrb_ffi_type(mrb, mrb_class_ptr(klass));
    return mft->c_to_mrb(mrb, cfunc_pointer_ptr(pointer));
}
Ejemplo n.º 2
0
static void
cfunc_pointer_mrb_to_c(mrb_state *mrb, mrb_value val, void *p)
{
    if(mrb_nil_p(val)) {
        *(void**)p = NULL;
    }
    else {
        *(void**)p = cfunc_pointer_ptr(val);
    }
}
Ejemplo n.º 3
0
mrb_value
cfunc_type_class_set(mrb_state *mrb, mrb_value klass)
{
    mrb_value pointer, val;
    mrb_get_args(mrb, "oo", &pointer, &val);

    struct mrb_ffi_type *mft = rclass_to_mrb_ffi_type(mrb, mrb_class_ptr(klass));
    mft->mrb_to_c(mrb, val, cfunc_pointer_ptr(pointer));

    return val;
}
Ejemplo n.º 4
0
// sint64 specific
mrb_value
cfunc_sint64_class_get(mrb_state *mrb, mrb_value klass)
{
    mrb_value pointer;
    mrb_get_args(mrb, "o", &pointer);

    int64_t sint64 = *(int64_t*)cfunc_pointer_ptr(pointer);

    if(sint64 > INT32_MAX || sint64 < INT32_MIN) {
        mrb_raise(mrb, E_TYPE_ERROR, "out of range. Use low, high");
    }
    return int64_to_mrb(mrb, sint64);
}
Ejemplo n.º 5
0
// uint64 specific
mrb_value
cfunc_uint64_class_get(mrb_state *mrb, mrb_value klass)
{
    mrb_value pointer;
    mrb_get_args(mrb, "o", &pointer);

    uint64_t uint64 = *(uint64_t*)cfunc_pointer_ptr(pointer);

    if(uint64 > UINT32_MAX) {
        mrb_raise(mrb, E_TYPE_ERROR, "too big. Use low, high");
    }
    return int64_to_mrb(mrb, uint64);
}
Ejemplo n.º 6
0
static mrb_value
cfunc_type_class_refer(mrb_state *mrb, mrb_value klass)
{
    struct RClass *c = mrb_class_ptr(klass);
    struct cfunc_type_data *data = mrb_malloc(mrb, sizeof(struct cfunc_type_data));
    data->autofree = false;

    mrb_value pointer;
    mrb_get_args(mrb, "o", &pointer);

    data->refer = true;
    data->value._pointer = cfunc_pointer_ptr(pointer);

    struct RObject *obj = (struct RObject *)Data_Wrap_Struct(mrb, c, &cfunc_type_data, data);
    mrb_obj_iv_set(mrb, obj, mrb_intern_cstr(mrb, "parent_pointer"), pointer); // keep for GC
    return mrb_obj_value(obj);
}
Ejemplo n.º 7
0
mrb_value
cfunc_pointer_initialize(mrb_state *mrb, mrb_value self)
{
    struct cfunc_type_data *data;
    data = mrb_data_check_get_ptr(mrb, self, &cfunc_pointer_data_type);
    if(!data) {
        data = mrb_malloc(mrb, sizeof(struct cfunc_type_data));
        DATA_PTR(self) = data;
        DATA_TYPE(self) = &cfunc_pointer_data_type;   
    }
    data->refer = false;
    data->autofree = false;

    mrb_value ptr;
    int argc = mrb_get_args(mrb, "|o", &ptr);
    if(argc == 0) {
        set_cfunc_pointer_data(data, NULL);
    }
    else {
        set_cfunc_pointer_data(data, cfunc_pointer_ptr(ptr));
    }

    return self;
}
Ejemplo n.º 8
0
static mrb_value
cfunc_call(mrb_state *mrb, mrb_value self)
{
    int margc;
    mrb_value mresult_type, mname, *margs;
    void **values = NULL;
    ffi_type **args = NULL;

    mrb_get_args(mrb, "oo*", &mresult_type, &mname, &margs, &margc);

    void *fp = NULL;
    if(mrb_string_p(mname) || mrb_symbol_p(mname)) {
        void *dlh = dlopen(NULL, RTLD_LAZY);
        fp = dlsym(dlh, mrb_string_value_ptr(mrb, mname));
        dlclose(dlh);
    }
    else {
        fp = cfunc_pointer_ptr(mname);
    }

    if(fp == NULL) {
        mrb_raisef(mrb, E_NAME_ERROR, "can't find C function %s", mrb_string_value_ptr(mrb, mname));
        goto cfunc_call_exit;
    }

    args = malloc(sizeof(ffi_type*) * margc);
    values = malloc(sizeof(void*) * margc);
    mrb_sym sym_to_ffi_value = mrb_intern(mrb, "to_ffi_value");

    mrb_value nil_ary[1];
    nil_ary[0] = mrb_nil_value();
    for(int i = 0; i < margc; ++i) {
        if(mrb_respond_to(mrb, margs[i], sym_to_ffi_value)) {
            args[i] = mrb_value_to_mrb_ffi_type(mrb, margs[i])->ffi_type_value;
            values[i] = cfunc_pointer_ptr(mrb_funcall_argv(mrb, margs[i], sym_to_ffi_value, 1, nil_ary));
        }
        else {
            cfunc_mrb_raise_without_jump(mrb, E_TYPE_ERROR, "ignore argument type %s", mrb_obj_classname(mrb, margs[i]));
            goto cfunc_call_exit;
        }
    }

    ffi_type *result_type = rclass_to_mrb_ffi_type(mrb, mrb_class_ptr(mresult_type))->ffi_type_value;
    if (result_type == NULL) {
        cfunc_mrb_raise_without_jump(mrb, E_ARGUMENT_ERROR, "ignore return type %s", mrb_class_name(mrb, mrb_class_ptr(mresult_type)));
        goto cfunc_call_exit;
    }

    mrb_value mresult = mrb_nil_value();
    ffi_cif cif;
    if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, margc, result_type, args) == FFI_OK) {
        void *result;
        if(result_type->size > sizeof(long)) {
            result = malloc(result_type->size);
        }
        else if(result_type->size) {
            result = malloc(sizeof(long));
        }
        else {
            result = NULL;
        }
        ffi_call(&cif, fp, result, values);

        if(result) {
            mrb_value result_ptr = cfunc_pointer_new_with_pointer(mrb, result, true);
            mresult = mrb_funcall(mrb, mresult_type, "refer", 1, result_ptr);
        }
    }
    else {
        mrb_raisef(mrb, E_NAME_ERROR, "Can't find C function %s", mname);
        goto cfunc_call_exit;
    }

cfunc_call_exit:
    free(values);
    free(args);
    return mresult;
}
Ejemplo n.º 9
0
static void
cfunc_closure_mrb_to_data(mrb_state *mrb, mrb_value val, struct cfunc_type_data *data)
{
    set_cfunc_pointer_data(data, cfunc_pointer_ptr(val));
}
Ejemplo n.º 10
0
static void
cfunc_closure_mrb_to_c(mrb_state *mrb, mrb_value val, void *p)
{
    *(void**)p = cfunc_pointer_ptr(val);
}