diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..3388018 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "ext/quickjsrb/quickjs"] + path = ext/quickjsrb/quickjs + url = https://github.com/bellard/quickjs.git diff --git a/ext/quickjsrb/extconf.rb b/ext/quickjsrb/extconf.rb index 0602c9c..da49070 100644 --- a/ext/quickjsrb/extconf.rb +++ b/ext/quickjsrb/extconf.rb @@ -2,9 +2,44 @@ require 'mkmf' +$VPATH << "$(srcdir)/quickjs" + +$srcs = [ + 'libunicode.c', + 'libbf.c', + 'libregexp.c', + 'cutils.c', + 'quickjs.c', + 'quickjs-libc.c', + 'quickjsrb.c', +] + +append_cflags('-I$(srcdir)/quickjs') + +append_cflags('-fwrapv') +append_cflags('-g') +append_cflags('-O2') +append_cflags('-Wall') +append_cflags('-MMD') +append_cflags('-MF') +append_cflags('-Wextra') +append_cflags('-Wno-sign-compare') +append_cflags('-Wno-missing-field-initializers') +append_cflags('-Wundef -Wuninitialized') +append_cflags('-Wunused -Wno-unused-parameter') +append_cflags('-Wwrite-strings') +append_cflags('-Wchar-subscripts -funsigned-char') +append_cflags('-D_GNU_SOURCE -DCONFIG_VERSION=\"2024-02-14\" -DCONFIG_BIGNUM') + +abort('could not find quickjs.h') unless find_header('quickjs.h') +abort('could not find cutils.h') unless find_header('cutils.h') +abort('could not find quickjs-libc.h') unless find_header('quickjs-libc.h') +#abort('could not find libbf.h') unless find_header('libbf.h') + # Makes all symbols private by default to avoid unintended conflict # with other gems. To explicitly export symbols you can use RUBY_FUNC_EXPORTED # selectively, or entirely remove this flag. append_cflags('-fvisibility=hidden') +$warnflags = '' create_makefile('quickjsrb/quickjsrb') diff --git a/ext/quickjsrb/quickjs b/ext/quickjsrb/quickjs new file mode 160000 index 0000000..36911f0 --- /dev/null +++ b/ext/quickjsrb/quickjs @@ -0,0 +1 @@ +Subproject commit 36911f0d3ab1a4c190a4d5cbe7c2db225a455389 diff --git a/ext/quickjsrb/quickjsrb.c b/ext/quickjsrb/quickjsrb.c index 56ca9a1..675fb4f 100644 --- a/ext/quickjsrb/quickjsrb.c +++ b/ext/quickjsrb/quickjsrb.c @@ -2,16 +2,42 @@ VALUE rb_mQuickjs; - -VALUE rb_module_say_hi(VALUE klass) +VALUE rb_module_eval_js_code(VALUE klass, VALUE r_code) { - VALUE r_hello = rb_str_new2("Hello!"); - return r_hello; + JSRuntime *rt = JS_NewRuntime(); + JSContext *ctx = JS_NewContext(rt); + + JS_SetMemoryLimit(rt, 0x4000000); + JS_SetMaxStackSize(rt, 0x10000); + JS_AddIntrinsicBigFloat(ctx); + JS_AddIntrinsicBigDecimal(ctx); + JS_AddIntrinsicOperators(ctx); + JS_EnableBignumExt(ctx, 1); + JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL); + js_std_add_helpers(ctx, 0, NULL); + + js_std_init_handlers(rt); + js_init_module_std(ctx, "std"); + js_init_module_os(ctx, "os"); + + char *code = StringValueCStr(r_code); + JSValue res = JS_Eval(ctx, code, strlen(code), "", JS_EVAL_TYPE_GLOBAL); + + int r = 0; + if (JS_IsException(res)) { + } else { + JS_ToInt32(ctx, &r, res); + } + JS_FreeValue(ctx, res); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); + + return INT2NUM(r); } RUBY_FUNC_EXPORTED void Init_quickjsrb(void) { rb_mQuickjs = rb_define_module("Quickjs"); - rb_define_module_function(rb_mQuickjs, "say_hi", rb_module_say_hi, 0); + rb_define_module_function(rb_mQuickjs, "evalCode", rb_module_eval_js_code, 1); } diff --git a/ext/quickjsrb/quickjsrb.h b/ext/quickjsrb/quickjsrb.h index 95d32c7..860b820 100644 --- a/ext/quickjsrb/quickjsrb.h +++ b/ext/quickjsrb/quickjsrb.h @@ -1,6 +1,14 @@ -#ifndef QUICKJS_H -#define QUICKJS_H 1 +#ifndef QUICKJSRB_H +#define QUICKJSRB_H 1 #include "ruby.h" -#endif /* QUICKJS_H */ +#include "quickjs.h" +#include "quickjs-libc.h" + +#include +#include +#include + + +#endif /* QUICKJSRB_H */ diff --git a/test/quickjs_test.rb b/test/quickjs_test.rb index 4f939a6..dd9e974 100644 --- a/test/quickjs_test.rb +++ b/test/quickjs_test.rb @@ -9,7 +9,8 @@ class QuickjsTest < Test::Unit::TestCase end end - test "something useful" do - assert_equal(::Quickjs.say_hi, "Hello!") + test "support returning integer" do + assert_equal(::Quickjs.evalCode("2+3"), 5) + assert_equal(::Quickjs.evalCode("const func = () => 8; func();"), 8) end end