quickjs 0.11.0 → 0.11.2
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/ext/quickjsrb/extconf.rb +2 -1
- data/ext/quickjsrb/quickjsrb.c +27 -7
- data/ext/quickjsrb/quickjsrb.h +14 -2
- data/lib/quickjs/version.rb +1 -1
- metadata +3 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 29ad9419055f853b82d642f0c5404d24d476dcc3d0d8e7da4364f06a819b10a3
|
|
4
|
+
data.tar.gz: 77b07d4c214663c8fd716ab2c9dda3d88c327f3f77b0d350f2987d506a70677e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 75ba55882ce0d5371e3ba3d584849d012c06a955d230e7b9975266852753dae3db45244fc8b9bf967f86ba25fff52d7c6d8118bab131f9e8b61bb421356597c0
|
|
7
|
+
data.tar.gz: 97964de7f1ef9f20c548cc8e69da09fe058112193593bb433e8b93e3e42424582f111a306df13df78dd583442dd712bc71e6da8ff0ce17116f19618f8aa803d2
|
data/ext/quickjsrb/extconf.rb
CHANGED
|
@@ -37,7 +37,8 @@ else
|
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
append_cflags('-fwrapv')
|
|
40
|
-
|
|
40
|
+
# NDEBUG: suppress QuickJS debug assertions that conflict with Ruby 4.0 GC
|
|
41
|
+
$CFLAGS << ' ' << '-D_GNU_SOURCE -DCONFIG_VERSION=\"2024-02-14\" -DNDEBUG'
|
|
41
42
|
|
|
42
43
|
abort('could not find quickjs.h') unless find_header('quickjs.h')
|
|
43
44
|
abort('could not find cutils.h') unless find_header('cutils.h')
|
data/ext/quickjsrb/quickjsrb.c
CHANGED
|
@@ -8,6 +8,10 @@ JSValue j_error_from_ruby_error(JSContext *ctx, VALUE r_error)
|
|
|
8
8
|
int objectId = NUM2INT(r_object_id);
|
|
9
9
|
JS_SetPropertyStr(ctx, j_error, "rb_object_id", JS_NewInt32(ctx, objectId));
|
|
10
10
|
|
|
11
|
+
// Keep the error alive in VMData to prevent GC before find_ruby_error retrieves it
|
|
12
|
+
VMData *data = JS_GetContextOpaque(ctx);
|
|
13
|
+
rb_hash_aset(data->alive_errors, r_object_id, r_error);
|
|
14
|
+
|
|
11
15
|
VALUE r_exception_message = rb_funcall(r_error, rb_intern("message"), 0);
|
|
12
16
|
const char *errorMessage = StringValueCStr(r_exception_message);
|
|
13
17
|
JS_SetPropertyStr(ctx, j_error, "message", JS_NewString(ctx, errorMessage));
|
|
@@ -89,8 +93,11 @@ VALUE find_ruby_error(JSContext *ctx, JSValue j_error)
|
|
|
89
93
|
JS_FreeValue(ctx, j_errorOriginalRubyObjectId);
|
|
90
94
|
if (errorOriginalRubyObjectId > 0)
|
|
91
95
|
{
|
|
92
|
-
|
|
93
|
-
|
|
96
|
+
VMData *data = JS_GetContextOpaque(ctx);
|
|
97
|
+
VALUE r_key = INT2NUM(errorOriginalRubyObjectId);
|
|
98
|
+
VALUE r_error = rb_hash_aref(data->alive_errors, r_key);
|
|
99
|
+
rb_hash_delete(data->alive_errors, r_key);
|
|
100
|
+
return r_error;
|
|
94
101
|
}
|
|
95
102
|
}
|
|
96
103
|
else
|
|
@@ -329,7 +336,7 @@ static JSValue js_quickjsrb_call_global(JSContext *ctx, JSValueConst _this, int
|
|
|
329
336
|
JS_FreeValue(ctx, j_v);
|
|
330
337
|
}
|
|
331
338
|
rb_ary_push(r_call_args, r_argv);
|
|
332
|
-
rb_ary_push(r_call_args, ULONG2NUM(data->eval_time->
|
|
339
|
+
rb_ary_push(r_call_args, ULONG2NUM(data->eval_time->limit_ms));
|
|
333
340
|
|
|
334
341
|
int sadnessHappened;
|
|
335
342
|
|
|
@@ -507,7 +514,7 @@ static VALUE vm_m_initialize(int argc, VALUE *argv, VALUE r_self)
|
|
|
507
514
|
VMData *data;
|
|
508
515
|
TypedData_Get_Struct(r_self, VMData, &vm_type, data);
|
|
509
516
|
|
|
510
|
-
data->eval_time->
|
|
517
|
+
data->eval_time->limit_ms = (int64_t)NUM2UINT(r_timeout_msec);
|
|
511
518
|
JS_SetContextOpaque(data->context, data);
|
|
512
519
|
JSRuntime *runtime = JS_GetRuntime(data->context);
|
|
513
520
|
|
|
@@ -580,7 +587,11 @@ static VALUE vm_m_initialize(int argc, VALUE *argv, VALUE r_self)
|
|
|
580
587
|
static int interrupt_handler(JSRuntime *runtime, void *opaque)
|
|
581
588
|
{
|
|
582
589
|
EvalTime *eval_time = opaque;
|
|
583
|
-
|
|
590
|
+
struct timespec now;
|
|
591
|
+
clock_gettime(CLOCK_MONOTONIC, &now);
|
|
592
|
+
int64_t elapsed_ms = (int64_t)(now.tv_sec - eval_time->started_at.tv_sec) * 1000
|
|
593
|
+
+ (now.tv_nsec - eval_time->started_at.tv_nsec) / 1000000;
|
|
594
|
+
return elapsed_ms >= eval_time->limit_ms ? 1 : 0;
|
|
584
595
|
}
|
|
585
596
|
|
|
586
597
|
static VALUE vm_m_evalCode(VALUE r_self, VALUE r_code)
|
|
@@ -588,7 +599,13 @@ static VALUE vm_m_evalCode(VALUE r_self, VALUE r_code)
|
|
|
588
599
|
VMData *data;
|
|
589
600
|
TypedData_Get_Struct(r_self, VMData, &vm_type, data);
|
|
590
601
|
|
|
591
|
-
|
|
602
|
+
if (!RB_TYPE_P(r_code, T_STRING))
|
|
603
|
+
{
|
|
604
|
+
VALUE r_code_class = rb_class_name(CLASS_OF(r_code));
|
|
605
|
+
rb_raise(rb_eTypeError, "JavaScript code must be a String, got %s", StringValueCStr(r_code_class));
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
clock_gettime(CLOCK_MONOTONIC, &data->eval_time->started_at);
|
|
592
609
|
JS_SetInterruptHandler(JS_GetRuntime(data->context), interrupt_handler, data->eval_time);
|
|
593
610
|
|
|
594
611
|
char *code = StringValueCStr(r_code);
|
|
@@ -606,9 +623,12 @@ static VALUE vm_m_evalCode(VALUE r_self, VALUE r_code)
|
|
|
606
623
|
}
|
|
607
624
|
else
|
|
608
625
|
{
|
|
626
|
+
// Free j_awaitedResult before to_rb_value because to_rb_value may
|
|
627
|
+
// raise (longjmp) for JS exceptions, which would skip any cleanup
|
|
628
|
+
// after it and leak JS GC objects.
|
|
629
|
+
JS_FreeValue(data->context, j_awaitedResult);
|
|
609
630
|
VALUE result = to_rb_value(data->context, j_returnedValue);
|
|
610
631
|
JS_FreeValue(data->context, j_returnedValue);
|
|
611
|
-
JS_FreeValue(data->context, j_awaitedResult);
|
|
612
632
|
return result;
|
|
613
633
|
}
|
|
614
634
|
}
|
data/ext/quickjsrb/quickjsrb.h
CHANGED
|
@@ -39,8 +39,8 @@ const char *native_errors[] = {
|
|
|
39
39
|
|
|
40
40
|
typedef struct EvalTime
|
|
41
41
|
{
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
int64_t limit_ms;
|
|
43
|
+
struct timespec started_at;
|
|
44
44
|
} EvalTime;
|
|
45
45
|
|
|
46
46
|
typedef struct VMData
|
|
@@ -49,6 +49,7 @@ typedef struct VMData
|
|
|
49
49
|
VALUE defined_functions;
|
|
50
50
|
struct EvalTime *eval_time;
|
|
51
51
|
VALUE logs;
|
|
52
|
+
VALUE alive_errors;
|
|
52
53
|
} VMData;
|
|
53
54
|
|
|
54
55
|
static void vm_free(void *ptr)
|
|
@@ -75,6 +76,15 @@ static void vm_mark(void *ptr)
|
|
|
75
76
|
VMData *data = (VMData *)ptr;
|
|
76
77
|
rb_gc_mark_movable(data->defined_functions);
|
|
77
78
|
rb_gc_mark_movable(data->logs);
|
|
79
|
+
rb_gc_mark_movable(data->alive_errors);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
static void vm_compact(void *ptr)
|
|
83
|
+
{
|
|
84
|
+
VMData *data = (VMData *)ptr;
|
|
85
|
+
data->defined_functions = rb_gc_location(data->defined_functions);
|
|
86
|
+
data->logs = rb_gc_location(data->logs);
|
|
87
|
+
data->alive_errors = rb_gc_location(data->alive_errors);
|
|
78
88
|
}
|
|
79
89
|
|
|
80
90
|
static const rb_data_type_t vm_type = {
|
|
@@ -83,6 +93,7 @@ static const rb_data_type_t vm_type = {
|
|
|
83
93
|
.dmark = vm_mark,
|
|
84
94
|
.dfree = vm_free,
|
|
85
95
|
.dsize = vm_size,
|
|
96
|
+
.dcompact = vm_compact,
|
|
86
97
|
},
|
|
87
98
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
|
88
99
|
};
|
|
@@ -93,6 +104,7 @@ static VALUE vm_alloc(VALUE r_self)
|
|
|
93
104
|
VALUE obj = TypedData_Make_Struct(r_self, VMData, &vm_type, data);
|
|
94
105
|
data->defined_functions = rb_hash_new();
|
|
95
106
|
data->logs = rb_ary_new();
|
|
107
|
+
data->alive_errors = rb_hash_new();
|
|
96
108
|
|
|
97
109
|
EvalTime *eval_time = malloc(sizeof(EvalTime));
|
|
98
110
|
data->eval_time = eval_time;
|
data/lib/quickjs/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: quickjs
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.11.
|
|
4
|
+
version: 0.11.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- hmsk
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: json
|
|
@@ -89,7 +88,6 @@ metadata:
|
|
|
89
88
|
homepage_uri: https://github.com/hmsk/quickjs.rb
|
|
90
89
|
source_code_uri: https://github.com/hmsk/quickjs.rb
|
|
91
90
|
changelog_uri: https://github.com/hmsk/quickjs.rb/blob/main/CHANGELOG.md
|
|
92
|
-
post_install_message:
|
|
93
91
|
rdoc_options: []
|
|
94
92
|
require_paths:
|
|
95
93
|
- lib
|
|
@@ -104,8 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
104
102
|
- !ruby/object:Gem::Version
|
|
105
103
|
version: '0'
|
|
106
104
|
requirements: []
|
|
107
|
-
rubygems_version:
|
|
108
|
-
signing_key:
|
|
105
|
+
rubygems_version: 4.0.3
|
|
109
106
|
specification_version: 4
|
|
110
107
|
summary: Run binding of QuickJS
|
|
111
108
|
test_files: []
|