Skip to content

Instantly share code, notes, and snippets.

@fl0l0u
Created October 29, 2017 14:31
Show Gist options
  • Save fl0l0u/0bd057b0872403b68fed88412379b863 to your computer and use it in GitHub Desktop.
Save fl0l0u/0bd057b0872403b68fed88412379b863 to your computer and use it in GitHub Desktop.
mruby interfacing with c
#include <mruby.h>
#include <mruby/array.h>
#include <mruby/hash.h>
#include <mruby/irep.h>
#include <mruby/string.h>
#include <unistd.h>
mrb_value qux(mrb_state*, mrb_value);
int main(int argc, char** argv, char** envp) {
// def foo
// puts "foo"
// end
const uint8_t bytecode[] = {
0x52,0x49,0x54,0x45,0x30,0x30,0x30,0x34,0x37,0x40,0x00,0x00,0x00,0xa1,0x4d,0x41,
0x54,0x5a,0x30,0x30,0x30,0x30,0x49,0x52,0x45,0x50,0x00,0x00,0x00,0x73,0x30,0x30,
0x30,0x30,0x00,0x00,0x00,0x34,0x00,0x01,0x00,0x03,0x00,0x01,0x00,0x00,0x00,0x05,
0x00,0x80,0x00,0x48,0x01,0x00,0x00,0xc0,0x00,0x80,0x00,0x46,0x00,0x80,0x00,0x04,
0x00,0x00,0x00,0x4a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x03,0x66,0x6f,
0x6f,0x00,0x00,0x00,0x00,0x3b,0x00,0x02,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x05,
0x00,0x00,0x00,0x26,0x01,0x00,0x00,0x06,0x01,0x80,0x00,0x3d,0x01,0x00,0x00,0xa0,
0x01,0x00,0x00,0x29,0x00,0x00,0x00,0x01,0x00,0x00,0x03,0x66,0x6f,0x6f,0x00,0x00,
0x00,0x01,0x00,0x04,0x70,0x75,0x74,0x73,0x00,0x4c,0x56,0x41,0x52,0x00,0x00,0x00,
0x10,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x45,0x4e,0x44,0x00,0x00,0x00,0x00,
0x08
};
const char code[] = \
"foo \n"
"puts 'bar' \n"
"def baz(str)\n"
" puts str \n"
"end";
/* instanciate vm */
mrb_state* mrb = mrb_open();
if (!mrb) { return 1; }
/* passing c args */
mrb_value ARGV = mrb_ary_new_capa(mrb, argc);
for (int i = 0; i < argc; i++) {
char* utf8 = mrb_utf8_from_locale(argv[i], -1);
mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, utf8));
}
mrb_define_global_const(mrb, "ARGV", ARGV);
/* passing c envp */
mrb_value ENV = mrb_hash_new(mrb);
for (char** env = envp; *env != 0; env++) {
char* key_val = *env;
mrb_value key = mrb_str_new_cstr(mrb, strtok(key_val, "="));
mrb_value val = mrb_str_new_cstr(mrb, strtok(NULL, "="));
mrb_hash_set(mrb, ENV, key, val);
}
mrb_define_global_const(mrb, "ENV", ENV);
/* executing bytecode */
mrb_load_irep(mrb, bytecode);
/* compiling and executing code */
mrb_load_string(mrb, code);
/* calling mrb method */
mrb_value obj = mrb_top_self(mrb);
mrb_int _argc = 1;
mrb_value str = mrb_str_new_cstr(mrb, "baz");
mrb_funcall(mrb, obj, "baz", _argc, str); // vm, object, method_name, arity, args...
/* registering c function to a module */
mrb_define_method(mrb, mrb->kernel_module, "qux", qux, MRB_ARGS_REQ(1));
mrb_load_string(mrb, "qux(\"qux\")");
/* cleaning up */
mrb_close(mrb);
return 0;
}
mrb_value qux(mrb_state* mrb, mrb_value self) {
mrb_value obj;
mrb_get_args(mrb, "S", &obj);
if (mrb_string_p(obj)) {
char* utf8 = mrb_str_to_cstr(mrb, obj);
char* str = mrb_locale_from_utf8(utf8, -1);
printf("%s\n", str);
}
return mrb_nil_value();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment