opal 1.8.0.alpha1 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.js +1 -0
  3. data/CHANGELOG.md +119 -2
  4. data/README.md +7 -7
  5. data/UNRELEASED.md +1 -78
  6. data/docs/releasing.md +8 -16
  7. data/lib/opal/cli_runners/chrome.rb +5 -1
  8. data/lib/opal/nodes/closure.rb +15 -7
  9. data/lib/opal/nodes/defined.rb +1 -1
  10. data/lib/opal/nodes/literal.rb +10 -6
  11. data/lib/opal/nodes/rescue.rb +1 -1
  12. data/lib/opal/simple_server.rb +2 -2
  13. data/lib/opal/version.rb +1 -1
  14. data/opal/corelib/array.rb +39 -21
  15. data/opal/corelib/class.rb +26 -8
  16. data/opal/corelib/complex.rb +1 -1
  17. data/opal/corelib/constants.rb +2 -2
  18. data/opal/corelib/enumerator/arithmetic_sequence.rb +1 -1
  19. data/opal/corelib/error.rb +10 -0
  20. data/opal/corelib/hash.rb +36 -20
  21. data/opal/corelib/kernel.rb +0 -1
  22. data/opal/corelib/method.rb +1 -0
  23. data/opal/corelib/module.rb +82 -22
  24. data/opal/corelib/number.rb +28 -1
  25. data/opal/corelib/range.rb +55 -11
  26. data/opal/corelib/rational.rb +1 -1
  27. data/opal/corelib/runtime.js +132 -50
  28. data/opal/corelib/string.rb +36 -8
  29. data/opal/corelib/struct.rb +1 -1
  30. data/opal/corelib/time.rb +1 -1
  31. data/spec/filters/bugs/array.rb +58 -0
  32. data/spec/filters/bugs/basicobject.rb +7 -0
  33. data/spec/filters/bugs/bigdecimal.rb +1 -2
  34. data/spec/filters/bugs/binding.rb +1 -0
  35. data/spec/filters/bugs/cgi.rb +40 -0
  36. data/spec/filters/bugs/class.rb +2 -3
  37. data/spec/filters/bugs/complex.rb +3 -0
  38. data/spec/filters/bugs/date.rb +5 -2
  39. data/spec/filters/bugs/datetime.rb +1 -0
  40. data/spec/filters/bugs/delegate.rb +1 -2
  41. data/spec/filters/bugs/encoding.rb +1 -1
  42. data/spec/filters/bugs/enumerable.rb +11 -0
  43. data/spec/filters/bugs/enumerator.rb +15 -2
  44. data/spec/filters/bugs/exception.rb +9 -4
  45. data/spec/filters/bugs/file.rb +2 -0
  46. data/spec/filters/bugs/float.rb +1 -0
  47. data/spec/filters/bugs/freeze.rb +5 -49
  48. data/spec/filters/bugs/hash.rb +1 -0
  49. data/spec/filters/bugs/integer.rb +5 -6
  50. data/spec/filters/bugs/kernel.rb +12 -6
  51. data/spec/filters/bugs/language.rb +33 -15
  52. data/spec/filters/bugs/marshal.rb +63 -4
  53. data/spec/filters/bugs/method.rb +2 -13
  54. data/spec/filters/bugs/module.rb +19 -17
  55. data/spec/filters/bugs/objectspace.rb +2 -0
  56. data/spec/filters/bugs/pathname.rb +1 -0
  57. data/spec/filters/bugs/proc.rb +4 -2
  58. data/spec/filters/bugs/random.rb +0 -3
  59. data/spec/filters/bugs/range.rb +3 -17
  60. data/spec/filters/bugs/rational.rb +2 -0
  61. data/spec/filters/bugs/refinement.rb +19 -0
  62. data/spec/filters/bugs/regexp.rb +27 -5
  63. data/spec/filters/bugs/ruby-32.rb +0 -4
  64. data/spec/filters/bugs/set.rb +10 -2
  65. data/spec/filters/bugs/singleton.rb +0 -2
  66. data/spec/filters/bugs/string.rb +140 -1
  67. data/spec/filters/bugs/struct.rb +15 -5
  68. data/spec/filters/bugs/time.rb +56 -2
  69. data/spec/filters/bugs/trace_point.rb +1 -0
  70. data/spec/filters/bugs/unboundmethod.rb +4 -9
  71. data/spec/filters/bugs/warnings.rb +0 -1
  72. data/spec/filters/platform/firefox/exception.rb +3 -3
  73. data/spec/filters/platform/firefox/kernel.rb +1 -0
  74. data/spec/filters/platform/safari/exception.rb +2 -2
  75. data/spec/filters/platform/safari/float.rb +1 -0
  76. data/spec/filters/platform/safari/kernel.rb +1 -0
  77. data/spec/filters/platform/safari/literal_regexp.rb +2 -2
  78. data/spec/filters/unsupported/hash.rb +1 -1
  79. data/spec/lib/compiler_spec.rb +4 -0
  80. data/spec/opal/core/class/clone_spec.rb +36 -0
  81. data/spec/opal/core/module/define_method_spec.rb +29 -0
  82. data/spec/opal/core/object_id_spec.rb +0 -6
  83. data/spec/opal/language/predefined_spec.rb +20 -0
  84. data/spec/opal/language/yield_spec.rb +43 -0
  85. data/spec/ruby_specs +1 -2
  86. data/stdlib/bigdecimal.rb +2 -0
  87. data/stdlib/cgi/util.rb +89 -0
  88. data/stdlib/cgi.rb +1 -14
  89. data/stdlib/delegate.rb +3 -4
  90. data/stdlib/pathname.rb +1 -1
  91. data/stdlib/promise/v2.rb +22 -7
  92. data/stdlib/stringio.rb +2 -0
  93. data/tasks/testing.rake +15 -11
  94. data/test/opal/promisev2/test_always.rb +14 -0
  95. data/test/opal/unsupported_and_bugs.rb +0 -8
  96. metadata +16 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c756d4ba883cb8f7c7bdfefa6b88cf4a2db0604d1ef8a906d7c58add76eee1bf
