opal 1.8.0.alpha1 → 1.8.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.eslintrc.js +1 -0
- data/README.md +7 -7
- data/UNRELEASED.md +14 -0
- data/docs/releasing.md +8 -16
- data/lib/opal/cli_runners/chrome.rb +5 -1
- data/lib/opal/nodes/closure.rb +15 -7
- data/lib/opal/nodes/defined.rb +1 -1
- data/lib/opal/nodes/literal.rb +10 -6
- data/lib/opal/nodes/rescue.rb +1 -1
- data/lib/opal/simple_server.rb +2 -2
- data/lib/opal/version.rb +1 -1
- data/opal/corelib/array.rb +39 -21
- data/opal/corelib/class.rb +26 -8
- data/opal/corelib/complex.rb +1 -1
- data/opal/corelib/constants.rb +2 -2
- data/opal/corelib/enumerator/arithmetic_sequence.rb +1 -1
- data/opal/corelib/error.rb +10 -0
- data/opal/corelib/hash.rb +30 -18
- data/opal/corelib/kernel.rb +0 -1
- data/opal/corelib/module.rb +44 -5
- data/opal/corelib/number.rb +28 -1
- data/opal/corelib/range.rb +1 -1
- data/opal/corelib/rational.rb +1 -1
- data/opal/corelib/runtime.js +124 -42
- data/opal/corelib/string.rb +36 -8
- data/opal/corelib/struct.rb +1 -1
- data/opal/corelib/time.rb +1 -1
- data/spec/filters/bugs/array.rb +58 -0
- data/spec/filters/bugs/basicobject.rb +7 -0
- data/spec/filters/bugs/bigdecimal.rb +1 -2
- data/spec/filters/bugs/binding.rb +1 -0
- data/spec/filters/bugs/class.rb +2 -3
- data/spec/filters/bugs/complex.rb +3 -0
- data/spec/filters/bugs/date.rb +5 -2
- data/spec/filters/bugs/datetime.rb +1 -0
- data/spec/filters/bugs/delegate.rb +1 -2
- data/spec/filters/bugs/encoding.rb +1 -1
- data/spec/filters/bugs/enumerable.rb +11 -0
- data/spec/filters/bugs/enumerator.rb +15 -2
- data/spec/filters/bugs/exception.rb +9 -4
- data/spec/filters/bugs/file.rb +2 -0
- data/spec/filters/bugs/float.rb +1 -0
- data/spec/filters/bugs/freeze.rb +5 -49
- data/spec/filters/bugs/hash.rb +1 -0
- data/spec/filters/bugs/integer.rb +5 -6
- data/spec/filters/bugs/kernel.rb +12 -5
- data/spec/filters/bugs/language.rb +33 -15
- data/spec/filters/bugs/marshal.rb +63 -4
- data/spec/filters/bugs/method.rb +2 -10
- data/spec/filters/bugs/module.rb +18 -7
- data/spec/filters/bugs/objectspace.rb +2 -0
- data/spec/filters/bugs/pathname.rb +1 -0
- data/spec/filters/bugs/proc.rb +4 -2
- data/spec/filters/bugs/random.rb +0 -3
- data/spec/filters/bugs/range.rb +1 -1
- data/spec/filters/bugs/rational.rb +2 -0
- data/spec/filters/bugs/refinement.rb +19 -0
- data/spec/filters/bugs/regexp.rb +27 -5
- data/spec/filters/bugs/ruby-32.rb +0 -4
- data/spec/filters/bugs/set.rb +10 -2
- data/spec/filters/bugs/singleton.rb +0 -2
- data/spec/filters/bugs/string.rb +140 -1
- data/spec/filters/bugs/struct.rb +15 -5
- data/spec/filters/bugs/time.rb +56 -2
- data/spec/filters/bugs/trace_point.rb +1 -0
- data/spec/filters/bugs/unboundmethod.rb +4 -9
- data/spec/filters/bugs/warnings.rb +0 -1
- data/spec/filters/platform/firefox/exception.rb +3 -3
- data/spec/filters/platform/firefox/kernel.rb +1 -0
- data/spec/filters/platform/safari/exception.rb +2 -2
- data/spec/filters/platform/safari/float.rb +1 -0
- data/spec/filters/platform/safari/kernel.rb +1 -0
- data/spec/filters/platform/safari/literal_regexp.rb +2 -2
- data/spec/filters/unsupported/hash.rb +1 -1
- data/spec/lib/compiler_spec.rb +4 -0
- data/spec/opal/core/class/clone_spec.rb +36 -0
- data/spec/opal/core/object_id_spec.rb +0 -6
- data/spec/opal/language/predefined_spec.rb +20 -0
- data/spec/opal/language/yield_spec.rb +43 -0
- data/spec/ruby_specs +0 -2
- data/stdlib/bigdecimal.rb +2 -0
- data/stdlib/delegate.rb +3 -4
- data/stdlib/pathname.rb +1 -1
- data/stdlib/promise/v2.rb +22 -7
- data/stdlib/stringio.rb +2 -0
- data/tasks/testing.rake +15 -11
- data/test/opal/promisev2/test_always.rb +14 -0
- data/test/opal/unsupported_and_bugs.rb +0 -8
- metadata +10 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 506ba9114548fa5c492467950421043dbf46d0b72df49eab40c5a62e6f6c2ce6
|
4
|
+
data.tar.gz: e59c280933851d6de0a63f42b19139e5b16c90f68fe0c4652cf555a5ef7e1968
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8536d4701b9197c3cee876bb35bb3fd34cee5726241069d108fa12f8c83753c43d8bc6ac8f95fd867ee5da23ba98b2c8a1b3e284a56df7b6656ffa17850b36c4
|
7
|
+
data.tar.gz: b0f0283471809563e3ea29afcef0b911109aa7d9d9a1f04701c34f48facc8654f20cacc3bd7061273bf74d837c7ae1256d13249e1eb9371e6faa94e3f54fa22b
|
data/.eslintrc.js
CHANGED
data/README.md
CHANGED
@@ -145,12 +145,7 @@ The test suite can be run using:
|
|
145
145
|
|
146
146
|
$ bundle exec rake
|
147
147
|
|
148
|
-
This
|
149
|
-
|
150
|
-
#### Automated runs
|
151
|
-
|
152
|
-
A `Guardfile` with decent mappings between specs and lib/corelib/stdlib files is in place.
|
153
|
-
Run `bundle exec guard -i` to start `guard`.
|
148
|
+
This command will run all RSpec and MSpec examples in sequence.
|
154
149
|
|
155
150
|
|
156
151
|
### MSpec
|
@@ -170,6 +165,11 @@ visit `http://localhost:9292/` in any web browser.
|
|
170
165
|
$ rake rspec
|
171
166
|
|
172
167
|
|
168
|
+
### Automated runs
|
169
|
+
|
170
|
+
A `Guardfile` with decent mappings between specs and lib/corelib/stdlib files is in place.
|
171
|
+
Run `bundle exec guard -i` to start `guard`.
|
172
|
+
|
173
173
|
## Code Overview
|
174
174
|
|
175
175
|
What code is supposed to run where?
|
@@ -247,7 +247,7 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
|
|
247
247
|
|
248
248
|
### Sponsored Contributions
|
249
249
|
|
250
|
-
<a href="https://nebulab.it/?utm_source=github&utm_medium=sponsors" target="_blank"><img src="https://
|
250
|
+
<a href="https://nebulab.it/?utm_source=github&utm_medium=sponsors" target="_blank"><img src="https://raw.githubusercontent.com/solidusio/brand/master/partners/Nebulab/logo-dark-light.svg" alt="Nebulab Logo"></a>
|
251
251
|
|
252
252
|
|
253
253
|
## License
|
data/UNRELEASED.md
CHANGED
@@ -41,6 +41,8 @@ This release brings a lot of performance improvements, our tests on Asciidoctor
|
|
41
41
|
### Compatibility
|
42
42
|
|
43
43
|
- Add a magic-comment that will disable x-string compilation to JavaScript (#2543)
|
44
|
+
- Pass value in `PromiseV2#always` just like `PromiseV1#always` does it (#2579)
|
45
|
+
- `#hash` now returns integers #2582)
|
44
46
|
|
45
47
|
### Fixed
|
46
48
|
|
@@ -53,6 +55,13 @@ This release brings a lot of performance improvements, our tests on Asciidoctor
|
|
53
55
|
- Propagate removal of method from included/prepended modules (#2553)
|
54
56
|
- Restore `nodejs/yaml` functionality (#2551)
|
55
57
|
- Fix sine `Range#size` edge cases (#2541)
|
58
|
+
- Use a Map instead of a POJO for the jsid_cache (#2584)
|
59
|
+
- Fix `String#object_id`, `String#__id__`, `String#hash` to match CRuby's behavior (#2576)
|
60
|
+
- Lowercase response headers in `SimpleServer` for rack 3.0 compatibility (#2578)
|
61
|
+
- Fix `Module#clone` and `Module#dup` to properly copy methods (#2572)
|
62
|
+
- Chrome runner fix: support code that contains `</script>` (#2581)
|
63
|
+
- Do not skip `$truthy` when left hand side of a comparison is `self` (#2596)
|
64
|
+
- Unexpected `return`/`break` should raise `LocalJumpError` (#2591)
|
56
65
|
|
57
66
|
### Added
|
58
67
|
|
@@ -67,6 +76,7 @@ This release brings a lot of performance improvements, our tests on Asciidoctor
|
|
67
76
|
### Documentation
|
68
77
|
|
69
78
|
- Bridging documentation (#2541)
|
79
|
+
- Fix Typo in Running tests Section of README.md File (#2580)
|
70
80
|
|
71
81
|
### Performance
|
72
82
|
|
@@ -78,6 +88,10 @@ This release brings a lot of performance improvements, our tests on Asciidoctor
|
|
78
88
|
- Optimize argument slicing in runtime for performance (#2555)
|
79
89
|
- Closure: Generate a JavaScript object, not an Error, gain up to 15% on Asciidoctor (#2556)
|
80
90
|
- Optimize `String#split` and `String#start_with` (#2560)
|
91
|
+
- Compute `$@` dynamically (#2592)
|
92
|
+
- Optimize the `$prop` helper (#2597)
|
93
|
+
- Improve `Array.push()` performance when pushing many items (#2565)
|
94
|
+
-
|
81
95
|
|
82
96
|
### Internal
|
83
97
|
|
data/docs/releasing.md
CHANGED
@@ -8,21 +8,14 @@ _This guide is a work-in-progress._
|
|
8
8
|
|
9
9
|
All of the following is now covered by `bin/rake release:prepare VERSION=v1.2.3`
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
- Update `
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
- [skip for pre-releases] Run `bin/rake changelog VERSION=v1.2.3` specifying the version number you're about to release
|
20
|
-
- [skip for pre-releases] Empty UNRELEASED.md
|
21
|
-
|
22
|
-
### The commit
|
23
|
-
|
24
|
-
- Commit the updated changelog along with the version bump using this commit message:
|
25
|
-
"Release v1.2.3"
|
11
|
+
1. Update the version
|
12
|
+
- Update `lib/opal/version.rb`
|
13
|
+
- Update `opal/corelib/constants.rb` with the same version number along with release dates
|
14
|
+
2. Update the changelog
|
15
|
+
- Ensure all the unreleased changes are documented in UNRELEASED.md
|
16
|
+
- [skip for pre-releases] Run `bin/rake changelog VERSION=v1.2.3` specifying the version number you're about to release
|
17
|
+
- [skip for pre-releases] Empty UNRELEASED.md
|
18
|
+
3. Commit the updated changelog along with the version bump using this commit message: "Release v1.2.3"
|
26
19
|
|
27
20
|
---
|
28
21
|
|
@@ -56,4 +49,3 @@ All of the following is now covered by `bin/rake release:prepare VERSION=v1.2.3`
|
|
56
49
|
- Create a new pull request that:
|
57
50
|
- Updates a version to `v1.x.0.dev` in both `lib/opal/version.rb` and `opal/corelib/constants.rb`
|
58
51
|
- Remember to merge that PR before merging anything else next once we decide to not release any more point releases from `master`.
|
59
|
-
|
@@ -70,6 +70,10 @@ module Opal
|
|
70
70
|
ext = builder.output_extension
|
71
71
|
module_type = ' type="module"' if builder.esm?
|
72
72
|
|
73
|
+
# Some maps may contain `</script>` fragment (eg. in strings) which would close our
|
74
|
+
# `<script>` tag prematurely. For this case, we need to escape the `</script>` tag.
|
75
|
+
map_json = map.to_json.gsub(/(<\/scr)(ipt>)/i, '\1"+"\2')
|
76
|
+
|
73
77
|
# Chrome can't handle huge data passed to `addScriptToEvaluateOnLoad`
|
74
78
|
# https://groups.google.com/a/chromium.org/forum/#!topic/chromium-discuss/U5qyeX_ydBo
|
75
79
|
# The only way is to create temporary files and pass them to chrome.
|
@@ -86,7 +90,7 @@ module Opal
|
|
86
90
|
sourceMapSupport.install({
|
87
91
|
retrieveSourceMap: function(path) {
|
88
92
|
return path.endsWith('/index.#{ext}') ? {
|
89
|
-
url: './index.map', map: #{
|
93
|
+
url: './index.map', map: #{map_json}
|
90
94
|
} : null;
|
91
95
|
}
|
92
96
|
});
|
data/lib/opal/nodes/closure.rb
CHANGED
@@ -102,7 +102,7 @@ module Opal
|
|
102
102
|
def generate_thrower(type, closure, value)
|
103
103
|
id = closure.register_catcher(type)
|
104
104
|
closure.register_thrower(type, id)
|
105
|
-
push id, '.$throw(',
|
105
|
+
push id, '.$throw(', expr_or_nil(value), ', ', scope.identify!, '.$$is_lambda)'
|
106
106
|
id
|
107
107
|
end
|
108
108
|
|
@@ -113,11 +113,11 @@ module Opal
|
|
113
113
|
id = closure.throwers[type]
|
114
114
|
else
|
115
115
|
id = compiler.unique_temp('t_')
|
116
|
-
|
117
|
-
|
116
|
+
parent_scope = closure.node.scope&.parent || top_scope
|
117
|
+
parent_scope.add_scope_temp("#{id} = $thrower('#{type}')")
|
118
118
|
closure.register_thrower(type, id)
|
119
119
|
end
|
120
|
-
push id, '.$throw(',
|
120
|
+
push id, '.$throw(', expr_or_nil(value), ', ', scope.identify!, '.$$is_lambda)'
|
121
121
|
id
|
122
122
|
end
|
123
123
|
|
@@ -132,7 +132,7 @@ module Opal
|
|
132
132
|
if iter_closure
|
133
133
|
generate_thrower_without_catcher(:return, iter_closure, value)
|
134
134
|
elsif compiler.eval?
|
135
|
-
push 'Opal.t_eval_return.$throw(',
|
135
|
+
push 'Opal.t_eval_return.$throw(', expr_or_nil(value), ', false)'
|
136
136
|
else
|
137
137
|
error 'Invalid return'
|
138
138
|
end
|
@@ -211,9 +211,11 @@ module Opal
|
|
211
211
|
|
212
212
|
helper :thrower
|
213
213
|
|
214
|
+
catchers_without_eval_return = catchers.grep_v(:eval_return)
|
215
|
+
|
214
216
|
push "} catch($e) {"
|
215
217
|
indent do
|
216
|
-
|
218
|
+
catchers.each do |type|
|
217
219
|
case type
|
218
220
|
when :eval_return
|
219
221
|
line "if ($e === Opal.t_eval_return) return $e.$v;"
|
@@ -225,9 +227,15 @@ module Opal
|
|
225
227
|
end
|
226
228
|
line "}"
|
227
229
|
|
230
|
+
unless catchers_without_eval_return.empty?
|
231
|
+
push " finally {", *catchers_without_eval_return.map { |type| "$t_#{type}.is_orphan = true;" }, "}"
|
232
|
+
end
|
233
|
+
|
228
234
|
unshift "return " if closure_is? SEND
|
229
235
|
|
230
|
-
|
236
|
+
unless catchers_without_eval_return.empty?
|
237
|
+
unshift "var ", catchers_without_eval_return.map { |type| "$t_#{type} = $thrower('#{type}')" }.join(", "), "; "
|
238
|
+
end
|
231
239
|
unshift "try { "
|
232
240
|
|
233
241
|
unless closure_is? JS_FUNCTION
|
data/lib/opal/nodes/defined.rb
CHANGED
data/lib/opal/nodes/literal.rb
CHANGED
@@ -5,14 +5,10 @@ require 'opal/nodes/base'
|
|
5
5
|
module Opal
|
6
6
|
module Nodes
|
7
7
|
class ValueNode < Base
|
8
|
-
handle :true, :false, :
|
8
|
+
handle :true, :false, :nil
|
9
9
|
|
10
10
|
def compile
|
11
|
-
|
12
|
-
push scope.self
|
13
|
-
else
|
14
|
-
push type.to_s
|
15
|
-
end
|
11
|
+
push type.to_s
|
16
12
|
end
|
17
13
|
|
18
14
|
def self.truthy_optimize?
|
@@ -20,6 +16,14 @@ module Opal
|
|
20
16
|
end
|
21
17
|
end
|
22
18
|
|
19
|
+
class SelfNode < Base
|
20
|
+
handle :self
|
21
|
+
|
22
|
+
def compile
|
23
|
+
push scope.self
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
23
27
|
class NumericNode < Base
|
24
28
|
handle :int, :float
|
25
29
|
|
data/lib/opal/nodes/rescue.rb
CHANGED
data/lib/opal/simple_server.rb
CHANGED
@@ -51,7 +51,7 @@ class Opal::SimpleServer
|
|
51
51
|
asset = fetch_asset(path)
|
52
52
|
[
|
53
53
|
200,
|
54
|
-
{ '
|
54
|
+
{ 'content-type' => 'application/javascript' },
|
55
55
|
[asset[:data], "\n", asset[:map].to_data_uri_comment],
|
56
56
|
]
|
57
57
|
end
|
@@ -99,6 +99,6 @@ class Opal::SimpleServer
|
|
99
99
|
</html>
|
100
100
|
HTML
|
101
101
|
end
|
102
|
-
[200, { '
|
102
|
+
[200, { 'content-type' => 'text/html' }, [html]]
|
103
103
|
end
|
104
104
|
end
|
data/lib/opal/version.rb
CHANGED
data/opal/corelib/array.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# helpers: truthy, falsy,
|
1
|
+
# helpers: truthy, falsy, yield1, hash_get, hash_put, hash_delete, coerce_to, respond_to, deny_frozen_access, freeze, opal32_init, opal32_add
|
2
2
|
# backtick_javascript: true
|
3
3
|
|
4
4
|
require 'corelib/enumerable'
|
@@ -76,6 +76,22 @@ class ::Array < `Array`
|
|
76
76
|
}
|
77
77
|
return #{`array`.to_a};
|
78
78
|
}
|
79
|
+
|
80
|
+
function fast_push(arr, objects) {
|
81
|
+
// push.apply() for arrays longer than 32767 may cause various argument errors in browsers
|
82
|
+
// but it is significantly faster than a for loop, which pushes each element separately
|
83
|
+
// but apply() has a overhead by itself, for a small number of elements
|
84
|
+
// the for loop is significantly faster
|
85
|
+
// this is using the best option depending on objects.length
|
86
|
+
var length = objects.length;
|
87
|
+
if (length > 6 && length < 32767) {
|
88
|
+
arr.push.apply(arr, objects);
|
89
|
+
} else {
|
90
|
+
for (var i = 0; i < length; i++) {
|
91
|
+
arr.push(objects[i]);
|
92
|
+
}
|
93
|
+
}
|
94
|
+
}
|
79
95
|
}
|
80
96
|
|
81
97
|
def self.[](*objects)
|
@@ -99,7 +115,7 @@ class ::Array < `Array`
|
|
99
115
|
}
|
100
116
|
|
101
117
|
if (arguments.length === 0) {
|
102
|
-
self.splice(0, self.length);
|
118
|
+
if (self.length > 0) self.splice(0, self.length);
|
103
119
|
return self;
|
104
120
|
}
|
105
121
|
|
@@ -253,7 +269,7 @@ class ::Array < `Array`
|
|
253
269
|
end
|
254
270
|
|
255
271
|
%x{
|
256
|
-
if (#{
|
272
|
+
if (#{self} === #{other}) {
|
257
273
|
return 0;
|
258
274
|
}
|
259
275
|
|
@@ -1216,7 +1232,7 @@ class ::Array < `Array`
|
|
1216
1232
|
result.push(ary);
|
1217
1233
|
break;
|
1218
1234
|
default:
|
1219
|
-
|
1235
|
+
fast_push(result, _flatten(ary, level - 1));
|
1220
1236
|
}
|
1221
1237
|
}
|
1222
1238
|
return result;
|
@@ -1260,27 +1276,31 @@ class ::Array < `Array`
|
|
1260
1276
|
`$freeze(self)`
|
1261
1277
|
end
|
1262
1278
|
|
1279
|
+
`var $hash_ids`
|
1280
|
+
|
1263
1281
|
def hash
|
1264
1282
|
%x{
|
1265
1283
|
var top = ($hash_ids === undefined),
|
1266
|
-
result =
|
1284
|
+
result = $opal32_init(),
|
1267
1285
|
hash_id = self.$object_id(),
|
1268
1286
|
item, i, key;
|
1269
1287
|
|
1270
|
-
|
1271
|
-
|
1272
|
-
$hash_ids = Object.create(null);
|
1273
|
-
}
|
1288
|
+
result = $opal32_add(result, 0xA);
|
1289
|
+
result = $opal32_add(result, self.length);
|
1274
1290
|
|
1275
|
-
|
1276
|
-
|
1277
|
-
|
1278
|
-
|
1291
|
+
if (top) {
|
1292
|
+
$hash_ids = Object.create(null);
|
1293
|
+
}
|
1294
|
+
// return early for recursive structures
|
1295
|
+
else if ($hash_ids[hash_id]) {
|
1296
|
+
return $opal32_add(result, 0x01010101);
|
1297
|
+
}
|
1279
1298
|
|
1299
|
+
try {
|
1280
1300
|
for (key in $hash_ids) {
|
1281
1301
|
item = $hash_ids[key];
|
1282
1302
|
if (#{eql?(`item`)}) {
|
1283
|
-
return
|
1303
|
+
return $opal32_add(result, 0x01010101);
|
1284
1304
|
}
|
1285
1305
|
}
|
1286
1306
|
|
@@ -1288,10 +1308,10 @@ class ::Array < `Array`
|
|
1288
1308
|
|
1289
1309
|
for (i = 0; i < self.length; i++) {
|
1290
1310
|
item = self[i];
|
1291
|
-
result
|
1311
|
+
result = $opal32_add(result, item.$hash());
|
1292
1312
|
}
|
1293
1313
|
|
1294
|
-
return result
|
1314
|
+
return result;
|
1295
1315
|
} finally {
|
1296
1316
|
if (top) {
|
1297
1317
|
$hash_ids = undefined;
|
@@ -1741,9 +1761,7 @@ class ::Array < `Array`
|
|
1741
1761
|
%x{
|
1742
1762
|
$deny_frozen_access(self);
|
1743
1763
|
|
1744
|
-
|
1745
|
-
self.push(objects[i]);
|
1746
|
-
}
|
1764
|
+
fast_push(self, objects);
|
1747
1765
|
}
|
1748
1766
|
|
1749
1767
|
self
|
@@ -1801,8 +1819,8 @@ class ::Array < `Array`
|
|
1801
1819
|
other = `convertToArray(other)`
|
1802
1820
|
|
1803
1821
|
%x{
|
1804
|
-
self.splice(0, self.length);
|
1805
|
-
|
1822
|
+
if (self.length > 0) self.splice(0, self.length);
|
1823
|
+
fast_push(self, other);
|
1806
1824
|
}
|
1807
1825
|
|
1808
1826
|
self
|
data/opal/corelib/class.rb
CHANGED
@@ -24,6 +24,32 @@ class ::Class
|
|
24
24
|
}
|
25
25
|
end
|
26
26
|
|
27
|
+
def clone(freeze: nil)
|
28
|
+
unless freeze.nil? || freeze == true || freeze == false
|
29
|
+
raise ArgumentError, "unexpected value for freeze: #{freeze.class}"
|
30
|
+
end
|
31
|
+
|
32
|
+
copy = `Opal.allocate_class(nil, self.$$super)`
|
33
|
+
copy.copy_instance_variables(self)
|
34
|
+
copy.copy_singleton_methods(self)
|
35
|
+
copy.initialize_clone(self, freeze: freeze)
|
36
|
+
|
37
|
+
if freeze == true || (freeze.nil? && frozen?)
|
38
|
+
copy.freeze
|
39
|
+
end
|
40
|
+
|
41
|
+
copy
|
42
|
+
end
|
43
|
+
|
44
|
+
def dup
|
45
|
+
copy = `Opal.allocate_class(nil, self.$$super)`
|
46
|
+
|
47
|
+
copy.copy_instance_variables(self)
|
48
|
+
copy.initialize_dup(self)
|
49
|
+
|
50
|
+
copy
|
51
|
+
end
|
52
|
+
|
27
53
|
def descendants
|
28
54
|
subclasses + subclasses.map(&:descendants).flatten
|
29
55
|
end
|
@@ -31,14 +57,6 @@ class ::Class
|
|
31
57
|
def inherited(cls)
|
32
58
|
end
|
33
59
|
|
34
|
-
def initialize_dup(original)
|
35
|
-
initialize_copy(original)
|
36
|
-
%x{
|
37
|
-
self.$$name = null;
|
38
|
-
self.$$full_name = null;
|
39
|
-
}
|
40
|
-
end
|
41
|
-
|
42
60
|
def new(*args, &block)
|
43
61
|
%x{
|
44
62
|
var object = #{allocate};
|
data/opal/corelib/complex.rb
CHANGED
data/opal/corelib/constants.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
::RUBY_PLATFORM = 'opal'
|
2
2
|
::RUBY_ENGINE = 'opal'
|
3
3
|
::RUBY_VERSION = '3.2.0'
|
4
|
-
::RUBY_ENGINE_VERSION = '1.8.0.
|
5
|
-
::RUBY_RELEASE_DATE = '2023-
|
4
|
+
::RUBY_ENGINE_VERSION = '1.8.0.beta1'
|
5
|
+
::RUBY_RELEASE_DATE = '2023-10-12'
|
6
6
|
::RUBY_PATCHLEVEL = 0
|
7
7
|
::RUBY_REVISION = '0'
|
8
8
|
::RUBY_COPYRIGHT = 'opal - Copyright (C) 2011-2023 Adam Beynon and the Opal contributors'
|
data/opal/corelib/error.rb
CHANGED
@@ -316,6 +316,16 @@ class ::KeyError
|
|
316
316
|
end
|
317
317
|
end
|
318
318
|
|
319
|
+
class ::LocalJumpError
|
320
|
+
attr_reader :exit_value, :reason
|
321
|
+
|
322
|
+
def initialize(message, exit_value = nil, reason = :noreason)
|
323
|
+
super message
|
324
|
+
@exit_value = exit_value
|
325
|
+
@reason = reason
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
319
329
|
module ::JS
|
320
330
|
class Error
|
321
331
|
end
|
data/opal/corelib/hash.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# helpers: yield1, hash_clone, hash_delete, hash_each, hash_get, hash_put, deny_frozen_access, freeze
|
1
|
+
# helpers: yield1, hash_clone, hash_delete, hash_each, hash_get, hash_put, deny_frozen_access, freeze, opal32_init, opal32_add
|
2
2
|
# backtick_javascript: true
|
3
3
|
|
4
4
|
require 'corelib/enumerable'
|
@@ -481,41 +481,53 @@ class ::Hash < `Map`
|
|
481
481
|
}
|
482
482
|
end
|
483
483
|
|
484
|
+
`var $hash_ids`
|
485
|
+
|
484
486
|
def hash
|
485
487
|
%x{
|
486
|
-
var top = (
|
488
|
+
var top = ($hash_ids === undefined),
|
487
489
|
hash_id = self.$object_id(),
|
488
|
-
result =
|
489
|
-
key, item
|
490
|
+
result = $opal32_init(),
|
491
|
+
key, item, i,
|
492
|
+
size = self.size, ary = new Int32Array(size);
|
490
493
|
|
491
|
-
|
492
|
-
|
493
|
-
Opal.hash_ids = Object.create(null);
|
494
|
-
}
|
494
|
+
result = $opal32_add(result, 0x4);
|
495
|
+
result = $opal32_add(result, size);
|
495
496
|
|
496
|
-
|
497
|
-
|
498
|
-
|
497
|
+
if (top) {
|
498
|
+
$hash_ids = Object.create(null);
|
499
|
+
}
|
500
|
+
else if ($hash_ids[hash_id]) {
|
501
|
+
return $opal32_add(result, 0x01010101);
|
502
|
+
}
|
499
503
|
|
500
|
-
|
501
|
-
|
504
|
+
try {
|
505
|
+
for (key in $hash_ids) {
|
506
|
+
item = $hash_ids[key];
|
502
507
|
if (#{eql?(`item`)}) {
|
503
|
-
return
|
508
|
+
return $opal32_add(result, 0x01010101);
|
504
509
|
}
|
505
510
|
}
|
506
511
|
|
507
|
-
|
512
|
+
$hash_ids[hash_id] = self;
|
513
|
+
i = 0
|
508
514
|
|
509
515
|
$hash_each(self, false, function(key, value) {
|
510
|
-
|
516
|
+
ary[i] = [0x70414952, key, value].$hash();
|
517
|
+
i++;
|
511
518
|
return [false, false];
|
512
519
|
});
|
513
520
|
|
514
|
-
|
521
|
+
ary = ary.sort();
|
522
|
+
|
523
|
+
for (i = 0; i < ary.length; i++) {
|
524
|
+
result = $opal32_add(result, ary[i]);
|
525
|
+
}
|
515
526
|
|
527
|
+
return result;
|
516
528
|
} finally {
|
517
529
|
if (top) {
|
518
|
-
|
530
|
+
$hash_ids = undefined;
|
519
531
|
}
|
520
532
|
}
|
521
533
|
}
|
data/opal/corelib/kernel.rb
CHANGED
data/opal/corelib/module.rb
CHANGED
@@ -733,11 +733,50 @@ class ::Module
|
|
733
733
|
}
|
734
734
|
end
|
735
735
|
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
736
|
+
%x{
|
737
|
+
function copyInstanceMethods(from, to) {
|
738
|
+
var i, method_names = Opal.own_instance_methods(from);
|
739
|
+
for (i = 0; i < method_names.length; i++) {
|
740
|
+
var name = method_names[i],
|
741
|
+
jsid = $jsid(name),
|
742
|
+
body = from.$$prototype[jsid],
|
743
|
+
wrapped = Opal.wrapMethodBody(body);
|
744
|
+
|
745
|
+
wrapped.$$jsid = name;
|
746
|
+
Opal.defn(to, jsid, wrapped);
|
747
|
+
}
|
748
|
+
}
|
749
|
+
|
750
|
+
function copyIncludedModules(from, to) {
|
751
|
+
var modules = from.$$own_included_modules;
|
752
|
+
for (var i = modules.length - 1; i >= 0; i--) {
|
753
|
+
Opal.append_features(modules[i], to);
|
754
|
+
}
|
755
|
+
}
|
756
|
+
|
757
|
+
function copyPrependedModules(from, to) {
|
758
|
+
var modules = from.$$own_prepended_modules;
|
759
|
+
for (var i = modules.length - 1; i >= 0; i--) {
|
760
|
+
Opal.prepend_features(modules[i], to);
|
761
|
+
}
|
762
|
+
}
|
763
|
+
}
|
764
|
+
|
765
|
+
def initialize_copy(other)
|
766
|
+
%x{
|
767
|
+
copyInstanceMethods(other, self);
|
768
|
+
copyIncludedModules(other, self);
|
769
|
+
copyPrependedModules(other, self);
|
770
|
+
self.$$cloned_from = other.$$cloned_from.concat(other);
|
771
|
+
}
|
772
|
+
copy_class_variables(other)
|
773
|
+
copy_constants(other)
|
774
|
+
end
|
775
|
+
|
776
|
+
def initialize_dup(other)
|
777
|
+
super
|
778
|
+
# Unlike other classes, Module's singleton methods are copied on Object#dup.
|
779
|
+
copy_singleton_methods(other)
|
741
780
|
end
|
742
781
|
|
743
782
|
def copy_class_variables(other)
|