quickjs 0.2.1 → 0.2.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7afae8229fda495f4a4c40c5c3ec1527bbb5491f23cd46ac1cf7d94badaa6a8b
4
- data.tar.gz: 62abbf8909cabf1e5d22b7228eda4fe3bd2193122573ad38b6491a7e60c142e2
3
+ metadata.gz: 5f57f31bd8921f897f9d1c81d1c50d24774bbfba5d31a99528b138e82d3fad58
4
+ data.tar.gz: 28216a7b1711fe08ad3e2a5b021abebaadd2b5d3808584ff259d0129abf0adf6
5
5
  SHA512:
6
- metadata.gz: 6fad5187a6672299187de72faf8ccb3cc5402858c65a12edb808ae5759c1665ec90c75cbc34194b9d81e28c4ca5b8616de9174cbac060ba74da4509a28b21d85
7
- data.tar.gz: dd8505b9ac5459fa2a2859cb1108b27861efcd59f234290ec43c4e2dc80e8ee61ea1ae34dba2f013036b495bcf6e9013f0fad0822a5249a43f7eba7cd3864251
6
+ metadata.gz: 355b53297b3c27269b71dca93e057ecfe02eac70755b5bd336b212092fb6da3c14ff3b2dd2f77214a62891b28d860e33f961329374ddef485e168dea41b50097
7
+ data.tar.gz: 7ff16986a8ef0efeff790389805fa6d36f6b03b5983e8f8131ff33f8369514344cc9f9b9f103f036ad305441e06dfdfdacd125bdb8b061967337235d4913c525
data/README.md CHANGED
@@ -114,10 +114,21 @@ vm = Quickjs::VM.new(timeout_msec: 1_000)
114
114
 
115
115
  ```rb
116
116
  vm = Quickjs::VM.new
117
+
118
+ # Equivalent to `import { default: aliasedDefault, member: member } from './exports.esm.js';`
117
119
  vm.import({ default: 'aliasedDefault', member: 'member' }, from: File.read('exports.esm.js'))
118
120
 
119
121
  vm.eval_code("aliasedDefault()") #=> Exported `default` of the ESM is called
120
122
  vm.eval_code("member()") #=> Exported `member` of the ESM is called
123
+
124
+ # import { member, defaultMember } from './exports.esm.js';
125
+ vm.import(['member', 'defaultMember'], from: File.read('exports.esm.js'))
126
+
127
+ # import DefaultExport from './exports.esm.js';
128
+ vm.import('DefaultExport', from: File.read('exports.esm.js'))
129
+
130
+ # import * as all from './exports.esm.js';
131
+ vm.import('* as all', from: File.read('exports.esm.js'))
121
132
  ```
122
133
 
123
134
  #### `Quickjs::VM#define_function`: 💎 Define a global function for JS by Ruby
@@ -131,6 +142,20 @@ end
131
142
  vm.eval_code("greetingTo('Rick')") #=> 'Hello! Rick'
132
143
  ```
133
144
 
145
+ #### `Quickjs::VM#logs`: 💾 Capture console logs
146
+
147
+ All logs by `console.(log|info|debug|warn|error)` on VM are recorded and inspectable.
148
+
149
+ ```rb
150
+ vm = Quickjs::VM.new
151
+ vm.eval_code('console.log("log me", null)')
152
+
153
+ vm.logs #=> Array of Quickjs::VM::Log
154
+ vm.logs.last.severity #=> :info
155
+ vm.logs.last.to_s #=> 'log me null'
156
+ vm,logs.last.raw #=> ['log me', nil]
157
+ ```
158
+
134
159
  ## License
135
160
 
136
161
  Every file in `ext/quickjsrb/quickjs` is licensed under [the MIT License Copyright 2017-2021 by Fabrice Bellard and Charlie Goron](/ext/quickjsrb/quickjs/LICENSE).
@@ -34,7 +34,7 @@
34
34
  #include <time.h>
35
35
  #if defined(__APPLE__)
36
36
  #include <malloc/malloc.h>
37
- #elif defined(__linux__)
37
+ #elif defined(__linux__) || defined(__GLIBC__)
38
38
  #include <malloc.h>
39
39
  #elif defined(__FreeBSD__)
40
40
  #include <malloc_np.h>
@@ -151,7 +151,7 @@ static size_t js_trace_malloc_usable_size(const void *ptr)
151
151
  return _msize((void *)ptr);
152
152
  #elif defined(EMSCRIPTEN)
153
153
  return 0;
154
- #elif defined(__linux__)
154
+ #elif defined(__linux__) || defined(__GLIBC__)
155
155
  return malloc_usable_size((void *)ptr);
156
156
  #else
157
157
  /* change this to `return 0;` if compilation fails */
@@ -78,6 +78,10 @@ typedef sig_t sighandler_t;
78
78
  #include "list.h"
79
79
  #include "quickjs-libc.h"
80
80
 
81
+ #if !defined(PATH_MAX)
82
+ #define PATH_MAX 4096
83
+ #endif
84
+
81
85
  /* TODO:
82
86
  - add socket calls
83
87
  */
