mini_racer-csim 0.21.1.0 → 0.21.1.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 +8 -1
- data/README.md +2 -9
- data/ext/mini_racer_extension/extconf.rb +0 -5
- data/ext/mini_racer_extension/mini_racer_extension.c +228 -0
- data/ext/mini_racer_extension/mini_racer_v8.cc +495 -105
- data/ext/mini_racer_extension/mini_racer_v8.h +3 -0
- data/ext/mini_racer_loader/extconf.rb +0 -5
- data/lib/mini_racer/version.rb +1 -1
- data/lib/mini_racer.rb +18 -20
- metadata +1 -3
- data/lib/mini_racer/shared.rb +0 -395
- data/lib/mini_racer/truffleruby.rb +0 -479
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8674864924ab7e282736f327fc6bda583750e6cd3e61df57d4dd09005966812b
|
|
4
|
+
data.tar.gz: 6e98c37b07f580c5b9ad2d5af887ec0a420ec95b2c4f58f929eb8aae031ca5ac
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 72b2991b309086e5e089a1bb9e3a07517a417c6435444e457d1b5ca42ab095290b2c13f1559ac0c8c384794b240acaf063ca0691724dc9bd3647677bb8c88261
|
|
7
|
+
data.tar.gz: 4b7ffa6b04dcca1c2771ef3993095a36210638a120b341eddde6e3615d9bccd3845d98c92271f58cd3d9671ba364442689df0792179963c8efab9815046e30db
|
data/CHANGELOG
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
-
|
|
1
|
+
- 0.21.1.1 - 07-06-2026
|
|
2
|
+
- Drop the TruffleRuby backend: mini_racer-csim is now a hard fork targeting CRuby/V8 only (the GraalJS/TruffleRuby shims and their tests are removed)
|
|
3
|
+
- Add per-frame realms via `Context#create_realm`, returning a `MiniRacer::Realm` (multiple V8 realms in one isolate, browser-iframe semantics) with `Realm#eval` / `call` / `attach` / `dispose` / `disposed?`
|
|
4
|
+
- all realms share one security token so they can reach each other's globals (same-origin iframe model)
|
|
5
|
+
- `__mr_realmGlobal(id)` returns a realm's live `globalThis` cross-realm; `__mr_realmOf(fn)` reports the realm a callback was created in ([[Realm]]) for WebIDL-style error attribution
|
|
6
|
+
- unhandled promise rejections are tracked and delivered per realm via `globalThis.__mr_emitUnhandledRejection(reason, promise)`; the queue is purged when a realm is disposed or reset so a stale rejection never fires against a fresh realm
|
|
7
|
+
|
|
8
|
+
- 0.21.1.0 - 06-06-2026
|
|
2
9
|
- Add `Context#perform_microtask_checkpoint` to synchronously drain the V8 microtask queue, useful for spec-compliant `dispatchEvent` sequencing inside Ruby callbacks
|
|
3
10
|
- Expose V8 ScriptCompiler::CachedData via Context#compile / MiniRacer::Script (#411)
|
|
4
11
|
- script = ctx.compile(src, filename:, cached_data:, produce_cache:) → Script handle
|
data/README.md
CHANGED
|
@@ -31,7 +31,7 @@ The fork is periodically rebased on upstream `mini_racer` to pick up V8 / `libv8
|
|
|
31
31
|
|
|
32
32
|
## Supported Ruby Versions & Troubleshooting
|
|
33
33
|
|
|
34
|
-
MiniRacer only supports non-EOL versions of Ruby. See [Ruby Maintenance Branches](https://www.ruby-lang.org/en/downloads/branches/) for the list of non-EOL Rubies. If you require support for older versions of Ruby install an older version of the gem.
|
|
34
|
+
MiniRacer only supports non-EOL versions of Ruby. See [Ruby Maintenance Branches](https://www.ruby-lang.org/en/downloads/branches/) for the list of non-EOL Rubies. If you require support for older versions of Ruby install an older version of the gem. (The `mini_racer-csim` fork is CRuby/V8 only — the TruffleRuby backend that upstream supports has been removed.)
|
|
35
35
|
|
|
36
36
|
MiniRacer **does not support**
|
|
37
37
|
|
|
@@ -228,10 +228,6 @@ Notes:
|
|
|
228
228
|
reuse still works under `:single_threaded`. If you need both cross-process
|
|
229
229
|
reuse and `:single_threaded` (e.g. for fork-safety reasons), disable
|
|
230
230
|
`:single_threaded` for the path that produces / consumes the cache.
|
|
231
|
-
- On TruffleRuby, `Script` is implemented as source replay (GraalJS has no
|
|
232
|
-
equivalent per-script bytecode cache reachable from `Polyglot::InnerContext`),
|
|
233
|
-
so `cached_data` and `produce_cache` are silently ignored and `cached_data`
|
|
234
|
-
always returns `nil`, and `MiniRacer::V8_CACHED_DATA_VERSION_TAG` is `0`.
|
|
235
231
|
|
|
236
232
|
### Fork Safety
|
|
237
233
|
|
|
@@ -501,7 +497,7 @@ context.eval("log")
|
|
|
501
497
|
# => ["before", "microtask", "after"]
|
|
502
498
|
```
|
|
503
499
|
|
|
504
|
-
`host_namespace:` accepts a String (the global name to use — it must be a valid JavaScript identifier), `true` (the default name `"MiniRacer"`), or `nil`/`false` (the default — inject nothing). The namespace object is defined non-enumerable so it does not appear in `Object.keys(globalThis)`, while its methods are ordinary properties discoverable via `Object.keys(MiniRacer)`. Like `perform_microtask_checkpoint`, `drainMicrotasks()` is a no-op while a microtask checkpoint is already in progress, and it lets watchdog/out-of-memory termination propagate to the enclosing `eval`/`call`.
|
|
500
|
+
`host_namespace:` accepts a String (the global name to use — it must be a valid JavaScript identifier), `true` (the default name `"MiniRacer"`), or `nil`/`false` (the default — inject nothing). The namespace object is defined non-enumerable so it does not appear in `Object.keys(globalThis)`, while its methods are ordinary properties discoverable via `Object.keys(MiniRacer)`. Like `perform_microtask_checkpoint`, `drainMicrotasks()` is a no-op while a microtask checkpoint is already in progress, and it lets watchdog/out-of-memory termination propagate to the enclosing `eval`/`call`.
|
|
505
501
|
|
|
506
502
|
### ES modules
|
|
507
503
|
|
|
@@ -570,9 +566,6 @@ Notes:
|
|
|
570
566
|
accumulate handles until `Context#dispose` clears them.
|
|
571
567
|
- Top-level await is not yet supported; `evaluate` raises if the
|
|
572
568
|
module's evaluation promise stays pending after the microtask drain.
|
|
573
|
-
- On TruffleRuby, `Context#compile_module` raises `NotImplementedError`
|
|
574
|
-
— GraalJS has its own module-loading mechanism that doesn't map onto
|
|
575
|
-
this handle-based API. PRs to bridge are welcome.
|
|
576
569
|
|
|
577
570
|
## Performance
|
|
578
571
|
|
|
@@ -2,11 +2,6 @@ require 'mkmf'
|
|
|
2
2
|
|
|
3
3
|
$srcs = ["mini_racer_extension.c", "mini_racer_v8.cc"]
|
|
4
4
|
|
|
5
|
-
if RUBY_ENGINE == "truffleruby"
|
|
6
|
-
File.write("Makefile", dummy_makefile($srcdir).join(""))
|
|
7
|
-
return
|
|
8
|
-
end
|
|
9
|
-
|
|
10
5
|
require_relative '../../lib/mini_racer/version'
|
|
11
6
|
gem 'libv8-node', MiniRacer::LIBV8_NODE_VERSION
|
|
12
7
|
require 'libv8-node'
|
|
@@ -204,6 +204,15 @@ typedef struct Script {
|
|
|
204
204
|
int disposed;
|
|
205
205
|
} Script;
|
|
206
206
|
|
|
207
|
+
// A per-frame realm (extra v8::Context in the same isolate); see
|
|
208
|
+
// Context#create_realm. Like Script/Module, the C++ realm is freed eagerly via
|
|
209
|
+
// Realm#dispose or at Context teardown — realm_free can't send a dispose RPC.
|
|
210
|
+
typedef struct Realm {
|
|
211
|
+
VALUE context; // parent Context VALUE (kept alive via mark)
|
|
212
|
+
int32_t id; // realm id (0 = main, never wrapped as a Realm)
|
|
213
|
+
int disposed;
|
|
214
|
+
} Realm;
|
|
215
|
+
|
|
207
216
|
static void context_destroy(Context *c);
|
|
208
217
|
static void context_free(void *arg);
|
|
209
218
|
static void context_mark(void *arg);
|
|
@@ -257,6 +266,19 @@ static const rb_data_type_t module_type = {
|
|
|
257
266
|
},
|
|
258
267
|
};
|
|
259
268
|
|
|
269
|
+
static void realm_free(void *arg);
|
|
270
|
+
static void realm_mark(void *arg);
|
|
271
|
+
static size_t realm_size(const void *arg);
|
|
272
|
+
|
|
273
|
+
static const rb_data_type_t realm_type = {
|
|
274
|
+
.wrap_struct_name = "mini_racer/realm",
|
|
275
|
+
.function = {
|
|
276
|
+
.dfree = realm_free,
|
|
277
|
+
.dmark = realm_mark,
|
|
278
|
+
.dsize = realm_size,
|
|
279
|
+
},
|
|
280
|
+
};
|
|
281
|
+
|
|
260
282
|
static VALUE platform_init_error;
|
|
261
283
|
static VALUE context_disposed_error;
|
|
262
284
|
static VALUE parse_error;
|
|
@@ -270,6 +292,7 @@ static VALUE context_class;
|
|
|
270
292
|
static VALUE snapshot_class;
|
|
271
293
|
static VALUE script_class;
|
|
272
294
|
static VALUE module_class;
|
|
295
|
+
static VALUE realm_class;
|
|
273
296
|
static VALUE date_time_class;
|
|
274
297
|
static VALUE binary_class;
|
|
275
298
|
static VALUE js_function_class;
|
|
@@ -885,6 +908,7 @@ static void dispatch1(Context *c, const uint8_t *p, size_t n)
|
|
|
885
908
|
assert(n > 0);
|
|
886
909
|
switch (*p) {
|
|
887
910
|
case 'A': return v8_attach(c->pst, p+1, n-1);
|
|
911
|
+
case 'B': return v8_create_realm(c->pst); // (B)uild realm
|
|
888
912
|
case 'C': return v8_timedwait(c, p+1, n-1, v8_call);
|
|
889
913
|
case 'D': return v8_dispose_script(c->pst, p+1, n-1);
|
|
890
914
|
case 'E': return v8_timedwait(c, p+1, n-1, v8_eval);
|
|
@@ -903,6 +927,8 @@ static void dispatch1(Context *c, const uint8_t *p, size_t n)
|
|
|
903
927
|
case 'U': return v8_module_status(c->pst, p+1, n-1); // (U) module status — non-blocking
|
|
904
928
|
case 'V': return v8_timedwait(c, p+1, n-1, v8_evaluate_module); // e(V)aluate
|
|
905
929
|
case 'W': return v8_warmup(c->pst, p+1, n-1);
|
|
930
|
+
case 'X': return v8_dispose_realm(c->pst, p+1, n-1); // e(X)punge realm
|
|
931
|
+
case '@': return v8_timedwait(c, p+1, n-1, v8_realm_dispatch); // realm-scoped op
|
|
906
932
|
case 'Z': return v8_dispose_module(c->pst, p+1, n-1); // (Z) dispose module handle
|
|
907
933
|
case 'L':
|
|
908
934
|
b = 0;
|
|
@@ -1896,6 +1922,197 @@ static VALUE context_reset_realm(VALUE self)
|
|
|
1896
1922
|
return Qnil;
|
|
1897
1923
|
}
|
|
1898
1924
|
|
|
1925
|
+
// -- MiniRacer::Realm (per-frame realm = extra v8::Context in this isolate) --
|
|
1926
|
+
|
|
1927
|
+
static void realm_free(void *arg)
|
|
1928
|
+
{
|
|
1929
|
+
// Like module_free: no dispose RPC from a finalizer. State::~State()
|
|
1930
|
+
// tears every realm down at Context teardown; use Realm#dispose to free
|
|
1931
|
+
// a realm eagerly mid-lifetime.
|
|
1932
|
+
ruby_xfree(arg);
|
|
1933
|
+
}
|
|
1934
|
+
|
|
1935
|
+
static void realm_mark(void *arg)
|
|
1936
|
+
{
|
|
1937
|
+
Realm *r = arg;
|
|
1938
|
+
rb_gc_mark(r->context);
|
|
1939
|
+
}
|
|
1940
|
+
|
|
1941
|
+
static size_t realm_size(const void *arg)
|
|
1942
|
+
{
|
|
1943
|
+
(void)arg;
|
|
1944
|
+
return sizeof(Realm);
|
|
1945
|
+
}
|
|
1946
|
+
|
|
1947
|
+
static VALUE realm_alloc(VALUE klass)
|
|
1948
|
+
{
|
|
1949
|
+
Realm *r;
|
|
1950
|
+
return TypedData_Make_Struct(klass, Realm, &realm_type, r);
|
|
1951
|
+
}
|
|
1952
|
+
|
|
1953
|
+
static VALUE realm_initialize(int argc, VALUE *argv, VALUE self)
|
|
1954
|
+
{
|
|
1955
|
+
(void)argc; (void)argv; (void)self;
|
|
1956
|
+
rb_raise(runtime_error, "MiniRacer::Realm must be created via Context#create_realm");
|
|
1957
|
+
}
|
|
1958
|
+
|
|
1959
|
+
// Resolve the parent Context, raising if the realm or its context is disposed.
|
|
1960
|
+
static Context *realm_live_context(VALUE self, Realm **out)
|
|
1961
|
+
{
|
|
1962
|
+
Realm *r;
|
|
1963
|
+
Context *c;
|
|
1964
|
+
|
|
1965
|
+
TypedData_Get_Struct(self, Realm, &realm_type, r);
|
|
1966
|
+
if (r->disposed)
|
|
1967
|
+
rb_raise(runtime_error, "disposed realm");
|
|
1968
|
+
TypedData_Get_Struct(r->context, Context, &context_type, c);
|
|
1969
|
+
if (atomic_load(&c->quit))
|
|
1970
|
+
rb_raise(context_disposed_error, "disposed context");
|
|
1971
|
+
*out = r;
|
|
1972
|
+
return c;
|
|
1973
|
+
}
|
|
1974
|
+
|
|
1975
|
+
// Wrap an inner request (built with ser_init1(op)...) as a realm-scoped request
|
|
1976
|
+
// '@' + id(4 raw bytes) + inner, and dispatch it. Frees |inner|; the reply has
|
|
1977
|
+
// the same shape as the inner op's reply.
|
|
1978
|
+
static VALUE realm_rendezvous(Context *c, int32_t id, Ser *inner)
|
|
1979
|
+
{
|
|
1980
|
+
Buf req;
|
|
1981
|
+
buf_init(&req);
|
|
1982
|
+
buf_putc(&req, '@');
|
|
1983
|
+
buf_put(&req, &id, sizeof(id)); // same process => host endianness ok
|
|
1984
|
+
buf_put(&req, inner->b.buf, inner->b.len);
|
|
1985
|
+
ser_reset(inner); // release the inner buffer
|
|
1986
|
+
return rendezvous(c, &req); // takes ownership of |req|
|
|
1987
|
+
}
|
|
1988
|
+
|
|
1989
|
+
static VALUE realm_id(VALUE self)
|
|
1990
|
+
{
|
|
1991
|
+
Realm *r;
|
|
1992
|
+
TypedData_Get_Struct(self, Realm, &realm_type, r);
|
|
1993
|
+
return INT2NUM(r->id);
|
|
1994
|
+
}
|
|
1995
|
+
|
|
1996
|
+
static VALUE realm_disposed_p(VALUE self)
|
|
1997
|
+
{
|
|
1998
|
+
Realm *r;
|
|
1999
|
+
TypedData_Get_Struct(self, Realm, &realm_type, r);
|
|
2000
|
+
return r->disposed ? Qtrue : Qfalse;
|
|
2001
|
+
}
|
|
2002
|
+
|
|
2003
|
+
static VALUE realm_eval(int argc, VALUE *argv, VALUE self)
|
|
2004
|
+
{
|
|
2005
|
+
VALUE a, e, source, filename, kwargs;
|
|
2006
|
+
Realm *r;
|
|
2007
|
+
Context *c = realm_live_context(self, &r);
|
|
2008
|
+
Ser s;
|
|
2009
|
+
|
|
2010
|
+
filename = Qnil;
|
|
2011
|
+
rb_scan_args(argc, argv, "1:", &source, &kwargs);
|
|
2012
|
+
Check_Type(source, T_STRING);
|
|
2013
|
+
if (!NIL_P(kwargs))
|
|
2014
|
+
filename = rb_hash_aref(kwargs, rb_id2sym(rb_intern("filename")));
|
|
2015
|
+
if (NIL_P(filename))
|
|
2016
|
+
filename = rb_str_new_cstr("<eval>");
|
|
2017
|
+
Check_Type(filename, T_STRING);
|
|
2018
|
+
ser_init1(&s, 'E');
|
|
2019
|
+
ser_array_begin(&s, 2);
|
|
2020
|
+
add_string(&s, filename);
|
|
2021
|
+
add_string(&s, source);
|
|
2022
|
+
ser_array_end(&s, 2);
|
|
2023
|
+
a = realm_rendezvous(c, r->id, &s);
|
|
2024
|
+
e = rb_ary_pop(a);
|
|
2025
|
+
handle_exception(e);
|
|
2026
|
+
return rb_ary_pop(a);
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
static VALUE realm_call(int argc, VALUE *argv, VALUE self)
|
|
2030
|
+
{
|
|
2031
|
+
VALUE name, args, a, e;
|
|
2032
|
+
Realm *r;
|
|
2033
|
+
Context *c = realm_live_context(self, &r);
|
|
2034
|
+
Ser s;
|
|
2035
|
+
|
|
2036
|
+
rb_scan_args(argc, argv, "1*", &name, &args);
|
|
2037
|
+
Check_Type(name, T_STRING);
|
|
2038
|
+
rb_ary_unshift(args, name);
|
|
2039
|
+
ser_init1(&s, 'C');
|
|
2040
|
+
if (serialize(&s, args)) {
|
|
2041
|
+
ser_reset(&s);
|
|
2042
|
+
rb_raise(runtime_error, "Realm#call: %s", s.err);
|
|
2043
|
+
}
|
|
2044
|
+
a = realm_rendezvous(c, r->id, &s);
|
|
2045
|
+
e = rb_ary_pop(a);
|
|
2046
|
+
handle_exception(e);
|
|
2047
|
+
return rb_ary_pop(a);
|
|
2048
|
+
}
|
|
2049
|
+
|
|
2050
|
+
static VALUE realm_attach(VALUE self, VALUE name, VALUE proc)
|
|
2051
|
+
{
|
|
2052
|
+
VALUE e;
|
|
2053
|
+
Realm *r;
|
|
2054
|
+
Context *c = realm_live_context(self, &r);
|
|
2055
|
+
Ser s;
|
|
2056
|
+
|
|
2057
|
+
ser_init1(&s, 'A');
|
|
2058
|
+
ser_array_begin(&s, 2);
|
|
2059
|
+
add_string(&s, name);
|
|
2060
|
+
ser_int(&s, RARRAY_LENINT(c->procs));
|
|
2061
|
+
ser_array_end(&s, 2);
|
|
2062
|
+
rb_ary_push(c->procs, proc);
|
|
2063
|
+
e = realm_rendezvous(c, r->id, &s);
|
|
2064
|
+
handle_exception(e);
|
|
2065
|
+
return Qnil;
|
|
2066
|
+
}
|
|
2067
|
+
|
|
2068
|
+
static VALUE realm_dispose(VALUE self)
|
|
2069
|
+
{
|
|
2070
|
+
Realm *r;
|
|
2071
|
+
Context *c;
|
|
2072
|
+
Ser s;
|
|
2073
|
+
|
|
2074
|
+
TypedData_Get_Struct(self, Realm, &realm_type, r);
|
|
2075
|
+
if (r->disposed)
|
|
2076
|
+
return Qnil;
|
|
2077
|
+
TypedData_Get_Struct(r->context, Context, &context_type, c);
|
|
2078
|
+
// Mark disposed before the rendezvous: once we have committed to expunging
|
|
2079
|
+
// the realm, disposed? must report true even if the rendezvous below raises
|
|
2080
|
+
// (e.g. the context is concurrently disposed). The realm is unusable either
|
|
2081
|
+
// way, and leaving the flag clear would re-send the request on a retry.
|
|
2082
|
+
r->disposed = 1;
|
|
2083
|
+
if (!atomic_load(&c->quit)) {
|
|
2084
|
+
ser_init1(&s, 'X'); // e(X)punge realm, payload [id]
|
|
2085
|
+
ser_int(&s, r->id);
|
|
2086
|
+
rendezvous(c, &s.b); // reply is an empty string; ignore
|
|
2087
|
+
}
|
|
2088
|
+
return Qnil;
|
|
2089
|
+
}
|
|
2090
|
+
|
|
2091
|
+
static VALUE context_create_realm(VALUE self)
|
|
2092
|
+
{
|
|
2093
|
+
Context *c;
|
|
2094
|
+
VALUE a, e, result, realm_v;
|
|
2095
|
+
Realm *r;
|
|
2096
|
+
Buf b;
|
|
2097
|
+
|
|
2098
|
+
TypedData_Get_Struct(self, Context, &context_type, c);
|
|
2099
|
+
if (atomic_load(&c->quit))
|
|
2100
|
+
rb_raise(context_disposed_error, "disposed context");
|
|
2101
|
+
buf_init(&b);
|
|
2102
|
+
buf_putc(&b, 'B'); // (B)uild realm, returns [id, err]
|
|
2103
|
+
a = rendezvous(c, &b); // takes ownership of |b|
|
|
2104
|
+
e = rb_ary_pop(a);
|
|
2105
|
+
handle_exception(e);
|
|
2106
|
+
result = rb_ary_pop(a);
|
|
2107
|
+
|
|
2108
|
+
realm_v = rb_obj_alloc(realm_class); // skip the raising initialize
|
|
2109
|
+
TypedData_Get_Struct(realm_v, Realm, &realm_type, r);
|
|
2110
|
+
r->context = self;
|
|
2111
|
+
r->id = NUM2INT(result);
|
|
2112
|
+
r->disposed = 0;
|
|
2113
|
+
return realm_v;
|
|
2114
|
+
}
|
|
2115
|
+
|
|
1899
2116
|
static VALUE context_pump_message_loop(VALUE self)
|
|
1900
2117
|
{
|
|
1901
2118
|
Context *c;
|
|
@@ -2855,6 +3072,7 @@ void Init_mini_racer_extension(void)
|
|
|
2855
3072
|
rb_define_method(c, "heap_snapshot", context_heap_snapshot, 0);
|
|
2856
3073
|
rb_define_method(c, "perform_microtask_checkpoint", context_perform_microtask_checkpoint, 0);
|
|
2857
3074
|
rb_define_method(c, "reset_realm", context_reset_realm, 0);
|
|
3075
|
+
rb_define_method(c, "create_realm", context_create_realm, 0);
|
|
2858
3076
|
rb_define_method(c, "pump_message_loop", context_pump_message_loop, 0);
|
|
2859
3077
|
rb_define_method(c, "low_memory_notification", context_low_memory_notification, 0);
|
|
2860
3078
|
rb_define_method(c, "dynamic_import_resolver", context_get_dynamic_import_resolver, 0);
|
|
@@ -2882,6 +3100,16 @@ void Init_mini_racer_extension(void)
|
|
|
2882
3100
|
rb_define_method(c, "disposed?", module_disposed_p, 0);
|
|
2883
3101
|
rb_define_alloc_func(c, module_alloc);
|
|
2884
3102
|
|
|
3103
|
+
c = realm_class = rb_define_class_under(m, "Realm", rb_cObject);
|
|
3104
|
+
rb_define_method(c, "initialize", realm_initialize, -1);
|
|
3105
|
+
rb_define_method(c, "id", realm_id, 0);
|
|
3106
|
+
rb_define_method(c, "eval", realm_eval, -1);
|
|
3107
|
+
rb_define_method(c, "call", realm_call, -1);
|
|
3108
|
+
rb_define_method(c, "attach", realm_attach, 2);
|
|
3109
|
+
rb_define_method(c, "dispose", realm_dispose, 0);
|
|
3110
|
+
rb_define_method(c, "disposed?", realm_disposed_p, 0);
|
|
3111
|
+
rb_define_alloc_func(c, realm_alloc);
|
|
3112
|
+
|
|
2885
3113
|
c = snapshot_class = rb_define_class_under(m, "Snapshot", rb_cObject);
|
|
2886
3114
|
rb_define_method(c, "initialize", snapshot_initialize, -1);
|
|
2887
3115
|
rb_define_method(c, "warmup!", snapshot_warmup, 1);
|