quickjs 0.1.8 → 0.1.9
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 +0 -1
- data/ext/quickjsrb/quickjsrb.c +42 -21
- data/ext/quickjsrb/quickjsrb.h +0 -2
- data/lib/quickjs/version.rb +1 -1
- metadata +2 -4
- data/ext/quickjsrb/procs.c +0 -80
- data/ext/quickjsrb/procs.h +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f0461f98dbe3171e88609b060aa9fb414ba881b0977d983d6ec7897726a0559c
|
4
|
+
data.tar.gz: 84ed4cf19c1d5191e9cd57b789cc3138691f7ad2059b515a2ce4280051105c46
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c98d7daf116e5513a19b99e4ef387f3b1b60389c3bb9f91822cc1d437bf87cc72041cd97c7cdf2a8a8cb55a86df93a3cf7fe472733017ae4a315831397a56cd5
|
7
|
+
data.tar.gz: f177d0e31b8d6499fcf922bd85dc594aa2acd0bf8d93d696256c4a3a7a1595eeb874df7e14e8447694a3045b3f2b9d8279633550e535fc8f257311c613c043b6
|
data/ext/quickjsrb/extconf.rb
CHANGED
data/ext/quickjsrb/quickjsrb.c
CHANGED
@@ -8,13 +8,15 @@ typedef struct EvalTime {
|
|
8
8
|
typedef struct VMData {
|
9
9
|
char alive;
|
10
10
|
struct JSContext *context;
|
11
|
-
|
11
|
+
VALUE defined_functions;
|
12
12
|
struct EvalTime *eval_time;
|
13
13
|
} VMData;
|
14
14
|
|
15
|
-
void vm_free(void*
|
15
|
+
static void vm_free(void* ptr)
|
16
16
|
{
|
17
|
-
|
17
|
+
VMData *data = (VMData *)ptr;
|
18
|
+
free(data->eval_time);
|
19
|
+
xfree(ptr);
|
18
20
|
}
|
19
21
|
|
20
22
|
size_t vm_size(const void* data)
|
@@ -22,10 +24,16 @@ size_t vm_size(const void* data)
|
|
22
24
|
return sizeof(data);
|
23
25
|
}
|
24
26
|
|
27
|
+
static void vm_mark(void *ptr)
|
28
|
+
{
|
29
|
+
VMData *data = (VMData *)ptr;
|
30
|
+
rb_gc_mark_movable(data->defined_functions);
|
31
|
+
}
|
32
|
+
|
25
33
|
static const rb_data_type_t vm_type = {
|
26
|
-
.wrap_struct_name = "
|
34
|
+
.wrap_struct_name = "quickjsvm",
|
27
35
|
.function = {
|
28
|
-
.dmark =
|
36
|
+
.dmark = vm_mark,
|
29
37
|
.dfree = vm_free,
|
30
38
|
.dsize = vm_size,
|
31
39
|
},
|
@@ -33,10 +41,16 @@ static const rb_data_type_t vm_type = {
|
|
33
41
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
34
42
|
};
|
35
43
|
|
36
|
-
VALUE vm_alloc(VALUE self)
|
44
|
+
static VALUE vm_alloc(VALUE self)
|
37
45
|
{
|
38
46
|
VMData *data;
|
39
|
-
|
47
|
+
VALUE obj = TypedData_Make_Struct(self, VMData, &vm_type, data);
|
48
|
+
data->defined_functions = rb_hash_new();
|
49
|
+
|
50
|
+
EvalTime *eval_time = malloc(sizeof(EvalTime));
|
51
|
+
data->eval_time = eval_time;
|
52
|
+
|
53
|
+
return obj;
|
40
54
|
}
|
41
55
|
|
42
56
|
VALUE rb_mQuickjs;
|
@@ -60,6 +74,7 @@ JSValue to_js_value(JSContext *ctx, VALUE r_value) {
|
|
60
74
|
JSValue stringified = JS_Call(ctx, numberClass, JS_UNDEFINED, 1, &j_str);
|
61
75
|
JS_FreeValue(ctx, global);
|
62
76
|
JS_FreeValue(ctx, numberClass);
|
77
|
+
JS_FreeValue(ctx, j_str);
|
63
78
|
|
64
79
|
return stringified;
|
65
80
|
}
|
@@ -88,8 +103,9 @@ JSValue to_js_value(JSContext *ctx, VALUE r_value) {
|
|
88
103
|
JSValue j_str = JS_NewString(ctx, str);
|
89
104
|
JSValue stringified = JS_Call(ctx, parseFunc, jsonClass, 1, &j_str);
|
90
105
|
JS_FreeValue(ctx, global);
|
91
|
-
JS_FreeValue(ctx, parseFunc);
|
92
106
|
JS_FreeValue(ctx, jsonClass);
|
107
|
+
JS_FreeValue(ctx, parseFunc);
|
108
|
+
JS_FreeValue(ctx, j_str);
|
93
109
|
|
94
110
|
return stringified;
|
95
111
|
}
|
@@ -123,14 +139,23 @@ VALUE to_rb_value(JSValue jsv, JSContext *ctx) {
|
|
123
139
|
case JS_TAG_STRING: {
|
124
140
|
JSValue maybeString = JS_ToString(ctx, jsv);
|
125
141
|
const char *msg = JS_ToCString(ctx, maybeString);
|
142
|
+
JS_FreeValue(ctx, maybeString);
|
126
143
|
return rb_str_new2(msg);
|
127
144
|
}
|
128
145
|
case JS_TAG_OBJECT: {
|
129
146
|
int promiseState = JS_PromiseState(ctx, jsv);
|
130
147
|
if (promiseState == JS_PROMISE_FULFILLED || promiseState == JS_PROMISE_PENDING) {
|
131
|
-
|
148
|
+
JSValue awaited = js_std_await(ctx, jsv);
|
149
|
+
VALUE rb_awaited = to_rb_value(awaited, ctx); // TODO: should have timeout
|
150
|
+
JS_FreeValue(ctx, awaited);
|
151
|
+
return rb_awaited;
|
132
152
|
} else if (promiseState == JS_PROMISE_REJECTED) {
|
133
|
-
|
153
|
+
JSValue promiseResult = JS_PromiseResult(ctx, jsv);
|
154
|
+
JSValue throw = JS_Throw(ctx, promiseResult);
|
155
|
+
JS_FreeValue(ctx, promiseResult);
|
156
|
+
VALUE rb_errored = to_rb_value(throw, ctx);
|
157
|
+
JS_FreeValue(ctx, throw);
|
158
|
+
return rb_errored;
|
134
159
|
}
|
135
160
|
|
136
161
|
JSValue global = JS_GetGlobalObject(ctx);
|
@@ -199,16 +224,17 @@ static JSValue js_quickjsrb_call_global(JSContext *ctx, JSValueConst _this, int
|
|
199
224
|
const char *funcName = JS_ToCString(ctx, maybeFuncName);
|
200
225
|
JS_FreeValue(ctx, maybeFuncName);
|
201
226
|
|
202
|
-
VALUE proc =
|
227
|
+
VALUE proc = rb_hash_aref(data->defined_functions, rb_str_new2(funcName));
|
203
228
|
if (proc == Qnil) { // Shouldn't happen
|
204
229
|
return JS_ThrowReferenceError(ctx, "Proc `%s` is not defined", funcName);
|
205
230
|
}
|
206
231
|
|
232
|
+
// TODO: cover timeout for calling proc
|
207
233
|
VALUE r_result = rb_apply(proc, rb_intern("call"), to_rb_value(argv[1], ctx));
|
208
234
|
return to_js_value(ctx, r_result);
|
209
235
|
}
|
210
236
|
|
211
|
-
VALUE vm_m_initialize(int argc, VALUE* argv, VALUE self)
|
237
|
+
static VALUE vm_m_initialize(int argc, VALUE* argv, VALUE self)
|
212
238
|
{
|
213
239
|
VALUE r_opts;
|
214
240
|
rb_scan_args(argc, argv, ":", &r_opts);
|
@@ -228,10 +254,6 @@ VALUE vm_m_initialize(int argc, VALUE* argv, VALUE self)
|
|
228
254
|
|
229
255
|
JSRuntime *runtime = JS_NewRuntime();
|
230
256
|
data->context = JS_NewContext(runtime);
|
231
|
-
data->procs = create_proc_entries();
|
232
|
-
|
233
|
-
EvalTime *eval_time = malloc(sizeof(EvalTime));
|
234
|
-
data->eval_time = eval_time;
|
235
257
|
data->eval_time->limit = (clock_t)(CLOCKS_PER_SEC * NUM2UINT(r_timeout_msec) / 1000);
|
236
258
|
data->alive = 1;
|
237
259
|
JS_SetContextOpaque(data->context, data);
|
@@ -281,7 +303,7 @@ static int interrupt_handler(JSRuntime *runtime, void *opaque) {
|
|
281
303
|
return clock() >= eval_time->started_at + eval_time->limit ? 1 : 0;
|
282
304
|
}
|
283
305
|
|
284
|
-
VALUE vm_m_evalCode(VALUE self, VALUE r_code)
|
306
|
+
static VALUE vm_m_evalCode(VALUE self, VALUE r_code)
|
285
307
|
{
|
286
308
|
VMData *data;
|
287
309
|
TypedData_Get_Struct(self, VMData, &vm_type, data);
|
@@ -302,7 +324,7 @@ VALUE vm_m_evalCode(VALUE self, VALUE r_code)
|
|
302
324
|
return result;
|
303
325
|
}
|
304
326
|
|
305
|
-
VALUE vm_m_defineGlobalFunction(VALUE self, VALUE r_name)
|
327
|
+
static VALUE vm_m_defineGlobalFunction(VALUE self, VALUE r_name)
|
306
328
|
{
|
307
329
|
rb_need_block();
|
308
330
|
|
@@ -314,7 +336,7 @@ VALUE vm_m_defineGlobalFunction(VALUE self, VALUE r_name)
|
|
314
336
|
|
315
337
|
char *funcName = StringValueCStr(r_name);
|
316
338
|
|
317
|
-
|
339
|
+
rb_hash_aset(data->defined_functions, r_name, proc);
|
318
340
|
|
319
341
|
const char* template = "globalThis.__ruby['%s'] = (...args) => rubyGlobal('%s', args);\nglobalThis['%s'] = globalThis.__ruby['%s'];\n";
|
320
342
|
int length = snprintf(NULL, 0, template, funcName, funcName, funcName, funcName);
|
@@ -331,7 +353,7 @@ VALUE vm_m_defineGlobalFunction(VALUE self, VALUE r_name)
|
|
331
353
|
return Qnil;
|
332
354
|
}
|
333
355
|
|
334
|
-
VALUE vm_m_dispose(VALUE self)
|
356
|
+
static VALUE vm_m_dispose(VALUE self)
|
335
357
|
{
|
336
358
|
VMData *data;
|
337
359
|
TypedData_Get_Struct(self, VMData, &vm_type, data);
|
@@ -339,7 +361,6 @@ VALUE vm_m_dispose(VALUE self)
|
|
339
361
|
JSRuntime *runtime = JS_GetRuntime(data->context);
|
340
362
|
JS_SetInterruptHandler(runtime, NULL, NULL);
|
341
363
|
js_std_free_handlers(runtime);
|
342
|
-
free_proc_entry_map(data->procs);
|
343
364
|
JS_FreeContext(data->context);
|
344
365
|
JS_FreeRuntime(runtime);
|
345
366
|
data->alive = 0;
|
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.9
|
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-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -37,8 +37,6 @@ files:
|
|
37
37
|
- README.md
|
38
38
|
- Rakefile
|
39
39
|
- ext/quickjsrb/extconf.rb
|
40
|
-
- ext/quickjsrb/procs.c
|
41
|
-
- ext/quickjsrb/procs.h
|
42
40
|
- ext/quickjsrb/quickjs/LICENSE
|
43
41
|
- ext/quickjsrb/quickjs/cutils.c
|
44
42
|
- ext/quickjsrb/quickjs/cutils.h
|
data/ext/quickjsrb/procs.c
DELETED
@@ -1,80 +0,0 @@
|
|
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
|
-
}
|
data/ext/quickjsrb/procs.h
DELETED
@@ -1,18 +0,0 @@
|
|
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);
|