quickjs 0.1.9 → 0.1.10
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 +0 -6
- data/ext/quickjsrb/quickjsrb.c +158 -128
- data/lib/quickjs/version.rb +1 -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: 8eba12c1c34fab81270517de72da6a8b3c9b561d521a42b80c14411c23555684
|
4
|
+
data.tar.gz: 4bced848c986a41c787306e799b40622d97dff999994b64e615cd3b1c79e586e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3598ef1f8b5bcbeedf916c101387477b8318e6550a1aa52b6fa4ddb269e261447768428eb4b644e2a0a9cc64ae084830c511cb077b7e25e292eb5d8e84a96460
|
7
|
+
data.tar.gz: 686a93a0a00d747c99d8a0a0f0072a2d0451cc6bfdeeeb512f02817288636d7192a2e2dda52d0e9bf05b92ebb1930f503ca7ce2251c8419ca568c66f825bca1f
|
data/README.md
CHANGED
data/ext/quickjsrb/quickjsrb.c
CHANGED
@@ -1,27 +1,35 @@
|
|
1
1
|
#include "quickjsrb.h"
|
2
2
|
|
3
|
-
typedef struct EvalTime
|
3
|
+
typedef struct EvalTime
|
4
|
+
{
|
4
5
|
clock_t limit;
|
5
6
|
clock_t started_at;
|
6
7
|
} EvalTime;
|
7
8
|
|
8
|
-
typedef struct VMData
|
9
|
-
|
9
|
+
typedef struct VMData
|
10
|
+
{
|
10
11
|
struct JSContext *context;
|
11
12
|
VALUE defined_functions;
|
12
13
|
struct EvalTime *eval_time;
|
13
14
|
} VMData;
|
14
15
|
|
15
|
-
static void vm_free(void*
|
16
|
+
static void vm_free(void *ptr)
|
16
17
|
{
|
17
18
|
VMData *data = (VMData *)ptr;
|
18
19
|
free(data->eval_time);
|
20
|
+
|
21
|
+
JSRuntime *runtime = JS_GetRuntime(data->context);
|
22
|
+
JS_SetInterruptHandler(runtime, NULL, NULL);
|
23
|
+
js_std_free_handlers(runtime);
|
24
|
+
JS_FreeContext(data->context);
|
25
|
+
JS_FreeRuntime(runtime);
|
26
|
+
|
19
27
|
xfree(ptr);
|
20
28
|
}
|
21
29
|
|
22
|
-
size_t vm_size(const void*
|
30
|
+
size_t vm_size(const void *data)
|
23
31
|
{
|
24
|
-
return sizeof(
|
32
|
+
return sizeof(VMData);
|
25
33
|
}
|
26
34
|
|
27
35
|
static void vm_mark(void *ptr)
|
@@ -31,14 +39,13 @@ static void vm_mark(void *ptr)
|
|
31
39
|
}
|
32
40
|
|
33
41
|
static const rb_data_type_t vm_type = {
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
42
|
+
.wrap_struct_name = "quickjsvm",
|
43
|
+
.function = {
|
44
|
+
.dmark = vm_mark,
|
45
|
+
.dfree = vm_free,
|
46
|
+
.dsize = vm_size,
|
47
|
+
},
|
48
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
42
49
|
};
|
43
50
|
|
44
51
|
static VALUE vm_alloc(VALUE self)
|
@@ -50,6 +57,9 @@ static VALUE vm_alloc(VALUE self)
|
|
50
57
|
EvalTime *eval_time = malloc(sizeof(EvalTime));
|
51
58
|
data->eval_time = eval_time;
|
52
59
|
|
60
|
+
JSRuntime *runtime = JS_NewRuntime();
|
61
|
+
data->context = JS_NewContext(runtime);
|
62
|
+
|
53
63
|
return obj;
|
54
64
|
}
|
55
65
|
|
@@ -60,96 +70,115 @@ const char *nanId = "NaN";
|
|
60
70
|
const char *featureStdId = "feature_std";
|
61
71
|
const char *featureOsId = "feature_os";
|
62
72
|
|
63
|
-
JSValue to_js_value(JSContext *ctx, VALUE r_value)
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
case T_STRING: {
|
82
|
-
char *str = StringValueCStr(r_value);
|
73
|
+
JSValue to_js_value(JSContext *ctx, VALUE r_value)
|
74
|
+
{
|
75
|
+
switch (TYPE(r_value))
|
76
|
+
{
|
77
|
+
case T_NIL:
|
78
|
+
return JS_NULL;
|
79
|
+
case T_FIXNUM:
|
80
|
+
case T_FLOAT:
|
81
|
+
{
|
82
|
+
VALUE r_str = rb_funcall(r_value, rb_intern("to_s"), 0, NULL);
|
83
|
+
char *str = StringValueCStr(r_str);
|
84
|
+
JSValue global = JS_GetGlobalObject(ctx);
|
85
|
+
JSValue numberClass = JS_GetPropertyStr(ctx, global, "Number");
|
86
|
+
JSValue j_str = JS_NewString(ctx, str);
|
87
|
+
JSValue stringified = JS_Call(ctx, numberClass, JS_UNDEFINED, 1, &j_str);
|
88
|
+
JS_FreeValue(ctx, global);
|
89
|
+
JS_FreeValue(ctx, numberClass);
|
90
|
+
JS_FreeValue(ctx, j_str);
|
83
91
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
92
|
+
return stringified;
|
93
|
+
}
|
94
|
+
case T_STRING:
|
95
|
+
{
|
96
|
+
char *str = StringValueCStr(r_value);
|
89
97
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
case T_HASH:
|
97
|
-
case T_ARRAY: {
|
98
|
-
VALUE r_json_str = rb_funcall(r_value, rb_intern("to_json"), 0, NULL);
|
99
|
-
char *str = StringValueCStr(r_json_str);
|
100
|
-
JSValue global = JS_GetGlobalObject(ctx);
|
101
|
-
JSValue jsonClass = JS_GetPropertyStr(ctx, global, "JSON");
|
102
|
-
JSValue parseFunc = JS_GetPropertyStr(ctx, jsonClass, "parse");
|
103
|
-
JSValue j_str = JS_NewString(ctx, str);
|
104
|
-
JSValue stringified = JS_Call(ctx, parseFunc, jsonClass, 1, &j_str);
|
105
|
-
JS_FreeValue(ctx, global);
|
106
|
-
JS_FreeValue(ctx, jsonClass);
|
107
|
-
JS_FreeValue(ctx, parseFunc);
|
108
|
-
JS_FreeValue(ctx, j_str);
|
109
|
-
|
110
|
-
return stringified;
|
111
|
-
}
|
112
|
-
default: {
|
113
|
-
VALUE r_inspect_str = rb_funcall(r_value, rb_intern("inspect"), 0, NULL);
|
114
|
-
char *str = StringValueCStr(r_inspect_str);
|
98
|
+
return JS_NewString(ctx, str);
|
99
|
+
}
|
100
|
+
case T_SYMBOL:
|
101
|
+
{
|
102
|
+
VALUE r_str = rb_funcall(r_value, rb_intern("to_s"), 0, NULL);
|
103
|
+
char *str = StringValueCStr(r_str);
|
115
104
|
|
116
|
-
|
117
|
-
|
105
|
+
return JS_NewString(ctx, str);
|
106
|
+
}
|
107
|
+
case T_TRUE:
|
108
|
+
return JS_TRUE;
|
109
|
+
case T_FALSE:
|
110
|
+
return JS_FALSE;
|
111
|
+
case T_HASH:
|
112
|
+
case T_ARRAY:
|
113
|
+
{
|
114
|
+
VALUE r_json_str = rb_funcall(r_value, rb_intern("to_json"), 0, NULL);
|
115
|
+
char *str = StringValueCStr(r_json_str);
|
116
|
+
JSValue global = JS_GetGlobalObject(ctx);
|
117
|
+
JSValue jsonClass = JS_GetPropertyStr(ctx, global, "JSON");
|
118
|
+
JSValue parseFunc = JS_GetPropertyStr(ctx, jsonClass, "parse");
|
119
|
+
JSValue j_str = JS_NewString(ctx, str);
|
120
|
+
JSValue stringified = JS_Call(ctx, parseFunc, jsonClass, 1, &j_str);
|
121
|
+
JS_FreeValue(ctx, global);
|
122
|
+
JS_FreeValue(ctx, jsonClass);
|
123
|
+
JS_FreeValue(ctx, parseFunc);
|
124
|
+
JS_FreeValue(ctx, j_str);
|
125
|
+
|
126
|
+
return stringified;
|
127
|
+
}
|
128
|
+
default:
|
129
|
+
{
|
130
|
+
VALUE r_inspect_str = rb_funcall(r_value, rb_intern("inspect"), 0, NULL);
|
131
|
+
char *str = StringValueCStr(r_inspect_str);
|
132
|
+
|
133
|
+
return JS_NewString(ctx, str);
|
134
|
+
}
|
118
135
|
}
|
119
136
|
}
|
120
137
|
|
121
|
-
VALUE to_rb_value(JSValue jsv, JSContext *ctx)
|
122
|
-
|
123
|
-
|
138
|
+
VALUE to_rb_value(JSValue jsv, JSContext *ctx)
|
139
|
+
{
|
140
|
+
switch (JS_VALUE_GET_NORM_TAG(jsv))
|
141
|
+
{
|
142
|
+
case JS_TAG_INT:
|
143
|
+
{
|
124
144
|
int int_res = 0;
|
125
145
|
JS_ToInt32(ctx, &int_res, jsv);
|
126
146
|
return INT2NUM(int_res);
|
127
147
|
}
|
128
|
-
case JS_TAG_FLOAT64:
|
129
|
-
|
148
|
+
case JS_TAG_FLOAT64:
|
149
|
+
{
|
150
|
+
if (JS_VALUE_IS_NAN(jsv))
|
151
|
+
{
|
130
152
|
return ID2SYM(rb_intern(nanId));
|
131
153
|
}
|
132
154
|
double double_res;
|
133
155
|
JS_ToFloat64(ctx, &double_res, jsv);
|
134
156
|
return DBL2NUM(double_res);
|
135
157
|
}
|
136
|
-
case JS_TAG_BOOL:
|
158
|
+
case JS_TAG_BOOL:
|
159
|
+
{
|
137
160
|
return JS_ToBool(ctx, jsv) > 0 ? Qtrue : Qfalse;
|
138
161
|
}
|
139
|
-
case JS_TAG_STRING:
|
162
|
+
case JS_TAG_STRING:
|
163
|
+
{
|
140
164
|
JSValue maybeString = JS_ToString(ctx, jsv);
|
141
165
|
const char *msg = JS_ToCString(ctx, maybeString);
|
142
166
|
JS_FreeValue(ctx, maybeString);
|
167
|
+
JS_FreeCString(ctx, msg);
|
143
168
|
return rb_str_new2(msg);
|
144
169
|
}
|
145
|
-
case JS_TAG_OBJECT:
|
170
|
+
case JS_TAG_OBJECT:
|
171
|
+
{
|
146
172
|
int promiseState = JS_PromiseState(ctx, jsv);
|
147
|
-
if (promiseState == JS_PROMISE_FULFILLED || promiseState == JS_PROMISE_PENDING)
|
173
|
+
if (promiseState == JS_PROMISE_FULFILLED || promiseState == JS_PROMISE_PENDING)
|
174
|
+
{
|
148
175
|
JSValue awaited = js_std_await(ctx, jsv);
|
149
176
|
VALUE rb_awaited = to_rb_value(awaited, ctx); // TODO: should have timeout
|
150
177
|
JS_FreeValue(ctx, awaited);
|
151
178
|
return rb_awaited;
|
152
|
-
}
|
179
|
+
}
|
180
|
+
else if (promiseState == JS_PROMISE_REJECTED)
|
181
|
+
{
|
153
182
|
JSValue promiseResult = JS_PromiseResult(ctx, jsv);
|
154
183
|
JSValue throw = JS_Throw(ctx, promiseResult);
|
155
184
|
JS_FreeValue(ctx, promiseResult);
|
@@ -165,6 +194,7 @@ VALUE to_rb_value(JSValue jsv, JSContext *ctx) {
|
|
165
194
|
|
166
195
|
const char *msg = JS_ToCString(ctx, strigified);
|
167
196
|
VALUE rbString = rb_str_new2(msg);
|
197
|
+
JS_FreeCString(ctx, msg);
|
168
198
|
|
169
199
|
JS_FreeValue(ctx, global);
|
170
200
|
JS_FreeValue(ctx, strigified);
|
@@ -177,9 +207,11 @@ VALUE to_rb_value(JSValue jsv, JSContext *ctx) {
|
|
177
207
|
return Qnil;
|
178
208
|
case JS_TAG_UNDEFINED:
|
179
209
|
return ID2SYM(rb_intern(undefinedId));
|
180
|
-
case JS_TAG_EXCEPTION:
|
210
|
+
case JS_TAG_EXCEPTION:
|
211
|
+
{
|
181
212
|
JSValue exceptionVal = JS_GetException(ctx);
|
182
|
-
if (JS_IsError(ctx, exceptionVal))
|
213
|
+
if (JS_IsError(ctx, exceptionVal))
|
214
|
+
{
|
183
215
|
JSValue jsErrorClassName = JS_GetPropertyStr(ctx, exceptionVal, "name");
|
184
216
|
const char *errorClassName = JS_ToCString(ctx, jsErrorClassName);
|
185
217
|
|
@@ -189,24 +221,33 @@ VALUE to_rb_value(JSValue jsv, JSContext *ctx) {
|
|
189
221
|
JS_FreeValue(ctx, jsErrorClassMessage);
|
190
222
|
JS_FreeValue(ctx, jsErrorClassName);
|
191
223
|
|
192
|
-
|
193
|
-
|
224
|
+
VALUE rb_errorMessage = rb_sprintf("%s: %s", errorClassName, errorClassMessage);
|
225
|
+
JS_FreeCString(ctx, errorClassName);
|
226
|
+
JS_FreeCString(ctx, errorClassMessage);
|
227
|
+
JS_FreeValue(ctx, exceptionVal);
|
228
|
+
rb_exc_raise(rb_exc_new_str(rb_eRuntimeError, rb_errorMessage));
|
229
|
+
}
|
230
|
+
else
|
231
|
+
{
|
194
232
|
const char *errorMessage = JS_ToCString(ctx, exceptionVal);
|
195
233
|
|
196
|
-
|
234
|
+
VALUE rb_errorMessage = rb_sprintf("%s", errorMessage);
|
235
|
+
JS_FreeCString(ctx, errorMessage);
|
236
|
+
JS_FreeValue(ctx, exceptionVal);
|
237
|
+
rb_exc_raise(rb_exc_new_str(rb_eRuntimeError, rb_errorMessage));
|
197
238
|
}
|
198
|
-
|
199
|
-
JS_FreeValue(ctx, exceptionVal);
|
200
239
|
return Qnil;
|
201
240
|
}
|
202
|
-
case JS_TAG_BIG_INT:
|
241
|
+
case JS_TAG_BIG_INT:
|
242
|
+
{
|
203
243
|
JSValue toStringFunc = JS_GetPropertyStr(ctx, jsv, "toString");
|
204
244
|
JSValue strigified = JS_Call(ctx, toStringFunc, jsv, 0, NULL);
|
205
245
|
|
206
246
|
const char *msg = JS_ToCString(ctx, strigified);
|
207
247
|
VALUE rbString = rb_str_new2(msg);
|
208
|
-
JS_FreeValue(ctx, strigified);
|
209
248
|
JS_FreeValue(ctx, toStringFunc);
|
249
|
+
JS_FreeValue(ctx, strigified);
|
250
|
+
JS_FreeCString(ctx, msg);
|
210
251
|
|
211
252
|
return rb_funcall(rbString, rb_intern("to_i"), 0, NULL);
|
212
253
|
}
|
@@ -218,45 +259,51 @@ VALUE to_rb_value(JSValue jsv, JSContext *ctx) {
|
|
218
259
|
}
|
219
260
|
}
|
220
261
|
|
221
|
-
static JSValue js_quickjsrb_call_global(JSContext *ctx, JSValueConst _this, int _argc, JSValueConst *argv)
|
262
|
+
static JSValue js_quickjsrb_call_global(JSContext *ctx, JSValueConst _this, int _argc, JSValueConst *argv)
|
263
|
+
{
|
222
264
|
VMData *data = JS_GetContextOpaque(ctx);
|
223
265
|
JSValue maybeFuncName = JS_ToString(ctx, argv[0]);
|
224
266
|
const char *funcName = JS_ToCString(ctx, maybeFuncName);
|
225
267
|
JS_FreeValue(ctx, maybeFuncName);
|
226
268
|
|
227
269
|
VALUE proc = rb_hash_aref(data->defined_functions, rb_str_new2(funcName));
|
228
|
-
if (proc == Qnil)
|
270
|
+
if (proc == Qnil)
|
271
|
+
{ // Shouldn't happen
|
229
272
|
return JS_ThrowReferenceError(ctx, "Proc `%s` is not defined", funcName);
|
230
273
|
}
|
274
|
+
JS_FreeCString(ctx, funcName);
|
231
275
|
|
232
276
|
// TODO: cover timeout for calling proc
|
233
277
|
VALUE r_result = rb_apply(proc, rb_intern("call"), to_rb_value(argv[1], ctx));
|
234
278
|
return to_js_value(ctx, r_result);
|
235
279
|
}
|
236
280
|
|
237
|
-
static VALUE vm_m_initialize(int argc, VALUE*
|
281
|
+
static VALUE vm_m_initialize(int argc, VALUE *argv, VALUE self)
|
238
282
|
{
|
239
283
|
VALUE r_opts;
|
240
284
|
rb_scan_args(argc, argv, ":", &r_opts);
|
241
|
-
if (NIL_P(r_opts))
|
285
|
+
if (NIL_P(r_opts))
|
286
|
+
r_opts = rb_hash_new();
|
242
287
|
|
243
288
|
VALUE r_memoryLimit = rb_hash_aref(r_opts, ID2SYM(rb_intern("memory_limit")));
|
244
|
-
if (NIL_P(r_memoryLimit))
|
289
|
+
if (NIL_P(r_memoryLimit))
|
290
|
+
r_memoryLimit = UINT2NUM(1024 * 1024 * 128);
|
245
291
|
VALUE r_maxStackSize = rb_hash_aref(r_opts, ID2SYM(rb_intern("max_stack_size")));
|
246
|
-
if (NIL_P(r_maxStackSize))
|
292
|
+
if (NIL_P(r_maxStackSize))
|
293
|
+
r_maxStackSize = UINT2NUM(1024 * 1024 * 4);
|
247
294
|
VALUE r_features = rb_hash_aref(r_opts, ID2SYM(rb_intern("features")));
|
248
|
-
if (NIL_P(r_features))
|
295
|
+
if (NIL_P(r_features))
|
296
|
+
r_features = rb_ary_new();
|
249
297
|
VALUE r_timeout_msec = rb_hash_aref(r_opts, ID2SYM(rb_intern("timeout_msec")));
|
250
|
-
if (NIL_P(r_timeout_msec))
|
298
|
+
if (NIL_P(r_timeout_msec))
|
299
|
+
r_timeout_msec = UINT2NUM(100);
|
251
300
|
|
252
301
|
VMData *data;
|
253
302
|
TypedData_Get_Struct(self, VMData, &vm_type, data);
|
254
303
|
|
255
|
-
JSRuntime *runtime = JS_NewRuntime();
|
256
|
-
data->context = JS_NewContext(runtime);
|
257
304
|
data->eval_time->limit = (clock_t)(CLOCKS_PER_SEC * NUM2UINT(r_timeout_msec) / 1000);
|
258
|
-
data->alive = 1;
|
259
305
|
JS_SetContextOpaque(data->context, data);
|
306
|
+
JSRuntime *runtime = JS_GetRuntime(data->context);
|
260
307
|
|
261
308
|
JS_SetMemoryLimit(runtime, NUM2UINT(r_memoryLimit));
|
262
309
|
JS_SetMaxStackSize(runtime, NUM2UINT(r_maxStackSize));
|
@@ -270,18 +317,20 @@ static VALUE vm_m_initialize(int argc, VALUE* argv, VALUE self)
|
|
270
317
|
JS_SetModuleLoaderFunc(runtime, NULL, js_module_loader, NULL);
|
271
318
|
js_std_init_handlers(runtime);
|
272
319
|
|
273
|
-
if (RTEST(rb_funcall(r_features, rb_intern("include?"), 1, ID2SYM(rb_intern(featureStdId)))))
|
320
|
+
if (RTEST(rb_funcall(r_features, rb_intern("include?"), 1, ID2SYM(rb_intern(featureStdId)))))
|
321
|
+
{
|
274
322
|
js_init_module_std(data->context, "std");
|
275
323
|
const char *enableStd = "import * as std from 'std';\n"
|
276
|
-
|
324
|
+
"globalThis.std = std;\n";
|
277
325
|
JSValue stdEval = JS_Eval(data->context, enableStd, strlen(enableStd), "<vm>", JS_EVAL_TYPE_MODULE);
|
278
326
|
JS_FreeValue(data->context, stdEval);
|
279
327
|
}
|
280
328
|
|
281
|
-
if (RTEST(rb_funcall(r_features, rb_intern("include?"), 1, ID2SYM(rb_intern(featureOsId)))))
|
329
|
+
if (RTEST(rb_funcall(r_features, rb_intern("include?"), 1, ID2SYM(rb_intern(featureOsId)))))
|
330
|
+
{
|
282
331
|
js_init_module_os(data->context, "os");
|
283
332
|
const char *enableOs = "import * as os from 'os';\n"
|
284
|
-
|
333
|
+
"globalThis.os = os;\n";
|
285
334
|
JSValue osEval = JS_Eval(data->context, enableOs, strlen(enableOs), "<vm>", JS_EVAL_TYPE_MODULE);
|
286
335
|
JS_FreeValue(data->context, osEval);
|
287
336
|
}
|
@@ -298,9 +347,10 @@ static VALUE vm_m_initialize(int argc, VALUE* argv, VALUE self)
|
|
298
347
|
return self;
|
299
348
|
}
|
300
349
|
|
301
|
-
static int interrupt_handler(JSRuntime *runtime, void *opaque)
|
302
|
-
|
303
|
-
|
350
|
+
static int interrupt_handler(JSRuntime *runtime, void *opaque)
|
351
|
+
{
|
352
|
+
EvalTime *eval_time = opaque;
|
353
|
+
return clock() >= eval_time->started_at + eval_time->limit ? 1 : 0;
|
304
354
|
}
|
305
355
|
|
306
356
|
static VALUE vm_m_evalCode(VALUE self, VALUE r_code)
|
@@ -308,11 +358,6 @@ static VALUE vm_m_evalCode(VALUE self, VALUE r_code)
|
|
308
358
|
VMData *data;
|
309
359
|
TypedData_Get_Struct(self, VMData, &vm_type, data);
|
310
360
|
|
311
|
-
if (data->alive < 1) {
|
312
|
-
rb_raise(rb_eRuntimeError, "Quickjs::VM was disposed");
|
313
|
-
return Qnil;
|
314
|
-
}
|
315
|
-
|
316
361
|
data->eval_time->started_at = clock();
|
317
362
|
JS_SetInterruptHandler(JS_GetRuntime(data->context), interrupt_handler, data->eval_time);
|
318
363
|
|
@@ -331,43 +376,29 @@ static VALUE vm_m_defineGlobalFunction(VALUE self, VALUE r_name)
|
|
331
376
|
VMData *data;
|
332
377
|
TypedData_Get_Struct(self, VMData, &vm_type, data);
|
333
378
|
|
334
|
-
if (rb_block_given_p())
|
379
|
+
if (rb_block_given_p())
|
380
|
+
{
|
335
381
|
VALUE proc = rb_block_proc();
|
336
382
|
|
337
383
|
char *funcName = StringValueCStr(r_name);
|
338
384
|
|
339
385
|
rb_hash_aset(data->defined_functions, r_name, proc);
|
340
386
|
|
341
|
-
const char*
|
387
|
+
const char *template = "globalThis.__ruby['%s'] = (...args) => rubyGlobal('%s', args);\nglobalThis['%s'] = globalThis.__ruby['%s'];\n";
|
342
388
|
int length = snprintf(NULL, 0, template, funcName, funcName, funcName, funcName);
|
343
|
-
char*
|
389
|
+
char *result = (char *)malloc(length + 1);
|
344
390
|
snprintf(result, length + 1, template, funcName, funcName, funcName, funcName);
|
345
391
|
|
346
392
|
JSValue codeResult = JS_Eval(data->context, result, strlen(result), "<vm>", JS_EVAL_TYPE_MODULE);
|
347
393
|
|
348
|
-
JS_FreeValue(data->context, codeResult);
|
349
394
|
free(result);
|
395
|
+
JS_FreeValue(data->context, codeResult);
|
350
396
|
return rb_funcall(r_name, rb_intern("to_sym"), 0, NULL);
|
351
397
|
}
|
352
398
|
|
353
399
|
return Qnil;
|
354
400
|
}
|
355
401
|
|
356
|
-
static VALUE vm_m_dispose(VALUE self)
|
357
|
-
{
|
358
|
-
VMData *data;
|
359
|
-
TypedData_Get_Struct(self, VMData, &vm_type, data);
|
360
|
-
|
361
|
-
JSRuntime *runtime = JS_GetRuntime(data->context);
|
362
|
-
JS_SetInterruptHandler(runtime, NULL, NULL);
|
363
|
-
js_std_free_handlers(runtime);
|
364
|
-
JS_FreeContext(data->context);
|
365
|
-
JS_FreeRuntime(runtime);
|
366
|
-
data->alive = 0;
|
367
|
-
|
368
|
-
return Qnil;
|
369
|
-
}
|
370
|
-
|
371
402
|
RUBY_FUNC_EXPORTED void
|
372
403
|
Init_quickjsrb(void)
|
373
404
|
{
|
@@ -384,5 +415,4 @@ Init_quickjsrb(void)
|
|
384
415
|
rb_define_method(vmClass, "initialize", vm_m_initialize, -1);
|
385
416
|
rb_define_method(vmClass, "eval_code", vm_m_evalCode, 1);
|
386
417
|
rb_define_method(vmClass, "define_function", vm_m_defineGlobalFunction, 1);
|
387
|
-
rb_define_method(vmClass, "dispose!", vm_m_dispose, 0);
|
388
418
|
}
|
data/lib/quickjs/version.rb
CHANGED
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.1.
|
4
|
+
version: 0.1.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- hmsk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-07-
|
11
|
+
date: 2024-07-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|