4
- data.tar.gz: e88f7de8d6add79b64c7d6b896fbd1c94f51edd34754e6da3ceb59e3fa501134
3
+ metadata.gz: ea935af6a628e09fb047d39c25422f717a4a4b9ef442fe7ec06183134b3163a1
4
+ data.tar.gz: d539d6a55c69651064a272a6110498bdba7d2146fa08704f4e759ee7693c28b2
5
5
  SHA512:
6
- metadata.gz: 1d9e3b8b4cc8decc9fc5644eb842ee84290bb0c6f231de362d259a691570296ac9fab95e400dccda20d317e12b7f3d58334d816a8f5279b304d0435d15ac699f
7
- data.tar.gz: '02883fef4e6869c54b718c370ddd03a934e50698eb37638da6788d212286fbc57ecab6c5e0c2c46bd02931ff75e39455f09a6de462157433b03cb8535d1ce76b'
6
+ metadata.gz: 603568ce7472d94e52edc2b4862a5cadb72313e8e1f344c723655a7a691b09cbde1d208e30935a68a2a78c59fa073724d66b24ef7cf56cf69eb8567b9aa851f4
7
+ data.tar.gz: 7ea6135b1f97d50584259706244705273b429d1eff03c44742f7c165b6caec782a06d33ac209f94545ec2c4f8665c1992367aebbf5699052fc62163414c99e1d
data/.eslintrc.js CHANGED
@@ -32,6 +32,7 @@ module.exports = {
32
32
  "Proxy": "readonly",
33
33
  "Reflect": "readonly",
34
34
  "Uint8Array": "readonly",
35
+ "Int32Array": "readonly",
35
36
  "WeakRef": "readonly",
36
37
  "Map": "readonly",
37
38
  }
data/CHANGELOG.md CHANGED
@@ -16,18 +16,135 @@ Changes are grouped as follows:
16
16
 
17
17
 
18
18
 
19
- ## [1.7.3](https://github.com/opal/opal/compare/v1.7.2...v1.7.3) - 2023-03-23
19
+ ## [1.8.0](https://github.com/opal/opal/compare/v1.7.4...v1.8.0) - 2023-10-26
20
20
 
21
21
 
22
22
  <!--
23
23
  ### Internal
24
- ### Changed
25
24
  ### Added
26
25
  ### Removed
27
26
  ### Deprecated
