quickjs 0.1.5 → 0.1.7
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 +21 -5
- data/ext/quickjsrb/extconf.rb +1 -0
- data/ext/quickjsrb/procs.c +80 -0
- data/ext/quickjsrb/procs.h +18 -0
- data/ext/quickjsrb/quickjsrb.c +186 -45
- data/ext/quickjsrb/quickjsrb.h +2 -0
- data/lib/quickjs/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9a639b7afafb5c155725cba8d7927b7f4e146e21369a65a3902e8fe23ef1e3dd
|
4
|
+
data.tar.gz: b0e098ae6c193e761f456642cdcaf5396251785d5bc56b5e807fd540a0615f87
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9ad93ee1c056d68409daeba63515b8afa8555150044e0543a97bb2f3cb64abf5b8f5a5b1fce75e952721b0277a7807ce521289b70b63157cc489032da7da8f7c
|
7
|
+
data.tar.gz: b36a5f2e7402156e94403c5110ec1acc6141d657b236562b18b57c63c68fd966d4ef25096e3b515f9633093bee2e2a89f65578b4426e0c4184197078c9c2c578
|
data/README.md
CHANGED
@@ -40,10 +40,10 @@ Quickjs.eval_code("Number('whatever')") #=> :NaN (Quickjs::Value::NAN)
|
|
40
40
|
|
41
41
|
```rb
|
42
42
|
# 1GB memory limit
|
43
|
-
Quickjs.eval_code(code, {
|
43
|
+
Quickjs.eval_code(code, { memory_limit: 1024 ** 3 })
|
44
44
|
|
45
45
|
# 1MB max stack size
|
46
|
-
Quickjs.eval_code(code, {
|
46
|
+
Quickjs.eval_code(code, { max_stack_size: 1024 ** 2 })
|
47
47
|
```
|
48
48
|
|
49
49
|
#### Enable built-in modules
|
@@ -58,7 +58,7 @@ Quickjs.eval_code(code, { features: [Quickjs::MODULE_STD] })
|
|
58
58
|
Quickjs.eval_code(code, { features: [Quickjs::MODULE_OS] })
|
59
59
|
```
|
60
60
|
|
61
|
-
### Maintain a consistent VM/runtime
|
61
|
+
### `Quickjs::VM`: Maintain a consistent VM/runtime
|
62
62
|
|
63
63
|
```rb
|
64
64
|
vm = Quickjs::VM.new
|
@@ -72,15 +72,20 @@ vm.eval_code('a.b;') #=> "d"
|
|
72
72
|
|
73
73
|
```rb
|
74
74
|
vm = Quickjs::VM.new(
|
75
|
-
memory_limit: 1024
|
76
|
-
max_stack_size: 1024
|
75
|
+
memory_limit: 1024 ** 3,
|
76
|
+
max_stack_size: 1024 ** 2,
|
77
77
|
)
|
78
78
|
```
|
79
79
|
|
80
80
|
```rb
|
81
|
+
# enable std module
|
82
|
+
# https://bellard.org/quickjs/quickjs.html#std-module
|
81
83
|
vm = Quickjs::VM.new(
|
82
84
|
features: [::Quickjs::MODULE_STD],
|
83
85
|
)
|
86
|
+
|
87
|
+
# enable os module
|
88
|
+
# https://bellard.org/quickjs/quickjs.html#os-module
|
84
89
|
vm = Quickjs::VM.new(
|
85
90
|
features: [::Quickjs::MODULE_OS],
|
86
91
|
)
|
@@ -92,6 +97,17 @@ vm = Quickjs::VM.new(
|
|
92
97
|
vm.dispose!
|
93
98
|
```
|
94
99
|
|
100
|
+
#### Define a global function for JS
|
101
|
+
|
102
|
+
```rb
|
103
|
+
vm = Quickjs::VM.new
|
104
|
+
vm.define_function("greetingTo") do |arg1|
|
105
|
+
['Hello!', arg1].join(' ')
|
106
|
+
end
|
107
|
+
|
108
|
+
vm.eval_code("greetingTo('Rick')") #=> 'Hello! Rick'
|
109
|
+
```
|
110
|
+
|
95
111
|
## License
|
96
112
|
|
97
113
|
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).
|
data/ext/quickjsrb/extconf.rb
CHANGED
@@ -0,0 +1,80 @@
|
|
1
|
+
#include "procs.h"
|
2
|
+
|
3
|
+
unsigned int hash(const char *key) {
|
4
|
+
unsigned long int value = 0;
|
5
|
+
unsigned int i = 0;
|
6
|
+
unsigned int key_len = strlen(key);
|
7
|
+
|
8
|
+
for (; i < key_len; ++i) {
|
9
|
+
value = value * 37 + key[i];
|
10
|
+
}
|
11
|
+
return value % MAX_NUM_OF_PROCS;
|
12
|
+
}
|
13
|
+
|
14
|
+
ProcEntry *create_proc_entry(const char *key, VALUE proc) {
|
15
|
+
ProcEntry *entry = malloc(sizeof(ProcEntry));
|
16
|
+
entry->key = strdup(key);
|
17
|
+
entry->proc = proc;
|
18
|
+
entry->next = NULL;
|
19
|
+
return entry;
|
20
|
+
}
|
21
|
+
|
22
|
+
ProcEntryMap *create_proc_entries() {
|
23
|
+
ProcEntryMap *entryMap = malloc(sizeof(ProcEntryMap));
|
24
|
+
entryMap->entries = malloc(sizeof(ProcEntry *) * MAX_NUM_OF_PROCS);
|
25
|
+
for (int i = 0; i < MAX_NUM_OF_PROCS; ++i) {
|
26
|
+
entryMap->entries[i] = NULL;
|
27
|
+
}
|
28
|
+
return entryMap;
|
29
|
+
}
|
30
|
+
|
31
|
+
void set_proc(ProcEntryMap *entryMap, const char *key, VALUE proc) {
|
32
|
+
unsigned int slot = hash(key);
|
33
|
+
ProcEntry *entry = entryMap->entries[slot];
|
34
|
+
|
35
|
+
if (entry == NULL) {
|
36
|
+
entryMap->entries[slot] = create_proc_entry(key, proc);
|
37
|
+
return;
|
38
|
+
}
|
39
|
+
|
40
|
+
ProcEntry *prev;
|
41
|
+
while (entry != NULL) {
|
42
|
+
if (strcmp(entry->key, key) == 0) {
|
43
|
+
entry->proc = proc;
|
44
|
+
return;
|
45
|
+
}
|
46
|
+
prev = entry;
|
47
|
+
entry = prev->next;
|
48
|
+
}
|
49
|
+
|
50
|
+
prev->next = create_proc_entry(key, proc);
|
51
|
+
}
|
52
|
+
|
53
|
+
VALUE get_proc(ProcEntryMap *entryMap, const char *key) {
|
54
|
+
unsigned int slot = hash(key);
|
55
|
+
|
56
|
+
ProcEntry *entry = entryMap->entries[slot];
|
57
|
+
|
58
|
+
while (entry != NULL) {
|
59
|
+
if (strcmp(entry->key, key) == 0) {
|
60
|
+
return entry->proc;
|
61
|
+
}
|
62
|
+
entry = entry->next;
|
63
|
+
}
|
64
|
+
|
65
|
+
return Qnil;
|
66
|
+
}
|
67
|
+
|
68
|
+
void free_proc_entry_map(ProcEntryMap *entryMap) {
|
69
|
+
for (int i = 0; i < MAX_NUM_OF_PROCS; ++i) {
|
70
|
+
ProcEntry *entry = entryMap->entries[i];
|
71
|
+
while (entry != NULL) {
|
72
|
+
ProcEntry *temp = entry;
|
73
|
+
entry = entry->next;
|
74
|
+
free(temp->key);
|
75
|
+
free(temp);
|
76
|
+
}
|
77
|
+
}
|
78
|
+
free(entryMap->entries);
|
79
|
+
free(entryMap);
|
80
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
|
3
|
+
#define MAX_NUM_OF_PROCS 100
|
4
|
+
|
5
|
+
typedef struct ProcEntry {
|
6
|
+
char *key;
|
7
|
+
VALUE proc;
|
8
|
+
struct ProcEntry *next;
|
9
|
+
} ProcEntry;
|
10
|
+
|
11
|
+
typedef struct ProcEntryMap {
|
12
|
+
ProcEntry **entries;
|
13
|
+
} ProcEntryMap;
|
14
|
+
|
15
|
+
ProcEntryMap *create_proc_entries();
|
16
|
+
void set_proc(ProcEntryMap *entryMap, const char *key, VALUE proc);
|
17
|
+
VALUE get_proc(ProcEntryMap *entryMap, const char *key);
|
18
|
+
void free_proc_entry_map(ProcEntryMap *entryMap);
|
data/ext/quickjsrb/quickjsrb.c
CHANGED
@@ -1,5 +1,39 @@
|
|
1
1
|
#include "quickjsrb.h"
|
2
2
|
|
3
|
+
typedef struct VMData {
|
4
|
+
char alive;
|
5
|
+
struct JSContext *context;
|
6
|
+
struct QuickjsrbRuntimeState *state;
|
7
|
+
struct ProcEntryMap *procs;
|
8
|
+
} VMData;
|
9
|
+
|
10
|
+
void vm_free(void* data)
|
11
|
+
{
|
12
|
+
free(data);
|
13
|
+
}
|
14
|
+
|
15
|
+
size_t vm_size(const void* data)
|
16
|
+
{
|
17
|
+
return sizeof(data);
|
18
|
+
}
|
19
|
+
|
20
|
+
static const rb_data_type_t vm_type = {
|
21
|
+
.wrap_struct_name = "vm",
|
22
|
+
.function = {
|
23
|
+
.dmark = NULL,
|
24
|
+
.dfree = vm_free,
|
25
|
+
.dsize = vm_size,
|
26
|
+
},
|
27
|
+
.data = NULL,
|
28
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
29
|
+
};
|
30
|
+
|
31
|
+
VALUE vm_alloc(VALUE self)
|
32
|
+
{
|
33
|
+
VMData *data;
|
34
|
+
return TypedData_Make_Struct(self, VMData, &vm_type, data);
|
35
|
+
}
|
36
|
+
|
3
37
|
VALUE rb_mQuickjs;
|
4
38
|
const char *undefinedId = "undefined";
|
5
39
|
const char *nanId = "NaN";
|
@@ -7,7 +41,63 @@ const char *nanId = "NaN";
|
|
7
41
|
const char *featureStdId = "feature_std";
|
8
42
|
const char *featureOsId = "feature_os";
|
9
43
|
|
10
|
-
|
44
|
+
JSValue to_js_value(JSContext *ctx, VALUE r_value) {
|
45
|
+
switch (TYPE(r_value)) {
|
46
|
+
case T_NIL:
|
47
|
+
return JS_NULL;
|
48
|
+
case T_FIXNUM:
|
49
|
+
case T_FLOAT: {
|
50
|
+
VALUE r_str = rb_funcall(r_value, rb_intern("to_s"), 0, NULL);
|
51
|
+
char *str = StringValueCStr(r_str);
|
52
|
+
JSValue global = JS_GetGlobalObject(ctx);
|
53
|
+
JSValue numberClass = JS_GetPropertyStr(ctx, global, "Number");
|
54
|
+
JSValue j_str = JS_NewString(ctx, str);
|
55
|
+
JSValue stringified = JS_Call(ctx, numberClass, JS_UNDEFINED, 1, &j_str);
|
56
|
+
JS_FreeValue(ctx, global);
|
57
|
+
JS_FreeValue(ctx, numberClass);
|
58
|
+
|
59
|
+
return stringified;
|
60
|
+
}
|
61
|
+
case T_STRING: {
|
62
|
+
char *str = StringValueCStr(r_value);
|
63
|
+
|
64
|
+
return JS_NewString(ctx, str);
|
65
|
+
}
|
66
|
+
case T_SYMBOL: {
|
67
|
+
VALUE r_str = rb_funcall(r_value, rb_intern("to_s"), 0, NULL);
|
68
|
+
char *str = StringValueCStr(r_str);
|
69
|
+
|
70
|
+
return JS_NewString(ctx, str);
|
71
|
+
}
|
72
|
+
case T_TRUE:
|
73
|
+
return JS_TRUE;
|
74
|
+
case T_FALSE:
|
75
|
+
return JS_FALSE;
|
76
|
+
case T_HASH:
|
77
|
+
case T_ARRAY: {
|
78
|
+
VALUE r_json_str = rb_funcall(r_value, rb_intern("to_json"), 0, NULL);
|
79
|
+
char *str = StringValueCStr(r_json_str);
|
80
|
+
JSValue global = JS_GetGlobalObject(ctx);
|
81
|
+
JSValue jsonClass = JS_GetPropertyStr(ctx, global, "JSON");
|
82
|
+
JSValue parseFunc = JS_GetPropertyStr(ctx, jsonClass, "parse");
|
83
|
+
JSValue j_str = JS_NewString(ctx, str);
|
84
|
+
JSValue stringified = JS_Call(ctx, parseFunc, jsonClass, 1, &j_str);
|
85
|
+
JS_FreeValue(ctx, global);
|
86
|
+
JS_FreeValue(ctx, parseFunc);
|
87
|
+
JS_FreeValue(ctx, jsonClass);
|
88
|
+
|
89
|
+
return stringified;
|
90
|
+
}
|
91
|
+
default: {
|
92
|
+
VALUE r_inspect_str = rb_funcall(r_value, rb_intern("inspect"), 0, NULL);
|
93
|
+
char *str = StringValueCStr(r_inspect_str);
|
94
|
+
|
95
|
+
return JS_NewString(ctx, str);
|
96
|
+
}
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
VALUE to_rb_value(JSValue jsv, JSContext *ctx) {
|
11
101
|
switch(JS_VALUE_GET_NORM_TAG(jsv)) {
|
12
102
|
case JS_TAG_INT: {
|
13
103
|
int int_res = 0;
|
@@ -31,6 +121,13 @@ VALUE to_rb_value (JSValue jsv, JSContext *ctx) {
|
|
31
121
|
return rb_str_new2(msg);
|
32
122
|
}
|
33
123
|
case JS_TAG_OBJECT: {
|
124
|
+
int promiseState = JS_PromiseState(ctx, jsv);
|
125
|
+
if (promiseState == JS_PROMISE_FULFILLED || promiseState == JS_PROMISE_PENDING) {
|
126
|
+
return to_rb_value(js_std_await(ctx, jsv), ctx);
|
127
|
+
} else if (promiseState == JS_PROMISE_REJECTED) {
|
128
|
+
return to_rb_value(JS_Throw(ctx, JS_PromiseResult(ctx, jsv)), ctx);
|
129
|
+
}
|
130
|
+
|
34
131
|
JSValue global = JS_GetGlobalObject(ctx);
|
35
132
|
JSValue jsonClass = JS_GetPropertyStr(ctx, global, "JSON");
|
36
133
|
JSValue stringifyFunc = JS_GetPropertyStr(ctx, jsonClass, "stringify");
|
@@ -50,9 +147,28 @@ VALUE to_rb_value (JSValue jsv, JSContext *ctx) {
|
|
50
147
|
return Qnil;
|
51
148
|
case JS_TAG_UNDEFINED:
|
52
149
|
return ID2SYM(rb_intern(undefinedId));
|
53
|
-
case JS_TAG_EXCEPTION:
|
54
|
-
|
150
|
+
case JS_TAG_EXCEPTION: {
|
151
|
+
JSValue exceptionVal = JS_GetException(ctx);
|
152
|
+
if (JS_IsError(ctx, exceptionVal)) {
|
153
|
+
JSValue jsErrorClassName = JS_GetPropertyStr(ctx, exceptionVal, "name");
|
154
|
+
const char *errorClassName = JS_ToCString(ctx, jsErrorClassName);
|
155
|
+
|
156
|
+
JSValue jsErrorClassMessage = JS_GetPropertyStr(ctx, exceptionVal, "message");
|
157
|
+
const char *errorClassMessage = JS_ToCString(ctx, jsErrorClassMessage);
|
158
|
+
|
159
|
+
JS_FreeValue(ctx, jsErrorClassMessage);
|
160
|
+
JS_FreeValue(ctx, jsErrorClassName);
|
161
|
+
|
162
|
+
rb_raise(rb_eRuntimeError, "%s: %s", errorClassName, errorClassMessage);
|
163
|
+
} else {
|
164
|
+
const char *errorMessage = JS_ToCString(ctx, exceptionVal);
|
165
|
+
|
166
|
+
rb_raise(rb_eRuntimeError, "%s", errorMessage);
|
167
|
+
}
|
168
|
+
|
169
|
+
JS_FreeValue(ctx, exceptionVal);
|
55
170
|
return Qnil;
|
171
|
+
}
|
56
172
|
case JS_TAG_BIG_INT: {
|
57
173
|
JSValue toStringFunc = JS_GetPropertyStr(ctx, jsv, "toString");
|
58
174
|
JSValue strigified = JS_Call(ctx, toStringFunc, jsv, 0, NULL);
|
@@ -72,40 +188,22 @@ VALUE to_rb_value (JSValue jsv, JSContext *ctx) {
|
|
72
188
|
}
|
73
189
|
}
|
74
190
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
void qvm_free(void* data)
|
81
|
-
{
|
82
|
-
free(data);
|
83
|
-
}
|
84
|
-
|
85
|
-
size_t qvm_size(const void* data)
|
86
|
-
{
|
87
|
-
return sizeof(data);
|
88
|
-
}
|
89
|
-
|
90
|
-
static const rb_data_type_t qvm_type = {
|
91
|
-
.wrap_struct_name = "qvm",
|
92
|
-
.function = {
|
93
|
-
.dmark = NULL,
|
94
|
-
.dfree = qvm_free,
|
95
|
-
.dsize = qvm_size,
|
96
|
-
},
|
97
|
-
.data = NULL,
|
98
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
99
|
-
};
|
191
|
+
static JSValue js_quickjsrb_call_global(JSContext *ctx, JSValueConst _this, int _argc, JSValueConst *argv) {
|
192
|
+
VMData *data = JS_GetContextOpaque(ctx);
|
193
|
+
JSValue maybeFuncName = JS_ToString(ctx, argv[0]);
|
194
|
+
const char *funcName = JS_ToCString(ctx, maybeFuncName);
|
195
|
+
JS_FreeValue(ctx, maybeFuncName);
|
100
196
|
|
101
|
-
VALUE
|
102
|
-
{
|
103
|
-
|
197
|
+
VALUE proc = get_proc(data->procs, funcName);
|
198
|
+
if (proc == Qnil) { // Shouldn't happen
|
199
|
+
return JS_ThrowReferenceError(ctx, "Proc `%s` is not defined", funcName);
|
200
|
+
}
|
104
201
|
|
105
|
-
|
202
|
+
VALUE r_result = rb_apply(proc, rb_intern("call"), to_rb_value(argv[1], ctx));
|
203
|
+
return to_js_value(ctx, r_result);
|
106
204
|
}
|
107
205
|
|
108
|
-
VALUE
|
206
|
+
VALUE vm_m_initialize(int argc, VALUE* argv, VALUE self)
|
109
207
|
{
|
110
208
|
VALUE r_opts;
|
111
209
|
rb_scan_args(argc, argv, ":", &r_opts);
|
@@ -118,11 +216,14 @@ VALUE qvm_m_initialize(int argc, VALUE* argv, VALUE self)
|
|
118
216
|
VALUE r_features = rb_hash_aref(r_opts, ID2SYM(rb_intern("features")));
|
119
217
|
if (NIL_P(r_features)) r_features = rb_ary_new();
|
120
218
|
|
121
|
-
|
122
|
-
TypedData_Get_Struct(self,
|
219
|
+
VMData *data;
|
220
|
+
TypedData_Get_Struct(self, VMData, &vm_type, data);
|
221
|
+
|
123
222
|
JSRuntime *runtime = JS_NewRuntime();
|
124
223
|
data->context = JS_NewContext(runtime);
|
224
|
+
data->procs = create_proc_entries();
|
125
225
|
data->alive = 1;
|
226
|
+
JS_SetContextOpaque(data->context, data);
|
126
227
|
|
127
228
|
JS_SetMemoryLimit(runtime, NUM2UINT(r_memoryLimit));
|
128
229
|
JS_SetMaxStackSize(runtime, NUM2UINT(r_maxStackSize));
|
@@ -152,13 +253,22 @@ VALUE qvm_m_initialize(int argc, VALUE* argv, VALUE self)
|
|
152
253
|
JS_FreeValue(data->context, osEval);
|
153
254
|
}
|
154
255
|
|
256
|
+
const char *setupGlobalRuby = "globalThis.__ruby = {};\n";
|
257
|
+
JSValue rubyEval = JS_Eval(data->context, setupGlobalRuby, strlen(setupGlobalRuby), "<vm>", JS_EVAL_TYPE_MODULE);
|
258
|
+
JS_FreeValue(data->context, rubyEval);
|
259
|
+
|
260
|
+
JSValue global = JS_GetGlobalObject(data->context);
|
261
|
+
JSValue func = JS_NewCFunction(data->context, js_quickjsrb_call_global, "rubyGlobal", 2);
|
262
|
+
JS_SetPropertyStr(data->context, global, "rubyGlobal", func);
|
263
|
+
JS_FreeValue(data->context, global);
|
264
|
+
|
155
265
|
return self;
|
156
266
|
}
|
157
267
|
|
158
|
-
VALUE
|
268
|
+
VALUE vm_m_evalCode(VALUE self, VALUE r_code)
|
159
269
|
{
|
160
|
-
|
161
|
-
TypedData_Get_Struct(self,
|
270
|
+
VMData *data;
|
271
|
+
TypedData_Get_Struct(self, VMData, &vm_type, data);
|
162
272
|
|
163
273
|
if (data->alive < 1) {
|
164
274
|
rb_raise(rb_eRuntimeError, "Quickjs::VM was disposed");
|
@@ -172,13 +282,43 @@ VALUE qvm_m_evalCode(VALUE self, VALUE r_code)
|
|
172
282
|
return result;
|
173
283
|
}
|
174
284
|
|
175
|
-
VALUE
|
285
|
+
VALUE vm_m_defineGlobalFunction(VALUE self, VALUE r_name)
|
286
|
+
{
|
287
|
+
rb_need_block();
|
288
|
+
|
289
|
+
VMData *data;
|
290
|
+
TypedData_Get_Struct(self, VMData, &vm_type, data);
|
291
|
+
|
292
|
+
if (rb_block_given_p()) {
|
293
|
+
VALUE proc = rb_block_proc();
|
294
|
+
|
295
|
+
char *funcName = StringValueCStr(r_name);
|
296
|
+
|
297
|
+
set_proc(data->procs, funcName, proc);
|
298
|
+
|
299
|
+
const char* template = "globalThis.__ruby['%s'] = (...args) => rubyGlobal('%s', args);\nglobalThis['%s'] = globalThis.__ruby['%s'];\n";
|
300
|
+
int length = snprintf(NULL, 0, template, funcName, funcName, funcName, funcName);
|
301
|
+
char* result = (char*)malloc(length + 1);
|
302
|
+
snprintf(result, length + 1, template, funcName, funcName, funcName, funcName);
|
303
|
+
|
304
|
+
JSValue codeResult = JS_Eval(data->context, result, strlen(result), "<vm>", JS_EVAL_TYPE_MODULE);
|
305
|
+
|
306
|
+
JS_FreeValue(data->context, codeResult);
|
307
|
+
free(result);
|
308
|
+
return rb_funcall(r_name, rb_intern("to_sym"), 0, NULL);
|
309
|
+
}
|
310
|
+
|
311
|
+
return Qnil;
|
312
|
+
}
|
313
|
+
|
314
|
+
VALUE vm_m_dispose(VALUE self)
|
176
315
|
{
|
177
|
-
|
178
|
-
TypedData_Get_Struct(self,
|
316
|
+
VMData *data;
|
317
|
+
TypedData_Get_Struct(self, VMData, &vm_type, data);
|
179
318
|
|
180
319
|
JSRuntime *runtime = JS_GetRuntime(data->context);
|
181
320
|
js_std_free_handlers(runtime);
|
321
|
+
free_proc_entry_map(data->procs);
|
182
322
|
JS_FreeContext(data->context);
|
183
323
|
JS_FreeRuntime(runtime);
|
184
324
|
data->alive = 0;
|
@@ -198,8 +338,9 @@ Init_quickjsrb(void)
|
|
198
338
|
rb_define_const(valueClass, "NAN", ID2SYM(rb_intern(nanId)));
|
199
339
|
|
200
340
|
VALUE vmClass = rb_define_class_under(rb_mQuickjs, "VM", rb_cObject);
|
201
|
-
rb_define_alloc_func(vmClass,
|
202
|
-
rb_define_method(vmClass, "initialize",
|
203
|
-
rb_define_method(vmClass, "eval_code",
|
204
|
-
rb_define_method(vmClass, "
|
341
|
+
rb_define_alloc_func(vmClass, vm_alloc);
|
342
|
+
rb_define_method(vmClass, "initialize", vm_m_initialize, -1);
|
343
|
+
rb_define_method(vmClass, "eval_code", vm_m_evalCode, 1);
|
344
|
+
rb_define_method(vmClass, "define_function", vm_m_defineGlobalFunction, 1);
|
345
|
+
rb_define_method(vmClass, "dispose!", vm_m_dispose, 0);
|
205
346
|
}
|
data/ext/quickjsrb/quickjsrb.h
CHANGED
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.7
|
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-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -37,6 +37,8 @@ files:
|
|
37
37
|
- README.md
|
38
38
|
- Rakefile
|
39
39
|
- ext/quickjsrb/extconf.rb
|
40
|
+
- ext/quickjsrb/procs.c
|
41
|
+
- ext/quickjsrb/procs.h
|
40
42
|
- ext/quickjsrb/quickjs/LICENSE
|
41
43
|
- ext/quickjsrb/quickjs/cutils.c
|
42
44
|
- ext/quickjsrb/quickjs/cutils.h
|