@@ -1090,7 +1094,7 @@ static JSValue js_std_file_tell(JSContext *ctx, JSValueConst this_val,
1090
1094
  int64_t pos;
1091
1095
  if (!f)
1092
1096
  return JS_EXCEPTION;
1093
- #if defined(__linux__)
1097
+ #if defined(__linux__) || defined(__GLIBC__)
1094
1098
  pos = ftello(f);
1095
1099
  #else
1096
1100
  pos = ftell(f);
@@ -1113,7 +1117,7 @@ static JSValue js_std_file_seek(JSContext *ctx, JSValueConst this_val,
1113
1117
  return JS_EXCEPTION;
1114
1118
  if (JS_ToInt32(ctx, &whence, argv[1]))
1115
1119
  return JS_EXCEPTION;
1116
- #if defined(__linux__)
1120
+ #if defined(__linux__) || defined(__GLIBC__)
1117
1121
  ret = fseeko(f, pos, whence);
1118
1122
  #else
1119
1123
  ret = fseek(f, pos, whence);
@@ -34,7 +34,7 @@
34
34
  #include <math.h>
35
35
  #if defined(__APPLE__)
36
36
  #include <malloc/malloc.h>
37
- #elif defined(__linux__)
37
+ #elif defined(__linux__) || defined(__GLIBC__)
38
38
  #include <malloc.h>
39
39
  #elif defined(__FreeBSD__)
40
40
  #include <malloc_np.h>
@@ -1681,7 +1681,7 @@ JSRuntime *JS_NewRuntime2(const JSMallocFunctions *mf, void *opaque)
1681
1681
  rt->stack_size = JS_DEFAULT_STACK_SIZE;
1682
1682
  JS_UpdateStackTop(rt);
1683
1683
 
1684
- rt->current_exception = JS_NULL;
1684
+ rt->current_exception = JS_UNINITIALIZED;
1685
1685
 
1686
1686
  return rt;
1687
1687
  fail:
@@ -1708,7 +1708,7 @@ static size_t js_def_malloc_usable_size(const void *ptr)
1708
1708
  return _msize((void *)ptr);
1709
1709
  #elif defined(EMSCRIPTEN)
1710
1710
  return 0;
1711
- #elif defined(__linux__)
1711
+ #elif defined(__linux__) || defined(__GLIBC__)
1712
1712
  return malloc_usable_size((void *)ptr);
1713
1713
  #else
1714
1714
  /* change this to `return 0;` if compilation fails */
@@ -6398,13 +6398,13 @@ JSValue JS_GetException(JSContext *ctx)
6398
6398
  JSValue val;
6399
6399
  JSRuntime *rt = ctx->rt;
6400
6400
  val = rt->current_exception;
6401
- rt->current_exception = JS_NULL;
6401
+ rt->current_exception = JS_UNINITIALIZED;
6402
6402
  return val;
6403
6403
  }
6404
6404
 
6405
6405
  JS_BOOL JS_HasException(JSContext *ctx)
6406
6406
  {
6407
- return !JS_IsNull(ctx->rt->current_exception);
6407
+ return !JS_IsUninitialized(ctx->rt->current_exception);
6408
6408
  }
6409
6409
 
6410
6410
  static void dbuf_put_leb128(DynBuf *s, uint32_t v)
@@ -15321,7 +15321,7 @@ static int JS_IteratorClose(JSContext *ctx, JSValueConst enum_obj,
15321
15321
 
15322
15322
  if (is_exception_pending) {
15323
15323
  ex_obj = ctx->rt->current_exception;
15324
- ctx->rt->current_exception = JS_NULL;
15324
+ ctx->rt->current_exception = JS_UNINITIALIZED;
15325
15325
  res = -1;
15326
15326
  } else {
15327
15327
  ex_obj = JS_UNDEFINED;
@@ -18674,7 +18674,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
18674
18674
  JS_IteratorClose(ctx, sp[-1], TRUE);
18675
18675
  } else {
18676
18676
  *sp++ = rt->current_exception;
18677
- rt->current_exception = JS_NULL;
18677
+ rt->current_exception = JS_UNINITIALIZED;
18678
18678
  pc = b->byte_code_buf + pos;
18679
18679
  goto restart;
18680
18680
  }
@@ -46151,8 +46151,10 @@ static JSValue js_proxy_get(JSContext *ctx, JSValueConst obj, JSAtom atom,
46151
46151
  if (JS_IsException(ret))
46152
46152
  return JS_EXCEPTION;
46153
46153
  res = JS_GetOwnPropertyInternal(ctx, &desc, JS_VALUE_GET_OBJ(s->target), atom);
46154
- if (res < 0)
46154
+ if (res < 0) {
46155
+ JS_FreeValue(ctx, ret);
46155
46156
  return JS_EXCEPTION;
46157
+ }
46156
46158
  if (res) {
46157
46159
  if ((desc.flags & (JS_PROP_GETSET | JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE)) == 0) {
46158
46160
  if (!js_same_value(ctx, desc.value, ret)) {
@@ -1,79 +1,5 @@
1
1
  #include "quickjsrb.h"
2
2
 
3
- typedef struct EvalTime
4
- {
5
- clock_t limit;
6
- clock_t started_at;
7
- } EvalTime;
8
-
9
- typedef struct VMData
10
- {
11
- struct JSContext *context;
12
- VALUE defined_functions;
13
- struct EvalTime *eval_time;
14
- VALUE logs;
15
- } VMData;
16
-
17
- static void vm_free(void *ptr)
18
- {
19
- VMData *data = (VMData *)ptr;
20
- free(data->eval_time);
21
-
22
- JSRuntime *runtime = JS_GetRuntime(data->context);
23
- JS_SetInterruptHandler(runtime, NULL, NULL);
24
- js_std_free_handlers(runtime);
25
- JS_FreeContext(data->context);
26
- JS_FreeRuntime(runtime);
27
-
28
- xfree(ptr);
29
- }
30
-
31
- size_t vm_size(const void *data)
32
- {
33
- return sizeof(VMData);
34
- }
35
-
36
- static void vm_mark(void *ptr)
37
- {
38
- VMData *data = (VMData *)ptr;
39
- rb_gc_mark_movable(data->defined_functions);
40
- rb_gc_mark_movable(data->logs);
41
- }
42
-
43
- static const rb_data_type_t vm_type = {
44
- .wrap_struct_name = "quickjsvm",
45
- .function = {
46
- .dmark = vm_mark,
47
- .dfree = vm_free,
48
- .dsize = vm_size,
49
- },
50
- .flags = RUBY_TYPED_FREE_IMMEDIATELY,
51
- };
52
-
53
- static VALUE vm_alloc(VALUE r_self)
54
- {
55
- VMData *data;
56
- VALUE obj = TypedData_Make_Struct(r_self, VMData, &vm_type, data);
57
- data->defined_functions = rb_hash_new();
58
- data->logs = rb_ary_new();
59
-
60
- EvalTime *eval_time = malloc(sizeof(EvalTime));
61
- data->eval_time = eval_time;
62
-
63
- JSRuntime *runtime = JS_NewRuntime();
64
- data->context = JS_NewContext(runtime);
65
-
66
- return obj;
67
- }
68
-
69
- VALUE rb_cQuickjsVMLog, rb_cQuickjsSyntaxError, rb_cQuickjsRuntimeError, rb_cQuickjsInterruptedError, rb_cQuickjsNoAwaitError, rb_cQuickjsTypeError, rb_cQuickjsReferenceError, rb_cQuickjsRangeError, rb_cQuickjsEvalError, rb_cQuickjsURIError, rb_cQuickjsAggregateError;
70
- const char *undefinedId = "undefined";
71
- const char *nanId = "NaN";
72
-
73
- const char *featureStdId = "feature_std";
74
- const char *featureOsId = "feature_os";
75
- const char *featureOsTimeoutId = "feature_os_timeout";
76
-
77
3
  JSValue to_js_value(JSContext *ctx, VALUE r_value)
78
4
  {
79
5
  if (RTEST(rb_funcall(
@@ -168,7 +94,7 @@ VALUE to_rb_value(JSContext *ctx, JSValue j_val)
168
94
  {
169
95
  if (JS_VALUE_IS_NAN(j_val))
170
96
  {
171
- return ID2SYM(rb_intern(nanId));
97
+ return QUICKJSRB_SYM(nanId);
172
98
  }
173
99
  double double_res;
174
100
  JS_ToFloat64(ctx, &double_res, j_val);
@@ -191,7 +117,7 @@ VALUE to_rb_value(JSContext *ctx, JSValue j_val)
191
117
  if (promiseState != -1)
192
118
  {
193
119
  VALUE r_error_message = rb_str_new2("cannot translate a Promise to Ruby. await within JavaScript's end");
194
- rb_exc_raise(rb_funcall(rb_cQuickjsRuntimeError, rb_intern("new"), 2, r_error_message, Qnil));
120
+ rb_exc_raise(rb_funcall(QUICKJSRB_ERROR_FOR(QUICKJSRB_ROOT_RUNTIME_ERROR), rb_intern("new"), 2, r_error_message, Qnil));
195
121
  return Qnil;
196
122
  }
197
123
 
@@ -204,17 +130,17 @@ VALUE to_rb_value(JSContext *ctx, JSValue j_val)
204
130
  VALUE r_str = rb_str_new2(msg);
205
131
  JS_FreeCString(ctx, msg);
206
132
 
207
- JS_FreeValue(ctx, j_global);
208
133
  JS_FreeValue(ctx, j_strigified);
209
134
  JS_FreeValue(ctx, j_stringifyFunc);
210
135
  JS_FreeValue(ctx, j_jsonClass);
136
+ JS_FreeValue(ctx, j_global);
211
137
 
212
138
  return rb_funcall(rb_const_get(rb_cClass, rb_intern("JSON")), rb_intern("parse"), 1, r_str);
213
139
  }
214
140
  case JS_TAG_NULL:
215
141
  return Qnil;
216
142
  case JS_TAG_UNDEFINED:
217
- return ID2SYM(rb_intern(undefinedId));
143
+ return QUICKJSRB_SYM(undefinedId);
218
144
  case JS_TAG_EXCEPTION:
219
145
  {
220
146
  JSValue j_exceptionVal = JS_GetException(ctx);
@@ -230,47 +156,27 @@ VALUE to_rb_value(JSContext *ctx, JSValue j_val)
230
156
  JS_FreeValue(ctx, j_errorClassName);
231
157
 
232
158
  VALUE r_error_class, r_error_message = rb_str_new2(errorClassMessage);
233
-
234
- if (strcmp(errorClassName, "SyntaxError") == 0)
235
- {
236
- r_error_class = rb_cQuickjsSyntaxError;
237
- }
238
- else if (strcmp(errorClassName, "TypeError") == 0)
239
- {
240
- r_error_class = rb_cQuickjsTypeError;
241
- }
242
- else if (strcmp(errorClassName, "ReferenceError") == 0)
243
- {
244
- r_error_class = rb_cQuickjsReferenceError;
245
- }
246
- else if (strcmp(errorClassName, "RangeError") == 0)
247
- {
248
- r_error_class = rb_cQuickjsRangeError;
249
- }
250
- else if (strcmp(errorClassName, "EvalError") == 0)
251
- {
252
- r_error_class = rb_cQuickjsEvalError;
253
- }
254
- else if (strcmp(errorClassName, "URIError") == 0)
159
+ if (is_native_error_name(errorClassName))
255
160
  {
256
- r_error_class = rb_cQuickjsURIError;
257
- }
258
- else if (strcmp(errorClassName, "AggregateError") == 0)
259
- {
260
- r_error_class = rb_cQuickjsAggregateError;
161
+ r_error_class = QUICKJSRB_ERROR_FOR(errorClassName);
261
162
  }
262
163
  else if (strcmp(errorClassName, "InternalError") == 0 && strstr(errorClassMessage, "interrupted") != NULL)
263
164
  {
264
- r_error_class = rb_cQuickjsInterruptedError;
165
+ r_error_class = QUICKJSRB_ERROR_FOR(QUICKJSRB_INTERRUPTED_ERROR);
265
166
  r_error_message = rb_str_new2("Code evaluation is interrupted by the timeout or something");
266
167
  }
168
+ else if (strcmp(errorClassName, "InternalError") == 0 && strstr(errorClassMessage, "Ruby") != NULL)
169
+ {
170
+ r_error_class = QUICKJSRB_ERROR_FOR(QUICKJSRB_RUBY_FUNCTION_ERROR);
171
+ }
172
+
267
173
  else if (strcmp(errorClassName, "Quickjs::InterruptedError") == 0)
268
174
  {
269
- r_error_class = rb_cQuickjsInterruptedError;
175
+ r_error_class = QUICKJSRB_ERROR_FOR(QUICKJSRB_INTERRUPTED_ERROR);
270
176
  }
271
177
  else
272
178
  {
273
- r_error_class = rb_cQuickjsRuntimeError;
179
+ r_error_class = QUICKJSRB_ERROR_FOR(QUICKJSRB_ROOT_RUNTIME_ERROR);
274
180
  }
275
181
  JS_FreeCString(ctx, errorClassName);
276
182
  JS_FreeCString(ctx, errorClassMessage);
@@ -285,7 +191,7 @@ VALUE to_rb_value(JSContext *ctx, JSValue j_val)
285
191
 
286
192
  JS_FreeCString(ctx, errorMessage);
287
193
  JS_FreeValue(ctx, j_exceptionVal);
288
- rb_exc_raise(rb_funcall(rb_cQuickjsRuntimeError, rb_intern("new"), 2, r_error_message, Qnil));
194
+ rb_exc_raise(rb_funcall(QUICKJSRB_ERROR_FOR(QUICKJSRB_ROOT_RUNTIME_ERROR), rb_intern("new"), 2, r_error_message, Qnil));
289
195
  }
290
196
  return Qnil;
291
197
  }
@@ -310,6 +216,18 @@ VALUE to_rb_value(JSContext *ctx, JSValue j_val)
310
216
  }
311
217
  }
312
218
 
219
+ static VALUE r_try_call_proc(VALUE r_try_args)
220
+ {
221
+ return rb_funcall(
222
+ rb_const_get(rb_cClass, rb_intern("Quickjs")),
223
+ rb_intern("_with_timeout"),
224
+ 3,
225
+ RARRAY_AREF(r_try_args, 2), // timeout
226
+ RARRAY_AREF(r_try_args, 0), // proc
227
+ RARRAY_AREF(r_try_args, 1) // args for proc
228
+ );
229
+ }
230
+
313
231
  static JSValue js_quickjsrb_call_global(JSContext *ctx, JSValueConst _this, int _argc, JSValueConst *argv)
314
232
  {
315
233
  VMData *data = JS_GetContextOpaque(ctx);
@@ -322,17 +240,25 @@ static JSValue js_quickjsrb_call_global(JSContext *ctx, JSValueConst _this, int
322
240
  { // Shouldn't happen
323
241
  return JS_ThrowReferenceError(ctx, "Proc `%s` is not defined", funcName);
324
242
  }
325
- JS_FreeCString(ctx, funcName);
326
243
 
327
- VALUE r_result = rb_funcall(
328
- rb_const_get(rb_cClass, rb_intern("Quickjs")),
329
- rb_intern("_with_timeout"),
330
- 3,
331
- ULONG2NUM(data->eval_time->limit * 1000 / CLOCKS_PER_SEC),
332
- r_proc,
333
- to_rb_value(ctx, argv[1]));
244
+ VALUE r_call_args = rb_ary_new();
245
+ rb_ary_push(r_call_args, r_proc);
246
+ rb_ary_push(r_call_args, to_rb_value(ctx, argv[1]));
247
+ rb_ary_push(r_call_args, ULONG2NUM(data->eval_time->limit * 1000 / CLOCKS_PER_SEC));
334
248
 
335
- return to_js_value(ctx, r_result);
249
+ int sadnessHappened;
250
+ VALUE r_result = rb_protect(r_try_call_proc, r_call_args, &sadnessHappened);
251
+ JSValue j_result;
252
+ if (sadnessHappened)
253
+ {
254
+ j_result = JS_ThrowInternalError(ctx, "unintentional error is raised while executing the function by Ruby: `%s`", funcName);
255
+ }
256
+ else
257
+ {
258
+ j_result = to_js_value(ctx, r_result);
259
+ }
260
+ JS_FreeCString(ctx, funcName);
261
+ return j_result;
336
262
  }
337
263
 
338
264
  static JSValue js_quickjsrb_log(JSContext *ctx, JSValueConst _this, int _argc, JSValueConst *argv)
@@ -342,8 +268,10 @@ static JSValue js_quickjsrb_log(JSContext *ctx, JSValueConst _this, int _argc, J
342
268
  const char *severity = JS_ToCString(ctx, j_severity);
343
269
  JS_FreeValue(ctx, j_severity);
344
270
 
345
- VALUE r_log = rb_funcall(rb_cQuickjsVMLog, rb_intern("new"), 0);
271
+ VALUE r_log_class = rb_const_get(rb_const_get(rb_const_get(rb_cClass, rb_intern("Quickjs")), rb_intern("VM")), rb_intern("Log"));
272
+ VALUE r_log = rb_funcall(r_log_class, rb_intern("new"), 0);
346
273
  rb_iv_set(r_log, "@severity", ID2SYM(rb_intern(severity)));
274
+ JS_FreeCString(ctx, severity);
347
275
 
348
276
  VALUE r_row = rb_ary_new();
349
277
  int i;
@@ -351,22 +279,28 @@ static JSValue js_quickjsrb_log(JSContext *ctx, JSValueConst _this, int _argc, J
351
279
  int count;
352
280
  JS_ToInt32(ctx, &count, j_length);
353
281
  JS_FreeValue(ctx, j_length);
282
+
354
283
  for (i = 0; i < count; i++)
355
284
  {
285
+ VALUE r_loghash = rb_hash_new();
356
286
  JSValue j_logged = JS_GetPropertyUint32(ctx, argv[1], i);
287
+ if (JS_VALUE_GET_NORM_TAG(j_logged) == JS_TAG_OBJECT && JS_PromiseState(ctx, j_logged) != -1)
288
+ {
289
+ rb_hash_aset(r_loghash, ID2SYM(rb_intern("raw")), rb_str_new2("Promise"));
290
+ }
291
+ else
292
+ {
293
+ rb_hash_aset(r_loghash, ID2SYM(rb_intern("raw")), to_rb_value(ctx, j_logged));
294
+ }
357
295
  const char *body = JS_ToCString(ctx, j_logged);
358
- VALUE r_loghash = rb_hash_new();
359
- rb_hash_aset(r_loghash, ID2SYM(rb_intern("c")), rb_str_new2(body));
360
- rb_hash_aset(r_loghash, ID2SYM(rb_intern("raw")), to_rb_value(ctx, j_logged));
361
- rb_ary_push(r_row, r_loghash);
362
296
  JS_FreeValue(ctx, j_logged);
297
+ rb_hash_aset(r_loghash, ID2SYM(rb_intern("c")), rb_str_new2(body));
363
298
  JS_FreeCString(ctx, body);
299
+ rb_ary_push(r_row, r_loghash);
364
300
  }
365
301
 
366
302
  rb_iv_set(r_log, "@row", r_row);
367
303
  rb_ary_push(data->logs, r_log);
368
- JS_FreeCString(ctx, severity);
369
-
370
304
  return JS_UNDEFINED;
371
305
  }
372
306
 
@@ -408,7 +342,7 @@ static VALUE vm_m_initialize(int argc, VALUE *argv, VALUE r_self)
408
342
  JS_SetModuleLoaderFunc(runtime, NULL, js_module_loader, NULL);
409
343
  js_std_init_handlers(runtime);
410
344
 
411
- if (RTEST(rb_funcall(r_features, rb_intern("include?"), 1, ID2SYM(rb_intern(featureStdId)))))
345
+ if (RTEST(rb_funcall(r_features, rb_intern("include?"), 1, QUICKJSRB_SYM(featureStdId))))
412
346
  {
413
347
  js_init_module_std(data->context, "std");
414
348
  const char *enableStd = "import * as std from 'std';\n"
@@ -417,7 +351,7 @@ static VALUE vm_m_initialize(int argc, VALUE *argv, VALUE r_self)
417
351
  JS_FreeValue(data->context, j_stdEval);
418
352
  }
419
353
 
420
- if (RTEST(rb_funcall(r_features, rb_intern("include?"), 1, ID2SYM(rb_intern(featureOsId)))))
354
+ if (RTEST(rb_funcall(r_features, rb_intern("include?"), 1, QUICKJSRB_SYM(featureOsId))))
421
355
  {
422
356
  js_init_module_os(data->context, "os");
423
357
  const char *enableOs = "import * as os from 'os';\n"
@@ -425,13 +359,19 @@ static VALUE vm_m_initialize(int argc, VALUE *argv, VALUE r_self)
425
359
  JSValue j_osEval = JS_Eval(data->context, enableOs, strlen(enableOs), "<vm>", JS_EVAL_TYPE_MODULE);
426
360
  JS_FreeValue(data->context, j_osEval);
427
361
  }
428
- else if (RTEST(rb_funcall(r_features, rb_intern("include?"), 1, ID2SYM(rb_intern(featureOsTimeoutId)))))
362
+ else if (RTEST(rb_funcall(r_features, rb_intern("include?"), 1, QUICKJSRB_SYM(featureOsTimeoutId))))
429
363
  {
430
- js_init_module_os(data->context, "_os"); // Better if this is limited just only for setTimeout and clearTimeout
431
- const char *enableTimeout = "import * as _os from '_os';\n"
432
- "globalThis.setTimeout = _os.setTimeout;\n"
433
- "globalThis.clearTimeout = _os.clearTimeout;\n";
364
+ char *filename = random_string();
365
+ js_init_module_os(data->context, filename); // Better if this is limited just only for setTimeout and clearTimeout
366
+ const char *enableTimeoutTemplate = "import * as _os from '%s';\n"
367
+ "globalThis.setTimeout = _os.setTimeout;\n"
368
+ "globalThis.clearTimeout = _os.clearTimeout;\n";
369
+ int length = snprintf(NULL, 0, enableTimeoutTemplate, filename);
370
+ char *enableTimeout = (char *)malloc(length + 1);
371
+ snprintf(enableTimeout, length + 1, enableTimeoutTemplate, filename);
372
+
434
373
  JSValue j_timeoutEval = JS_Eval(data->context, enableTimeout, strlen(enableTimeout), "<vm>", JS_EVAL_TYPE_MODULE);
374
+ free(enableTimeout);
435
375
  JS_FreeValue(data->context, j_timeoutEval);
436
376
  }
437
377
 
@@ -477,7 +417,7 @@ static VALUE vm_m_evalCode(VALUE r_self, VALUE r_code)
477
417
 
478
418
  char *code = StringValueCStr(r_code);
479
419
  JSValue j_codeResult = JS_Eval(data->context, code, strlen(code), "<code>", JS_EVAL_TYPE_GLOBAL | JS_EVAL_FLAG_ASYNC);
480
- JSValue j_awaitedResult = js_std_await(data->context, j_codeResult);
420
+ JSValue j_awaitedResult = js_std_await(data->context, j_codeResult); // This frees j_codeResult
481
421
  JSValue j_returnedValue = JS_GetPropertyStr(data->context, j_awaitedResult, "value");
482
422
  // Do this by rescuing to_rb_value
483
423
  if (JS_VALUE_GET_NORM_TAG(j_returnedValue) == JS_TAG_OBJECT && JS_PromiseState(data->context, j_returnedValue) != -1)
@@ -485,7 +425,7 @@ static VALUE vm_m_evalCode(VALUE r_self, VALUE r_code)
485
425
  JS_FreeValue(data->context, j_returnedValue);
486
426
  JS_FreeValue(data->context, j_awaitedResult);
487
427
  VALUE r_error_message = rb_str_new2("An unawaited Promise was returned to the top-level");
488
- rb_exc_raise(rb_funcall(rb_cQuickjsNoAwaitError, rb_intern("new"), 2, r_error_message, Qnil));
428
+ rb_exc_raise(rb_funcall(QUICKJSRB_ERROR_FOR(QUICKJSRB_NO_AWAIT_ERROR), rb_intern("new"), 2, r_error_message, Qnil));
489
429
  return Qnil;
490
430
  }
491
431
  else
@@ -497,30 +437,34 @@ static VALUE vm_m_evalCode(VALUE r_self, VALUE r_code)
497
437
  }
498
438
  }
499
439
 
500
- static VALUE vm_m_defineGlobalFunction(VALUE r_self, VALUE r_name)
440
+ static VALUE vm_m_defineGlobalFunction(int argc, VALUE *argv, VALUE r_self)
501
441
  {
502
442
  rb_need_block();
503
443
 
444
+ VALUE r_name;
445
+ VALUE r_flags;
446
+ VALUE r_block;
447
+ rb_scan_args(argc, argv, "10*&", &r_name, &r_flags, &r_block);
448
+
449
+ const char *asyncKeyword =
450
+ RTEST(rb_funcall(r_flags, rb_intern("include?"), 1, ID2SYM(rb_intern("async")))) ? "async " : "";
451
+
504
452
  VMData *data;
505
453
  TypedData_Get_Struct(r_self, VMData, &vm_type, data);
506
454
 
507
- if (rb_block_given_p())
508
- {
509
- VALUE r_proc = rb_block_proc();
510
- rb_hash_aset(data->defined_functions, r_name, r_proc);
511
- char *funcName = StringValueCStr(r_name);
455
+ rb_hash_aset(data->defined_functions, r_name, r_block);
456
+ char *funcName = StringValueCStr(r_name);
512
457
 
513
- const char *template = "globalThis['%s'] = (...args) => __quickjsrb.runRubyMethod('%s', args);\n";
514
- int length = snprintf(NULL, 0, template, funcName, funcName);
515
- char *result = (char *)malloc(length + 1);
516
- snprintf(result, length + 1, template, funcName, funcName);
458
+ const char *template = "globalThis['%s'] = %s(...args) => __quickjsrb.runRubyMethod('%s', args);\n";
459
+ int length = snprintf(NULL, 0, template, funcName, asyncKeyword, funcName);
460
+ char *result = (char *)malloc(length + 1);
461
+ snprintf(result, length + 1, template, funcName, asyncKeyword, funcName);
517
462
 
518
- JSValue j_codeResult = JS_Eval(data->context, result, strlen(result), "<vm>", JS_EVAL_TYPE_MODULE);
463
+ JSValue j_codeResult = JS_Eval(data->context, result, strlen(result), "<vm>", JS_EVAL_TYPE_MODULE);
519
464
 
520
- free(result);
521
- JS_FreeValue(data->context, j_codeResult);
522
- return rb_funcall(r_name, rb_intern("to_sym"), 0, NULL);
523
- }
465
+ free(result);
466
+ JS_FreeValue(data->context, j_codeResult);
467
+ return rb_funcall(r_name, rb_intern("to_sym"), 0, NULL);
524
468
 
525
469
  return Qnil;
526
470
  }
@@ -535,15 +479,16 @@ static VALUE vm_m_import(int argc, VALUE *argv, VALUE r_self)
535
479
  if (NIL_P(r_from))
536
480
  {
537
481
  VALUE r_error_message = rb_str_new2("missing import source");
538
- rb_exc_raise(rb_funcall(rb_cQuickjsRuntimeError, rb_intern("new"), 2, r_error_message, Qnil));
482
+ rb_exc_raise(rb_funcall(QUICKJSRB_ERROR_FOR(QUICKJSRB_ROOT_RUNTIME_ERROR), rb_intern("new"), 2, r_error_message, Qnil));
539
483
  return Qnil;
540
484
  }
541
485
 
542
486
  VMData *data;
543
487
  TypedData_Get_Struct(r_self, VMData, &vm_type, data);
544
488
 
489
+ char *filename = random_string();
545
490
  char *source = StringValueCStr(r_from);
546
- JSValue func = JS_Eval(data->context, source, strlen(source), "mmmodule", JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
491
+ JSValue func = JS_Eval(data->context, source, strlen(source), filename, JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
547
492
  js_module_set_import_meta(data->context, func, TRUE, FALSE);
548
493
  JS_FreeValue(data->context, func);
549
494
 
@@ -557,11 +502,11 @@ static VALUE vm_m_import(int argc, VALUE *argv, VALUE r_self)
557
502
  VALUE r_globalize = rb_ary_entry(r_import_settings, 1);
558
503
  char *globalize = StringValueCStr(r_globalize);
559
504
 
560
- const char *importAndGlobalizeModule = "import %s from 'mmmodule';\n"
505
+ const char *importAndGlobalizeModule = "import %s from '%s';\n"
561
506
  "%s\n";
562
- int length = snprintf(NULL, 0, importAndGlobalizeModule, import_name, globalize);
507
+ int length = snprintf(NULL, 0, importAndGlobalizeModule, import_name, filename, globalize);
563
508
  char *result = (char *)malloc(length + 1);
564
- snprintf(result, length + 1, importAndGlobalizeModule, import_name, globalize);
509
+ snprintf(result, length + 1, importAndGlobalizeModule, import_name, filename, globalize);
565
510
 
566
511
  JSValue j_codeResult = JS_Eval(data->context, result, strlen(result), "<vm>", JS_EVAL_TYPE_MODULE);
567
512
  free(result);
@@ -570,7 +515,7 @@ static VALUE vm_m_import(int argc, VALUE *argv, VALUE r_self)
570
515
  return Qtrue;
571
516
  }
572
517
 
573
- static VALUE vm_m_getLogs(VALUE r_self)
518
+ static VALUE vm_m_logs(VALUE r_self)
574
519
  {
575
520
  VMData *data;
576
521
  TypedData_Get_Struct(r_self, VMData, &vm_type, data);
@@ -578,77 +523,21 @@ static VALUE vm_m_getLogs(VALUE r_self)
578
523
  return data->logs;
579
524
  }
580
525
 
581
- static VALUE pick_raw(VALUE block_arg, VALUE data, int argc, const VALUE *argv, VALUE blockarg)
582
- {
583
- return rb_hash_aref(block_arg, ID2SYM(rb_intern("raw")));
584
- }
585
-
586
- static VALUE vm_m_raw(VALUE r_self)
587
- {
588
- VALUE row = rb_iv_get(r_self, "@row");
589
- VALUE r_ary = rb_block_call(row, rb_intern("map"), 0, NULL, pick_raw, Qnil);
590
-
591
- return r_ary;
592
- }
593
-
594
- static VALUE pick_c(VALUE block_arg, VALUE data, int argc, const VALUE *argv, VALUE blockarg)
595
- {
596
- return rb_hash_aref(block_arg, ID2SYM(rb_intern("c")));
597
- }
598
-
599
- static VALUE vm_m_to_s(VALUE r_self)
600
- {
601
- VALUE row = rb_iv_get(r_self, "@row");
602
- VALUE r_ary = rb_block_call(row, rb_intern("map"), 0, NULL, pick_c, Qnil);
603
-
604
- return rb_funcall(r_ary, rb_intern("join"), 1, rb_str_new2(" "));
605
- }
606
-
607
- VALUE vm_m_initialize_quickjs_error(VALUE self, VALUE r_message, VALUE r_js_name)
608
- {
609
- rb_call_super(1, &r_message);
610
- rb_iv_set(self, "@js_name", r_js_name);
611
-
612
- return self;
613
- }
614
-
615
526
  RUBY_FUNC_EXPORTED void Init_quickjsrb(void)
616
527
  {
617
- VALUE rb_mQuickjs = rb_define_module("Quickjs");
618
- rb_define_const(rb_mQuickjs, "MODULE_STD", ID2SYM(rb_intern(featureStdId)));
619
- rb_define_const(rb_mQuickjs, "MODULE_OS", ID2SYM(rb_intern(featureOsId)));
620
- rb_define_const(rb_mQuickjs, "FEATURES_TIMEOUT", ID2SYM(rb_intern(featureOsTimeoutId)));
621
-
622
- VALUE rb_cQuickjsValue = rb_define_class_under(rb_mQuickjs, "Value", rb_cObject);
623
- rb_define_const(rb_cQuickjsValue, "UNDEFINED", ID2SYM(rb_intern(undefinedId)));
624
- rb_define_const(rb_cQuickjsValue, "NAN", ID2SYM(rb_intern(nanId)));
625
-
626
- VALUE rb_cQuickjsVM = rb_define_class_under(rb_mQuickjs, "VM", rb_cObject);
627
- rb_define_alloc_func(rb_cQuickjsVM, vm_alloc);
628
- rb_define_method(rb_cQuickjsVM, "initialize", vm_m_initialize, -1);
629
- rb_define_method(rb_cQuickjsVM, "eval_code", vm_m_evalCode, 1);
630
- rb_define_method(rb_cQuickjsVM, "define_function", vm_m_defineGlobalFunction, 1);
631
- rb_define_method(rb_cQuickjsVM, "import", vm_m_import, -1);
632
- rb_define_method(rb_cQuickjsVM, "logs", vm_m_getLogs, 0);
633
-
634
- rb_cQuickjsVMLog = rb_define_class_under(rb_cQuickjsVM, "Log", rb_cObject);
635
- rb_define_attr(rb_cQuickjsVMLog, "severity", 1, 0);
636
- rb_define_method(rb_cQuickjsVMLog, "raw", vm_m_raw, 0);
637
- rb_define_method(rb_cQuickjsVMLog, "to_s", vm_m_to_s, 0);
638
- rb_define_method(rb_cQuickjsVMLog, "inspect", vm_m_to_s, 0);
639
-
640
- rb_cQuickjsRuntimeError = rb_define_class_under(rb_mQuickjs, "RuntimeError", rb_eRuntimeError);
641
- rb_define_method(rb_cQuickjsRuntimeError, "initialize", vm_m_initialize_quickjs_error, 2);
642
- rb_define_attr(rb_cQuickjsRuntimeError, "js_name", 1, 0);
643
-
644
- rb_cQuickjsSyntaxError = rb_define_class_under(rb_mQuickjs, "SyntaxError", rb_cQuickjsRuntimeError);
645
- rb_cQuickjsTypeError = rb_define_class_under(rb_mQuickjs, "TypeError", rb_cQuickjsRuntimeError);
646
- rb_cQuickjsRangeError = rb_define_class_under(rb_mQuickjs, "RangeError", rb_cQuickjsRuntimeError);
647
- rb_cQuickjsReferenceError = rb_define_class_under(rb_mQuickjs, "ReferenceError", rb_cQuickjsRuntimeError);
648
- rb_cQuickjsURIError = rb_define_class_under(rb_mQuickjs, "URIError", rb_cQuickjsRuntimeError);
649
- rb_cQuickjsEvalError = rb_define_class_under(rb_mQuickjs, "EvalError", rb_cQuickjsRuntimeError);
650
- rb_cQuickjsAggregateError = rb_define_class_under(rb_mQuickjs, "AggregateError", rb_cQuickjsRuntimeError);
651
-
652
- rb_cQuickjsInterruptedError = rb_define_class_under(rb_mQuickjs, "InterruptedError", rb_cQuickjsRuntimeError);
653
- rb_cQuickjsNoAwaitError = rb_define_class_under(rb_mQuickjs, "NoAwaitError", rb_cQuickjsRuntimeError);
528
+ rb_require("json");
529
+ rb_require("securerandom");
530
+
531
+ VALUE r_module_quickjs = rb_define_module("Quickjs");
532
+ r_define_constants(r_module_quickjs);
533
+ r_define_exception_classes(r_module_quickjs);
534
+
535
+ VALUE r_class_vm = rb_define_class_under(r_module_quickjs, "VM", rb_cObject);
536
+ rb_define_alloc_func(r_class_vm, vm_alloc);
537
+ rb_define_method(r_class_vm, "initialize", vm_m_initialize, -1);
538
+ rb_define_method(r_class_vm, "eval_code", vm_m_evalCode, 1);
539
+ rb_define_method(r_class_vm, "define_function", vm_m_defineGlobalFunction, -1);
540
+ rb_define_method(r_class_vm, "import", vm_m_import, -1);
541
+ rb_define_method(r_class_vm, "logs", vm_m_logs, 0);
542
+ r_define_log_class(r_class_vm);
654
543
  }
@@ -12,4 +12,207 @@
12
12
  #include <string.h>
13
13
  #include <time.h>
14
14
 
15
+ const char *featureStdId = "feature_std";
16
+ const char *featureOsId = "feature_os";
17
+ const char *featureOsTimeoutId = "feature_os_timeout";
18
+
19
+ const char *undefinedId = "undefined";
20
+ const char *nanId = "NaN";
21
+
22
+ const char *native_errors[] = {
23
+ "SyntaxError",
24
+ "TypeError",
25
+ "ReferenceError",
26
+ "RangeError",
27
+ "EvalError",
28
+ "URIError",
29
+ "AggregateError"};
30
+
31
+ #define QUICKJSRB_SYM(id) \
32
+ (VALUE) { ID2SYM(rb_intern(id)) }
33
+
34
+ // VM data structure
35
+
36
+ typedef struct EvalTime
37
+ {
38
+ clock_t limit;
39
+ clock_t started_at;
40
+ } EvalTime;
41
+
42
+ typedef struct VMData
43
+ {
44
+ struct JSContext *context;
45
+ VALUE defined_functions;
46
+ struct EvalTime *eval_time;
47
+ VALUE logs;
48
+ } VMData;
49
+
50
+ static void vm_free(void *ptr)
51
+ {
52
+ VMData *data = (VMData *)ptr;
53
+ free(data->eval_time);
54
+
55
+ JSRuntime *runtime = JS_GetRuntime(data->context);
56
+ JS_SetInterruptHandler(runtime, NULL, NULL);
57
+ js_std_free_handlers(runtime);
58
+ JS_FreeContext(data->context);
59
+ JS_FreeRuntime(runtime);
60
+
61
+ xfree(ptr);
62
+ }
63
+
64
+ size_t vm_size(const void *data)
65
+ {
66
+ return sizeof(VMData);
67
+ }
68
+
69
+ static void vm_mark(void *ptr)
70
+ {
71
+ VMData *data = (VMData *)ptr;
72
+ rb_gc_mark_movable(data->defined_functions);
73
+ rb_gc_mark_movable(data->logs);
74
+ }
75
+
76
+ static const rb_data_type_t vm_type = {
77
+ .wrap_struct_name = "quickjsvm",
78
+ .function = {
79
+ .dmark = vm_mark,
80
+ .dfree = vm_free,
81
+ .dsize = vm_size,
82
+ },
83
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
84
+ };
85
+
86
+ static VALUE vm_alloc(VALUE r_self)
87
+ {
88
+ VMData *data;
89
+ VALUE obj = TypedData_Make_Struct(r_self, VMData, &vm_type, data);
90
+ data->defined_functions = rb_hash_new();
91
+ data->logs = rb_ary_new();
92
+
93
+ EvalTime *eval_time = malloc(sizeof(EvalTime));
94
+ data->eval_time = eval_time;
95
+
96
+ JSRuntime *runtime = JS_NewRuntime();
97
+ data->context = JS_NewContext(runtime);
98
+
99
+ return obj;
100
+ }
101
+
102
+ // Utils
103
+
104
+ static char *random_string()
105
+ {
106
+ VALUE r_rand = rb_funcall(
107
+ rb_const_get(rb_cClass, rb_intern("SecureRandom")),
108
+ rb_intern("alphanumeric"),
109
+ 1,
110
+ INT2NUM(12));
111
+ return StringValueCStr(r_rand);
112
+ }
113
+
114
+ static bool is_native_error_name(const char *error_name)
115
+ {
116
+ bool is_native_error = false;
117
+ int numStrings = sizeof(native_errors) / sizeof(native_errors[0]);
118
+ for (int i = 0; i < numStrings; i++)
119
+ {
120
+ if (strcmp(native_errors[i], error_name) == 0)
121
+ {
122
+ is_native_error = true;
123
+ break;
124
+ }
125
+ }
126
+ return is_native_error;
127
+ }
128
+
129
+ // Constants
130
+
131
+ static void r_define_constants(VALUE r_parent_class)
132
+ {
133
+ rb_define_const(r_parent_class, "MODULE_STD", QUICKJSRB_SYM(featureStdId));
134
+ rb_define_const(r_parent_class, "MODULE_OS", QUICKJSRB_SYM(featureOsId));
135
+ rb_define_const(r_parent_class, "FEATURES_TIMEOUT", QUICKJSRB_SYM(featureOsTimeoutId));
136
+
137
+ VALUE rb_cQuickjsValue = rb_define_class_under(r_parent_class, "Value", rb_cObject);
138
+ rb_define_const(rb_cQuickjsValue, "UNDEFINED", QUICKJSRB_SYM(undefinedId));
139
+ rb_define_const(rb_cQuickjsValue, "NAN", QUICKJSRB_SYM(nanId));
140
+ }
141
+
142
+ // Log class
143
+
144
+ static VALUE r_proc_pick_raw(VALUE block_arg, VALUE data, int argc, const VALUE *argv, VALUE blockarg)
145
+ {
146
+ return rb_hash_aref(block_arg, ID2SYM(rb_intern("raw")));
147
+ }
148
+
149
+ static VALUE r_log_m_raw(VALUE r_self)
150
+ {
151
+ VALUE row = rb_iv_get(r_self, "@row");
152
+ VALUE r_ary = rb_block_call(row, rb_intern("map"), 0, NULL, r_proc_pick_raw, Qnil);
153
+
154
+ return r_ary;
155
+ }
156
+
157
+ static VALUE r_proc_pick_c(VALUE block_arg, VALUE data, int argc, const VALUE *argv, VALUE blockarg)
158
+ {
159
+ return rb_hash_aref(block_arg, ID2SYM(rb_intern("c")));
160
+ }
161
+
162
+ static VALUE r_log_m_to_s(VALUE r_self)
163
+ {
164
+ VALUE row = rb_iv_get(r_self, "@row");
165
+ VALUE r_ary = rb_block_call(row, rb_intern("map"), 0, NULL, r_proc_pick_c, Qnil);
166
+
167
+ return rb_funcall(r_ary, rb_intern("join"), 1, rb_str_new2(" "));
168
+ }
169
+
170
+ static VALUE r_define_log_class(VALUE r_parent_class)
171
+ {
172
+ VALUE r_log_class = rb_define_class_under(r_parent_class, "Log", rb_cObject);
173
+ rb_define_attr(r_log_class, "severity", 1, 0);
174
+ rb_define_method(r_log_class, "raw", r_log_m_raw, 0);
175
+ rb_define_method(r_log_class, "to_s", r_log_m_to_s, 0);
176
+ rb_define_method(r_log_class, "inspect", r_log_m_to_s, 0);
177
+
178
+ return r_log_class;
179
+ }
180
+
181
+ // Exceptions
182
+
183
+ #define QUICKJSRB_ROOT_RUNTIME_ERROR "RuntimeError"
184
+ #define QUICKJSRB_INTERRUPTED_ERROR "InterruptedError"
185
+ #define QUICKJSRB_NO_AWAIT_ERROR "NoAwaitError"
186
+ #define QUICKJSRB_RUBY_FUNCTION_ERROR "RubyFunctionError"
187
+
188
+ #define QUICKJSRB_ERROR_FOR(name) \
189
+ (VALUE) { rb_const_get(rb_const_get(rb_cClass, rb_intern("Quickjs")), rb_intern(name)) }
190
+
191
+ VALUE vm_m_initialize_quickjs_error(VALUE self, VALUE r_message, VALUE r_js_name)
192
+ {
193
+ rb_call_super(1, &r_message);
194
+ rb_iv_set(self, "@js_name", r_js_name);
195
+
196
+ return self;
197
+ }
198
+
199
+ static void r_define_exception_classes(VALUE r_parent_class)
200
+ {
201
+ VALUE r_runtime_error = rb_define_class_under(r_parent_class, QUICKJSRB_ROOT_RUNTIME_ERROR, rb_eRuntimeError);
202
+ rb_define_method(r_runtime_error, "initialize", vm_m_initialize_quickjs_error, 2);
203
+ rb_define_attr(r_runtime_error, "js_name", 1, 0);
204
+
205
+ // JS native errors
206
+ int numStrings = sizeof(native_errors) / sizeof(native_errors[0]);
207
+ for (int i = 0; i < numStrings; i++)
208
+ {
209
+ rb_define_class_under(r_parent_class, native_errors[i], r_runtime_error);
210
+ }
211
+
212
+ // quickjsrb specific errors
213
+ rb_define_class_under(r_parent_class, QUICKJSRB_INTERRUPTED_ERROR, r_runtime_error);
214
+ rb_define_class_under(r_parent_class, QUICKJSRB_NO_AWAIT_ERROR, r_runtime_error);
215
+ rb_define_class_under(r_parent_class, QUICKJSRB_RUBY_FUNCTION_ERROR, r_runtime_error);
216
+ }
217
+
15
218
  #endif /* QUICKJSRB_H */
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Quickjs
4
- VERSION = "0.2.1"
4
+ VERSION = "0.2.3"
5
5
  end
data/lib/quickjs.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "timeout"
4
- require "json"
5
4
  require_relative "quickjs/version"
6
5
  require_relative "quickjs/quickjsrb"
7
6
 
@@ -18,8 +17,8 @@ module Quickjs
18
17
  Timeout.timeout(msec / 1_000.0) { proc.call(*args) }
19
18
  rescue Timeout::Error
20
19
  Quickjs::InterruptedError.new('Ruby runtime got timeout', nil)
21
- rescue => e
22
- e
20
+ rescue
21
+ raise
23
22
  end
24
23
  module_function :_with_timeout
25
24
 
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.2.1
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - hmsk
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-15 00:00:00.000000000 Z
11
+ date: 2024-10-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: securerandom
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  description: A native wrapper to run QuickJS in Ruby
28
42
  email:
29
43
  - k.hamasaki@gmail.com