Skip to content

Instantly share code, notes, and snippets.

@kugel-
Last active September 26, 2016 21:51
Show Gist options
  • Save kugel-/20412b414ea5a10ea55079d9b43c82e8 to your computer and use it in GitHub Desktop.
Save kugel-/20412b414ea5a10ea55079d9b43c82e8 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <dlfcn.h>
#include <ruby.h>
#include <gtk/gtk.h>
#include <libpeas/peas-activatable.h>
static VALUE wrap_rb_load(VALUE v)
{
rb_load(v, 0);
return Qnil;
}
static VALUE wrap_rb_f_require(VALUE v)
{
return rb_f_require(Qnil, v);
}
static void require(const char *script)
{
VALUE ret;
int exc_state;
VALUE fn = rb_str_new2(script);
OBJ_FREEZE(fn);
rb_protect(wrap_rb_f_require, fn, &exc_state);
//~ rb_protect(wrap_rb_load, script, &exc_state);
if (exc_state)
{
VALUE e = rb_errinfo();
ret = rb_funcall(e, rb_intern("message"), 0);
fprintf(stderr, "%s\n", StringValueCStr(ret));
rb_set_errinfo(Qnil);
}
}
static void *ffiptr2gobj(VALUE obj)
{
VALUE ptr = rb_funcall(obj, rb_intern("to_ptr"), 0);
VALUE addr = rb_funcall(ptr, rb_intern("address"), 0);
return (void*)((uintptr_t) NUM2ULL(addr));
}
int main(int argc, char* argv[])
{
VALUE foo;
VALUE script;
VALUE ret;
void *p;
int state;
/* construct the VM */
ruby_init();
ruby_init_loadpath();
/* Ruby goes here */
char frame[32];
void (*rbffi_frame_push)(void* frame);
require("/tmp/test.rb");
/* THIS WORKS AROUND THE FREEZE BELOW */
rbffi_frame_push = dlsym(NULL, "rbffi_frame_push");
rbffi_frame_push(frame);
/* */
foo = rb_gv_get("$foo");
if (NIL_P(foo)) {
printf("foo is nil\n");
goto out;
}
ret = rb_funcall(foo, rb_intern("inspect"), 0);
printf("%s\n", StringValueCStr(ret));
p = rb_protect(ffiptr2gobj, foo, &state);
if (state)
{
VALUE e = rb_errinfo();
ret = rb_funcall(e, rb_intern("message"), 0);
fprintf(stderr, "exc %s\n", StringValueCStr(ret));
rb_set_errinfo(Qnil);
p = NULL;
}
if (p && PEAS_IS_ACTIVATABLE(p)) {
PeasActivatableInterface *iface = PEAS_ACTIVATABLE_GET_IFACE (p);
printf("vfuncs: %p %p %p %p\n",
p, iface->activate, iface->deactivate, iface->update_state);
/* THIS HANGS FOREVER */
peas_activatable_activate(p);
/* */
}
out:
/* destruct the VM */
return ruby_cleanup(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment