示例#1
0
  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);
  }
示例#2
0
  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));
  }
示例#3
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);
  }
示例#5
0
  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);
  }
示例#6
0
  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;
  }
示例#7
0
  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);
  }
示例#9
0
  /* 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;
  }
示例#10
0
  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);
  }
示例#13
0
  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);
  }
示例#16
0
  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);
  }
示例#17
0
  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;
  }
示例#18
0
/* 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;
    }
}
示例#19
0
  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));
  }
示例#21
0
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;
}
示例#22
0
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"));
 }