28
27
  ### Performance
28
+ ### Fixed
29
+ ### Documentation
29
30
  -->
30
31
 
32
+ ## Highlights
33
+
34
+ ### `Hash` is now bridged to JavaScript `Map`
35
+
36
+ This change brings a lot of benefits, but also some incompatibilities. The main benefit is that `Hash` now is both more performant and relies on native JavaScript capabilities.
37
+ This improves interoperability with JavaScript. As a downside, applications reaching for internal `Hash` data structures will need to be updated.
38
+
39
+ Interacting with `Hash` from `JavaScript` is easier than ever:
40
+
41
+ ```ruby
42
+ hash = `new Map([['a', 1], ['b', 2]])`
43
+ hash # => {a: 1, b: 2}
44
+ `console.log(hash)` # => Map(2) {"a" => 1, "b" => 2}
45
+ `hash.get('a')` # => 1
46
+ `hash.set('c', 3)`
47
+ hash # => {a: 1, b: 2, c: 3}
48
+ hash.keys # => ["a", "b", "c"]
49
+ hash.values # => [1, 2, 3]
50
+ ```
51
+
52
+ ### Performance improvements
53
+
54
+ This release brings a lot of performance improvements, our tests on Asciidoctor show a 25% improvement in performance, but we've seen up to 66% performance improvement on some applications.
55
+
56
+ ## Changelog
57
+
58
+ ### Deprecated
59
+
60
+ - Deprecate using x-string to access JavaScript without an explicit magic-comment ([#2543](https://github.com/opal/opal/pull/2543))
61
+
62
+ ### Compatibility
63
+
64
+ - Add a magic-comment that will disable x-string compilation to JavaScript ([#2543](https://github.com/opal/opal/pull/2543))
65
+ - Pass value in `PromiseV2#always` just like `PromiseV1#always` does it ([#2579](https://github.com/opal/opal/pull/2579))
66
+ - `#hash` now returns integers ([#2582](https://github.com/opal/opal/pull/2582))
67
+ - Improve `Range#include?`/`member?`/`cover?`/`===` ([#2598](https://github.com/opal/opal/pull/2598))
68
+ - Make `Module#define_method` more compatible with CRuby ([#2593](https://github.com/opal/opal/pull/2593))
69
+ - `Hash#clone` must freeze clone if original is frozen, but `Hash#dup` must not ([#2603](https://github.com/opal/opal/pull/2603))
70
+
71
+ ### Fixed
72
+
73
+ - Fix `Kernel#Float` with `exception:` option ([#2532](https://github.com/opal/opal/pull/2532))
74
+ - Fix `Kernel#Integer` with `exception:` option ([#2531](https://github.com/opal/opal/pull/2531))
75
+ - Fix `String#split` with limit and capturing regexp ([#2544](https://github.com/opal/opal/pull/2544))
76
+ - Fix `switch` with Object-wrapped values ([#2542](https://github.com/opal/opal/pull/2542))
77
+ - Fix non-direct subclasses of bridged classes not calling the original constructor ([#2546](https://github.com/opal/opal/pull/2546))
78
+ - Regexp.escape: Cast to String or drop exception ([#2552](https://github.com/opal/opal/pull/2552))
79
+ - Propagate removal of method from included/prepended modules ([#2553](https://github.com/opal/opal/pull/2553))
80
+ - Restore `nodejs/yaml` functionality ([#2551](https://github.com/opal/opal/pull/2551))
81
+ - Fix sine `Range#size` edge cases ([#2541](https://github.com/opal/opal/pull/2541))
82
+ - Use a Map instead of a POJO for the jsid_cache ([#2584](https://github.com/opal/opal/pull/2584))
83
+ - Fix `String#object_id`, `String#__id__`, `String#hash` to match CRuby's behavior ([#2576](https://github.com/opal/opal/pull/2576))
84
+ - Lowercase response headers in `SimpleServer` for rack 3.0 compatibility ([#2578](https://github.com/opal/opal/pull/2578))
85
+ - Fix `Module#clone` and `Module#dup` to properly copy methods ([#2572](https://github.com/opal/opal/pull/2572))
86
+ - Chrome runner fix: support code that contains `</script>` ([#2581](https://github.com/opal/opal/pull/2581))
87
+ - Do not skip `$truthy` when left hand side of a comparison is `self` ([#2596](https://github.com/opal/opal/pull/2596))
88
+ - Unexpected `return`/`break` should raise `LocalJumpError` ([#2591](https://github.com/opal/opal/pull/2591))
89
+
90
+ ### Added
91
+
92
+ - SourceMap support for `Kernel#eval` ([#2534](https://github.com/opal/opal/pull/2534))
93
+ - Add `CGI::Util#escapeURIComponent` and `CGI::Util#unescapeURIComponent` ([#2566](https://github.com/opal/opal/pull/2566))
94
+ - `CGI::Util` implement additional methods ([#2601](https://github.com/opal/opal/pull/2601))
95
+
96
+ ### Changed
97
+
98
+ - Change compilation of Regexp nodes that may contain advanced features, so if invalid that they would raise at runtime, not parse-time ([#2548](https://github.com/opal/opal/pull/2548))
99
+ - `Hash` is now bridged to JavaScript `Map` and support for non-symbol keys in keyword arguments ([#2568](https://github.com/opal/opal/pull/2568))
100
+
101
+ ### Documentation
102
+
103
+ - Bridging documentation ([#2541](https://github.com/opal/opal/pull/2541))
104
+ - Fix Typo in Running tests Section of README.md File ([#2580](https://github.com/opal/opal/pull/2580))
105
+
106
+ ### Performance
107
+
108
+ - Improve performance of `Array#intersect?` and `#intersection` ([#2533](https://github.com/opal/opal/pull/2533))
109
+ - `Proc#call`: Refactor for performance ([#2541](https://github.com/opal/opal/pull/2541))
110
+ - Opal.stub_for: optimize ([#2541](https://github.com/opal/opal/pull/2541))
111
+ - Hash: Optimize `#to_a` ([#2541](https://github.com/opal/opal/pull/2541))
112
+ - Array: Optimize `#collect`/`#map` ([#2541](https://github.com/opal/opal/pull/2541))
113
+ - Optimize argument slicing in runtime for performance ([#2555](https://github.com/opal/opal/pull/2555))
114
+ - Closure: Generate a JavaScript object, not an Error, gain up to 15% on Asciidoctor ([#2556](https://github.com/opal/opal/pull/2556))
115
+ - Optimize `String#split` and `String#start_with` ([#2560](https://github.com/opal/opal/pull/2560))
116
+ - Compute `$@` dynamically ([#2592](https://github.com/opal/opal/pull/2592))
117
+ - Optimize the `$prop` helper ([#2597](https://github.com/opal/opal/pull/2597))
118
+ - Improve `Array.push()` performance when pushing many items ([#2565](https://github.com/opal/opal/pull/2565))
119
+ - Optimize `Opal.instance_methods` ([#2600](https://github.com/opal/opal/pull/2600))
120
+
121
+ ### Internal
122
+
123
+ - Update rubocop ([#2535](https://github.com/opal/opal/pull/2535))
124
+ - Match3Node Cleanup ([#2541](https://github.com/opal/opal/pull/2541))
125
+ - IFlipFlop/EFlipFlop: Refactor for readability ([#2541](https://github.com/opal/opal/pull/2541))
126
+ - ForRewriter: Refactor for readability ([#2541](https://github.com/opal/opal/pull/2541))
127
+
128
+
129
+
130
+
131
+ ## [1.7.4](https://github.com/opal/opal/compare/v1.7.3...v1.7.4) - 2023-09-14
132
+
133
+
134
+ ### Fixed
135
+
136
+ - Use a Map instead of a POJO for the jsid_cache ([#2584](https://github.com/opal/opal/pull/2584))
137
+ - Lowercase response headers in `SimpleServer` for rack 3.0 compatibility ([#2578](https://github.com/opal/opal/pull/2578))
138
+ - Fix `switch` with Object-wrapped values ([#2542](https://github.com/opal/opal/pull/2542))
139
+ - Regexp.escape: Cast to String or drop exception ([#2552](https://github.com/opal/opal/pull/2552))
140
+ - Chrome runner fix: support code that contains `</script>` ([#2581](https://github.com/opal/opal/pull/2581))
141
+
142
+
143
+
144
+
145
+ ## [1.7.3](https://github.com/opal/opal/compare/v1.7.2...v1.7.3) - 2023-03-23
146
+
147
+
31
148
  ### Fixed
32
149
 
33
150
  - Disallow to define a singleton class for Number ([#2521](https://github.com/opal/opal/pull/2521))
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 will command will run all RSpec and MSpec examples in sequence.
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://nebulab.com/assets/img/logo-nebulab_black.svg" alt="Nebulab Logo"></a>
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
@@ -1,87 +1,10 @@
1
1
  <!--
2
2
  ### Internal
3
+ ### Changed
3
4
  ### Added
4
5
  ### Removed
5
6
  ### Deprecated
6
7
  ### Performance
7
8
  ### Fixed
8
- ### Documentation
9
9
  -->
10
10
 
11
- ## Highlights
12
-
13
- ### `Hash` is now bridged to JavaScript `Map`
14
-
15
- This change brings a lot of benefits, but also some incompatibilities. The main benefit is that `Hash` now is both more performant and relies on native JavaScript capabilities.
16
- This improves interoperability with JavaScript. As a downside, applications reaching for internal `Hash` data structures will need to be updated.
17
-
18
- Interacting with `Hash` from `JavaScript` is easier than ever:
19
-
20
- ```ruby
21
- hash = `new Map([['a', 1], ['b', 2]])`
22
- hash # => {a: 1, b: 2}
23
- `console.log(hash)` # => Map(2) {"a" => 1, "b" => 2}
24
- `hash.get('a')` # => 1
25
- `hash.set('c', 3)`
26
- hash # => {a: 1, b: 2, c: 3}
27
- hash.keys # => ["a", "b", "c"]
28
- hash.values # => [1, 2, 3]
29
- ```
30
-
31
- ### Performance improvements
32
-
33
- This release brings a lot of performance improvements, our tests on Asciidoctor show a 25% improvement in performance, but we've seen up to 66% performance improvement on some applications.
34
-
35
- ## Changelog
36
-
37
- ### Deprecated
38
-
39
- - Deprecate using x-string to access JavaScript without an explicit magic-comment (#2543)
40
-
41
- ### Compatibility
42
-
43
- - Add a magic-comment that will disable x-string compilation to JavaScript (#2543)
44
-
45
- ### Fixed
46
-
47
- - Fix `Kernel#Float` with `exception:` option (#2532)
48
- - Fix `Kernel#Integer` with `exception:` option (#2531)
49
- - Fix `String#split` with limit and capturing regexp (#2544)
50
- - Fix `switch` with Object-wrapped values (#2542)
51
- - Fix non-direct subclasses of bridged classes not calling the original constructor (#2546)
52
- - Regexp.escape: Cast to String or drop exception (#2552)
53
- - Propagate removal of method from included/prepended modules (#2553)
54
- - Restore `nodejs/yaml` functionality (#2551)
55
- - Fix sine `Range#size` edge cases (#2541)
56
-
57
- ### Added
58
-
59
- - SourceMap support for `Kernel#eval` (#2534)
60
- - Add `CGI::Util#escapeURIComponent` and `CGI::Util#unescapeURIComponent` (#2566)
61
-
62
- ### Changed
63
-
64
- - Change compilation of Regexp nodes that may contain advanced features, so if invalid that they would raise at runtime, not parse-time (#2548)
65
- - `Hash` is now bridged to JavaScript `Map` and support for non-symbol keys in keyword arguments (#2568)
66
-
67
- ### Documentation
68
-
69
- - Bridging documentation (#2541)
70
-
71
- ### Performance
72
-
73
- - Improve performance of `Array#intersect?` and `#intersection` (#2533)
74
- - `Proc#call`: Refactor for performance (#2541)
75
- - Opal.stub_for: optimize (#2541)
76
- - Hash: Optimize `#to_a` (#2541)
77
- - Array: Optimize `#collect`/`#map` (#2541)
78
- - Optimize argument slicing in runtime for performance (#2555)
79
- - Closure: Generate a JavaScript object, not an Error, gain up to 15% on Asciidoctor (#2556)
80
- - Optimize `String#split` and `String#start_with` (#2560)
81
-
82
- ### Internal
83
-
84
- - Update rubocop (#2535)
85
- - Match3Node Cleanup (#2541)
86
- - IFlipFlop/EFlipFlop: Refactor for readability (#2541)
87
- - ForRewriter: Refactor for readability (#2541)
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
- ### Updating the version
12
-
13
- - Update `lib/opal/version.rb`
14
- - Update `opal/corelib/constants.rb` with the same version number along with release dates
15
-
16
- ### Updating the changelog
17
-
18
- - Ensure all the unreleased changes are documented in UNRELEASED.md
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: #{map.to_json}
93
+ url: './index.map', map: #{map_json}
90
94
  } : null;
91
95
  }
92
96
  });
@@ -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(', expr_or_empty(value), ')'
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
- scope = closure.node.scope&.parent || top_scope
117
- scope.add_scope_temp("#{id} = $thrower('#{type}')")
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(', expr_or_empty(value), ')'
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(', expr_or_empty(value), ')'
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
- @closure.catchers.each do |type|
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
- unshift "var ", catchers.map { |type| "$t_#{type} = $thrower('#{type}')" }.join(", "), "; "
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
@@ -80,7 +80,7 @@ module Opal
80
80
  push ' if (Opal.rescue($err, [Opal.Exception])) {'
81
81
  push ' try {'
82
82
  push ' return false;'
83
- push ' } finally { Opal.pop_exception() }'
83
+ push ' } finally { Opal.pop_exception($err); }'
84
84
  push ' } else { throw $err; }'
85
85
  push '}})())'
86
86
 
@@ -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, :self, :nil
8
+ handle :true, :false, :nil
9
9
 
10
10
  def compile
11
- if type == :self
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
 
@@ -211,7 +211,7 @@ module Opal
211
211
  line stmt(rescue_body)
212
212
  end
213
213
  end
214
- line '} finally { Opal.pop_exception(); }'
214
+ line '} finally { Opal.pop_exception($err); }'
215
215
  end
216
216
  line '}'
217
217
  end
@@ -51,7 +51,7 @@ class Opal::SimpleServer
51
51
  asset = fetch_asset(path)
52
52
  [
53
53
  200,
54
- { 'Content-Type' => 'application/javascript' },
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, { 'Content-Type' => 'text/html' }, [html]]
102
+ [200, { 'content-type' => 'text/html' }, [html]]
103
103
  end
104
104
  end
data/lib/opal/version.rb CHANGED
@@ -3,5 +3,5 @@
3
3
  module Opal
4
4
  # WHEN RELEASING:
5
5
  # Remember to update RUBY_ENGINE_VERSION in opal/corelib/constants.rb too!
6
- VERSION = '1.8.0.alpha1'
6
+ VERSION = '1.8.0'
7
7
  end
@@ -1,4 +1,4 @@
1
- # helpers: truthy, falsy, hash_ids, yield1, hash_get, hash_put, hash_delete, coerce_to, respond_to, deny_frozen_access, freeze
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 (#{hash} === #{other.hash}) {
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
- result.push.apply(result, _flatten(ary, level - 1));
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 = ['A'],
1284
+ result = $opal32_init(),
1267
1285
  hash_id = self.$object_id(),
1268
1286
  item, i, key;
1269
1287
 
1270
- try {
1271
- if (top) {
1272
- $hash_ids = Object.create(null);
1273
- }
1288
+ result = $opal32_add(result, 0xA);
1289
+ result = $opal32_add(result, self.length);
1274
1290
 
1275
- // return early for recursive structures
1276
- if ($hash_ids[hash_id]) {
1277
- return 'self';
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 'self';
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.push(item.$hash());
1311
+ result = $opal32_add(result, item.$hash());
1292
1312
  }
1293
1313
 
1294
- return result.join(',');
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
- for (var i = 0, length = objects.length; i < length; i++) {
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
- self.push.apply(self, other);
1822
+ if (self.length > 0) self.splice(0, self.length);
1823
+ fast_push(self, other);
1806
1824
  }
1807
1825
 
1808
1826
  self
@@ -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};
@@ -180,7 +180,7 @@ class ::Complex < ::Numeric
180
180
  end
181
181
 
182
182
  def hash
183
- "Complex:#{@real}:#{@imag}"
183
+ [::Complex, @real, @imag].hash
184
184
  end
185
185
 
186
186
  def infinite?