quickjs 0.17.0 → 0.19.0.pre1
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 +122 -4
- data/ext/quickjsrb/extconf.rb +0 -5
- data/ext/quickjsrb/quickjsrb.c +389 -33
- data/ext/quickjsrb/quickjsrb.h +39 -9
- data/lib/quickjs/polyfills/intl-en.min.js +4 -0
- data/lib/quickjs/polyfills/intl.rb +11 -0
- data/lib/quickjs/polyfills.rb +67 -0
- data/lib/quickjs/version.rb +1 -1
- data/lib/quickjs.rb +23 -5
- data/polyfills/package-lock.json +110 -110
- data/polyfills/package.json +1 -1
- data/polyfills/rolldown.config.mjs +4 -1
- data/sig/quickjs.rbs +16 -2
- metadata +4 -2
- data/ext/quickjsrb/vendor/polyfill-intl-en.min.js +0 -4
data/ext/quickjsrb/quickjsrb.h
CHANGED
|
@@ -14,8 +14,6 @@
|
|
|
14
14
|
#include <string.h>
|
|
15
15
|
#include <time.h>
|
|
16
16
|
|
|
17
|
-
extern const uint32_t qjsc_polyfill_intl_en_min_size;
|
|
18
|
-
extern const uint8_t qjsc_polyfill_intl_en_min;
|
|
19
17
|
extern const uint32_t qjsc_polyfill_file_min_size;
|
|
20
18
|
extern const uint8_t qjsc_polyfill_file_min;
|
|
21
19
|
extern const uint32_t qjsc_polyfill_encoding_min_size;
|
|
@@ -57,6 +55,16 @@ typedef struct VMData
|
|
|
57
55
|
VALUE log_listener;
|
|
58
56
|
VALUE alive_objects;
|
|
59
57
|
VALUE module_loader;
|
|
58
|
+
VALUE on_unhandled_rejection;
|
|
59
|
+
// Memoize (specifier, importer) → canonical so the user's loader Proc
|
|
60
|
+
// runs at most once per distinct pair across the VM's lifetime. Without
|
|
61
|
+
// this, QuickJS calls normalize on every import statement — including
|
|
62
|
+
// duplicates within the same file — and we'd re-invoke the user proc.
|
|
63
|
+
VALUE module_resolution_cache;
|
|
64
|
+
// Carries `code` from the normalize-phase Proc call to the load-phase
|
|
65
|
+
// JS_Eval that follows. Keyed by canonical; populated when the user's
|
|
66
|
+
// loader returns either a raw source String or `{ code:, as: }`.
|
|
67
|
+
VALUE module_source_cache;
|
|
60
68
|
JSValue j_file_proxy_creator;
|
|
61
69
|
// Once the runtime has hit JS-level "out of memory", the QuickJS heap is in
|
|
62
70
|
// a fragile state where further evaluation can trigger a use-after-free in
|
|
@@ -64,21 +72,33 @@ typedef struct VMData
|
|
|
64
72
|
// Trip this flag so subsequent eval_code/call calls refuse cleanly with a
|
|
65
73
|
// Ruby exception instead of risking a process crash.
|
|
66
74
|
bool oom_poisoned;
|
|
75
|
+
// Set by VM#dispose! to release the multi-MB JS heap before Ruby GC sees
|
|
76
|
+
// enough pressure to collect the wrapper. Doubles as a double-free guard
|
|
77
|
+
// for the dfree handler.
|
|
78
|
+
bool disposed;
|
|
67
79
|
} VMData;
|
|
68
80
|
|
|
81
|
+
static void vm_teardown_context(JSContext *ctx)
|
|
82
|
+
{
|
|
83
|
+
JSRuntime *runtime = JS_GetRuntime(ctx);
|
|
84
|
+
JS_SetInterruptHandler(runtime, NULL, NULL);
|
|
85
|
+
js_std_free_handlers(runtime);
|
|
86
|
+
JS_FreeContext(ctx);
|
|
87
|
+
JS_FreeRuntime(runtime);
|
|
88
|
+
}
|
|
89
|
+
|
|
69
90
|
static void vm_free(void *ptr)
|
|
70
91
|
{
|
|
71
92
|
VMData *data = (VMData *)ptr;
|
|
72
93
|
free(data->eval_time);
|
|
73
94
|
|
|
74
|
-
if (!
|
|
75
|
-
|
|
95
|
+
if (!data->disposed)
|
|
96
|
+
{
|
|
97
|
+
if (!JS_IsUndefined(data->j_file_proxy_creator))
|
|
98
|
+
JS_FreeValue(data->context, data->j_file_proxy_creator);
|
|
76
99
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
js_std_free_handlers(runtime);
|
|
80
|
-
JS_FreeContext(data->context);
|
|
81
|
-
JS_FreeRuntime(runtime);
|
|
100
|
+
vm_teardown_context(data->context);
|
|
101
|
+
}
|
|
82
102
|
|
|
83
103
|
xfree(ptr);
|
|
84
104
|
}
|
|
@@ -95,6 +115,9 @@ static void vm_mark(void *ptr)
|
|
|
95
115
|
rb_gc_mark_movable(data->log_listener);
|
|
96
116
|
rb_gc_mark_movable(data->alive_objects);
|
|
97
117
|
rb_gc_mark_movable(data->module_loader);
|
|
118
|
+
rb_gc_mark_movable(data->on_unhandled_rejection);
|
|
119
|
+
rb_gc_mark_movable(data->module_resolution_cache);
|
|
120
|
+
rb_gc_mark_movable(data->module_source_cache);
|
|
98
121
|
}
|
|
99
122
|
|
|
100
123
|
static void vm_compact(void *ptr)
|
|
@@ -104,6 +127,9 @@ static void vm_compact(void *ptr)
|
|
|
104
127
|
data->log_listener = rb_gc_location(data->log_listener);
|
|
105
128
|
data->alive_objects = rb_gc_location(data->alive_objects);
|
|
106
129
|
data->module_loader = rb_gc_location(data->module_loader);
|
|
130
|
+
data->on_unhandled_rejection = rb_gc_location(data->on_unhandled_rejection);
|
|
131
|
+
data->module_resolution_cache = rb_gc_location(data->module_resolution_cache);
|
|
132
|
+
data->module_source_cache = rb_gc_location(data->module_source_cache);
|
|
107
133
|
}
|
|
108
134
|
|
|
109
135
|
static const rb_data_type_t vm_type = {
|
|
@@ -137,8 +163,12 @@ static VALUE vm_alloc(VALUE r_self)
|
|
|
137
163
|
data->log_listener = Qnil;
|
|
138
164
|
data->alive_objects = rb_hash_new();
|
|
139
165
|
data->module_loader = Qnil;
|
|
166
|
+
data->on_unhandled_rejection = Qnil;
|
|
167
|
+
data->module_resolution_cache = rb_hash_new();
|
|
168
|
+
data->module_source_cache = rb_hash_new();
|
|
140
169
|
data->j_file_proxy_creator = JS_UNDEFINED;
|
|
141
170
|
data->oom_poisoned = false;
|
|
171
|
+
data->disposed = false;
|
|
142
172
|
|
|
143
173
|
EvalTime *eval_time = malloc(sizeof(EvalTime));
|
|
144
174
|
data->eval_time = eval_time;
|