quickjs 0.2.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/quickjsrb/quickjsrb.c +89 -25
- data/ext/quickjsrb/quickjsrb.h +0 -2
- data/lib/quickjs/version.rb +1 -1
- data/lib/quickjs.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ecc8aa4eddd6aca97baf0e773c4880b4479b4ac4597e0edf811d256eeb61aeb9
|
4
|
+
data.tar.gz: 37c8eeef2cad6e0d7773e89759c7d2d1659219247883cfd1817f2603ffbf1543
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2728bcbae59fae1138bdb5aef4e2f22290db93ce6c1e81f031e25c43108287a4f4d93d20afcfd9cb19a0e55593e1ccdadf1d83ebfbb430ee802368b73994cc2b
|
7
|
+
data.tar.gz: d06939ece851f9f4fb1311846826cad5c92e594511948ac9659bb190ebe6f905fdce15b4b9d16cf5df3b08bc5483a6f27d847f3ddf752aaa18bfcf74fec087e1
|
data/ext/quickjsrb/quickjsrb.c
CHANGED
@@ -1,22 +1,22 @@
|
|
1
1
|
#include "quickjsrb.h"
|
2
2
|
|
3
|
-
JSValue
|
3
|
+
JSValue j_error_from_ruby_error(JSContext *ctx, VALUE r_error)
|
4
4
|
{
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
char *exceptionName = StringValueCStr(r_exception_name);
|
15
|
-
JS_SetPropertyStr(ctx, j_error, "name", JS_NewString(ctx, exceptionName));
|
16
|
-
JS_SetPropertyStr(ctx, j_error, "message", JS_NewString(ctx, exceptionMessage));
|
17
|
-
return JS_Throw(ctx, j_error);
|
18
|
-
}
|
5
|
+
JSValue j_error = JS_NewError(ctx); // may wanna have custom error class to determine in JS' end
|
6
|
+
|
7
|
+
VALUE r_object_id = rb_funcall(r_error, rb_intern("object_id"), 0, NULL);
|
8
|
+
int objectId = NUM2INT(r_object_id);
|
9
|
+
JS_SetPropertyStr(ctx, j_error, "rb_object_id", JS_NewInt32(ctx, objectId));
|
10
|
+
|
11
|
+
VALUE r_exception_message = rb_funcall(r_error, rb_intern("message"), 0, NULL);
|
12
|
+
const char *errorMessage = StringValueCStr(r_exception_message);
|
13
|
+
JS_SetPropertyStr(ctx, j_error, "message", JS_NewString(ctx, errorMessage));
|
19
14
|
|
15
|
+
return j_error;
|
16
|
+
}
|
17
|
+
|
18
|
+
JSValue to_js_value(JSContext *ctx, VALUE r_value)
|
19
|
+
{
|
20
20
|
switch (TYPE(r_value))
|
21
21
|
{
|
22
22
|
case T_NIL:
|
@@ -72,6 +72,13 @@ JSValue to_js_value(JSContext *ctx, VALUE r_value)
|
|
72
72
|
}
|
73
73
|
default:
|
74
74
|
{
|
75
|
+
if (TYPE(r_value) == T_OBJECT && RTEST(rb_funcall(
|
76
|
+
r_value,
|
77
|
+
rb_intern("is_a?"),
|
78
|
+
1, rb_const_get(rb_cClass, rb_intern("Exception")))))
|
79
|
+
{
|
80
|
+
return j_error_from_ruby_error(ctx, r_value);
|
81
|
+
}
|
75
82
|
VALUE r_inspect_str = rb_funcall(r_value, rb_intern("inspect"), 0, NULL);
|
76
83
|
char *str = StringValueCStr(r_inspect_str);
|
77
84
|
|
@@ -80,6 +87,11 @@ JSValue to_js_value(JSContext *ctx, VALUE r_value)
|
|
80
87
|
}
|
81
88
|
}
|
82
89
|
|
90
|
+
VALUE r_try_json_parse(VALUE r_str)
|
91
|
+
{
|
92
|
+
return rb_funcall(rb_const_get(rb_cClass, rb_intern("JSON")), rb_intern("parse"), 1, r_str);
|
93
|
+
}
|
94
|
+
|
83
95
|
VALUE to_rb_value(JSContext *ctx, JSValue j_val)
|
84
96
|
{
|
85
97
|
switch (JS_VALUE_GET_NORM_TAG(j_val))
|
@@ -121,6 +133,23 @@ VALUE to_rb_value(JSContext *ctx, JSValue j_val)
|
|
121
133
|
return Qnil;
|
122
134
|
}
|
123
135
|
|
136
|
+
if (JS_IsError(ctx, j_val))
|
137
|
+
{
|
138
|
+
JSValue j_errorOriginalRubyObjectId = JS_GetPropertyStr(ctx, j_val, "rb_object_id");
|
139
|
+
int errorOriginalRubyObjectId = 0;
|
140
|
+
if (JS_VALUE_GET_NORM_TAG(j_errorOriginalRubyObjectId) == JS_TAG_INT)
|
141
|
+
{
|
142
|
+
JS_ToInt32(ctx, &errorOriginalRubyObjectId, j_errorOriginalRubyObjectId);
|
143
|
+
JS_FreeValue(ctx, j_errorOriginalRubyObjectId);
|
144
|
+
if (errorOriginalRubyObjectId > 0)
|
145
|
+
{
|
146
|
+
// may be nice if cover the case of object is missing
|
147
|
+
return rb_funcall(rb_const_get(rb_cClass, rb_intern("ObjectSpace")), rb_intern("_id2ref"), 1, INT2NUM(errorOriginalRubyObjectId));
|
148
|
+
}
|
149
|
+
}
|
150
|
+
// will support other errors
|
151
|
+
}
|
152
|
+
|
124
153
|
JSValue j_global = JS_GetGlobalObject(ctx);
|
125
154
|
JSValue j_jsonClass = JS_GetPropertyStr(ctx, j_global, "JSON");
|
126
155
|
JSValue j_stringifyFunc = JS_GetPropertyStr(ctx, j_jsonClass, "stringify");
|
@@ -135,7 +164,21 @@ VALUE to_rb_value(JSContext *ctx, JSValue j_val)
|
|
135
164
|
JS_FreeValue(ctx, j_jsonClass);
|
136
165
|
JS_FreeValue(ctx, j_global);
|
137
166
|
|
138
|
-
|
167
|
+
if (rb_funcall(r_str, rb_intern("=="), 1, rb_str_new2("undefined")))
|
168
|
+
{
|
169
|
+
return QUICKJSRB_SYM(undefinedId);
|
170
|
+
}
|
171
|
+
|
172
|
+
int couldntParse;
|
173
|
+
VALUE r_result = rb_protect(r_try_json_parse, r_str, &couldntParse);
|
174
|
+
if (couldntParse)
|
175
|
+
{
|
176
|
+
return Qnil;
|
177
|
+
}
|
178
|
+
else
|
179
|
+
{
|
180
|
+
return r_result;
|
181
|
+
}
|
139
182
|
}
|
140
183
|
case JS_TAG_NULL:
|
141
184
|
return Qnil;
|
@@ -146,6 +189,21 @@ VALUE to_rb_value(JSContext *ctx, JSValue j_val)
|
|
146
189
|
JSValue j_exceptionVal = JS_GetException(ctx);
|
147
190
|
if (JS_IsError(ctx, j_exceptionVal))
|
148
191
|
{
|
192
|
+
JSValue j_errorOriginalRubyObjectId = JS_GetPropertyStr(ctx, j_exceptionVal, "rb_object_id");
|
193
|
+
int errorOriginalRubyObjectId = 0;
|
194
|
+
if (JS_VALUE_GET_NORM_TAG(j_errorOriginalRubyObjectId) == JS_TAG_INT)
|
195
|
+
{
|
196
|
+
JS_ToInt32(ctx, &errorOriginalRubyObjectId, j_errorOriginalRubyObjectId);
|
197
|
+
JS_FreeValue(ctx, j_errorOriginalRubyObjectId);
|
198
|
+
if (errorOriginalRubyObjectId > 0)
|
199
|
+
{
|
200
|
+
JS_FreeValue(ctx, j_exceptionVal);
|
201
|
+
// may be nice if cover the case of object is missing
|
202
|
+
rb_exc_raise(rb_funcall(rb_const_get(rb_cClass, rb_intern("ObjectSpace")), rb_intern("_id2ref"), 1, INT2NUM(errorOriginalRubyObjectId)));
|
203
|
+
return Qnil;
|
204
|
+
}
|
205
|
+
}
|
206
|
+
|
149
207
|
JSValue j_errorClassName = JS_GetPropertyStr(ctx, j_exceptionVal, "name");
|
150
208
|
const char *errorClassName = JS_ToCString(ctx, j_errorClassName);
|
151
209
|
|
@@ -165,11 +223,6 @@ VALUE to_rb_value(JSContext *ctx, JSValue j_val)
|
|
165
223
|
r_error_class = QUICKJSRB_ERROR_FOR(QUICKJSRB_INTERRUPTED_ERROR);
|
166
224
|
r_error_message = rb_str_new2("Code evaluation is interrupted by the timeout or something");
|
167
225
|
}
|
168
|
-
else if (strcmp(errorClassName, "InternalError") == 0 && strstr(errorClassMessage, "Ruby") != NULL)
|
169
|
-
{
|
170
|
-
r_error_class = QUICKJSRB_ERROR_FOR(QUICKJSRB_RUBY_FUNCTION_ERROR);
|
171
|
-
}
|
172
|
-
|
173
226
|
else if (strcmp(errorClassName, "Quickjs::InterruptedError") == 0)
|
174
227
|
{
|
175
228
|
r_error_class = QUICKJSRB_ERROR_FOR(QUICKJSRB_INTERRUPTED_ERROR);
|
@@ -251,7 +304,9 @@ static JSValue js_quickjsrb_call_global(JSContext *ctx, JSValueConst _this, int
|
|
251
304
|
JSValue j_result;
|
252
305
|
if (sadnessHappened)
|
253
306
|
{
|
254
|
-
|
307
|
+
VALUE r_error = rb_errinfo();
|
308
|
+
JSValue j_error = j_error_from_ruby_error(ctx, r_error);
|
309
|
+
return JS_Throw(ctx, j_error);
|
255
310
|
}
|
256
311
|
else
|
257
312
|
{
|
@@ -475,13 +530,14 @@ static VALUE vm_m_import(int argc, VALUE *argv, VALUE r_self)
|
|
475
530
|
rb_scan_args(argc, argv, "10:", &r_import_string, &r_opts);
|
476
531
|
if (NIL_P(r_opts))
|
477
532
|
r_opts = rb_hash_new();
|
478
|
-
VALUE r_from = rb_hash_aref(r_opts, ID2SYM(rb_intern("from")));
|
533
|
+
VALUE r_from = rb_hash_aref(r_opts, ID2SYM(rb_intern("from")));
|
479
534
|
if (NIL_P(r_from))
|
480
535
|
{
|
481
536
|
VALUE r_error_message = rb_str_new2("missing import source");
|
482
537
|
rb_exc_raise(rb_funcall(QUICKJSRB_ERROR_FOR(QUICKJSRB_ROOT_RUNTIME_ERROR), rb_intern("new"), 2, r_error_message, Qnil));
|
483
538
|
return Qnil;
|
484
539
|
}
|
540
|
+
VALUE r_custom_exposure = rb_hash_aref(r_opts, ID2SYM(rb_intern("code_to_expose")));
|
485
541
|
|
486
542
|
VMData *data;
|
487
543
|
TypedData_Get_Struct(r_self, VMData, &vm_type, data);
|
@@ -499,8 +555,16 @@ static VALUE vm_m_import(int argc, VALUE *argv, VALUE r_self)
|
|
499
555
|
r_import_string);
|
500
556
|
VALUE r_import_name = rb_ary_entry(r_import_settings, 0);
|
501
557
|
char *import_name = StringValueCStr(r_import_name);
|
502
|
-
VALUE
|
503
|
-
char *globalize
|
558
|
+
VALUE r_default_exposure = rb_ary_entry(r_import_settings, 1);
|
559
|
+
char *globalize;
|
560
|
+
if (RTEST(r_custom_exposure))
|
561
|
+
{
|
562
|
+
globalize = StringValueCStr(r_custom_exposure);
|
563
|
+
}
|
564
|
+
else
|
565
|
+
{
|
566
|
+
globalize = StringValueCStr(r_default_exposure);
|
567
|
+
}
|
504
568
|
|
505
569
|
const char *importAndGlobalizeModule = "import %s from '%s';\n"
|
506
570
|
"%s\n";
|
data/ext/quickjsrb/quickjsrb.h
CHANGED
@@ -183,7 +183,6 @@ static VALUE r_define_log_class(VALUE r_parent_class)
|
|
183
183
|
#define QUICKJSRB_ROOT_RUNTIME_ERROR "RuntimeError"
|
184
184
|
#define QUICKJSRB_INTERRUPTED_ERROR "InterruptedError"
|
185
185
|
#define QUICKJSRB_NO_AWAIT_ERROR "NoAwaitError"
|
186
|
-
#define QUICKJSRB_RUBY_FUNCTION_ERROR "RubyFunctionError"
|
187
186
|
|
188
187
|
#define QUICKJSRB_ERROR_FOR(name) \
|
189
188
|
(VALUE) { rb_const_get(rb_const_get(rb_cClass, rb_intern("Quickjs")), rb_intern(name)) }
|
@@ -212,7 +211,6 @@ static void r_define_exception_classes(VALUE r_parent_class)
|
|
212
211
|
// quickjsrb specific errors
|
213
212
|
rb_define_class_under(r_parent_class, QUICKJSRB_INTERRUPTED_ERROR, r_runtime_error);
|
214
213
|
rb_define_class_under(r_parent_class, QUICKJSRB_NO_AWAIT_ERROR, r_runtime_error);
|
215
|
-
rb_define_class_under(r_parent_class, QUICKJSRB_RUBY_FUNCTION_ERROR, r_runtime_error);
|
216
214
|
}
|
217
215
|
|
218
216
|
#endif /* QUICKJSRB_H */
|
data/lib/quickjs/version.rb
CHANGED
data/lib/quickjs.rb
CHANGED
@@ -16,7 +16,7 @@ module Quickjs
|
|
16
16
|
def _with_timeout(msec, proc, args)
|
17
17
|
Timeout.timeout(msec / 1_000.0) { proc.call(*args) }
|
18
18
|
rescue Timeout::Error
|
19
|
-
Quickjs::InterruptedError.new('Ruby runtime got timeout', nil)
|
19
|
+
raise Quickjs::InterruptedError.new('Ruby runtime got timeout', nil)
|
20
20
|
rescue
|
21
21
|
raise
|
22
22
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quickjs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- hmsk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-11-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|