void test_bind_with_unsigned_long() { String* name = String::create(state, "dummy_unsigned_long"); Array* args = Array::create(state, 1); args->set(state, 0, Fixnum::from(RBX_FFI_TYPE_ULONG)); Object* ret = Fixnum::from(RBX_FFI_TYPE_ULONG); NativeFunction *func = NativeFunction::bind(state, Qnil, name, args, ret); TS_ASSERT(!func->nil_p()); Array* input = Array::create(state, 1); input->set(state, 0, Fixnum::from(13)); Arguments args_obj(input); Object* out = func->call(state, args_obj, NULL); TS_ASSERT(kind_of<Integer>(out)); TS_ASSERT_EQUALS(as<Integer>(out)->to_native(), (native_int)13); input = Array::create(state, 1); input->set(state, 0, Integer::from(state, (unsigned long)2147483647)); Arguments args_obj2(input); out = func->call(state, args_obj2, NULL); TS_ASSERT(kind_of<Integer>(out)); TS_ASSERT_EQUALS(as<Integer>(out)->to_native(), (native_int)2147483647); }
void test_bind_with_unsigned_short() { String* name = String::create(state, "dummy_unsigned_short"); Array* args = Array::create(state, 1); args->set(state, 0, Fixnum::from(RBX_FFI_TYPE_USHORT)); Object* ret = Fixnum::from(RBX_FFI_TYPE_USHORT); NativeFunction *func = NativeFunction::bind(state, Qnil, name, args, ret); TS_ASSERT(!func->nil_p()); Array* input = Array::create(state, 2); input->set(state, 0, Fixnum::from(0)); Arguments args_obj(input); Object* out = func->call(state, args_obj, NULL); TS_ASSERT(kind_of<Fixnum>(out)); input = Array::create(state, 2); input->set(state, 0, out); Arguments args_obj2(input); out = func->call(state, args_obj2, NULL); TS_ASSERT(kind_of<Fixnum>(out)); TS_ASSERT_EQUALS(out, Fixnum::from(0)); }
/* Run when a NativeFunction is executed. Executes the related C function. */ ExecuteStatus NativeFunction::execute(STATE, Task* task, Message& msg) { NativeFunction* nfunc = as<NativeFunction>(msg.method); Object* obj = nfunc->call(state, &msg); task->push(obj); return cExecuteContinue; }
void test_bind_with_void() { Pointer* name = Pointer::create(state, (void*)dummy_void); Array* args = Array::create(state, 0); Object* ret = Fixnum::from(RBX_FFI_TYPE_VOID); NativeFunction *func = NativeFunction::generate(state, name, state->symbol("ffi"), args, ret); TS_ASSERT(!func->nil_p()); Arguments args_obj; Object* out = func->call(state, args_obj, NULL); TS_ASSERT_EQUALS(out, Qnil); }
void test_bind_with_void() { String* name = String::create(state, "dummy_void"); Array* args = Array::create(state, 0); Object* ret = Fixnum::from(RBX_FFI_TYPE_VOID); NativeFunction *func = NativeFunction::bind(state, Qnil, name, args, ret); TS_ASSERT(!func->nil_p()); Arguments args_obj; Object* out = func->call(state, args_obj, NULL); TS_ASSERT_EQUALS(out, Qnil); }
NativeFunction* NativeFunction::create(STATE, Object* name, int args) { NativeFunction* nf = (NativeFunction*)state->new_object(G(native_function)); nf->primitive(state, state->symbol("nativefunction_call")); nf->required(state, Fixnum::from(args)); nf->serial(state, Fixnum::from(0)); nf->name(state, name); nf->file(state, state->symbol("<system>")); nf->data(state, (MemoryPointer*)Qnil); nf->set_executor(NativeFunction::execute); return nf; }
void test_bind_with_string_and_ptr_for_null() { Array* args = Array::create(state, 0); Object* ret = Fixnum::from(RBX_FFI_TYPE_STRPTR); String* name = String::create(state, "null_string"); NativeFunction *func = NativeFunction::bind(state, Qnil, name, args, ret); TS_ASSERT(!func->nil_p()); Arguments args_obj; Array* out = try_as<Array>(func->call(state, args_obj, NULL)); TS_ASSERT(kind_of<Array>(out)); TS_ASSERT_EQUALS(out->get(state, 0), Qnil); TS_ASSERT_EQUALS(out->get(state, 1), Qnil); }
void test_bind_with_string_and_ptr_for_null() { Array* args = Array::create(state, 0); Object* ret = Fixnum::from(RBX_FFI_TYPE_STRPTR); Pointer* name = Pointer::create(state, (void*)null_string); NativeFunction *func = NativeFunction::generate(state, name, state->symbol("ffi"), args, ret); TS_ASSERT(!func->nil_p()); Arguments args_obj; Array* out = try_as<Array>(func->call(state, args_obj, NULL)); TS_ASSERT(kind_of<Array>(out)); TS_ASSERT_EQUALS(out->get(state, 0), Qnil); TS_ASSERT_EQUALS(out->get(state, 1), Qnil); }
/* Run when a NativeFunction is executed. Executes the related C function. */ Object* NativeFunction::execute(STATE, CallFrame* call_frame, Dispatch& msg, Arguments& args) { NativeFunction* nfunc = as<NativeFunction>(msg.method); state->set_call_frame(call_frame); #ifdef RBX_PROFILER if(unlikely(state->shared.profiling())) state->profiler()->enter_method(msg, args); #endif Object* obj = nfunc->call(state, args); #ifdef RBX_PROFILER if(unlikely(state->shared.profiling())) state->profiler()->leave(); #endif return obj; }
void test_bind_with_state() { global_state = state; String* name = String::create(state, "dummy_state"); Array* args = Array::create(state, 1); args->set(state, 0, Fixnum::from(RBX_FFI_TYPE_STATE)); Object* ret = Fixnum::from(RBX_FFI_TYPE_INT); NativeFunction *func = NativeFunction::bind(state, Qnil, name, args, ret); TS_ASSERT(!func->nil_p()); Arguments args_obj; Object* out = func->call(state, args_obj, NULL); TS_ASSERT(kind_of<Fixnum>(out)); TS_ASSERT(as<Fixnum>(out)->to_native()); }
void test_bind_with_state() { global_state = state; Pointer* name = Pointer::create(state, (void*)dummy_state); Array* args = Array::create(state, 1); args->set(state, 0, Fixnum::from(RBX_FFI_TYPE_STATE)); Object* ret = Fixnum::from(RBX_FFI_TYPE_INT); NativeFunction *func = NativeFunction::generate(state, name, state->symbol("ffi"), args, ret); TS_ASSERT(!func->nil_p()); Arguments args_obj; Object* out = func->call(state, args_obj, NULL); TS_ASSERT(kind_of<Fixnum>(out)); TS_ASSERT(as<Fixnum>(out)->to_native()); }
void test_bind_with_double() { Pointer* name = Pointer::create(state, (void*)dummy_double); Array* args = Array::create(state, 1); args->set(state, 0, Fixnum::from(RBX_FFI_TYPE_DOUBLE)); Object* ret = Fixnum::from(RBX_FFI_TYPE_DOUBLE); NativeFunction *func = NativeFunction::generate(state, name, state->symbol("ffi"), args, ret); TS_ASSERT(!func->nil_p()); Array* input = Array::create(state, 1); input->set(state, 0, Float::create(state, 13.2)); Arguments args_obj(input); Object* out = func->call(state, args_obj, NULL); TS_ASSERT(kind_of<Float>(out)); TS_ASSERT_EQUALS(as<Float>(out)->val, 13.2); }
void test_bind_with_double() { String* name = String::create(state, "dummy_double"); Array* args = Array::create(state, 1); args->set(state, 0, Fixnum::from(RBX_FFI_TYPE_DOUBLE)); Object* ret = Fixnum::from(RBX_FFI_TYPE_DOUBLE); NativeFunction *func = NativeFunction::bind(state, Qnil, name, args, ret); TS_ASSERT(!func->nil_p()); Array* input = Array::create(state, 1); input->set(state, 0, Float::create(state, 13.2)); Arguments args_obj(input); Object* out = func->call(state, args_obj, NULL); TS_ASSERT(kind_of<Float>(out)); TS_ASSERT_EQUALS(as<Float>(out)->val, 13.2); }
void test_bind_with_short() { Pointer* name = Pointer::create(state, (void*)dummy_short); Array* args = Array::create(state, 1); args->set(state, 0, Fixnum::from(RBX_FFI_TYPE_SHORT)); Object* ret = Fixnum::from(RBX_FFI_TYPE_SHORT); NativeFunction *func = NativeFunction::generate(state, name, state->symbol("ffi"), args, ret); TS_ASSERT(!func->nil_p()); Array* input = Array::create(state, 1); input->set(state, 0, Fixnum::from(13)); Arguments args_obj(input); Object* out = func->call(state, args_obj, NULL); TS_ASSERT(kind_of<Fixnum>(out)); TS_ASSERT_EQUALS(as<Fixnum>(out)->to_native(), 13); }
void test_bind_with_string() { Pointer* name = Pointer::create(state, (void*)strlen); Array* args = Array::create(state, 1); args->set(state, 0, Fixnum::from(RBX_FFI_TYPE_STRING)); Object* ret = Fixnum::from(RBX_FFI_TYPE_INT); NativeFunction *func = NativeFunction::generate(state, name, state->symbol("ffi"), args, ret); TS_ASSERT(!func->nil_p()); Array* input = Array::create(state, 1); input->set(state, 0, String::create(state, "strlen")); Arguments args_obj(input); Object* out = func->call(state, args_obj, NULL); TS_ASSERT(out->fixnum_p()); TS_ASSERT_EQUALS(as<Integer>(out)->to_native(), 6); }
void test_bind_with_char() { String* name = String::create(state, "dummy_char"); Array* args = Array::create(state, 1); args->set(state, 0, Fixnum::from(RBX_FFI_TYPE_CHAR)); Object* ret = Fixnum::from(RBX_FFI_TYPE_CHAR); NativeFunction *func = NativeFunction::bind(state, Qnil, name, args, ret); TS_ASSERT(!func->nil_p()); Array* input = Array::create(state, 1); input->set(state, 0, Fixnum::from(13)); Arguments args_obj(input); Object* out = func->call(state, args_obj, NULL); TS_ASSERT(kind_of<Fixnum>(out)); TS_ASSERT_EQUALS(as<Fixnum>(out)->to_native(), 13); }
NativeFunction* NativeFunction::create(STATE, Symbol* name, int args) { NativeFunction* nf = state->new_object<NativeFunction>(G(native_function)); nf->primitive(state, state->symbol("nativefunction_call")); nf->required(state, Fixnum::from(args)); nf->serial(state, Fixnum::from(0)); nf->name(state, name); nf->file(state, state->symbol("<system>")); nf->set_executor(NativeFunction::execute); return nf; }
/* Run when a NativeFunction is executed. Executes the related C function. */ Object* NativeFunction::execute(STATE, CallFrame* call_frame, Executable* exec, Module* mod, Arguments& args) { NativeFunction* nfunc = as<NativeFunction>(exec); state->set_call_frame(call_frame); try { OnStack<2> os(state, exec, mod); #ifdef RBX_PROFILER if(unlikely(state->vm()->tooling())) { tooling::MethodEntry method(state, exec, mod, args); RUBINIUS_METHOD_FFI_ENTRY_HOOK(state, mod, args.name(), call_frame); Object* ret = nfunc->call(state, args, call_frame); RUBINIUS_METHOD_FFI_RETURN_HOOK(state, mod, args.name(), call_frame); return ret; } else { RUBINIUS_METHOD_FFI_ENTRY_HOOK(state, mod, args.name(), call_frame); Object* ret = nfunc->call(state, args, call_frame); RUBINIUS_METHOD_FFI_RETURN_HOOK(state, mod, args.name(), call_frame); return ret; } #else RUBINIUS_METHOD_FFI_ENTRY_HOOK(state, mod, args.name(), call_frame); Object* ret = nfunc->call(state, args, call_frame); RUBINIUS_METHOD_FFI_RETURN_HOOK(state, mod, args.name(), call_frame); return ret; #endif } catch(TypeError &e) { Exception* exc = Exception::make_type_error(state, e.type, e.object, e.reason); exc->locations(state, Location::from_call_stack(state, call_frame)); state->raise_exception(exc); RUBINIUS_METHOD_FFI_RETURN_HOOK(state, mod, args.name(), call_frame); return NULL; } }
void test_bind_with_string_null() { String* name = String::create(state, "getcwd"); Array* args = Array::create(state, 2); args->set(state, 0, Fixnum::from(RBX_FFI_TYPE_STRING)); args->set(state, 1, Fixnum::from(RBX_FFI_TYPE_INT)); Object* ret = Fixnum::from(RBX_FFI_TYPE_STRING); NativeFunction *func = NativeFunction::bind(state, Qnil, name, args, ret); TS_ASSERT(!func->nil_p()); Array* input = Array::create(state, 2); input->set(state, 0, Qnil); input->set(state, 1, Fixnum::from(0)); Arguments args_obj(input); Object* out = func->call(state, args_obj, NULL); TS_ASSERT(kind_of<String>(out)); }
void test_bind_with_string_null() { Pointer* name = Pointer::create(state, (void*)getcwd); Array* args = Array::create(state, 2); args->set(state, 0, Fixnum::from(RBX_FFI_TYPE_STRING)); args->set(state, 1, Fixnum::from(RBX_FFI_TYPE_INT)); Object* ret = Fixnum::from(RBX_FFI_TYPE_STRING); NativeFunction *func = NativeFunction::generate(state, name, state->symbol("ffi"), args, ret); TS_ASSERT(!func->nil_p()); Array* input = Array::create(state, 2); input->set(state, 0, Qnil); input->set(state, 1, Fixnum::from(0)); Arguments args_obj(input); Object* out = func->call(state, args_obj, NULL); TS_ASSERT(kind_of<String>(out)); }
NativeFunction* NativeFunction::create(STATE, Symbol* name, int args) { NativeFunction* nf = state->new_object<NativeFunction>(G(native_function)); nf->primitive(state, state->symbol("nativefunction_call")); nf->required(state, Fixnum::from(args)); nf->varargs(state, cFalse); nf->serial(state, Fixnum::from(0)); nf->name(state, name); nf->file(state, state->symbol("<system>")); nf->set_executor(NativeFunction::execute); nf->inliners_ = 0; nf->prim_index_ = -1; nf->custom_call_site_ = false; nf->ffi_data = 0; return nf; }
void function_class_init(as_object& where, const ObjectURI& uri) { Global_as& gl = getGlobal(where); NativeFunction* func = new NativeFunction(gl, function_ctor); as_object* proto = createObject(gl); func->init_member(NSV::PROP_PROTOTYPE, proto); func->init_member(NSV::PROP_CONSTRUCTOR, func); proto->init_member(NSV::PROP_CONSTRUCTOR, func); // Register _global.Function, only visible for SWF6 up const int swf6flags = as_object::DefaultFlags | PropFlags::onlySWF6Up; func->init_member(NSV::PROP_uuPROTOuu, proto, swf6flags); where.init_member(uri, func, swf6flags); VM& vm = getVM(where); // Note: these are the first functions created, and they need the // Function class to be registered. proto->init_member("call", vm.getNative(101, 10), swf6flags); proto->init_member("apply", vm.getNative(101, 11), swf6flags); }
void test_create() { NativeFunction* func = NativeFunction::create(state, state->symbol("blah"), 0); TS_ASSERT_EQUALS(func->name(), state->symbol("blah")); }