quickjs 0.1.12 → 0.2.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/README.md +10 -0
- data/ext/quickjsrb/quickjsrb.c +50 -27
- data/lib/quickjs/version.rb +1 -1
- data/lib/quickjs.rb +13 -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: 30027c93cb2dd5dbb85d43ab40700f7ee06679a824b503bee42786a42bc5dc26
|
4
|
+
data.tar.gz: 51c60a962c82bbbbaa3a3fc4202255809751848d1474f9a4e9f6b7ebe4df0277
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e1f248cbafcc56ceba481f658aae542660ac8de6036b7fc1e9425e5f214f4f51a918a3051b82e796a075ed83726f59ba6b8dcc85e8b1c38ee1369b089ebd410a
|
7
|
+
data.tar.gz: 7c7346da3a318d3ed07bfd490561ced7deda800678bda0cb23c4f2b19b84b9720191a7999a7d9a5225d91d4c2140b7fffae03f16d75b791cd4d3b746bbab50a9
|
data/README.md
CHANGED
@@ -104,6 +104,16 @@ vm = Quickjs::VM.new(
|
|
104
104
|
)
|
105
105
|
```
|
106
106
|
|
107
|
+
#### ⚡️ Import ESM from source
|
108
|
+
|
109
|
+
```rb
|
110
|
+
vm = Quickjs::VM.new
|
111
|
+
vm.import({ default: 'aliasedDefault', member: 'member' }, from: File.read('exports.esm.js'))
|
112
|
+
|
113
|
+
vm.eval_code("aliasedDefault()") #=> Exported `default` of the ESM is called
|
114
|
+
vm.eval_code("member()") #=> Exported `member` of the ESM is called
|
115
|
+
```
|
116
|
+
|
107
117
|
#### ⚡️ Define a global function for JS by Ruby
|
108
118
|
|
109
119
|
```rb
|
data/ext/quickjsrb/quickjsrb.c
CHANGED
@@ -191,7 +191,7 @@ VALUE to_rb_value(JSContext *ctx, JSValue j_val)
|
|
191
191
|
if (promiseState != -1)
|
192
192
|
{
|
193
193
|
VALUE r_error_message = rb_str_new2("cannot translate a Promise to Ruby. await within JavaScript's end");
|
194
|
-
rb_exc_raise(
|
194
|
+
rb_exc_raise(rb_funcall(rb_cQuickjsRuntimeError, rb_intern("new"), 2, r_error_message, Qnil));
|
195
195
|
return Qnil;
|
196
196
|
}
|
197
197
|
|
@@ -229,43 +229,35 @@ VALUE to_rb_value(JSContext *ctx, JSValue j_val)
|
|
229
229
|
JS_FreeValue(ctx, j_errorClassMessage);
|
230
230
|
JS_FreeValue(ctx, j_errorClassName);
|
231
231
|
|
232
|
-
VALUE r_error_message =
|
233
|
-
VALUE r_error_class = rb_eRuntimeError;
|
232
|
+
VALUE r_error_class, r_error_message = rb_str_new2(errorClassMessage);
|
234
233
|
|
235
234
|
if (strcmp(errorClassName, "SyntaxError") == 0)
|
236
235
|
{
|
237
236
|
r_error_class = rb_cQuickjsSyntaxError;
|
238
|
-
r_error_message = rb_str_new2(errorClassMessage);
|
239
237
|
}
|
240
238
|
else if (strcmp(errorClassName, "TypeError") == 0)
|
241
239
|
{
|
242
240
|
r_error_class = rb_cQuickjsTypeError;
|
243
|
-
r_error_message = rb_str_new2(errorClassMessage);
|
244
241
|
}
|
245
242
|
else if (strcmp(errorClassName, "ReferenceError") == 0)
|
246
243
|
{
|
247
244
|
r_error_class = rb_cQuickjsReferenceError;
|
248
|
-
r_error_message = rb_str_new2(errorClassMessage);
|
249
245
|
}
|
250
246
|
else if (strcmp(errorClassName, "RangeError") == 0)
|
251
247
|
{
|
252
248
|
r_error_class = rb_cQuickjsRangeError;
|
253
|
-
r_error_message = rb_str_new2(errorClassMessage);
|
254
249
|
}
|
255
250
|
else if (strcmp(errorClassName, "EvalError") == 0)
|
256
251
|
{
|
257
252
|
r_error_class = rb_cQuickjsEvalError;
|
258
|
-
r_error_message = rb_str_new2(errorClassMessage);
|
259
253
|
}
|
260
254
|
else if (strcmp(errorClassName, "URIError") == 0)
|
261
255
|
{
|
262
256
|
r_error_class = rb_cQuickjsURIError;
|
263
|
-
r_error_message = rb_str_new2(errorClassMessage);
|
264
257
|
}
|
265
258
|
else if (strcmp(errorClassName, "AggregateError") == 0)
|
266
259
|
{
|
267
260
|
r_error_class = rb_cQuickjsAggregateError;
|
268
|
-
r_error_message = rb_str_new2(errorClassMessage);
|
269
261
|
}
|
270
262
|
else if (strcmp(errorClassName, "InternalError") == 0 && strstr(errorClassMessage, "interrupted") != NULL)
|
271
263
|
{
|
@@ -275,13 +267,16 @@ VALUE to_rb_value(JSContext *ctx, JSValue j_val)
|
|
275
267
|
else if (strcmp(errorClassName, "Quickjs::InterruptedError") == 0)
|
276
268
|
{
|
277
269
|
r_error_class = rb_cQuickjsInterruptedError;
|
278
|
-
|
270
|
+
}
|
271
|
+
else
|
272
|
+
{
|
273
|
+
r_error_class = rb_cQuickjsRuntimeError;
|
279
274
|
}
|
280
275
|
JS_FreeCString(ctx, errorClassName);
|
281
276
|
JS_FreeCString(ctx, errorClassMessage);
|
282
277
|
JS_FreeValue(ctx, j_exceptionVal);
|
283
278
|
|
284
|
-
rb_exc_raise(
|
279
|
+
rb_exc_raise(rb_funcall(r_error_class, rb_intern("new"), 2, r_error_message, rb_str_new2(errorClassName)));
|
285
280
|
}
|
286
281
|
else // exception without Error object
|
287
282
|
{
|
@@ -290,7 +285,7 @@ VALUE to_rb_value(JSContext *ctx, JSValue j_val)
|
|
290
285
|
|
291
286
|
JS_FreeCString(ctx, errorMessage);
|
292
287
|
JS_FreeValue(ctx, j_exceptionVal);
|
293
|
-
rb_exc_raise(
|
288
|
+
rb_exc_raise(rb_funcall(rb_cQuickjsRuntimeError, rb_intern("new"), 2, r_error_message, Qnil));
|
294
289
|
}
|
295
290
|
return Qnil;
|
296
291
|
}
|
@@ -362,6 +357,7 @@ static JSValue js_quickjsrb_log(JSContext *ctx, JSValueConst _this, int _argc, J
|
|
362
357
|
const char *body = JS_ToCString(ctx, j_logged);
|
363
358
|
VALUE r_loghash = rb_hash_new();
|
364
359
|
rb_hash_aset(r_loghash, ID2SYM(rb_intern("c")), rb_str_new2(body));
|
360
|
+
rb_hash_aset(r_loghash, ID2SYM(rb_intern("raw")), to_rb_value(ctx, j_logged));
|
365
361
|
rb_ary_push(r_row, r_loghash);
|
366
362
|
JS_FreeValue(ctx, j_logged);
|
367
363
|
JS_FreeCString(ctx, body);
|
@@ -489,7 +485,7 @@ static VALUE vm_m_evalCode(VALUE r_self, VALUE r_code)
|
|
489
485
|
JS_FreeValue(data->context, j_returnedValue);
|
490
486
|
JS_FreeValue(data->context, j_awaitedResult);
|
491
487
|
VALUE r_error_message = rb_str_new2("An unawaited Promise was returned to the top-level");
|
492
|
-
rb_exc_raise(
|
488
|
+
rb_exc_raise(rb_funcall(rb_cQuickjsNoAwaitError, rb_intern("new"), 2, r_error_message, Qnil));
|
493
489
|
return Qnil;
|
494
490
|
}
|
495
491
|
else
|
@@ -529,11 +525,6 @@ static VALUE vm_m_defineGlobalFunction(VALUE r_self, VALUE r_name)
|
|
529
525
|
return Qnil;
|
530
526
|
}
|
531
527
|
|
532
|
-
// WISH: vm.import('hey', from: '...source...') imports just default
|
533
|
-
// WISH: vm.import('{ member, member2 }', from: '...source...')
|
534
|
-
// WISH: vm.import('{ member as aliasedName }', from: '...source...')
|
535
|
-
// WISH: vm.import('defaultMember, { member }', from: '...source...')
|
536
|
-
// WISH: vm.import('* as all', from: '...source...')
|
537
528
|
static VALUE vm_m_import(int argc, VALUE *argv, VALUE r_self)
|
538
529
|
{
|
539
530
|
VALUE r_import_string, r_opts;
|
@@ -544,7 +535,7 @@ static VALUE vm_m_import(int argc, VALUE *argv, VALUE r_self)
|
|
544
535
|
if (NIL_P(r_from))
|
545
536
|
{
|
546
537
|
VALUE r_error_message = rb_str_new2("missing import source");
|
547
|
-
rb_exc_raise(
|
538
|
+
rb_exc_raise(rb_funcall(rb_cQuickjsRuntimeError, rb_intern("new"), 2, r_error_message, Qnil));
|
548
539
|
return Qnil;
|
549
540
|
}
|
550
541
|
|
@@ -552,16 +543,25 @@ static VALUE vm_m_import(int argc, VALUE *argv, VALUE r_self)
|
|
552
543
|
TypedData_Get_Struct(r_self, VMData, &vm_type, data);
|
553
544
|
|
554
545
|
char *source = StringValueCStr(r_from);
|
555
|
-
char *import_name = StringValueCStr(r_import_string);
|
556
546
|
JSValue func = JS_Eval(data->context, source, strlen(source), "mmmodule", JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
|
557
547
|
js_module_set_import_meta(data->context, func, TRUE, FALSE);
|
558
548
|
JS_FreeValue(data->context, func);
|
559
549
|
|
560
|
-
|
561
|
-
|
562
|
-
|
550
|
+
VALUE r_import_settings = rb_funcall(
|
551
|
+
rb_const_get(rb_cClass, rb_intern("Quickjs")),
|
552
|
+
rb_intern("_build_import"),
|
553
|
+
1,
|
554
|
+
r_import_string);
|
555
|
+
VALUE r_import_name = rb_ary_entry(r_import_settings, 0);
|
556
|
+
char *import_name = StringValueCStr(r_import_name);
|
557
|
+
VALUE r_globalize = rb_ary_entry(r_import_settings, 1);
|
558
|
+
char *globalize = StringValueCStr(r_globalize);
|
559
|
+
|
560
|
+
const char *importAndGlobalizeModule = "import %s from 'mmmodule';\n"
|
561
|
+
"%s\n";
|
562
|
+
int length = snprintf(NULL, 0, importAndGlobalizeModule, import_name, globalize);
|
563
563
|
char *result = (char *)malloc(length + 1);
|
564
|
-
snprintf(result, length + 1, importAndGlobalizeModule, import_name,
|
564
|
+
snprintf(result, length + 1, importAndGlobalizeModule, import_name, globalize);
|
565
565
|
|
566
566
|
JSValue j_codeResult = JS_Eval(data->context, result, strlen(result), "<vm>", JS_EVAL_TYPE_MODULE);
|
567
567
|
free(result);
|
@@ -578,6 +578,19 @@ static VALUE vm_m_getLogs(VALUE r_self)
|
|
578
578
|
return data->logs;
|
579
579
|
}
|
580
580
|
|
581
|
+
static VALUE pick_raw(VALUE block_arg, VALUE data, int argc, const VALUE *argv, VALUE blockarg)
|
582
|
+
{
|
583
|
+
return rb_hash_aref(block_arg, ID2SYM(rb_intern("raw")));
|
584
|
+
}
|
585
|
+
|
586
|
+
static VALUE vm_m_raw(VALUE r_self)
|
587
|
+
{
|
588
|
+
VALUE row = rb_iv_get(r_self, "@row");
|
589
|
+
VALUE r_ary = rb_block_call(row, rb_intern("map"), 0, NULL, pick_raw, Qnil);
|
590
|
+
|
591
|
+
return r_ary;
|
592
|
+
}
|
593
|
+
|
581
594
|
static VALUE pick_c(VALUE block_arg, VALUE data, int argc, const VALUE *argv, VALUE blockarg)
|
582
595
|
{
|
583
596
|
return rb_hash_aref(block_arg, ID2SYM(rb_intern("c")));
|
@@ -591,8 +604,15 @@ static VALUE vm_m_to_s(VALUE r_self)
|
|
591
604
|
return rb_funcall(r_ary, rb_intern("join"), 1, rb_str_new2(" "));
|
592
605
|
}
|
593
606
|
|
594
|
-
|
595
|
-
|
607
|
+
VALUE vm_m_initialize_quickjs_error(VALUE self, VALUE r_message, VALUE r_js_name)
|
608
|
+
{
|
609
|
+
rb_call_super(1, &r_message);
|
610
|
+
rb_iv_set(self, "@js_name", r_js_name);
|
611
|
+
|
612
|
+
return self;
|
613
|
+
}
|
614
|
+
|
615
|
+
RUBY_FUNC_EXPORTED void Init_quickjsrb(void)
|
596
616
|
{
|
597
617
|
VALUE rb_mQuickjs = rb_define_module("Quickjs");
|
598
618
|
rb_define_const(rb_mQuickjs, "MODULE_STD", ID2SYM(rb_intern(featureStdId)));
|
@@ -613,10 +633,13 @@ Init_quickjsrb(void)
|
|
613
633
|
|
614
634
|
rb_cQuickjsVMLog = rb_define_class_under(rb_cQuickjsVM, "Log", rb_cObject);
|
615
635
|
rb_define_attr(rb_cQuickjsVMLog, "severity", 1, 0);
|
636
|
+
rb_define_method(rb_cQuickjsVMLog, "raw", vm_m_raw, 0);
|
616
637
|
rb_define_method(rb_cQuickjsVMLog, "to_s", vm_m_to_s, 0);
|
617
638
|
rb_define_method(rb_cQuickjsVMLog, "inspect", vm_m_to_s, 0);
|
618
639
|
|
619
640
|
rb_cQuickjsRuntimeError = rb_define_class_under(rb_mQuickjs, "RuntimeError", rb_eRuntimeError);
|
641
|
+
rb_define_method(rb_cQuickjsRuntimeError, "initialize", vm_m_initialize_quickjs_error, 2);
|
642
|
+
rb_define_attr(rb_cQuickjsRuntimeError, "js_name", 1, 0);
|
620
643
|
|
621
644
|
rb_cQuickjsSyntaxError = rb_define_class_under(rb_mQuickjs, "SyntaxError", rb_cQuickjsRuntimeError);
|
622
645
|
rb_cQuickjsTypeError = rb_define_class_under(rb_mQuickjs, "TypeError", rb_cQuickjsRuntimeError);
|
data/lib/quickjs/version.rb
CHANGED
data/lib/quickjs.rb
CHANGED
@@ -17,9 +17,21 @@ module Quickjs
|
|
17
17
|
def _with_timeout(msec, proc, args)
|
18
18
|
Timeout.timeout(msec / 1_000.0) { proc.call(*args) }
|
19
19
|
rescue Timeout::Error
|
20
|
-
Quickjs::InterruptedError.new('Ruby runtime got timeout')
|
20
|
+
Quickjs::InterruptedError.new('Ruby runtime got timeout', nil)
|
21
21
|
rescue => e
|
22
22
|
e
|
23
23
|
end
|
24
24
|
module_function :_with_timeout
|
25
|
+
|
26
|
+
def _build_import(mappings)
|
27
|
+
imports, aliases = mappings.to_a.map do |imp|
|
28
|
+
["#{imp[0]} as #{imp[1]}", imp[1].to_s]
|
29
|
+
end.transpose
|
30
|
+
|
31
|
+
[
|
32
|
+
imports.join(", ").yield_self{|s| '{ %s }' % s },
|
33
|
+
aliases.map {|name| "globalThis['#{name}'] = #{name};"}.join("\n")
|
34
|
+
]
|
35
|
+
end
|
36
|
+
module_function :_build_import
|
25
37
|
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.2.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-10-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|