Exception: MiniRacer::EvalError
- Defined in:
- lib/mini_racer.rb,
ext/mini_racer_extension/mini_racer_extension.c
Direct Known Subclasses
InternalError, ParseError, RuntimeError, ScriptError, ScriptTerminatedError, V8OutOfMemoryError
Class Method Summary collapse
Instance Method Summary collapse
- #attach(name, proc) ⇒ Object
- #call(*args) ⇒ Object
- #dispose ⇒ Object
- #dump ⇒ Object
- #eval(*args) ⇒ Object
- #heap_snapshot ⇒ Object
- #heap_stats ⇒ Object
- #initialize(*args) ⇒ Object constructor
-
#low_memory_notification ⇒ Object
takes ownership of |b|.
- #perform_microtask_checkpoint ⇒ Object
-
#pump_message_loop ⇒ Object
takes ownership of |b|.
- #size ⇒ Object
- #stop ⇒ Object
- #warmup!(arg) ⇒ Object
Constructor Details
#initialize(*args) ⇒ Object
1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 |
# File 'ext/mini_racer_extension/mini_racer_extension.c', line 1922
static VALUE context_initialize(int argc, VALUE *argv, VALUE self)
{
VALUE kwargs, a, k, v;
pthread_attr_t attr;
const char *cause;
pthread_t thr;
Snapshot *ss;
Context *c;
char *s;
int r;
TypedData_Get_Struct(self, Context, &context_type, c);
rb_scan_args(argc, argv, ":", &kwargs);
if (NIL_P(kwargs))
goto init;
a = rb_ary_new();
rb_hash_foreach(kwargs, collect, a);
while (RARRAY_LENINT(a)) {
v = rb_ary_pop(a);
k = rb_ary_pop(a);
k = rb_sym2str(k);
s = RSTRING_PTR(k);
if (!strcmp(s, "ensure_gc_after_idle")) {
Check_Type(v, T_FIXNUM);
c->idle_gc = FIX2LONG(v);
if (c->idle_gc < 0 || c->idle_gc > INT32_MAX)
rb_raise(rb_eArgError, "bad ensure_gc_after_idle");
} else if (!strcmp(s, "max_memory")) {
Check_Type(v, T_FIXNUM);
c->max_memory = FIX2LONG(v);
if (c->max_memory < 0 || c->max_memory >= UINT32_MAX)
rb_raise(rb_eArgError, "bad max_memory");
} else if (!strcmp(s, "marshal_stack_depth")) { // backcompat, ignored
Check_Type(v, T_FIXNUM);
} else if (!strcmp(s, "timeout")) {
Check_Type(v, T_FIXNUM);
c->timeout = FIX2LONG(v);
if (c->timeout < 0 || c->timeout > INT32_MAX)
rb_raise(rb_eArgError, "bad timeout");
} else if (!strcmp(s, "snapshot")) {
if (NIL_P(v))
continue;
TypedData_Get_Struct(v, Snapshot, &snapshot_type, ss);
if (buf_put(&c->snapshot, RSTRING_PTR(ss->blob), RSTRING_LENINT(ss->blob)))
rb_raise(runtime_error, "out of memory");
} else if (!strcmp(s, "verbose_exceptions")) {
c->verbose_exceptions = !(v == Qfalse || v == Qnil);
} else {
rb_raise(runtime_error, "bad keyword: %s", s);
}
}
init:
if (single_threaded) {
v8_once_init();
c->pst = v8_thread_init(c, c->snapshot.buf, c->snapshot.len, c->max_memory, c->verbose_exceptions);
} else {
cause = "pthread_attr_init";
if ((r = pthread_attr_init(&attr)))
goto fail;
pthread_attr_setstacksize(&attr, 2<<20); // 2 MiB
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
// v8 thread takes ownership of |c|
cause = "pthread_create";
r = pthread_create(&thr, &attr, v8_thread_start, c);
pthread_attr_destroy(&attr);
if (r)
goto fail;
barrier_wait(&c->early_init);
barrier_wait(&c->late_init);
}
return Qnil;
fail:
rb_raise(runtime_error, "Context.initialize: %s: %s", cause, strerror(r));
return Qnil; // pacify compiler
}
|
Class Method Details
.load(blob) ⇒ Object
2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 |
# File 'ext/mini_racer_extension/mini_racer_extension.c', line 2096
static VALUE snapshot_load(VALUE klass, VALUE blob)
{
Snapshot *ss;
VALUE self;
Check_Type(blob, T_STRING);
self = snapshot_alloc(klass);
TypedData_Get_Struct(self, Snapshot, &snapshot_type, ss);
ss->blob = rb_str_dup(blob);
rb_enc_associate(ss->blob, rb_ascii8bit_encoding());
ENC_CODERANGE_SET(ss->blob, ENC_CODERANGE_VALID);
return self;
}
|
Instance Method Details
#attach(name, proc) ⇒ Object
1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 |
# File 'ext/mini_racer_extension/mini_racer_extension.c', line 1563
static VALUE context_attach(VALUE self, VALUE name, VALUE proc)
{
Context *c;
VALUE e;
Ser s;
long id;
TypedData_Get_Struct(self, Context, &context_type, c);
id = RARRAY_LEN(c->procs);
if (id > INT32_MAX)
rb_raise(runtime_error, "too many callbacks");
// request is (A)ttach, [name, id] array
ser_init1(&s, 'A');
ser_array_begin(&s, 2);
add_string(&s, name);
ser_int(&s, id);
ser_array_end(&s, 2);
rb_ary_push(c->procs, proc);
// response is an exception or undefined
e = rendezvous(c, &s.b);
handle_exception(e);
return Qnil;
}
|
#call(*args) ⇒ Object
1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 |
# File 'ext/mini_racer_extension/mini_racer_extension.c', line 1658
static VALUE context_call(int argc, VALUE *argv, VALUE self)
{
VALUE name, args;
VALUE a, e;
Context *c;
Ser s;
TypedData_Get_Struct(self, Context, &context_type, c);
rb_scan_args(argc, argv, "1*", &name, &args);
Check_Type(name, T_STRING);
rb_ary_unshift(args, name);
// request is (C)all, [name, args...] array
ser_init1(&s, 'C');
if (serialize(&s, args)) {
ser_reset(&s);
rb_raise(runtime_error, "Context.call: %s", s.err);
}
// response is [result, err] array
a = rendezvous(c, &s.b); // takes ownership of |s.b|
e = rb_ary_pop(a);
handle_exception(e);
return rb_ary_pop(a);
}
|
#dispose ⇒ Object
1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 |
# File 'ext/mini_racer_extension/mini_racer_extension.c', line 1633
static VALUE context_dispose(VALUE self)
{
Context *c;
void *r;
TypedData_Get_Struct(self, Context, &context_type, c);
r = rb_thread_call_without_gvl(context_dispose_do, c, terminate_ubf, c);
if (r)
rb_raise(runtime_error, "context dispose: %s", strerror((int)(intptr_t)r));
return Qnil;
}
|
#dump ⇒ Object
2088 2089 2090 2091 2092 2093 2094 |
# File 'ext/mini_racer_extension/mini_racer_extension.c', line 2088
static VALUE snapshot_dump(VALUE self)
{
Snapshot *ss;
TypedData_Get_Struct(self, Snapshot, &snapshot_type, ss);
return ss->blob;
}
|
#eval(*args) ⇒ Object
1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 |
# File 'ext/mini_racer_extension/mini_racer_extension.c', line 1682
static VALUE context_eval(int argc, VALUE *argv, VALUE self)
{
VALUE a, e, source, filename, kwargs;
Context *c;
Ser s;
TypedData_Get_Struct(self, Context, &context_type, c);
filename = Qnil;
rb_scan_args(argc, argv, "1:", &source, &kwargs);
Check_Type(source, T_STRING);
if (!NIL_P(kwargs))
filename = rb_hash_aref(kwargs, rb_id2sym(rb_intern("filename")));
if (NIL_P(filename))
filename = rb_str_new_cstr("<eval>");
Check_Type(filename, T_STRING);
// request is (E)val, [filename, source] array
ser_init1(&s, 'E');
ser_array_begin(&s, 2);
add_string(&s, filename);
add_string(&s, source);
ser_array_end(&s, 2);
// response is [result, errname] array
a = rendezvous(c, &s.b); // takes ownership of |s.b|
e = rb_ary_pop(a);
handle_exception(e);
return rb_ary_pop(a);
}
|
#heap_snapshot ⇒ Object
1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 |
# File 'ext/mini_racer_extension/mini_racer_extension.c', line 1746
static VALUE context_heap_snapshot(VALUE self)
{
Buf req, res;
Context *c;
TypedData_Get_Struct(self, Context, &context_type, c);
buf_init(&req);
buf_putc(&req, 'H'); // (H)eap snapshot, returns plain bytes
rendezvous_no_des(c, &req, &res); // takes ownership of |req|
return rb_ensure(heap_snapshot_to_str, (VALUE)&res,
buf_reset_ensure, (VALUE)&res);
}
|
#heap_stats ⇒ Object
1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 |
# File 'ext/mini_racer_extension/mini_racer_extension.c', line 1710
static VALUE context_heap_stats(VALUE self)
{
VALUE a, h, k, v;
Context *c;
int i, n;
Buf b;
TypedData_Get_Struct(self, Context, &context_type, c);
buf_init(&b);
buf_putc(&b, 'S'); // (S)tats, returns object
h = rendezvous(c, &b); // takes ownership of |b|
a = rb_ary_new();
rb_hash_foreach(h, collect, a);
for (i = 0, n = RARRAY_LENINT(a); i < n; i += 2) {
k = rb_ary_entry(a, i+0);
v = rb_ary_entry(a, i+1);
rb_hash_delete(h, k);
rb_hash_aset(h, rb_str_intern(k), v); // turn "key" into :key
}
return h;
}
|
#low_memory_notification ⇒ Object
takes ownership of |b|
1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 |
# File 'ext/mini_racer_extension/mini_racer_extension.c', line 1781
static VALUE context_low_memory_notification(VALUE self)
{
Buf req, res;
Context *c;
TypedData_Get_Struct(self, Context, &context_type, c);
buf_init(&req);
buf_putc(&req, 'L'); // (L)ow memory notification, returns nothing
rendezvous_no_des(c, &req, &res); // takes ownership of |req|
buf_reset(&res);
return Qnil;
}
|
#perform_microtask_checkpoint ⇒ Object
1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 |
# File 'ext/mini_racer_extension/mini_racer_extension.c', line 1759
static VALUE context_perform_microtask_checkpoint(VALUE self)
{
Context *c;
Buf b;
TypedData_Get_Struct(self, Context, &context_type, c);
buf_init(&b);
buf_putc(&b, 'M'); // (M)icrotask checkpoint, returns nil
return rendezvous(c, &b); // takes ownership of |b|
}
|
#pump_message_loop ⇒ Object
takes ownership of |b|
1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 |
# File 'ext/mini_racer_extension/mini_racer_extension.c', line 1770
static VALUE context_pump_message_loop(VALUE self)
{
Context *c;
Buf b;
TypedData_Get_Struct(self, Context, &context_type, c);
buf_init(&b);
buf_putc(&b, 'P'); // (P)ump, returns bool
return rendezvous(c, &b); // takes ownership of |b|
}
|
#size ⇒ Object
2110 2111 2112 2113 2114 2115 2116 |
# File 'ext/mini_racer_extension/mini_racer_extension.c', line 2110
static VALUE snapshot_size0(VALUE self)
{
Snapshot *ss;
TypedData_Get_Struct(self, Snapshot, &snapshot_type, ss);
return LONG2FIX(RSTRING_LENINT(ss->blob));
}
|
#stop ⇒ Object
1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 |
# File 'ext/mini_racer_extension/mini_racer_extension.c', line 1645
static VALUE context_stop(VALUE self)
{
Context *c;
// does not grab |mtx| because Context.stop can be called from another
// thread and then we deadlock if e.g. the V8 thread busy-loops in JS
TypedData_Get_Struct(self, Context, &context_type, c);
if (atomic_load(&c->quit))
rb_raise(context_disposed_error, "disposed context");
v8_terminate_execution(c->pst);
return Qnil;
}
|
#warmup!(arg) ⇒ Object
2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 |
# File 'ext/mini_racer_extension/mini_racer_extension.c', line 2058
static VALUE snapshot_warmup(VALUE self, VALUE arg)
{
VALUE a, e, cv;
Snapshot *ss;
Context *c;
DesCtx d;
Ser s;
TypedData_Get_Struct(self, Snapshot, &snapshot_type, ss);
Check_Type(arg, T_STRING);
cv = context_alloc(context_class);
context_initialize(0, NULL, cv);
TypedData_Get_Struct(cv, Context, &context_type, c);
// request is (W)armup, [snapshot, "warmup code"]
ser_init1(&s, 'W');
ser_array_begin(&s, 2);
ser_string8(&s, (const uint8_t *)RSTRING_PTR(ss->blob), RSTRING_LENINT(ss->blob));
add_string(&s, arg);
ser_array_end(&s, 2);
// response is [arraybuffer, error]
DesCtx_init(&d);
d.transcode_latin1 = 0; // don't mangle snapshot binary data
a = rendezvous1(c, &s.b, &d);
e = rb_ary_pop(a);
context_dispose(cv);
raise_exception_with_message(snapshot_error, e);
ss->blob = rb_ary_pop(a);
return self;
}
|