js 0.0.1 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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) {}
|