mini_racer 0.21.4 → 0.22.1
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/CHANGELOG +11 -0
- data/README.md +57 -0
- data/ext/mini_racer_extension/mini_racer_extension.c +97 -39
- data/ext/mini_racer_extension/mini_racer_v8.cc +180 -17
- data/ext/mini_racer_extension/mini_racer_v8.h +5 -1
- data/ext/mini_racer_extension/serde.c +17 -10
- data/lib/mini_racer/shared.rb +151 -111
- data/lib/mini_racer/truffleruby.rb +89 -66
- data/lib/mini_racer/version.rb +1 -1
- data/lib/mini_racer.rb +17 -9
- metadata +33 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 522742f60d9062d656ffab6c1eb7ead5ceb0eabb6918b9582e9eec32f1f8a4c8
|
|
4
|
+
data.tar.gz: 404097b19b0e243bcd995e54f2560dd8fa5097dcc94a9488b435242350bc6719
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 723b3777cf8085b76662a3f4ede9fcdd8d4d8b31c31346ed0a87af1092b6a0323579b4dd6c3ec45a3c06f6cecedda7a30b8e807e69ecceaf5c3bf2ab9ceabc07
|
|
7
|
+
data.tar.gz: 36e1ce3f381f3d4017c10d811805320af94fd026a81eca8bdc71e6fa0cecd58a23f4668883de3cf8810ce57e41e33e9e4560810d4621b9825104a22dd2076e6b
|
data/CHANGELOG
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
- 0.22.1 - 27-08-2026
|
|
2
|
+
- Fix building with Clang 22+ and big-endian bigint serialization by making bigint serialization byte-oriented instead of relying on native `uint64_t`/`unsigned long` representations
|
|
3
|
+
- Fix Ruby integers at or above 512 bits being silently truncated when passed to JavaScript, and large JavaScript bigints producing an invalid internal value when returned to Ruby
|
|
4
|
+
- Support Ruby and JavaScript bigints up to a 16 MiB magnitude, using allocation-free conversion for common sizes and bounded dynamic storage for larger values
|
|
5
|
+
|
|
6
|
+
- 0.22.0 - 12-08-2026
|
|
7
|
+
- Add `Context#call_await` and `Context#eval_await`: like `call`/`eval` but block until a returned Promise settles and return the settled value; rejections raise `MiniRacer::RuntimeError`
|
|
8
|
+
- Fix a `call` or `eval` made from a Ruby callback taking the timeout or `stop` meant for the evaluation around it, which then kept running
|
|
9
|
+
- Fix a timeout that fires just after its own evaluation ends, where it would stop the next evaluation instead
|
|
10
|
+
- Fix a race introduced in 0.21.4 where a request sent right after a nested dispatch (e.g. `perform_microtask_checkpoint` or a nested `call` from an attached callback) could be dropped, deadlocking the context
|
|
11
|
+
|
|
1
12
|
- 0.21.4 - 24-06-2026
|
|
2
13
|
- Fix stale V8 termination state after interrupts/timeouts so contexts remain usable after cancelled evaluations
|
|
3
14
|
- Let Ruby interrupts wake MiniRacer calls without immediately terminating V8, allowing signal traps and nested callbacks to unwind safely
|
data/README.md
CHANGED
|
@@ -60,6 +60,10 @@ puts context.eval("array_and_hash()")
|
|
|
60
60
|
# => {"a" => 1, "b" => [1, {"a" => 1}]}
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
+
Ruby `Integer` and JavaScript `BigInt` values are converted exactly up to a
|
|
64
|
+
16 MiB magnitude (about 134 million bits). Larger individual values are
|
|
65
|
+
rejected with a serialization error rather than truncated.
|
|
66
|
+
|
|
63
67
|
### Return binary data from Ruby to JavaScript
|
|
64
68
|
|
|
65
69
|
Attached Ruby functions can return binary data as `Uint8Array` using `MiniRacer::Binary`:
|
|
@@ -348,6 +352,40 @@ Performance is slightly better than running `context.eval("hello('George')")` si
|
|
|
348
352
|
* compilation of eval'd string is avoided
|
|
349
353
|
* function arguments don't need to be converted to JSON
|
|
350
354
|
|
|
355
|
+
### Promises: call_await and eval_await
|
|
356
|
+
|
|
357
|
+
`call_await` and `eval_await` work like `call` and `eval`, but when the result is a
|
|
358
|
+
Promise they block until it settles and return the settled value. A rejected
|
|
359
|
+
promise raises `MiniRacer::RuntimeError`, just like a synchronous `throw`:
|
|
360
|
+
|
|
361
|
+
```ruby
|
|
362
|
+
context = MiniRacer::Context.new
|
|
363
|
+
context.eval("async function f(x) { await Promise.resolve(); return x * 2 }")
|
|
364
|
+
context.call_await("f", 21)
|
|
365
|
+
# => 42
|
|
366
|
+
|
|
367
|
+
context.eval_await("(async () => 6 * 7)()")
|
|
368
|
+
# => 42
|
|
369
|
+
|
|
370
|
+
context.eval("async function boom() { throw new Error('kaboom') }")
|
|
371
|
+
context.call_await("boom")
|
|
372
|
+
# => raises MiniRacer::RuntimeError (Error: kaboom)
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
Non-Promise results pass through unchanged, so `call_await` is a drop-in
|
|
376
|
+
superset of `call` (same for `eval_await`/`eval`).
|
|
377
|
+
|
|
378
|
+
A promise that never settles blocks forever, just like an infinite loop. The
|
|
379
|
+
`timeout:` option and `Context#stop` both interrupt it, raising
|
|
380
|
+
`MiniRacer::ScriptTerminatedError`.
|
|
381
|
+
|
|
382
|
+
Calling `call_await` or `eval_await` recursively on the same context from an
|
|
383
|
+
attached Ruby callback is not supported and raises `MiniRacer::RuntimeError`.
|
|
384
|
+
V8 cannot run the nested microtask checkpoint needed to settle such a call.
|
|
385
|
+
Synchronous nested `call` and `eval` remain supported.
|
|
386
|
+
|
|
387
|
+
`call_await` and `eval_await` are not currently supported on TruffleRuby.
|
|
388
|
+
|
|
351
389
|
### Microtask checkpoints
|
|
352
390
|
|
|
353
391
|
V8 drains its microtask queue (e.g. callbacks queued via `Promise.resolve().then(...)`) automatically when script execution returns to the embedder, so most code "just works":
|
|
@@ -484,6 +522,25 @@ gcc >= 12.2 and Xcode >= 13 are, at the time of writing, known to work.
|
|
|
484
522
|
* Concurrent cause .... JRuby
|
|
485
523
|
* Supports execjs
|
|
486
524
|
|
|
525
|
+
## Community
|
|
526
|
+
|
|
527
|
+
Libraries and integrations built with MiniRacer:
|
|
528
|
+
|
|
529
|
+
- [Humid](https://github.com/thoughtbot/humid) — JavaScript server-side rendering helpers for Rails.
|
|
530
|
+
- [ExecJS](https://github.com/rails/execjs) — A common interface for executing JavaScript from Ruby, with a MiniRacer runtime.
|
|
531
|
+
- [Opal](https://github.com/opal/opal) — A Ruby-to-JavaScript compiler with a MiniRacer CLI runner.
|
|
532
|
+
- [Handlebars::Engine](https://github.com/gi/handlebars-ruby) — A complete Ruby interface to Handlebars.js.
|
|
533
|
+
- [Minibars](https://github.com/combinaut/minibars) — A lightweight Handlebars.rb replacement built on MiniRacer.
|
|
534
|
+
- [Rtlcss](https://github.com/discourse/rtlcss) — Runs rtlcss from Ruby to convert stylesheets between LTR and RTL.
|
|
535
|
+
- [MessageFormat](https://github.com/discourse/messageformat) — Compiles MessageFormat messages from Ruby using `@messageformat/core`.
|
|
536
|
+
- [feelin](https://github.com/ekzo-dev/ruby-feelin) — Evaluates DMN FEEL expressions from Ruby.
|
|
537
|
+
- [parse-css](https://github.com/camertron/parse-css) — Parses CSS, including nested CSS, through the JavaScript parse-css library.
|
|
538
|
+
|
|
539
|
+
### Notable users
|
|
540
|
+
|
|
541
|
+
- [Discourse](https://github.com/discourse/discourse) — A large Rails application using MiniRacer for JavaScript compilation, processing, and sandboxed evaluation.
|
|
542
|
+
- [rack-mini-profiler](https://github.com/MiniProfiler/rack-mini-profiler) — Uses MiniRacer in its JavaScript build tooling.
|
|
543
|
+
|
|
487
544
|
## Contributing
|
|
488
545
|
|
|
489
546
|
Bug reports and pull requests are welcome on GitHub at https://github.com/rubyjs/mini_racer. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
|
@@ -62,6 +62,8 @@ static inline void rb_thread_lock_native_thread(void)
|
|
|
62
62
|
|
|
63
63
|
#define countof(x) (sizeof(x) / sizeof(*(x)))
|
|
64
64
|
#define endof(x) ((x) + countof(x))
|
|
65
|
+
#define BIGINT_STACK_WORDS 64
|
|
66
|
+
#define BIGINT_MAX_BYTES (16 * 1024 * 1024)
|
|
65
67
|
|
|
66
68
|
// mostly RO: assigned once by platform_set_flag1 while holding |flags_mtx|,
|
|
67
69
|
// from then on read-only and accessible without holding locks
|
|
@@ -152,7 +154,8 @@ typedef struct Context
|
|
|
152
154
|
struct {
|
|
153
155
|
pthread_mutex_t mtx;
|
|
154
156
|
pthread_cond_t cv;
|
|
155
|
-
int
|
|
157
|
+
int active; // dispatch thread only
|
|
158
|
+
int cancel; // protected by |mtx|
|
|
156
159
|
} wd; // watchdog
|
|
157
160
|
Barrier early_init, late_init;
|
|
158
161
|
} Context;
|
|
@@ -352,33 +355,32 @@ static void des_date(void *arg, double v)
|
|
|
352
355
|
put(arg, rb_time_new(sec, usec));
|
|
353
356
|
}
|
|
354
357
|
|
|
355
|
-
// note: v8 stores bigints
|
|
356
|
-
// so we have to take additional steps to ensure correct conversion
|
|
358
|
+
// note: v8 stores bigints as a sign plus little-endian 64-bit magnitude words
|
|
357
359
|
static void des_bigint(void *arg, const void *p, size_t n, int sign)
|
|
358
360
|
{
|
|
359
361
|
VALUE v;
|
|
360
|
-
size_t i;
|
|
361
362
|
DesCtx *c;
|
|
362
|
-
|
|
363
|
+
int flags;
|
|
363
364
|
|
|
364
365
|
c = arg;
|
|
365
366
|
if (*c->err)
|
|
366
367
|
return;
|
|
367
|
-
if (n
|
|
368
|
+
if (n % sizeof(uint64_t)) {
|
|
369
|
+
snprintf(c->err, sizeof(c->err), "bad bigint");
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
if (n > BIGINT_MAX_BYTES) {
|
|
368
373
|
snprintf(c->err, sizeof(c->err), "bigint too big");
|
|
369
374
|
return;
|
|
370
375
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
+
if (n == 0) {
|
|
377
|
+
v = INT2FIX(0);
|
|
378
|
+
} else {
|
|
379
|
+
flags = INTEGER_PACK_LITTLE_ENDIAN;
|
|
380
|
+
if (sign < 0)
|
|
381
|
+
flags |= INTEGER_PACK_NEGATIVE;
|
|
382
|
+
v = rb_integer_unpack(p, n/sizeof(uint64_t), sizeof(uint64_t), 0, flags);
|
|
376
383
|
}
|
|
377
|
-
if (t >> 63)
|
|
378
|
-
*a++ = 0; // suppress sign extension
|
|
379
|
-
v = rb_big_unpack(limbs, a-limbs);
|
|
380
|
-
if (sign < 0)
|
|
381
|
-
v = rb_funcall(v, rb_intern("-@"), 0);
|
|
382
384
|
put(c, v);
|
|
383
385
|
}
|
|
384
386
|
|
|
@@ -579,12 +581,42 @@ static void add_string(Ser *s, VALUE v)
|
|
|
579
581
|
return ser_string(s, p, n);
|
|
580
582
|
}
|
|
581
583
|
|
|
584
|
+
// Keep small values allocation-free while allowing large values up to a
|
|
585
|
+
// deliberate per-value limit that bounds temporary conversion storage.
|
|
586
|
+
static int serialize_bigint(Ser *s, VALUE v)
|
|
587
|
+
{
|
|
588
|
+
uint64_t stack_words[BIGINT_STACK_WORDS];
|
|
589
|
+
uint64_t *words;
|
|
590
|
+
size_t nwords, nbytes;
|
|
591
|
+
int packed;
|
|
592
|
+
|
|
593
|
+
nwords = rb_absint_numwords(v, 64, NULL);
|
|
594
|
+
if (nwords == (size_t)-1 || nwords > BIGINT_MAX_BYTES/sizeof(*words))
|
|
595
|
+
return bail(&s->err, "bigint too big");
|
|
596
|
+
nbytes = nwords * sizeof(*words);
|
|
597
|
+
words = stack_words;
|
|
598
|
+
if (nwords > countof(stack_words)) {
|
|
599
|
+
words = malloc(nbytes);
|
|
600
|
+
if (!words)
|
|
601
|
+
return bail(&s->err, "out of memory");
|
|
602
|
+
}
|
|
603
|
+
packed = rb_integer_pack(v, words, nwords, sizeof(*words), 0,
|
|
604
|
+
INTEGER_PACK_LITTLE_ENDIAN);
|
|
605
|
+
if (packed < -1 || packed > 1) {
|
|
606
|
+
if (words != stack_words)
|
|
607
|
+
free(words);
|
|
608
|
+
return bail(&s->err, "bigint too big");
|
|
609
|
+
}
|
|
610
|
+
ser_bigint(s, words, nbytes, packed < 0 ? -1 : 1);
|
|
611
|
+
if (words != stack_words)
|
|
612
|
+
free(words);
|
|
613
|
+
return *s->err ? -1 : 0;
|
|
614
|
+
}
|
|
615
|
+
|
|
582
616
|
static int serialize1(Ser *s, VALUE refs, VALUE v)
|
|
583
617
|
{
|
|
584
|
-
unsigned long limbs[64];
|
|
585
618
|
VALUE a, t, id;
|
|
586
619
|
size_t i, n;
|
|
587
|
-
int sign;
|
|
588
620
|
|
|
589
621
|
if (*s->err)
|
|
590
622
|
return -1;
|
|
@@ -669,15 +701,7 @@ static int serialize1(Ser *s, VALUE refs, VALUE v)
|
|
|
669
701
|
ser_bool(s, 0);
|
|
670
702
|
break;
|
|
671
703
|
case T_BIGNUM:
|
|
672
|
-
|
|
673
|
-
// so we have to take additional steps to ensure correct conversion
|
|
674
|
-
memset(limbs, 0, sizeof(limbs));
|
|
675
|
-
sign = rb_big_sign(v) ? 1 : -1;
|
|
676
|
-
if (sign < 0)
|
|
677
|
-
v = rb_big_mul(v, LONG2FIX(-1));
|
|
678
|
-
rb_big_pack(v, limbs, countof(limbs));
|
|
679
|
-
ser_bigint(s, limbs, countof(limbs), sign);
|
|
680
|
-
break;
|
|
704
|
+
return serialize_bigint(s, v);
|
|
681
705
|
case T_FIXNUM:
|
|
682
706
|
ser_int(s, FIX2LONG(v));
|
|
683
707
|
break;
|
|
@@ -772,7 +796,7 @@ static void *v8_watchdog(void *arg)
|
|
|
772
796
|
if (c->wd.cancel)
|
|
773
797
|
break;
|
|
774
798
|
if (deadline_exceeded(deadline)) {
|
|
775
|
-
|
|
799
|
+
v8_terminate_watchdog(c->pst);
|
|
776
800
|
break;
|
|
777
801
|
}
|
|
778
802
|
}
|
|
@@ -786,8 +810,14 @@ static void v8_timedwait(Context *c, const uint8_t *p, size_t n,
|
|
|
786
810
|
pthread_t thr;
|
|
787
811
|
int r;
|
|
788
812
|
|
|
789
|
-
|
|
790
|
-
|
|
813
|
+
if (c->timeout <= 0 || c->wd.active) {
|
|
814
|
+
func(c->pst, p, n);
|
|
815
|
+
return;
|
|
816
|
+
}
|
|
817
|
+
c->wd.active = 1;
|
|
818
|
+
r = pthread_create(&thr, NULL, v8_watchdog, c);
|
|
819
|
+
if (r) {
|
|
820
|
+
c->wd.active = 0;
|
|
791
821
|
fprintf(stderr, "mini_racer: watchdog: pthread_create: %s\n", strerror(r));
|
|
792
822
|
fflush(stderr);
|
|
793
823
|
}
|
|
@@ -799,7 +829,9 @@ static void v8_timedwait(Context *c, const uint8_t *p, size_t n,
|
|
|
799
829
|
pthread_cond_signal(&c->wd.cv);
|
|
800
830
|
pthread_mutex_unlock(&c->wd.mtx);
|
|
801
831
|
pthread_join(thr, NULL);
|
|
832
|
+
v8_cancel_watchdog_termination(c->pst);
|
|
802
833
|
c->wd.cancel = 0;
|
|
834
|
+
c->wd.active = 0;
|
|
803
835
|
}
|
|
804
836
|
|
|
805
837
|
static void dispatch1(Context *c, const uint8_t *p, size_t n)
|
|
@@ -810,7 +842,9 @@ static void dispatch1(Context *c, const uint8_t *p, size_t n)
|
|
|
810
842
|
switch (*p) {
|
|
811
843
|
case 'A': return v8_attach(c->pst, p+1, n-1);
|
|
812
844
|
case 'C': return v8_timedwait(c, p+1, n-1, v8_call);
|
|
845
|
+
case 'D': return v8_timedwait(c, p+1, n-1, v8_call_await);
|
|
813
846
|
case 'E': return v8_timedwait(c, p+1, n-1, v8_eval);
|
|
847
|
+
case 'F': return v8_timedwait(c, p+1, n-1, v8_eval_await);
|
|
814
848
|
case 'H': return v8_heap_snapshot(c->pst);
|
|
815
849
|
case 'M': return v8_perform_microtask_checkpoint(c->pst);
|
|
816
850
|
case 'P': return v8_pump_message_loop(c->pst);
|
|
@@ -888,12 +922,12 @@ void v8_dispatch(Context *c)
|
|
|
888
922
|
pthread_mutex_unlock(&c->mtx);
|
|
889
923
|
}
|
|
890
924
|
|
|
891
|
-
// only called when inside v8_call, v8_eval
|
|
925
|
+
// only called when inside v8_call, v8_eval (and their await variants),
|
|
926
|
+
// or v8_pump_message_loop
|
|
892
927
|
void v8_roundtrip(Context *c, const uint8_t **p, size_t *n)
|
|
893
928
|
{
|
|
894
929
|
pthread_mutex_lock(&c->mtx);
|
|
895
930
|
buf_reset(&c->v8_req);
|
|
896
|
-
buf_reset(&c->req);
|
|
897
931
|
if (c->res.len)
|
|
898
932
|
c->res_ready = 1;
|
|
899
933
|
pthread_cond_signal(&c->cv);
|
|
@@ -947,6 +981,8 @@ static VALUE deserialize1(DesCtx *d, const uint8_t *p, size_t n)
|
|
|
947
981
|
|
|
948
982
|
if (des(&err, p, n, d))
|
|
949
983
|
rb_raise(runtime_error, "%s", err);
|
|
984
|
+
if (*d->err)
|
|
985
|
+
rb_raise(runtime_error, "%s", d->err);
|
|
950
986
|
if (d->tos != d->stack) // should not happen
|
|
951
987
|
rb_raise(runtime_error, "parse stack not empty");
|
|
952
988
|
return d->tos->a;
|
|
@@ -1009,7 +1045,7 @@ static void *rendezvous_callback(void *arg)
|
|
|
1009
1045
|
goto fail;
|
|
1010
1046
|
}
|
|
1011
1047
|
ser_init1(&s, 'c'); // callback reply
|
|
1012
|
-
if (serialize(&s, r)) {
|
|
1048
|
+
if (serialize(&s, r)) {
|
|
1013
1049
|
c->exception = rb_exc_new_cstr(internal_error, s.err);
|
|
1014
1050
|
ser_reset(&s);
|
|
1015
1051
|
goto fail;
|
|
@@ -1655,7 +1691,7 @@ static VALUE context_stop(VALUE self)
|
|
|
1655
1691
|
return Qnil;
|
|
1656
1692
|
}
|
|
1657
1693
|
|
|
1658
|
-
static VALUE
|
|
1694
|
+
static VALUE context_call_common(int argc, VALUE *argv, VALUE self, char op)
|
|
1659
1695
|
{
|
|
1660
1696
|
VALUE name, args;
|
|
1661
1697
|
VALUE a, e;
|
|
@@ -1666,8 +1702,8 @@ static VALUE context_call(int argc, VALUE *argv, VALUE self)
|
|
|
1666
1702
|
rb_scan_args(argc, argv, "1*", &name, &args);
|
|
1667
1703
|
Check_Type(name, T_STRING);
|
|
1668
1704
|
rb_ary_unshift(args, name);
|
|
1669
|
-
// request is (C)all, [name, args...] array
|
|
1670
|
-
ser_init1(&s,
|
|
1705
|
+
// request is (C)all or (D) call_await, [name, args...] array
|
|
1706
|
+
ser_init1(&s, op);
|
|
1671
1707
|
if (serialize(&s, args)) {
|
|
1672
1708
|
ser_reset(&s);
|
|
1673
1709
|
rb_raise(runtime_error, "Context.call: %s", s.err);
|
|
@@ -1679,7 +1715,17 @@ static VALUE context_call(int argc, VALUE *argv, VALUE self)
|
|
|
1679
1715
|
return rb_ary_pop(a);
|
|
1680
1716
|
}
|
|
1681
1717
|
|
|
1682
|
-
static VALUE
|
|
1718
|
+
static VALUE context_call(int argc, VALUE *argv, VALUE self)
|
|
1719
|
+
{
|
|
1720
|
+
return context_call_common(argc, argv, self, 'C');
|
|
1721
|
+
}
|
|
1722
|
+
|
|
1723
|
+
static VALUE context_call_await(int argc, VALUE *argv, VALUE self)
|
|
1724
|
+
{
|
|
1725
|
+
return context_call_common(argc, argv, self, 'D');
|
|
1726
|
+
}
|
|
1727
|
+
|
|
1728
|
+
static VALUE context_eval_common(int argc, VALUE *argv, VALUE self, char op)
|
|
1683
1729
|
{
|
|
1684
1730
|
VALUE a, e, source, filename, kwargs;
|
|
1685
1731
|
Context *c;
|
|
@@ -1694,8 +1740,8 @@ static VALUE context_eval(int argc, VALUE *argv, VALUE self)
|
|
|
1694
1740
|
if (NIL_P(filename))
|
|
1695
1741
|
filename = rb_str_new_cstr("<eval>");
|
|
1696
1742
|
Check_Type(filename, T_STRING);
|
|
1697
|
-
// request is (E)val, [filename, source] array
|
|
1698
|
-
ser_init1(&s,
|
|
1743
|
+
// request is (E)val or (F) eval_await, [filename, source] array
|
|
1744
|
+
ser_init1(&s, op);
|
|
1699
1745
|
ser_array_begin(&s, 2);
|
|
1700
1746
|
add_string(&s, filename);
|
|
1701
1747
|
add_string(&s, source);
|
|
@@ -1707,6 +1753,16 @@ static VALUE context_eval(int argc, VALUE *argv, VALUE self)
|
|
|
1707
1753
|
return rb_ary_pop(a);
|
|
1708
1754
|
}
|
|
1709
1755
|
|
|
1756
|
+
static VALUE context_eval(int argc, VALUE *argv, VALUE self)
|
|
1757
|
+
{
|
|
1758
|
+
return context_eval_common(argc, argv, self, 'E');
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
static VALUE context_eval_await(int argc, VALUE *argv, VALUE self)
|
|
1762
|
+
{
|
|
1763
|
+
return context_eval_common(argc, argv, self, 'F');
|
|
1764
|
+
}
|
|
1765
|
+
|
|
1710
1766
|
static VALUE context_heap_stats(VALUE self)
|
|
1711
1767
|
{
|
|
1712
1768
|
VALUE a, h, k, v;
|
|
@@ -2147,7 +2203,9 @@ void Init_mini_racer_extension(void)
|
|
|
2147
2203
|
rb_define_method(c, "dispose", context_dispose, 0);
|
|
2148
2204
|
rb_define_method(c, "stop", context_stop, 0);
|
|
2149
2205
|
rb_define_method(c, "call", context_call, -1);
|
|
2206
|
+
rb_define_method(c, "call_await", context_call_await, -1);
|
|
2150
2207
|
rb_define_method(c, "eval", context_eval, -1);
|
|
2208
|
+
rb_define_method(c, "eval_await", context_eval_await, -1);
|
|
2151
2209
|
rb_define_method(c, "heap_stats", context_heap_stats, 0);
|
|
2152
2210
|
rb_define_method(c, "heap_snapshot", context_heap_snapshot, 0);
|
|
2153
2211
|
rb_define_method(c, "perform_microtask_checkpoint", context_perform_microtask_checkpoint, 0);
|