js 0.0.1 → 2.5.0
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 +7 -0
- data/ext/js/bindgen/.clang-format +2 -0
- data/ext/js/bindgen/rb-js-abi-host.c +342 -0
- data/ext/js/bindgen/rb-js-abi-host.h +82 -0
- data/ext/js/bindgen/rb-js-abi-host.wit +47 -0
- data/ext/js/depend +10 -0
- data/ext/js/extconf.rb +3 -0
- data/ext/js/js-core.c +577 -0
- data/ext/witapi/bindgen/.clang-format +2 -0
- data/ext/witapi/bindgen/rb-abi-guest.c +222 -0
- data/ext/witapi/bindgen/rb-abi-guest.h +77 -0
- data/ext/witapi/bindgen/rb-abi-guest.wit +25 -0
- data/ext/witapi/depend +11 -0
- data/ext/witapi/extconf.rb +3 -0
- data/ext/witapi/witapi-core.c +325 -0
- data/js.gemspec +26 -16
- data/lib/js/array.rb +9 -0
- data/lib/js/hash.rb +8 -0
- data/lib/js/nil_class.rb +6 -0
- data/lib/js/require_remote/evaluator.rb +15 -0
- data/lib/js/require_remote/url_resolver.rb +45 -0
- data/lib/js/require_remote.rb +85 -0
- data/lib/js/version.rb +2 -2
- data/lib/js.rb +238 -3
- metadata +39 -22
- data/.gitignore +0 -17
- data/Gemfile +0 -4
- data/LICENSE.txt +0 -22
- data/README.md +0 -35
- data/Rakefile +0 -1
@@ -0,0 +1,222 @@
|
|
1
|
+
#include <stdlib.h>
|
2
|
+
#include <rb-abi-guest.h>
|
3
|
+
|
4
|
+
__attribute__((weak, export_name("cabi_realloc")))
|
5
|
+
void *cabi_realloc(
|
6
|
+
void *ptr,
|
7
|
+
size_t orig_size,
|
8
|
+
size_t org_align,
|
9
|
+
size_t new_size
|
10
|
+
) {
|
11
|
+
void *ret = realloc(ptr, new_size);
|
12
|
+
if (!ret)
|
13
|
+
abort();
|
14
|
+
return ret;
|
15
|
+
}
|
16
|
+
|
17
|
+
__attribute__((import_module("canonical_abi"), import_name("resource_drop_rb-iseq")))
|
18
|
+
void __resource_rb_iseq_drop(uint32_t idx);
|
19
|
+
|
20
|
+
void rb_abi_guest_rb_iseq_free(rb_abi_guest_rb_iseq_t *ptr) {
|
21
|
+
__resource_rb_iseq_drop(ptr->idx);
|
22
|
+
}
|
23
|
+
|
24
|
+
__attribute__((import_module("canonical_abi"), import_name("resource_clone_rb-iseq")))
|
25
|
+
uint32_t __resource_rb_iseq_clone(uint32_t idx);
|
26
|
+
|
27
|
+
rb_abi_guest_rb_iseq_t rb_abi_guest_rb_iseq_clone(rb_abi_guest_rb_iseq_t *ptr) {
|
28
|
+
return (rb_abi_guest_rb_iseq_t){__resource_rb_iseq_clone(ptr->idx)};
|
29
|
+
}
|
30
|
+
|
31
|
+
__attribute__((import_module("canonical_abi"), import_name("resource_new_rb-iseq")))
|
32
|
+
uint32_t __resource_rb_iseq_new(uint32_t val);
|
33
|
+
|
34
|
+
rb_abi_guest_rb_iseq_t rb_abi_guest_rb_iseq_new(void *data) {
|
35
|
+
return (rb_abi_guest_rb_iseq_t){__resource_rb_iseq_new((uint32_t) data)};
|
36
|
+
}
|
37
|
+
|
38
|
+
__attribute__((import_module("canonical_abi"), import_name("resource_get_rb-iseq")))
|
39
|
+
uint32_t __resource_rb_iseq_get(uint32_t idx);
|
40
|
+
|
41
|
+
void* rb_abi_guest_rb_iseq_get(rb_abi_guest_rb_iseq_t *ptr) {
|
42
|
+
return (void*) __resource_rb_iseq_get(ptr->idx);
|
43
|
+
}
|
44
|
+
|
45
|
+
__attribute__((export_name("canonical_abi_drop_rb-iseq")))
|
46
|
+
void __resource_rb_iseq_dtor(uint32_t val) {
|
47
|
+
if (rb_abi_guest_rb_iseq_dtor)
|
48
|
+
rb_abi_guest_rb_iseq_dtor((void*) val);
|
49
|
+
}
|
50
|
+
|
51
|
+
__attribute__((import_module("canonical_abi"), import_name("resource_drop_rb-abi-value")))
|
52
|
+
void __resource_rb_abi_value_drop(uint32_t idx);
|
53
|
+
|
54
|
+
void rb_abi_guest_rb_abi_value_free(rb_abi_guest_rb_abi_value_t *ptr) {
|
55
|
+
__resource_rb_abi_value_drop(ptr->idx);
|
56
|
+
}
|
57
|
+
|
58
|
+
__attribute__((import_module("canonical_abi"), import_name("resource_clone_rb-abi-value")))
|
59
|
+
uint32_t __resource_rb_abi_value_clone(uint32_t idx);
|
60
|
+
|
61
|
+
rb_abi_guest_rb_abi_value_t rb_abi_guest_rb_abi_value_clone(rb_abi_guest_rb_abi_value_t *ptr) {
|
62
|
+
return (rb_abi_guest_rb_abi_value_t){__resource_rb_abi_value_clone(ptr->idx)};
|
63
|
+
}
|
64
|
+
|
65
|
+
__attribute__((import_module("canonical_abi"), import_name("resource_new_rb-abi-value")))
|
66
|
+
uint32_t __resource_rb_abi_value_new(uint32_t val);
|
67
|
+
|
68
|
+
rb_abi_guest_rb_abi_value_t rb_abi_guest_rb_abi_value_new(void *data) {
|
69
|
+
return (rb_abi_guest_rb_abi_value_t){__resource_rb_abi_value_new((uint32_t) data)};
|
70
|
+
}
|
71
|
+
|
72
|
+
__attribute__((import_module("canonical_abi"), import_name("resource_get_rb-abi-value")))
|
73
|
+
uint32_t __resource_rb_abi_value_get(uint32_t idx);
|
74
|
+
|
75
|
+
void* rb_abi_guest_rb_abi_value_get(rb_abi_guest_rb_abi_value_t *ptr) {
|
76
|
+
return (void*) __resource_rb_abi_value_get(ptr->idx);
|
77
|
+
}
|
78
|
+
|
79
|
+
__attribute__((export_name("canonical_abi_drop_rb-abi-value")))
|
80
|
+
void __resource_rb_abi_value_dtor(uint32_t val) {
|
81
|
+
if (rb_abi_guest_rb_abi_value_dtor)
|
82
|
+
rb_abi_guest_rb_abi_value_dtor((void*) val);
|
83
|
+
}
|
84
|
+
#include <string.h>
|
85
|
+
|
86
|
+
void rb_abi_guest_string_set(rb_abi_guest_string_t *ret, const char *s) {
|
87
|
+
ret->ptr = (char*) s;
|
88
|
+
ret->len = strlen(s);
|
89
|
+
}
|
90
|
+
|
91
|
+
void rb_abi_guest_string_dup(rb_abi_guest_string_t *ret, const char *s) {
|
92
|
+
ret->len = strlen(s);
|
93
|
+
ret->ptr = cabi_realloc(NULL, 0, 1, ret->len);
|
94
|
+
memcpy(ret->ptr, s, ret->len);
|
95
|
+
}
|
96
|
+
|
97
|
+
void rb_abi_guest_string_free(rb_abi_guest_string_t *ret) {
|
98
|
+
if (ret->len > 0) {
|
99
|
+
free(ret->ptr);
|
100
|
+
}
|
101
|
+
ret->ptr = NULL;
|
102
|
+
ret->len = 0;
|
103
|
+
}
|
104
|
+
void rb_abi_guest_list_string_free(rb_abi_guest_list_string_t *ptr) {
|
105
|
+
for (size_t i = 0; i < ptr->len; i++) {
|
106
|
+
rb_abi_guest_string_free(&ptr->ptr[i]);
|
107
|
+
}
|
108
|
+
if (ptr->len > 0) {
|
109
|
+
free(ptr->ptr);
|
110
|
+
}
|
111
|
+
}
|
112
|
+
void rb_abi_guest_tuple2_rb_abi_value_s32_free(rb_abi_guest_tuple2_rb_abi_value_s32_t *ptr) {
|
113
|
+
rb_abi_guest_rb_abi_value_free(&ptr->f0);
|
114
|
+
}
|
115
|
+
void rb_abi_guest_list_rb_abi_value_free(rb_abi_guest_list_rb_abi_value_t *ptr) {
|
116
|
+
for (size_t i = 0; i < ptr->len; i++) {
|
117
|
+
rb_abi_guest_rb_abi_value_free(&ptr->ptr[i]);
|
118
|
+
}
|
119
|
+
if (ptr->len > 0) {
|
120
|
+
free(ptr->ptr);
|
121
|
+
}
|
122
|
+
}
|
123
|
+
|
124
|
+
__attribute__((aligned(4)))
|
125
|
+
static uint8_t RET_AREA[8];
|
126
|
+
__attribute__((export_name("ruby-show-version: func() -> ()")))
|
127
|
+
void __wasm_export_rb_abi_guest_ruby_show_version(void) {
|
128
|
+
rb_abi_guest_ruby_show_version();
|
129
|
+
}
|
130
|
+
__attribute__((export_name("ruby-init: func() -> ()")))
|
131
|
+
void __wasm_export_rb_abi_guest_ruby_init(void) {
|
132
|
+
rb_abi_guest_ruby_init();
|
133
|
+
}
|
134
|
+
__attribute__((export_name("ruby-sysinit: func(args: list<string>) -> ()")))
|
135
|
+
void __wasm_export_rb_abi_guest_ruby_sysinit(int32_t arg, int32_t arg0) {
|
136
|
+
rb_abi_guest_list_string_t arg1 = (rb_abi_guest_list_string_t) { (rb_abi_guest_string_t*)(arg), (size_t)(arg0) };
|
137
|
+
rb_abi_guest_ruby_sysinit(&arg1);
|
138
|
+
}
|
139
|
+
__attribute__((export_name("ruby-options: func(args: list<string>) -> handle<rb-iseq>")))
|
140
|
+
int32_t __wasm_export_rb_abi_guest_ruby_options(int32_t arg, int32_t arg0) {
|
141
|
+
rb_abi_guest_list_string_t arg1 = (rb_abi_guest_list_string_t) { (rb_abi_guest_string_t*)(arg), (size_t)(arg0) };
|
142
|
+
rb_abi_guest_rb_iseq_t ret = rb_abi_guest_ruby_options(&arg1);
|
143
|
+
return (ret).idx;
|
144
|
+
}
|
145
|
+
__attribute__((export_name("ruby-script: func(name: string) -> ()")))
|
146
|
+
void __wasm_export_rb_abi_guest_ruby_script(int32_t arg, int32_t arg0) {
|
147
|
+
rb_abi_guest_string_t arg1 = (rb_abi_guest_string_t) { (char*)(arg), (size_t)(arg0) };
|
148
|
+
rb_abi_guest_ruby_script(&arg1);
|
149
|
+
}
|
150
|
+
__attribute__((export_name("ruby-init-loadpath: func() -> ()")))
|
151
|
+
void __wasm_export_rb_abi_guest_ruby_init_loadpath(void) {
|
152
|
+
rb_abi_guest_ruby_init_loadpath();
|
153
|
+
}
|
154
|
+
__attribute__((export_name("rb-eval-string-protect: func(str: string) -> tuple<handle<rb-abi-value>, s32>")))
|
155
|
+
int32_t __wasm_export_rb_abi_guest_rb_eval_string_protect(int32_t arg, int32_t arg0) {
|
156
|
+
rb_abi_guest_string_t arg1 = (rb_abi_guest_string_t) { (char*)(arg), (size_t)(arg0) };
|
157
|
+
rb_abi_guest_tuple2_rb_abi_value_s32_t ret;
|
158
|
+
rb_abi_guest_rb_eval_string_protect(&arg1, &ret);
|
159
|
+
int32_t ptr = (int32_t) &RET_AREA;
|
160
|
+
*((int32_t*)(ptr + 0)) = ((ret).f0).idx;
|
161
|
+
*((int32_t*)(ptr + 4)) = (ret).f1;
|
162
|
+
return ptr;
|
163
|
+
}
|
164
|
+
__attribute__((export_name("rb-funcallv-protect: func(recv: handle<rb-abi-value>, mid: u32, args: list<handle<rb-abi-value>>) -> tuple<handle<rb-abi-value>, s32>")))
|
165
|
+
int32_t __wasm_export_rb_abi_guest_rb_funcallv_protect(int32_t arg, int32_t arg0, int32_t arg1, int32_t arg2) {
|
166
|
+
rb_abi_guest_list_rb_abi_value_t arg3 = (rb_abi_guest_list_rb_abi_value_t) { (rb_abi_guest_rb_abi_value_t*)(arg1), (size_t)(arg2) };
|
167
|
+
rb_abi_guest_tuple2_rb_abi_value_s32_t ret;
|
168
|
+
rb_abi_guest_rb_funcallv_protect((rb_abi_guest_rb_abi_value_t){ arg }, (uint32_t) (arg0), &arg3, &ret);
|
169
|
+
int32_t ptr = (int32_t) &RET_AREA;
|
170
|
+
*((int32_t*)(ptr + 0)) = ((ret).f0).idx;
|
171
|
+
*((int32_t*)(ptr + 4)) = (ret).f1;
|
172
|
+
return ptr;
|
173
|
+
}
|
174
|
+
__attribute__((export_name("rb-intern: func(name: string) -> u32")))
|
175
|
+
int32_t __wasm_export_rb_abi_guest_rb_intern(int32_t arg, int32_t arg0) {
|
176
|
+
rb_abi_guest_string_t arg1 = (rb_abi_guest_string_t) { (char*)(arg), (size_t)(arg0) };
|
177
|
+
rb_abi_guest_rb_id_t ret = rb_abi_guest_rb_intern(&arg1);
|
178
|
+
return (int32_t) (ret);
|
179
|
+
}
|
180
|
+
__attribute__((export_name("rb-errinfo: func() -> handle<rb-abi-value>")))
|
181
|
+
int32_t __wasm_export_rb_abi_guest_rb_errinfo(void) {
|
182
|
+
rb_abi_guest_rb_abi_value_t ret = rb_abi_guest_rb_errinfo();
|
183
|
+
return (ret).idx;
|
184
|
+
}
|
185
|
+
__attribute__((export_name("rb-clear-errinfo: func() -> ()")))
|
186
|
+
void __wasm_export_rb_abi_guest_rb_clear_errinfo(void) {
|
187
|
+
rb_abi_guest_rb_clear_errinfo();
|
188
|
+
}
|
189
|
+
__attribute__((export_name("rstring-ptr: func(value: handle<rb-abi-value>) -> string")))
|
190
|
+
int32_t __wasm_export_rb_abi_guest_rstring_ptr(int32_t arg) {
|
191
|
+
rb_abi_guest_string_t ret;
|
192
|
+
rb_abi_guest_rstring_ptr((rb_abi_guest_rb_abi_value_t){ arg }, &ret);
|
193
|
+
int32_t ptr = (int32_t) &RET_AREA;
|
194
|
+
*((int32_t*)(ptr + 4)) = (int32_t) (ret).len;
|
195
|
+
*((int32_t*)(ptr + 0)) = (int32_t) (ret).ptr;
|
196
|
+
return ptr;
|
197
|
+
}
|
198
|
+
__attribute__((export_name("cabi_post_rstring-ptr")))
|
199
|
+
void __wasm_export_rb_abi_guest_rstring_ptr_post_return(int32_t arg0) {
|
200
|
+
if ((*((int32_t*) (arg0 + 4))) > 0) {
|
201
|
+
free((void*) (*((int32_t*) (arg0 + 0))));
|
202
|
+
}
|
203
|
+
}
|
204
|
+
__attribute__((export_name("rb-vm-bugreport: func() -> ()")))
|
205
|
+
void __wasm_export_rb_abi_guest_rb_vm_bugreport(void) {
|
206
|
+
rb_abi_guest_rb_vm_bugreport();
|
207
|
+
}
|
208
|
+
__attribute__((export_name("rb-gc-enable: func() -> bool")))
|
209
|
+
int32_t __wasm_export_rb_abi_guest_rb_gc_enable(void) {
|
210
|
+
bool ret = rb_abi_guest_rb_gc_enable();
|
211
|
+
return ret;
|
212
|
+
}
|
213
|
+
__attribute__((export_name("rb-gc-disable: func() -> bool")))
|
214
|
+
int32_t __wasm_export_rb_abi_guest_rb_gc_disable(void) {
|
215
|
+
bool ret = rb_abi_guest_rb_gc_disable();
|
216
|
+
return ret;
|
217
|
+
}
|
218
|
+
__attribute__((export_name("rb-set-should-prohibit-rewind: func(new-value: bool) -> bool")))
|
219
|
+
int32_t __wasm_export_rb_abi_guest_rb_set_should_prohibit_rewind(int32_t arg) {
|
220
|
+
bool ret = rb_abi_guest_rb_set_should_prohibit_rewind(arg);
|
221
|
+
return ret;
|
222
|
+
}
|
@@ -0,0 +1,77 @@
|
|
1
|
+
#ifndef __BINDINGS_RB_ABI_GUEST_H
|
2
|
+
#define __BINDINGS_RB_ABI_GUEST_H
|
3
|
+
#ifdef __cplusplus
|
4
|
+
extern "C"
|
5
|
+
{
|
6
|
+
#endif
|
7
|
+
|
8
|
+
#include <stdint.h>
|
9
|
+
#include <stdbool.h>
|
10
|
+
|
11
|
+
typedef struct {
|
12
|
+
uint32_t idx;
|
13
|
+
} rb_abi_guest_rb_iseq_t;
|
14
|
+
void rb_abi_guest_rb_iseq_free(rb_abi_guest_rb_iseq_t *ptr);
|
15
|
+
rb_abi_guest_rb_iseq_t rb_abi_guest_rb_iseq_clone(rb_abi_guest_rb_iseq_t *ptr);
|
16
|
+
rb_abi_guest_rb_iseq_t rb_abi_guest_rb_iseq_new(void *data);
|
17
|
+
void* rb_abi_guest_rb_iseq_get(rb_abi_guest_rb_iseq_t *ptr);
|
18
|
+
|
19
|
+
__attribute__((weak))
|
20
|
+
void rb_abi_guest_rb_iseq_dtor(void *data);
|
21
|
+
|
22
|
+
typedef struct {
|
23
|
+
uint32_t idx;
|
24
|
+
} rb_abi_guest_rb_abi_value_t;
|
25
|
+
void rb_abi_guest_rb_abi_value_free(rb_abi_guest_rb_abi_value_t *ptr);
|
26
|
+
rb_abi_guest_rb_abi_value_t rb_abi_guest_rb_abi_value_clone(rb_abi_guest_rb_abi_value_t *ptr);
|
27
|
+
rb_abi_guest_rb_abi_value_t rb_abi_guest_rb_abi_value_new(void *data);
|
28
|
+
void* rb_abi_guest_rb_abi_value_get(rb_abi_guest_rb_abi_value_t *ptr);
|
29
|
+
|
30
|
+
__attribute__((weak))
|
31
|
+
void rb_abi_guest_rb_abi_value_dtor(void *data);
|
32
|
+
|
33
|
+
typedef struct {
|
34
|
+
char *ptr;
|
35
|
+
size_t len;
|
36
|
+
} rb_abi_guest_string_t;
|
37
|
+
|
38
|
+
void rb_abi_guest_string_set(rb_abi_guest_string_t *ret, const char *s);
|
39
|
+
void rb_abi_guest_string_dup(rb_abi_guest_string_t *ret, const char *s);
|
40
|
+
void rb_abi_guest_string_free(rb_abi_guest_string_t *ret);
|
41
|
+
typedef int32_t rb_abi_guest_rb_errno_t;
|
42
|
+
typedef uint32_t rb_abi_guest_rb_id_t;
|
43
|
+
typedef struct {
|
44
|
+
rb_abi_guest_string_t *ptr;
|
45
|
+
size_t len;
|
46
|
+
} rb_abi_guest_list_string_t;
|
47
|
+
void rb_abi_guest_list_string_free(rb_abi_guest_list_string_t *ptr);
|
48
|
+
typedef struct {
|
49
|
+
rb_abi_guest_rb_abi_value_t f0;
|
50
|
+
int32_t f1;
|
51
|
+
} rb_abi_guest_tuple2_rb_abi_value_s32_t;
|
52
|
+
void rb_abi_guest_tuple2_rb_abi_value_s32_free(rb_abi_guest_tuple2_rb_abi_value_s32_t *ptr);
|
53
|
+
typedef struct {
|
54
|
+
rb_abi_guest_rb_abi_value_t *ptr;
|
55
|
+
size_t len;
|
56
|
+
} rb_abi_guest_list_rb_abi_value_t;
|
57
|
+
void rb_abi_guest_list_rb_abi_value_free(rb_abi_guest_list_rb_abi_value_t *ptr);
|
58
|
+
void rb_abi_guest_ruby_show_version(void);
|
59
|
+
void rb_abi_guest_ruby_init(void);
|
60
|
+
void rb_abi_guest_ruby_sysinit(rb_abi_guest_list_string_t *args);
|
61
|
+
rb_abi_guest_rb_iseq_t rb_abi_guest_ruby_options(rb_abi_guest_list_string_t *args);
|
62
|
+
void rb_abi_guest_ruby_script(rb_abi_guest_string_t *name);
|
63
|
+
void rb_abi_guest_ruby_init_loadpath(void);
|
64
|
+
void rb_abi_guest_rb_eval_string_protect(rb_abi_guest_string_t *str, rb_abi_guest_tuple2_rb_abi_value_s32_t *ret0);
|
65
|
+
void rb_abi_guest_rb_funcallv_protect(rb_abi_guest_rb_abi_value_t recv, rb_abi_guest_rb_id_t mid, rb_abi_guest_list_rb_abi_value_t *args, rb_abi_guest_tuple2_rb_abi_value_s32_t *ret0);
|
66
|
+
rb_abi_guest_rb_id_t rb_abi_guest_rb_intern(rb_abi_guest_string_t *name);
|
67
|
+
rb_abi_guest_rb_abi_value_t rb_abi_guest_rb_errinfo(void);
|
68
|
+
void rb_abi_guest_rb_clear_errinfo(void);
|
69
|
+
void rb_abi_guest_rstring_ptr(rb_abi_guest_rb_abi_value_t value, rb_abi_guest_string_t *ret0);
|
70
|
+
void rb_abi_guest_rb_vm_bugreport(void);
|
71
|
+
bool rb_abi_guest_rb_gc_enable(void);
|
72
|
+
bool rb_abi_guest_rb_gc_disable(void);
|
73
|
+
bool rb_abi_guest_rb_set_should_prohibit_rewind(bool new_value);
|
74
|
+
#ifdef __cplusplus
|
75
|
+
}
|
76
|
+
#endif
|
77
|
+
#endif
|
@@ -0,0 +1,25 @@
|
|
1
|
+
resource rb-iseq
|
2
|
+
resource rb-abi-value
|
3
|
+
type rb-errno = s32
|
4
|
+
type rb-id = u32
|
5
|
+
|
6
|
+
ruby-show-version: func()
|
7
|
+
ruby-init: func()
|
8
|
+
ruby-sysinit: func(args: list<string>)
|
9
|
+
ruby-options: func(args: list<string>) -> rb-iseq
|
10
|
+
ruby-script: func(name: string)
|
11
|
+
ruby-init-loadpath: func()
|
12
|
+
rb-eval-string-protect: func(str: string) -> tuple<rb-abi-value, s32>
|
13
|
+
rb-funcallv-protect: func(recv: rb-abi-value, mid: rb-id, args: list<rb-abi-value>) -> tuple<rb-abi-value, s32>
|
14
|
+
rb-intern: func(name: string) -> rb-id
|
15
|
+
rb-errinfo: func() -> rb-abi-value
|
16
|
+
rb-clear-errinfo: func()
|
17
|
+
|
18
|
+
rstring-ptr: func(value: rb-abi-value) -> string
|
19
|
+
|
20
|
+
rb-vm-bugreport: func()
|
21
|
+
|
22
|
+
rb-gc-enable: func() -> bool
|
23
|
+
rb-gc-disable: func() -> bool
|
24
|
+
|
25
|
+
rb-set-should-prohibit-rewind: func(new-value: bool) -> bool
|
data/ext/witapi/depend
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
link.filelist:
|
2
|
+
echo $(foreach obj,$(OBJS),$(abspath $(obj))) > $@
|
3
|
+
echo -mexec-model=reactor >> $@
|
4
|
+
|
5
|
+
witapi.a: link.filelist
|
6
|
+
|
7
|
+
witapi-core.o: $(srcdir)/bindgen/rb-abi-guest.h
|
8
|
+
|
9
|
+
bindgen/%.o: $(srcdir)/bindgen/%.c
|
10
|
+
@mkdir -p "$(@D)"
|
11
|
+
$(CC) -c -I$(srcdir)/bindgen -o $@ $<
|
@@ -0,0 +1,325 @@
|
|
1
|
+
#include <stdlib.h>
|
2
|
+
|
3
|
+
#include "ruby.h"
|
4
|
+
#include "ruby/version.h"
|
5
|
+
|
6
|
+
static VALUE rb_eval_string_value_protect_thunk(VALUE str) {
|
7
|
+
const ID id_eval = rb_intern("eval");
|
8
|
+
VALUE binding = rb_const_get(rb_cObject, rb_intern("TOPLEVEL_BINDING"));
|
9
|
+
const VALUE file = rb_utf8_str_new("eval", 4);
|
10
|
+
VALUE args[3] = {str, binding, file};
|
11
|
+
return rb_funcallv(rb_mKernel, id_eval, 3, args);
|
12
|
+
}
|
13
|
+
|
14
|
+
static VALUE rb_eval_string_value_protect(VALUE str, int *pstate) {
|
15
|
+
return rb_protect(rb_eval_string_value_protect_thunk, str, pstate);
|
16
|
+
}
|
17
|
+
|
18
|
+
#define TAG_NONE 0
|
19
|
+
|
20
|
+
#include "bindgen/rb-abi-guest.h"
|
21
|
+
|
22
|
+
__attribute__((import_module("asyncify"), import_name("start_unwind"))) void
|
23
|
+
asyncify_start_unwind(void *buf);
|
24
|
+
#define asyncify_start_unwind(buf) \
|
25
|
+
do { \
|
26
|
+
extern void *rb_asyncify_unwind_buf; \
|
27
|
+
rb_asyncify_unwind_buf = (buf); \
|
28
|
+
asyncify_start_unwind((buf)); \
|
29
|
+
} while (0)
|
30
|
+
__attribute__((import_module("asyncify"), import_name("stop_unwind"))) void
|
31
|
+
asyncify_stop_unwind(void);
|
32
|
+
#define asyncify_stop_unwind() \
|
33
|
+
do { \
|
34
|
+
extern void *rb_asyncify_unwind_buf; \
|
35
|
+
rb_asyncify_unwind_buf = NULL; \
|
36
|
+
asyncify_stop_unwind(); \
|
37
|
+
} while (0)
|
38
|
+
__attribute__((import_module("asyncify"), import_name("start_rewind"))) void
|
39
|
+
asyncify_start_rewind(void *buf);
|
40
|
+
__attribute__((import_module("asyncify"), import_name("stop_rewind"))) void
|
41
|
+
asyncify_stop_rewind(void);
|
42
|
+
|
43
|
+
void *rb_wasm_handle_jmp_unwind(void);
|
44
|
+
void *rb_wasm_handle_scan_unwind(void);
|
45
|
+
void *rb_wasm_handle_fiber_unwind(void (**new_fiber_entry)(void *, void *),
|
46
|
+
void **arg0, void **arg1,
|
47
|
+
bool *is_new_fiber_started);
|
48
|
+
#define RB_WASM_ENABLE_DEBUG_LOG 0
|
49
|
+
|
50
|
+
#if RB_WASM_ENABLE_DEBUG_LOG
|
51
|
+
# define RB_WASM_DEBUG_LOG(...) fprintf(stderr, __VA_ARGS__)
|
52
|
+
#else
|
53
|
+
# define RB_WASM_DEBUG_LOG(...) (void)0
|
54
|
+
#endif
|
55
|
+
|
56
|
+
static bool rb_should_prohibit_rewind = false;
|
57
|
+
|
58
|
+
__attribute__((import_module("rb-js-abi-host"),
|
59
|
+
import_name("rb_wasm_throw_prohibit_rewind_exception")))
|
60
|
+
__attribute__((noreturn)) void
|
61
|
+
rb_wasm_throw_prohibit_rewind_exception(const char *c_msg, size_t msg_len);
|
62
|
+
|
63
|
+
#define RB_WASM_CHECK_REWIND_PROHIBITED(msg) \
|
64
|
+
/* \
|
65
|
+
If the unwond source and rewinding destination are same, it's acceptable \
|
66
|
+
to rewind even under nested VM operations. \
|
67
|
+
*/ \
|
68
|
+
if (rb_should_prohibit_rewind && \
|
69
|
+
(asyncify_buf != asyncify_unwound_buf || fiber_entry_point)) { \
|
70
|
+
rb_wasm_throw_prohibit_rewind_exception(msg, sizeof(msg) - 1); \
|
71
|
+
}
|
72
|
+
|
73
|
+
#define RB_WASM_LIB_RT(MAIN_ENTRY) \
|
74
|
+
{ \
|
75
|
+
\
|
76
|
+
void *arg0 = NULL, *arg1 = NULL; \
|
77
|
+
void (*fiber_entry_point)(void *, void *) = NULL; \
|
78
|
+
\
|
79
|
+
while (1) { \
|
80
|
+
if (fiber_entry_point) { \
|
81
|
+
fiber_entry_point(arg0, arg1); \
|
82
|
+
} else { \
|
83
|
+
MAIN_ENTRY; \
|
84
|
+
} \
|
85
|
+
\
|
86
|
+
bool new_fiber_started = false; \
|
87
|
+
void *asyncify_buf = NULL; \
|
88
|
+
extern void *rb_asyncify_unwind_buf; \
|
89
|
+
void *asyncify_unwound_buf = rb_asyncify_unwind_buf; \
|
90
|
+
if (asyncify_unwound_buf == NULL) \
|
91
|
+
break; \
|
92
|
+
asyncify_stop_unwind(); \
|
93
|
+
\
|
94
|
+
if ((asyncify_buf = rb_wasm_handle_jmp_unwind()) != NULL) { \
|
95
|
+
RB_WASM_CHECK_REWIND_PROHIBITED("rb_wasm_handle_jmp_unwind") \
|
96
|
+
asyncify_start_rewind(asyncify_buf); \
|
97
|
+
continue; \
|
98
|
+
} \
|
99
|
+
if ((asyncify_buf = rb_wasm_handle_scan_unwind()) != NULL) { \
|
100
|
+
RB_WASM_CHECK_REWIND_PROHIBITED("rb_wasm_handle_scan_unwind") \
|
101
|
+
asyncify_start_rewind(asyncify_buf); \
|
102
|
+
continue; \
|
103
|
+
} \
|
104
|
+
\
|
105
|
+
asyncify_buf = rb_wasm_handle_fiber_unwind(&fiber_entry_point, &arg0, \
|
106
|
+
&arg1, &new_fiber_started); \
|
107
|
+
if (asyncify_buf) { \
|
108
|
+
RB_WASM_CHECK_REWIND_PROHIBITED("rb_wasm_handle_fiber_unwind") \
|
109
|
+
asyncify_start_rewind(asyncify_buf); \
|
110
|
+
continue; \
|
111
|
+
} else if (new_fiber_started) { \
|
112
|
+
RB_WASM_CHECK_REWIND_PROHIBITED( \
|
113
|
+
"rb_wasm_handle_fiber_unwind but new fiber"); \
|
114
|
+
continue; \
|
115
|
+
} \
|
116
|
+
\
|
117
|
+
break; \
|
118
|
+
} \
|
119
|
+
}
|
120
|
+
|
121
|
+
#define c_strings_from_abi(list, new_args) \
|
122
|
+
{ \
|
123
|
+
new_args = alloca(sizeof(char *) * ((list)->len + 1)); \
|
124
|
+
for (size_t i = 0; i < (list)->len; i++) { \
|
125
|
+
new_args[i] = (list)->ptr[i].ptr; \
|
126
|
+
} \
|
127
|
+
}
|
128
|
+
|
129
|
+
static VALUE rb_abi_guest_arena_hash;
|
130
|
+
static VALUE rb_abi_guest_refcount_hash;
|
131
|
+
|
132
|
+
static VALUE rb_abi_lend_object_internal(VALUE obj) {
|
133
|
+
VALUE object_id = rb_obj_id(obj);
|
134
|
+
VALUE ref_count = rb_hash_lookup(rb_abi_guest_refcount_hash, object_id);
|
135
|
+
if (NIL_P(ref_count)) {
|
136
|
+
rb_hash_aset(rb_abi_guest_arena_hash, object_id, obj);
|
137
|
+
rb_hash_aset(rb_abi_guest_refcount_hash, object_id, INT2FIX(1));
|
138
|
+
} else {
|
139
|
+
rb_hash_aset(rb_abi_guest_refcount_hash, object_id,
|
140
|
+
INT2FIX(FIX2INT(ref_count) + 1));
|
141
|
+
}
|
142
|
+
return Qundef;
|
143
|
+
}
|
144
|
+
void rb_abi_lend_object(VALUE obj) {
|
145
|
+
RB_WASM_DEBUG_LOG("rb_abi_lend_object: obj = %p\n", (void *)obj);
|
146
|
+
int state;
|
147
|
+
RB_WASM_LIB_RT(rb_protect(rb_abi_lend_object_internal, obj, &state));
|
148
|
+
assert(state == TAG_NONE && "rb_abi_lend_object_internal failed");
|
149
|
+
}
|
150
|
+
|
151
|
+
static VALUE rb_abi_guest_rb_abi_value_dtor_internal(VALUE obj) {
|
152
|
+
VALUE object_id = rb_obj_id(obj);
|
153
|
+
VALUE ref_count = rb_hash_lookup(rb_abi_guest_refcount_hash, object_id);
|
154
|
+
if (NIL_P(ref_count)) {
|
155
|
+
rb_warning("rb_abi_guest_rb_abi_value_dtor: double free detected");
|
156
|
+
return Qundef;
|
157
|
+
}
|
158
|
+
if (ref_count == INT2FIX(1)) {
|
159
|
+
RB_WASM_DEBUG_LOG("rb_abi_guest_rb_abi_value_dtor: ref_count == 1\n");
|
160
|
+
rb_hash_delete(rb_abi_guest_refcount_hash, object_id);
|
161
|
+
rb_hash_delete(rb_abi_guest_arena_hash, object_id);
|
162
|
+
} else {
|
163
|
+
RB_WASM_DEBUG_LOG("rb_abi_guest_rb_abi_value_dtor: ref_count = %d\n",
|
164
|
+
FIX2INT(ref_count));
|
165
|
+
rb_hash_aset(rb_abi_guest_refcount_hash, object_id,
|
166
|
+
INT2FIX(FIX2INT(ref_count) - 1));
|
167
|
+
}
|
168
|
+
return Qundef;
|
169
|
+
}
|
170
|
+
|
171
|
+
void rb_abi_guest_rb_abi_value_dtor(void *data) {
|
172
|
+
RB_WASM_DEBUG_LOG("rb_abi_guest_rb_abi_value_dtor: data = %p\n", data);
|
173
|
+
int state;
|
174
|
+
RB_WASM_LIB_RT(
|
175
|
+
rb_protect(rb_abi_guest_rb_abi_value_dtor_internal, (VALUE)data, &state));
|
176
|
+
assert(state == TAG_NONE && "rb_abi_guest_rb_abi_value_dtor_internal failed");
|
177
|
+
}
|
178
|
+
|
179
|
+
// MARK: - Exported functions
|
180
|
+
// NOTE: Assume that callers always pass null terminated string by
|
181
|
+
// rb_abi_guest_string_t
|
182
|
+
|
183
|
+
void rb_abi_guest_ruby_show_version(void) { ruby_show_version(); }
|
184
|
+
|
185
|
+
void rb_abi_guest_ruby_init(void) {
|
186
|
+
RB_WASM_LIB_RT(ruby_init())
|
187
|
+
|
188
|
+
rb_abi_guest_arena_hash = rb_hash_new();
|
189
|
+
rb_abi_guest_refcount_hash = rb_hash_new();
|
190
|
+
|
191
|
+
rb_gc_register_mark_object(rb_abi_guest_arena_hash);
|
192
|
+
rb_gc_register_mark_object(rb_abi_guest_refcount_hash);
|
193
|
+
}
|
194
|
+
|
195
|
+
void rb_abi_guest_ruby_sysinit(rb_abi_guest_list_string_t *args) {
|
196
|
+
char **c_args;
|
197
|
+
int argc = args->len;
|
198
|
+
c_strings_from_abi(args, c_args);
|
199
|
+
RB_WASM_LIB_RT(ruby_sysinit(&argc, &c_args))
|
200
|
+
}
|
201
|
+
|
202
|
+
rb_abi_guest_rb_iseq_t
|
203
|
+
rb_abi_guest_ruby_options(rb_abi_guest_list_string_t *args) {
|
204
|
+
void *result;
|
205
|
+
char **c_args;
|
206
|
+
c_strings_from_abi(args, c_args);
|
207
|
+
RB_WASM_LIB_RT(result = ruby_options(args->len, c_args))
|
208
|
+
return rb_abi_guest_rb_iseq_new(result);
|
209
|
+
}
|
210
|
+
|
211
|
+
void rb_abi_guest_ruby_script(rb_abi_guest_string_t *name) {
|
212
|
+
RB_WASM_LIB_RT(ruby_script(name->ptr))
|
213
|
+
}
|
214
|
+
|
215
|
+
void rb_abi_guest_ruby_init_loadpath(void) {
|
216
|
+
RB_WASM_LIB_RT(ruby_init_loadpath())
|
217
|
+
}
|
218
|
+
|
219
|
+
void rb_abi_guest_rb_eval_string_protect(
|
220
|
+
rb_abi_guest_string_t *str, rb_abi_guest_tuple2_rb_abi_value_s32_t *ret0) {
|
221
|
+
VALUE retval;
|
222
|
+
RB_WASM_DEBUG_LOG("rb_eval_string_protect: str = %s\n", str->ptr);
|
223
|
+
VALUE utf8_str = rb_utf8_str_new(str->ptr, str->len);
|
224
|
+
RB_WASM_LIB_RT(retval = rb_eval_string_value_protect(utf8_str, &ret0->f1));
|
225
|
+
RB_WASM_DEBUG_LOG("rb_eval_string_protect: retval = %p, state = %d\n",
|
226
|
+
(void *)retval, ret0->f1);
|
227
|
+
|
228
|
+
if (ret0->f1 == TAG_NONE) {
|
229
|
+
rb_abi_lend_object(retval);
|
230
|
+
}
|
231
|
+
ret0->f0 = rb_abi_guest_rb_abi_value_new((void *)retval);
|
232
|
+
}
|
233
|
+
|
234
|
+
struct rb_funcallv_thunk_ctx {
|
235
|
+
VALUE recv;
|
236
|
+
ID mid;
|
237
|
+
rb_abi_guest_list_rb_abi_value_t *args;
|
238
|
+
};
|
239
|
+
|
240
|
+
VALUE rb_funcallv_thunk(VALUE arg) {
|
241
|
+
struct rb_funcallv_thunk_ctx *ctx = (struct rb_funcallv_thunk_ctx *)arg;
|
242
|
+
VALUE *c_argv = alloca(sizeof(VALUE) * ctx->args->len);
|
243
|
+
for (size_t i = 0; i < ctx->args->len; i++) {
|
244
|
+
c_argv[i] = (VALUE)rb_abi_guest_rb_abi_value_get(&ctx->args->ptr[i]);
|
245
|
+
}
|
246
|
+
return rb_funcallv(ctx->recv, ctx->mid, ctx->args->len, c_argv);
|
247
|
+
}
|
248
|
+
|
249
|
+
void rb_abi_guest_rb_funcallv_protect(
|
250
|
+
rb_abi_guest_rb_abi_value_t recv, rb_abi_guest_rb_id_t mid,
|
251
|
+
rb_abi_guest_list_rb_abi_value_t *args,
|
252
|
+
rb_abi_guest_tuple2_rb_abi_value_s32_t *ret0) {
|
253
|
+
VALUE retval;
|
254
|
+
VALUE r_recv = (VALUE)rb_abi_guest_rb_abi_value_get(&recv);
|
255
|
+
struct rb_funcallv_thunk_ctx ctx = {.recv = r_recv, .mid = mid, .args = args};
|
256
|
+
RB_WASM_LIB_RT(retval =
|
257
|
+
rb_protect(rb_funcallv_thunk, (VALUE)&ctx, &ret0->f1));
|
258
|
+
RB_WASM_DEBUG_LOG(
|
259
|
+
"rb_abi_guest_rb_funcallv_protect: retval = %p, state = %d\n",
|
260
|
+
(void *)retval, ret0->f1);
|
261
|
+
|
262
|
+
if (ret0->f1 == TAG_NONE) {
|
263
|
+
rb_abi_lend_object(retval);
|
264
|
+
}
|
265
|
+
ret0->f0 = rb_abi_guest_rb_abi_value_new((void *)retval);
|
266
|
+
}
|
267
|
+
|
268
|
+
rb_abi_guest_rb_id_t rb_abi_guest_rb_intern(rb_abi_guest_string_t *name) {
|
269
|
+
return rb_intern(name->ptr);
|
270
|
+
}
|
271
|
+
|
272
|
+
rb_abi_guest_rb_abi_value_t rb_abi_guest_rb_errinfo(void) {
|
273
|
+
VALUE retval;
|
274
|
+
RB_WASM_LIB_RT(retval = rb_errinfo());
|
275
|
+
rb_abi_lend_object(retval);
|
276
|
+
return rb_abi_guest_rb_abi_value_new((void *)retval);
|
277
|
+
}
|
278
|
+
|
279
|
+
void rb_abi_guest_rb_clear_errinfo(void) { rb_set_errinfo(Qnil); }
|
280
|
+
|
281
|
+
void rb_abi_guest_rstring_ptr(rb_abi_guest_rb_abi_value_t value,
|
282
|
+
rb_abi_guest_string_t *ret0) {
|
283
|
+
VALUE r_str = (VALUE)rb_abi_guest_rb_abi_value_get(&value);
|
284
|
+
ret0->len = RSTRING_LEN(r_str);
|
285
|
+
ret0->ptr = xmalloc(ret0->len);
|
286
|
+
memcpy(ret0->ptr, RSTRING_PTR(r_str), ret0->len);
|
287
|
+
}
|
288
|
+
|
289
|
+
uint32_t rb_abi_guest_rb_abi_value_data_ptr(rb_abi_guest_rb_abi_value_t self) {
|
290
|
+
VALUE obj = (VALUE)rb_abi_guest_rb_abi_value_get(&self);
|
291
|
+
return (uint32_t)DATA_PTR(obj);
|
292
|
+
}
|
293
|
+
|
294
|
+
_Static_assert(RUBY_API_VERSION_MAJOR == 3, "unsupported Ruby version");
|
295
|
+
#if RUBY_API_VERSION_MINOR == 2
|
296
|
+
void rb_vm_bugreport(const void *);
|
297
|
+
|
298
|
+
void rb_abi_guest_rb_vm_bugreport(void) { rb_vm_bugreport(NULL); }
|
299
|
+
#elif RUBY_API_VERSION_MINOR >= 3
|
300
|
+
bool rb_vm_bugreport(const void *, FILE *);
|
301
|
+
|
302
|
+
void rb_abi_guest_rb_vm_bugreport(void) { rb_vm_bugreport(NULL, stderr); }
|
303
|
+
#else
|
304
|
+
# error "unsupported Ruby version"
|
305
|
+
#endif
|
306
|
+
|
307
|
+
bool rb_abi_guest_rb_gc_enable(void) { return rb_gc_enable() == Qtrue; }
|
308
|
+
|
309
|
+
VALUE rb_gc_disable_no_rest(void);
|
310
|
+
bool rb_abi_guest_rb_gc_disable(void) {
|
311
|
+
// NOTE: rb_gc_disable() is usually preferred to free up memory as much as
|
312
|
+
// possible before disabling GC. However it may trigger GC through gc_rest(),
|
313
|
+
// and triggering GC having a sandwitched JS frame is unsafe because it misses
|
314
|
+
// to mark some living objects in the frames behind the JS frame. So we use
|
315
|
+
// rb_gc_disable_no_rest(), which does not trigger GC, instead.
|
316
|
+
return rb_gc_disable_no_rest() == Qtrue;
|
317
|
+
}
|
318
|
+
|
319
|
+
bool rb_abi_guest_rb_set_should_prohibit_rewind(bool value) {
|
320
|
+
bool old = rb_should_prohibit_rewind;
|
321
|
+
rb_should_prohibit_rewind = value;
|
322
|
+
return old;
|
323
|
+
}
|
324
|
+
|
325
|
+
void Init_witapi(void) {}
|