@ruby/wasm-wasi 2.3.0-2023-12-03-a → 2.3.0-2023-12-05-a
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.
- package/README.md +177 -2
- package/dist/browser.script.umd.js +56 -10
- package/dist/browser.umd.js +56 -10
- package/dist/cjs/index.d.ts +4 -0
- package/dist/cjs/index.js +56 -10
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +56 -10
- package/dist/index.umd.js +56 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,183 @@
|
|
|
1
1
|
# @ruby/wasm-wasi
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@ruby/wasm-wasi)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
This package core API for Ruby on WebAssembly targeting WASI-compatible environments. WebAssembly binaries are distributed in version-specific packages.
|
|
6
|
+
|
|
7
|
+
See [Cheat Sheet](https://github.com/ruby/ruby.wasm/blob/main/docs/cheat_sheet.md) for how to use this package.
|
|
8
|
+
|
|
9
|
+
## Ruby Version Support
|
|
10
|
+
|
|
11
|
+
| Version | Package |
|
|
6
12
|
| ------- | -------------------------------------------------- |
|
|
7
13
|
| `head` | [`@ruby/head-wasm-wasi`](./../ruby-head-wasm-wasi) |
|
|
8
14
|
| `3.2` | [`@ruby/3.2-wasm-wasi`](./../ruby-3.2-wasm-wasi) |
|
|
15
|
+
|
|
16
|
+
## API
|
|
17
|
+
|
|
18
|
+
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
|
|
19
|
+
|
|
20
|
+
### RubyVM
|
|
21
|
+
|
|
22
|
+
A Ruby VM instance
|
|
23
|
+
|
|
24
|
+
#### Examples
|
|
25
|
+
|
|
26
|
+
```javascript
|
|
27
|
+
const wasi = new WASI();
|
|
28
|
+
const vm = new RubyVM();
|
|
29
|
+
const imports = {
|
|
30
|
+
wasi_snapshot_preview1: wasi.wasiImport,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
vm.addToImports(imports);
|
|
34
|
+
|
|
35
|
+
const instance = await WebAssembly.instantiate(rubyModule, imports);
|
|
36
|
+
await vm.setInstance(instance);
|
|
37
|
+
wasi.initialize(instance);
|
|
38
|
+
vm.initialize();
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
#### initialize
|
|
42
|
+
|
|
43
|
+
Initialize the Ruby VM with the given command line arguments
|
|
44
|
+
|
|
45
|
+
##### Parameters
|
|
46
|
+
|
|
47
|
+
- `args` The command line arguments to pass to Ruby. Must be
|
|
48
|
+
an array of strings starting with the Ruby program name. (optional, default `["ruby.wasm","--disable-gems","-EUTF-8","-e_=0"]`)
|
|
49
|
+
|
|
50
|
+
#### setInstance
|
|
51
|
+
|
|
52
|
+
Set a given instance to interact JavaScript and Ruby's
|
|
53
|
+
WebAssembly instance. This method must be called before calling
|
|
54
|
+
Ruby API.
|
|
55
|
+
|
|
56
|
+
##### Parameters
|
|
57
|
+
|
|
58
|
+
- `instance` The WebAssembly instance to interact with. Must
|
|
59
|
+
be instantiated from a Ruby built with JS extension, and built
|
|
60
|
+
with Reactor ABI instead of command line.
|
|
61
|
+
|
|
62
|
+
#### addToImports
|
|
63
|
+
|
|
64
|
+
Add intrinsic import entries, which is necessary to interact JavaScript
|
|
65
|
+
and Ruby's WebAssembly instance.
|
|
66
|
+
|
|
67
|
+
##### Parameters
|
|
68
|
+
|
|
69
|
+
- `imports` The import object to add to the WebAssembly instance
|
|
70
|
+
|
|
71
|
+
#### printVersion
|
|
72
|
+
|
|
73
|
+
Print the Ruby version to stdout
|
|
74
|
+
|
|
75
|
+
#### eval
|
|
76
|
+
|
|
77
|
+
Runs a string of Ruby code from JavaScript
|
|
78
|
+
|
|
79
|
+
##### Parameters
|
|
80
|
+
|
|
81
|
+
- `code` The Ruby code to run
|
|
82
|
+
|
|
83
|
+
##### Examples
|
|
84
|
+
|
|
85
|
+
```javascript
|
|
86
|
+
vm.eval("puts 'hello world'");
|
|
87
|
+
const result = vm.eval("1 + 2");
|
|
88
|
+
console.log(result.toString()); // 3
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Returns **any** the result of the last expression
|
|
92
|
+
|
|
93
|
+
#### evalAsync
|
|
94
|
+
|
|
95
|
+
Runs a string of Ruby code with top-level `JS::Object#await`
|
|
96
|
+
Returns a promise that resolves when execution completes.
|
|
97
|
+
|
|
98
|
+
##### Parameters
|
|
99
|
+
|
|
100
|
+
- `code` The Ruby code to run
|
|
101
|
+
|
|
102
|
+
##### Examples
|
|
103
|
+
|
|
104
|
+
```javascript
|
|
105
|
+
const text = await vm.evalAsync(`
|
|
106
|
+
require 'js'
|
|
107
|
+
response = JS.global.fetch('https://example.com').await
|
|
108
|
+
response.text.await
|
|
109
|
+
`);
|
|
110
|
+
console.log(text.toString()); // <html>...</html>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Returns **any** a promise that resolves to the result of the last expression
|
|
114
|
+
|
|
115
|
+
#### wrap
|
|
116
|
+
|
|
117
|
+
Wrap a JavaScript value into a Ruby JS::Object
|
|
118
|
+
|
|
119
|
+
##### Parameters
|
|
120
|
+
|
|
121
|
+
- `value` The value to convert to RbValue
|
|
122
|
+
|
|
123
|
+
##### Examples
|
|
124
|
+
|
|
125
|
+
```javascript
|
|
126
|
+
const hash = vm.eval(`Hash.new`);
|
|
127
|
+
hash.call("store", vm.eval(`"key1"`), vm.wrap(new Object()));
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Returns **any** the RbValue object representing the given JS value
|
|
131
|
+
|
|
132
|
+
### RbValue
|
|
133
|
+
|
|
134
|
+
A RbValue is an object that represents a value in Ruby
|
|
135
|
+
|
|
136
|
+
#### call
|
|
137
|
+
|
|
138
|
+
Call a given method with given arguments
|
|
139
|
+
|
|
140
|
+
##### Parameters
|
|
141
|
+
|
|
142
|
+
- `callee` name of the Ruby method to call
|
|
143
|
+
- `args` **...any** arguments to pass to the method. Must be an array of RbValue
|
|
144
|
+
|
|
145
|
+
##### Examples
|
|
146
|
+
|
|
147
|
+
```javascript
|
|
148
|
+
const ary = vm.eval("[1, 2, 3]");
|
|
149
|
+
ary.call("push", 4);
|
|
150
|
+
console.log(ary.call("sample").toString());
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
#### toPrimitive
|
|
154
|
+
|
|
155
|
+
- **See**: <https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toPrimitive>
|
|
156
|
+
|
|
157
|
+
##### Parameters
|
|
158
|
+
|
|
159
|
+
- `hint` Preferred type of the result primitive value. `"number"`, `"string"`, or `"default"`.
|
|
160
|
+
|
|
161
|
+
#### toString
|
|
162
|
+
|
|
163
|
+
Returns a string representation of the value by calling `to_s`
|
|
164
|
+
|
|
165
|
+
#### toJS
|
|
166
|
+
|
|
167
|
+
Returns a JavaScript object representation of the value
|
|
168
|
+
by calling `to_js`.
|
|
169
|
+
|
|
170
|
+
Returns null if the value is not convertible to a JavaScript object.
|
|
171
|
+
|
|
172
|
+
### RbError
|
|
173
|
+
|
|
174
|
+
**Extends Error**
|
|
175
|
+
|
|
176
|
+
Error class thrown by Ruby execution
|
|
177
|
+
|
|
178
|
+
### RbFatalError
|
|
179
|
+
|
|
180
|
+
**Extends RbError**
|
|
181
|
+
|
|
182
|
+
Error class thrown by Ruby execution when it is not possible to recover.
|
|
183
|
+
This is usually caused when Ruby VM is in an inconsistent state.
|
|
@@ -2969,12 +2969,14 @@
|
|
|
2969
2969
|
wrap(value) {
|
|
2970
2970
|
return this.transport.importJsValue(value, this);
|
|
2971
2971
|
}
|
|
2972
|
+
/** @private */
|
|
2972
2973
|
privateObject() {
|
|
2973
2974
|
return {
|
|
2974
2975
|
transport: this.transport,
|
|
2975
2976
|
exceptionFormatter: this.exceptionFormatter,
|
|
2976
2977
|
};
|
|
2977
2978
|
}
|
|
2979
|
+
/** @private */
|
|
2978
2980
|
rbValueOfPointer(pointer) {
|
|
2979
2981
|
const abiValue = new RbAbiValue(pointer, this.guest);
|
|
2980
2982
|
return new RbValue(abiValue, this, this.privateObject());
|
|
@@ -3099,8 +3101,27 @@
|
|
|
3099
3101
|
class RbExceptionFormatter {
|
|
3100
3102
|
constructor() {
|
|
3101
3103
|
this.literalsCache = null;
|
|
3104
|
+
this.isFormmatting = false;
|
|
3102
3105
|
}
|
|
3103
3106
|
format(error, vm, privateObject) {
|
|
3107
|
+
// All Ruby exceptions raised during formatting exception message should
|
|
3108
|
+
// be caught and return a fallback message.
|
|
3109
|
+
// Therefore, we don't need to worry about infinite recursion here ideally
|
|
3110
|
+
// but checking re-entrancy just in case.
|
|
3111
|
+
class RbExceptionFormatterError extends Error {
|
|
3112
|
+
}
|
|
3113
|
+
if (this.isFormmatting) {
|
|
3114
|
+
throw new RbExceptionFormatterError("Unexpected exception occurred during formatting exception message");
|
|
3115
|
+
}
|
|
3116
|
+
this.isFormmatting = true;
|
|
3117
|
+
try {
|
|
3118
|
+
return this._format(error, vm, privateObject);
|
|
3119
|
+
}
|
|
3120
|
+
finally {
|
|
3121
|
+
this.isFormmatting = false;
|
|
3122
|
+
}
|
|
3123
|
+
}
|
|
3124
|
+
_format(error, vm, privateObject) {
|
|
3104
3125
|
const [zeroLiteral, oneLiteral, newLineLiteral] = (() => {
|
|
3105
3126
|
if (this.literalsCache == null) {
|
|
3106
3127
|
const zeroOneNewLine = [
|
|
@@ -3115,18 +3136,43 @@
|
|
|
3115
3136
|
return this.literalsCache;
|
|
3116
3137
|
}
|
|
3117
3138
|
})();
|
|
3118
|
-
|
|
3139
|
+
let className;
|
|
3140
|
+
let backtrace;
|
|
3141
|
+
let message;
|
|
3142
|
+
try {
|
|
3143
|
+
className = error.call("class").toString();
|
|
3144
|
+
}
|
|
3145
|
+
catch (e) {
|
|
3146
|
+
className = "unknown";
|
|
3147
|
+
}
|
|
3148
|
+
try {
|
|
3149
|
+
message = error.toString();
|
|
3150
|
+
}
|
|
3151
|
+
catch (e) {
|
|
3152
|
+
message = "unknown";
|
|
3153
|
+
}
|
|
3154
|
+
try {
|
|
3155
|
+
backtrace = error.call("backtrace");
|
|
3156
|
+
}
|
|
3157
|
+
catch (e) {
|
|
3158
|
+
return this.formatString(className, message);
|
|
3159
|
+
}
|
|
3119
3160
|
if (backtrace.call("nil?").toString() === "true") {
|
|
3120
|
-
return this.formatString(
|
|
3161
|
+
return this.formatString(className, message);
|
|
3162
|
+
}
|
|
3163
|
+
try {
|
|
3164
|
+
const firstLine = backtrace.call("at", zeroLiteral);
|
|
3165
|
+
const restLines = backtrace
|
|
3166
|
+
.call("drop", oneLiteral)
|
|
3167
|
+
.call("join", newLineLiteral);
|
|
3168
|
+
return this.formatString(className, message, [
|
|
3169
|
+
firstLine.toString(),
|
|
3170
|
+
restLines.toString(),
|
|
3171
|
+
]);
|
|
3172
|
+
}
|
|
3173
|
+
catch (e) {
|
|
3174
|
+
return this.formatString(className, message);
|
|
3121
3175
|
}
|
|
3122
|
-
const firstLine = backtrace.call("at", zeroLiteral);
|
|
3123
|
-
const restLines = backtrace
|
|
3124
|
-
.call("drop", oneLiteral)
|
|
3125
|
-
.call("join", newLineLiteral);
|
|
3126
|
-
return this.formatString(error.call("class").toString(), error.toString(), [
|
|
3127
|
-
firstLine.toString(),
|
|
3128
|
-
restLines.toString(),
|
|
3129
|
-
]);
|
|
3130
3176
|
}
|
|
3131
3177
|
formatString(klass, message, backtrace) {
|
|
3132
3178
|
if (backtrace) {
|
package/dist/browser.umd.js
CHANGED
|
@@ -2927,12 +2927,14 @@
|
|
|
2927
2927
|
wrap(value) {
|
|
2928
2928
|
return this.transport.importJsValue(value, this);
|
|
2929
2929
|
}
|
|
2930
|
+
/** @private */
|
|
2930
2931
|
privateObject() {
|
|
2931
2932
|
return {
|
|
2932
2933
|
transport: this.transport,
|
|
2933
2934
|
exceptionFormatter: this.exceptionFormatter,
|
|
2934
2935
|
};
|
|
2935
2936
|
}
|
|
2937
|
+
/** @private */
|
|
2936
2938
|
rbValueOfPointer(pointer) {
|
|
2937
2939
|
const abiValue = new RbAbiValue(pointer, this.guest);
|
|
2938
2940
|
return new RbValue(abiValue, this, this.privateObject());
|
|
@@ -3057,8 +3059,27 @@
|
|
|
3057
3059
|
class RbExceptionFormatter {
|
|
3058
3060
|
constructor() {
|
|
3059
3061
|
this.literalsCache = null;
|
|
3062
|
+
this.isFormmatting = false;
|
|
3060
3063
|
}
|
|
3061
3064
|
format(error, vm, privateObject) {
|
|
3065
|
+
// All Ruby exceptions raised during formatting exception message should
|
|
3066
|
+
// be caught and return a fallback message.
|
|
3067
|
+
// Therefore, we don't need to worry about infinite recursion here ideally
|
|
3068
|
+
// but checking re-entrancy just in case.
|
|
3069
|
+
class RbExceptionFormatterError extends Error {
|
|
3070
|
+
}
|
|
3071
|
+
if (this.isFormmatting) {
|
|
3072
|
+
throw new RbExceptionFormatterError("Unexpected exception occurred during formatting exception message");
|
|
3073
|
+
}
|
|
3074
|
+
this.isFormmatting = true;
|
|
3075
|
+
try {
|
|
3076
|
+
return this._format(error, vm, privateObject);
|
|
3077
|
+
}
|
|
3078
|
+
finally {
|
|
3079
|
+
this.isFormmatting = false;
|
|
3080
|
+
}
|
|
3081
|
+
}
|
|
3082
|
+
_format(error, vm, privateObject) {
|
|
3062
3083
|
const [zeroLiteral, oneLiteral, newLineLiteral] = (() => {
|
|
3063
3084
|
if (this.literalsCache == null) {
|
|
3064
3085
|
const zeroOneNewLine = [
|
|
@@ -3073,18 +3094,43 @@
|
|
|
3073
3094
|
return this.literalsCache;
|
|
3074
3095
|
}
|
|
3075
3096
|
})();
|
|
3076
|
-
|
|
3097
|
+
let className;
|
|
3098
|
+
let backtrace;
|
|
3099
|
+
let message;
|
|
3100
|
+
try {
|
|
3101
|
+
className = error.call("class").toString();
|
|
3102
|
+
}
|
|
3103
|
+
catch (e) {
|
|
3104
|
+
className = "unknown";
|
|
3105
|
+
}
|
|
3106
|
+
try {
|
|
3107
|
+
message = error.toString();
|
|
3108
|
+
}
|
|
3109
|
+
catch (e) {
|
|
3110
|
+
message = "unknown";
|
|
3111
|
+
}
|
|
3112
|
+
try {
|
|
3113
|
+
backtrace = error.call("backtrace");
|
|
3114
|
+
}
|
|
3115
|
+
catch (e) {
|
|
3116
|
+
return this.formatString(className, message);
|
|
3117
|
+
}
|
|
3077
3118
|
if (backtrace.call("nil?").toString() === "true") {
|
|
3078
|
-
return this.formatString(
|
|
3119
|
+
return this.formatString(className, message);
|
|
3120
|
+
}
|
|
3121
|
+
try {
|
|
3122
|
+
const firstLine = backtrace.call("at", zeroLiteral);
|
|
3123
|
+
const restLines = backtrace
|
|
3124
|
+
.call("drop", oneLiteral)
|
|
3125
|
+
.call("join", newLineLiteral);
|
|
3126
|
+
return this.formatString(className, message, [
|
|
3127
|
+
firstLine.toString(),
|
|
3128
|
+
restLines.toString(),
|
|
3129
|
+
]);
|
|
3130
|
+
}
|
|
3131
|
+
catch (e) {
|
|
3132
|
+
return this.formatString(className, message);
|
|
3079
3133
|
}
|
|
3080
|
-
const firstLine = backtrace.call("at", zeroLiteral);
|
|
3081
|
-
const restLines = backtrace
|
|
3082
|
-
.call("drop", oneLiteral)
|
|
3083
|
-
.call("join", newLineLiteral);
|
|
3084
|
-
return this.formatString(error.call("class").toString(), error.toString(), [
|
|
3085
|
-
firstLine.toString(),
|
|
3086
|
-
restLines.toString(),
|
|
3087
|
-
]);
|
|
3088
3134
|
}
|
|
3089
3135
|
formatString(klass, message, backtrace) {
|
|
3090
3136
|
if (backtrace) {
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -89,7 +89,9 @@ export declare class RubyVM {
|
|
|
89
89
|
* hash.call("store", vm.eval(`"key1"`), vm.wrap(new Object()));
|
|
90
90
|
*/
|
|
91
91
|
wrap(value: any): RbValue;
|
|
92
|
+
/** @private */
|
|
92
93
|
private privateObject;
|
|
94
|
+
/** @private */
|
|
93
95
|
private rbValueOfPointer;
|
|
94
96
|
}
|
|
95
97
|
/**
|
|
@@ -167,7 +169,9 @@ type RubyVMPrivate = {
|
|
|
167
169
|
};
|
|
168
170
|
declare class RbExceptionFormatter {
|
|
169
171
|
private literalsCache;
|
|
172
|
+
private isFormmatting;
|
|
170
173
|
format(error: RbValue, vm: RubyVM, privateObject: RubyVMPrivate): string;
|
|
174
|
+
private _format;
|
|
171
175
|
formatString(klass: string, message: string, backtrace?: [string, string]): string;
|
|
172
176
|
}
|
|
173
177
|
/**
|
package/dist/cjs/index.js
CHANGED
|
@@ -336,12 +336,14 @@ class RubyVM {
|
|
|
336
336
|
wrap(value) {
|
|
337
337
|
return this.transport.importJsValue(value, this);
|
|
338
338
|
}
|
|
339
|
+
/** @private */
|
|
339
340
|
privateObject() {
|
|
340
341
|
return {
|
|
341
342
|
transport: this.transport,
|
|
342
343
|
exceptionFormatter: this.exceptionFormatter,
|
|
343
344
|
};
|
|
344
345
|
}
|
|
346
|
+
/** @private */
|
|
345
347
|
rbValueOfPointer(pointer) {
|
|
346
348
|
const abiValue = new RbAbi.RbAbiValue(pointer, this.guest);
|
|
347
349
|
return new RbValue(abiValue, this, this.privateObject());
|
|
@@ -468,8 +470,27 @@ var ruby_tag_type;
|
|
|
468
470
|
class RbExceptionFormatter {
|
|
469
471
|
constructor() {
|
|
470
472
|
this.literalsCache = null;
|
|
473
|
+
this.isFormmatting = false;
|
|
471
474
|
}
|
|
472
475
|
format(error, vm, privateObject) {
|
|
476
|
+
// All Ruby exceptions raised during formatting exception message should
|
|
477
|
+
// be caught and return a fallback message.
|
|
478
|
+
// Therefore, we don't need to worry about infinite recursion here ideally
|
|
479
|
+
// but checking re-entrancy just in case.
|
|
480
|
+
class RbExceptionFormatterError extends Error {
|
|
481
|
+
}
|
|
482
|
+
if (this.isFormmatting) {
|
|
483
|
+
throw new RbExceptionFormatterError("Unexpected exception occurred during formatting exception message");
|
|
484
|
+
}
|
|
485
|
+
this.isFormmatting = true;
|
|
486
|
+
try {
|
|
487
|
+
return this._format(error, vm, privateObject);
|
|
488
|
+
}
|
|
489
|
+
finally {
|
|
490
|
+
this.isFormmatting = false;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
_format(error, vm, privateObject) {
|
|
473
494
|
const [zeroLiteral, oneLiteral, newLineLiteral] = (() => {
|
|
474
495
|
if (this.literalsCache == null) {
|
|
475
496
|
const zeroOneNewLine = [
|
|
@@ -484,18 +505,43 @@ class RbExceptionFormatter {
|
|
|
484
505
|
return this.literalsCache;
|
|
485
506
|
}
|
|
486
507
|
})();
|
|
487
|
-
|
|
508
|
+
let className;
|
|
509
|
+
let backtrace;
|
|
510
|
+
let message;
|
|
511
|
+
try {
|
|
512
|
+
className = error.call("class").toString();
|
|
513
|
+
}
|
|
514
|
+
catch (e) {
|
|
515
|
+
className = "unknown";
|
|
516
|
+
}
|
|
517
|
+
try {
|
|
518
|
+
message = error.toString();
|
|
519
|
+
}
|
|
520
|
+
catch (e) {
|
|
521
|
+
message = "unknown";
|
|
522
|
+
}
|
|
523
|
+
try {
|
|
524
|
+
backtrace = error.call("backtrace");
|
|
525
|
+
}
|
|
526
|
+
catch (e) {
|
|
527
|
+
return this.formatString(className, message);
|
|
528
|
+
}
|
|
488
529
|
if (backtrace.call("nil?").toString() === "true") {
|
|
489
|
-
return this.formatString(
|
|
530
|
+
return this.formatString(className, message);
|
|
531
|
+
}
|
|
532
|
+
try {
|
|
533
|
+
const firstLine = backtrace.call("at", zeroLiteral);
|
|
534
|
+
const restLines = backtrace
|
|
535
|
+
.call("drop", oneLiteral)
|
|
536
|
+
.call("join", newLineLiteral);
|
|
537
|
+
return this.formatString(className, message, [
|
|
538
|
+
firstLine.toString(),
|
|
539
|
+
restLines.toString(),
|
|
540
|
+
]);
|
|
541
|
+
}
|
|
542
|
+
catch (e) {
|
|
543
|
+
return this.formatString(className, message);
|
|
490
544
|
}
|
|
491
|
-
const firstLine = backtrace.call("at", zeroLiteral);
|
|
492
|
-
const restLines = backtrace
|
|
493
|
-
.call("drop", oneLiteral)
|
|
494
|
-
.call("join", newLineLiteral);
|
|
495
|
-
return this.formatString(error.call("class").toString(), error.toString(), [
|
|
496
|
-
firstLine.toString(),
|
|
497
|
-
restLines.toString(),
|
|
498
|
-
]);
|
|
499
545
|
}
|
|
500
546
|
formatString(klass, message, backtrace) {
|
|
501
547
|
if (backtrace) {
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -89,7 +89,9 @@ export declare class RubyVM {
|
|
|
89
89
|
* hash.call("store", vm.eval(`"key1"`), vm.wrap(new Object()));
|
|
90
90
|
*/
|
|
91
91
|
wrap(value: any): RbValue;
|
|
92
|
+
/** @private */
|
|
92
93
|
private privateObject;
|
|
94
|
+
/** @private */
|
|
93
95
|
private rbValueOfPointer;
|
|
94
96
|
}
|
|
95
97
|
/**
|
|
@@ -167,7 +169,9 @@ type RubyVMPrivate = {
|
|
|
167
169
|
};
|
|
168
170
|
declare class RbExceptionFormatter {
|
|
169
171
|
private literalsCache;
|
|
172
|
+
private isFormmatting;
|
|
170
173
|
format(error: RbValue, vm: RubyVM, privateObject: RubyVMPrivate): string;
|
|
174
|
+
private _format;
|
|
171
175
|
formatString(klass: string, message: string, backtrace?: [string, string]): string;
|
|
172
176
|
}
|
|
173
177
|
/**
|
package/dist/esm/index.js
CHANGED
|
@@ -332,12 +332,14 @@ export class RubyVM {
|
|
|
332
332
|
wrap(value) {
|
|
333
333
|
return this.transport.importJsValue(value, this);
|
|
334
334
|
}
|
|
335
|
+
/** @private */
|
|
335
336
|
privateObject() {
|
|
336
337
|
return {
|
|
337
338
|
transport: this.transport,
|
|
338
339
|
exceptionFormatter: this.exceptionFormatter,
|
|
339
340
|
};
|
|
340
341
|
}
|
|
342
|
+
/** @private */
|
|
341
343
|
rbValueOfPointer(pointer) {
|
|
342
344
|
const abiValue = new RbAbi.RbAbiValue(pointer, this.guest);
|
|
343
345
|
return new RbValue(abiValue, this, this.privateObject());
|
|
@@ -462,8 +464,27 @@ var ruby_tag_type;
|
|
|
462
464
|
class RbExceptionFormatter {
|
|
463
465
|
constructor() {
|
|
464
466
|
this.literalsCache = null;
|
|
467
|
+
this.isFormmatting = false;
|
|
465
468
|
}
|
|
466
469
|
format(error, vm, privateObject) {
|
|
470
|
+
// All Ruby exceptions raised during formatting exception message should
|
|
471
|
+
// be caught and return a fallback message.
|
|
472
|
+
// Therefore, we don't need to worry about infinite recursion here ideally
|
|
473
|
+
// but checking re-entrancy just in case.
|
|
474
|
+
class RbExceptionFormatterError extends Error {
|
|
475
|
+
}
|
|
476
|
+
if (this.isFormmatting) {
|
|
477
|
+
throw new RbExceptionFormatterError("Unexpected exception occurred during formatting exception message");
|
|
478
|
+
}
|
|
479
|
+
this.isFormmatting = true;
|
|
480
|
+
try {
|
|
481
|
+
return this._format(error, vm, privateObject);
|
|
482
|
+
}
|
|
483
|
+
finally {
|
|
484
|
+
this.isFormmatting = false;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
_format(error, vm, privateObject) {
|
|
467
488
|
const [zeroLiteral, oneLiteral, newLineLiteral] = (() => {
|
|
468
489
|
if (this.literalsCache == null) {
|
|
469
490
|
const zeroOneNewLine = [
|
|
@@ -478,18 +499,43 @@ class RbExceptionFormatter {
|
|
|
478
499
|
return this.literalsCache;
|
|
479
500
|
}
|
|
480
501
|
})();
|
|
481
|
-
|
|
502
|
+
let className;
|
|
503
|
+
let backtrace;
|
|
504
|
+
let message;
|
|
505
|
+
try {
|
|
506
|
+
className = error.call("class").toString();
|
|
507
|
+
}
|
|
508
|
+
catch (e) {
|
|
509
|
+
className = "unknown";
|
|
510
|
+
}
|
|
511
|
+
try {
|
|
512
|
+
message = error.toString();
|
|
513
|
+
}
|
|
514
|
+
catch (e) {
|
|
515
|
+
message = "unknown";
|
|
516
|
+
}
|
|
517
|
+
try {
|
|
518
|
+
backtrace = error.call("backtrace");
|
|
519
|
+
}
|
|
520
|
+
catch (e) {
|
|
521
|
+
return this.formatString(className, message);
|
|
522
|
+
}
|
|
482
523
|
if (backtrace.call("nil?").toString() === "true") {
|
|
483
|
-
return this.formatString(
|
|
524
|
+
return this.formatString(className, message);
|
|
525
|
+
}
|
|
526
|
+
try {
|
|
527
|
+
const firstLine = backtrace.call("at", zeroLiteral);
|
|
528
|
+
const restLines = backtrace
|
|
529
|
+
.call("drop", oneLiteral)
|
|
530
|
+
.call("join", newLineLiteral);
|
|
531
|
+
return this.formatString(className, message, [
|
|
532
|
+
firstLine.toString(),
|
|
533
|
+
restLines.toString(),
|
|
534
|
+
]);
|
|
535
|
+
}
|
|
536
|
+
catch (e) {
|
|
537
|
+
return this.formatString(className, message);
|
|
484
538
|
}
|
|
485
|
-
const firstLine = backtrace.call("at", zeroLiteral);
|
|
486
|
-
const restLines = backtrace
|
|
487
|
-
.call("drop", oneLiteral)
|
|
488
|
-
.call("join", newLineLiteral);
|
|
489
|
-
return this.formatString(error.call("class").toString(), error.toString(), [
|
|
490
|
-
firstLine.toString(),
|
|
491
|
-
restLines.toString(),
|
|
492
|
-
]);
|
|
493
539
|
}
|
|
494
540
|
formatString(klass, message, backtrace) {
|
|
495
541
|
if (backtrace) {
|
package/dist/index.umd.js
CHANGED
|
@@ -933,12 +933,14 @@
|
|
|
933
933
|
wrap(value) {
|
|
934
934
|
return this.transport.importJsValue(value, this);
|
|
935
935
|
}
|
|
936
|
+
/** @private */
|
|
936
937
|
privateObject() {
|
|
937
938
|
return {
|
|
938
939
|
transport: this.transport,
|
|
939
940
|
exceptionFormatter: this.exceptionFormatter,
|
|
940
941
|
};
|
|
941
942
|
}
|
|
943
|
+
/** @private */
|
|
942
944
|
rbValueOfPointer(pointer) {
|
|
943
945
|
const abiValue = new RbAbiValue(pointer, this.guest);
|
|
944
946
|
return new RbValue(abiValue, this, this.privateObject());
|
|
@@ -1063,8 +1065,27 @@
|
|
|
1063
1065
|
class RbExceptionFormatter {
|
|
1064
1066
|
constructor() {
|
|
1065
1067
|
this.literalsCache = null;
|
|
1068
|
+
this.isFormmatting = false;
|
|
1066
1069
|
}
|
|
1067
1070
|
format(error, vm, privateObject) {
|
|
1071
|
+
// All Ruby exceptions raised during formatting exception message should
|
|
1072
|
+
// be caught and return a fallback message.
|
|
1073
|
+
// Therefore, we don't need to worry about infinite recursion here ideally
|
|
1074
|
+
// but checking re-entrancy just in case.
|
|
1075
|
+
class RbExceptionFormatterError extends Error {
|
|
1076
|
+
}
|
|
1077
|
+
if (this.isFormmatting) {
|
|
1078
|
+
throw new RbExceptionFormatterError("Unexpected exception occurred during formatting exception message");
|
|
1079
|
+
}
|
|
1080
|
+
this.isFormmatting = true;
|
|
1081
|
+
try {
|
|
1082
|
+
return this._format(error, vm, privateObject);
|
|
1083
|
+
}
|
|
1084
|
+
finally {
|
|
1085
|
+
this.isFormmatting = false;
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
_format(error, vm, privateObject) {
|
|
1068
1089
|
const [zeroLiteral, oneLiteral, newLineLiteral] = (() => {
|
|
1069
1090
|
if (this.literalsCache == null) {
|
|
1070
1091
|
const zeroOneNewLine = [
|
|
@@ -1079,18 +1100,43 @@
|
|
|
1079
1100
|
return this.literalsCache;
|
|
1080
1101
|
}
|
|
1081
1102
|
})();
|
|
1082
|
-
|
|
1103
|
+
let className;
|
|
1104
|
+
let backtrace;
|
|
1105
|
+
let message;
|
|
1106
|
+
try {
|
|
1107
|
+
className = error.call("class").toString();
|
|
1108
|
+
}
|
|
1109
|
+
catch (e) {
|
|
1110
|
+
className = "unknown";
|
|
1111
|
+
}
|
|
1112
|
+
try {
|
|
1113
|
+
message = error.toString();
|
|
1114
|
+
}
|
|
1115
|
+
catch (e) {
|
|
1116
|
+
message = "unknown";
|
|
1117
|
+
}
|
|
1118
|
+
try {
|
|
1119
|
+
backtrace = error.call("backtrace");
|
|
1120
|
+
}
|
|
1121
|
+
catch (e) {
|
|
1122
|
+
return this.formatString(className, message);
|
|
1123
|
+
}
|
|
1083
1124
|
if (backtrace.call("nil?").toString() === "true") {
|
|
1084
|
-
return this.formatString(
|
|
1125
|
+
return this.formatString(className, message);
|
|
1126
|
+
}
|
|
1127
|
+
try {
|
|
1128
|
+
const firstLine = backtrace.call("at", zeroLiteral);
|
|
1129
|
+
const restLines = backtrace
|
|
1130
|
+
.call("drop", oneLiteral)
|
|
1131
|
+
.call("join", newLineLiteral);
|
|
1132
|
+
return this.formatString(className, message, [
|
|
1133
|
+
firstLine.toString(),
|
|
1134
|
+
restLines.toString(),
|
|
1135
|
+
]);
|
|
1136
|
+
}
|
|
1137
|
+
catch (e) {
|
|
1138
|
+
return this.formatString(className, message);
|
|
1085
1139
|
}
|
|
1086
|
-
const firstLine = backtrace.call("at", zeroLiteral);
|
|
1087
|
-
const restLines = backtrace
|
|
1088
|
-
.call("drop", oneLiteral)
|
|
1089
|
-
.call("join", newLineLiteral);
|
|
1090
|
-
return this.formatString(error.call("class").toString(), error.toString(), [
|
|
1091
|
-
firstLine.toString(),
|
|
1092
|
-
restLines.toString(),
|
|
1093
|
-
]);
|
|
1094
1140
|
}
|
|
1095
1141
|
formatString(klass, message, backtrace) {
|
|
1096
1142
|
if (backtrace) {
|