opal 1.7.4 → 1.8.0.alpha1

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.
Files changed (211) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build.yml +9 -9
  3. data/.rubocop/todo.yml +2 -2
  4. data/.rubocop.yml +17 -10
  5. data/.rubocop_todo.yml +311 -0
  6. data/CHANGELOG.md +1 -15
  7. data/UNRELEASED.md +78 -1
  8. data/benchmark-ips/bm_block_vs_yield.rb +3 -0
  9. data/benchmark-ips/bm_slice_or_not.rb +53 -0
  10. data/docs/bridging.md +112 -0
  11. data/docs/compiled_ruby.md +10 -10
  12. data/docs/getting_started.md +18 -22
  13. data/lib/opal/cli_runners/chrome.rb +1 -5
  14. data/lib/opal/cli_runners/chrome_cdp_interface.rb +1 -0
  15. data/lib/opal/cli_runners/firefox_cdp_interface.rb +1 -0
  16. data/lib/opal/compiler.rb +33 -1
  17. data/lib/opal/nodes/args/extract_kwoptarg.rb +2 -1
  18. data/lib/opal/nodes/call.rb +1 -1
  19. data/lib/opal/nodes/call_special.rb +71 -47
  20. data/lib/opal/nodes/hash.rb +14 -30
  21. data/lib/opal/nodes/if.rb +37 -29
  22. data/lib/opal/nodes/literal.rb +5 -1
  23. data/lib/opal/nodes/x_string.rb +13 -0
  24. data/lib/opal/parser/patch.rb +1 -0
  25. data/lib/opal/rewriters/for_rewriter.rb +36 -24
  26. data/lib/opal/simple_server.rb +2 -2
  27. data/lib/opal/source_map/file.rb +1 -1
  28. data/lib/opal/version.rb +1 -1
  29. data/opal/corelib/array/pack.rb +1 -0
  30. data/opal/corelib/array.rb +71 -43
  31. data/opal/corelib/basic_object.rb +1 -0
  32. data/opal/corelib/binding.rb +2 -0
  33. data/opal/corelib/boolean.rb +1 -0
  34. data/opal/corelib/class.rb +2 -0
  35. data/opal/corelib/comparable.rb +1 -0
  36. data/opal/corelib/complex.rb +2 -0
  37. data/opal/corelib/constants.rb +2 -2
  38. data/opal/corelib/dir.rb +2 -0
  39. data/opal/corelib/enumerable.rb +3 -2
  40. data/opal/corelib/enumerator/arithmetic_sequence.rb +2 -0
  41. data/opal/corelib/enumerator/chain.rb +1 -0
  42. data/opal/corelib/enumerator/generator.rb +1 -0
  43. data/opal/corelib/enumerator/lazy.rb +1 -0
  44. data/opal/corelib/enumerator/yielder.rb +2 -0
  45. data/opal/corelib/enumerator.rb +1 -0
  46. data/opal/corelib/error/errno.rb +2 -0
  47. data/opal/corelib/error.rb +12 -0
  48. data/opal/corelib/file.rb +1 -0
  49. data/opal/corelib/hash.rb +197 -504
  50. data/opal/corelib/helpers.rb +1 -0
  51. data/opal/corelib/io.rb +2 -0
  52. data/opal/corelib/irb.rb +2 -0
  53. data/opal/corelib/kernel/format.rb +1 -0
  54. data/opal/corelib/kernel.rb +70 -14
  55. data/opal/corelib/main.rb +2 -0
  56. data/opal/corelib/marshal/read_buffer.rb +2 -0
  57. data/opal/corelib/marshal/write_buffer.rb +2 -0
  58. data/opal/corelib/math/polyfills.rb +2 -0
  59. data/opal/corelib/math.rb +1 -0
  60. data/opal/corelib/method.rb +2 -0
  61. data/opal/corelib/module.rb +1 -0
  62. data/opal/corelib/nil.rb +3 -1
  63. data/opal/corelib/number.rb +2 -0
  64. data/opal/corelib/numeric.rb +2 -0
  65. data/opal/corelib/object_space.rb +1 -0
  66. data/opal/corelib/pack_unpack/format_string_parser.rb +2 -0
  67. data/opal/corelib/proc.rb +30 -28
  68. data/opal/corelib/process.rb +2 -0
  69. data/opal/corelib/random/formatter.rb +2 -0
  70. data/opal/corelib/random/math_random.js.rb +2 -0
  71. data/opal/corelib/random/mersenne_twister.rb +2 -0
  72. data/opal/corelib/random/seedrandom.js.rb +2 -0
  73. data/opal/corelib/random.rb +1 -0
  74. data/opal/corelib/range.rb +34 -12
  75. data/opal/corelib/rational.rb +2 -0
  76. data/opal/corelib/regexp.rb +1 -0
  77. data/opal/corelib/runtime.js +187 -231
  78. data/opal/corelib/set.rb +2 -0
  79. data/opal/corelib/string/encoding.rb +3 -0
  80. data/opal/corelib/string/unpack.rb +2 -0
  81. data/opal/corelib/string.rb +20 -12
  82. data/opal/corelib/struct.rb +3 -1
  83. data/opal/corelib/time.rb +1 -0
  84. data/opal/corelib/trace_point.rb +2 -0
  85. data/opal/corelib/unsupported.rb +2 -0
  86. data/opal/corelib/variables.rb +2 -0
  87. data/opal.gemspec +2 -2
  88. data/spec/filters/bugs/array.rb +0 -2
  89. data/spec/filters/bugs/enumerable.rb +0 -3
  90. data/spec/filters/bugs/hash.rb +0 -13
  91. data/spec/filters/bugs/kernel.rb +0 -38
  92. data/spec/filters/bugs/range.rb +0 -1
  93. data/spec/filters/bugs/ruby-32.rb +0 -2
  94. data/spec/filters/bugs/string.rb +0 -1
  95. data/spec/filters/bugs/struct.rb +1 -5
  96. data/spec/filters/unsupported/hash.rb +1 -0
  97. data/spec/lib/compiler_spec.rb +24 -17
  98. data/spec/mspec-opal/formatters.rb +2 -0
  99. data/spec/mspec-opal/runner.rb +2 -0
  100. data/spec/opal/core/array/dup_spec.rb +2 -0
  101. data/spec/opal/core/exception_spec.rb +2 -0
  102. data/spec/opal/core/hash/internals_spec.rb +154 -206
  103. data/spec/opal/core/hash_spec.rb +2 -0
  104. data/spec/opal/core/iterable_props_spec.rb +2 -0
  105. data/spec/opal/core/kernel/at_exit_spec.rb +2 -0
  106. data/spec/opal/core/kernel/respond_to_spec.rb +2 -0
  107. data/spec/opal/core/language/arguments/mlhs_arg_spec.rb +2 -0
  108. data/spec/opal/core/language/safe_navigator_spec.rb +2 -0
  109. data/spec/opal/core/language/xstring_send_spec.rb +15 -0
  110. data/spec/opal/core/language/xstring_spec.rb +2 -0
  111. data/spec/opal/core/language_spec.rb +2 -0
  112. data/spec/opal/core/module_spec.rb +44 -0
  113. data/spec/opal/core/number/to_i_spec.rb +2 -0
  114. data/spec/opal/core/object_id_spec.rb +2 -0
  115. data/spec/opal/core/regexp/match_spec.rb +2 -0
  116. data/spec/opal/core/runtime/bridged_classes_spec.rb +38 -0
  117. data/spec/opal/core/runtime/constants_spec.rb +2 -0
  118. data/spec/opal/core/runtime/eval_spec.rb +2 -0
  119. data/spec/opal/core/runtime/exit_spec.rb +2 -0
  120. data/spec/opal/core/runtime/is_a_spec.rb +2 -0
  121. data/spec/opal/core/runtime/loaded_spec.rb +2 -0
  122. data/spec/opal/core/runtime/method_missing_spec.rb +2 -0
  123. data/spec/opal/core/runtime/rescue_spec.rb +2 -0
  124. data/spec/opal/core/runtime/string_spec.rb +2 -0
  125. data/spec/opal/core/runtime/truthy_spec.rb +2 -0
  126. data/spec/opal/core/runtime_spec.rb +2 -6
  127. data/spec/opal/core/string/to_sym_spec.rb +2 -0
  128. data/spec/opal/stdlib/js_spec.rb +2 -0
  129. data/spec/opal/stdlib/native/alias_native_spec.rb +2 -0
  130. data/spec/opal/stdlib/native/array_spec.rb +2 -0
  131. data/spec/opal/stdlib/native/date_spec.rb +2 -0
  132. data/spec/opal/stdlib/native/each_spec.rb +2 -0
  133. data/spec/opal/stdlib/native/element_reference_spec.rb +2 -0
  134. data/spec/opal/stdlib/native/exposure_spec.rb +2 -0
  135. data/spec/opal/stdlib/native/ext_spec.rb +2 -0
  136. data/spec/opal/stdlib/native/hash_spec.rb +30 -2
  137. data/spec/opal/stdlib/native/initialize_spec.rb +2 -0
  138. data/spec/opal/stdlib/native/method_missing_spec.rb +2 -0
  139. data/spec/opal/stdlib/native/native_alias_spec.rb +2 -0
  140. data/spec/opal/stdlib/native/native_class_spec.rb +2 -0
  141. data/spec/opal/stdlib/native/native_module_spec.rb +2 -0
  142. data/spec/opal/stdlib/native/native_reader_spec.rb +2 -0
  143. data/spec/opal/stdlib/native/native_writer_spec.rb +2 -0
  144. data/spec/opal/stdlib/native/new_spec.rb +2 -0
  145. data/spec/opal/stdlib/native/struct_spec.rb +2 -0
  146. data/spec/spec_helper.rb +2 -0
  147. data/stdlib/await.rb +1 -0
  148. data/stdlib/base64.rb +2 -0
  149. data/stdlib/bigdecimal/bignumber.js.rb +2 -0
  150. data/stdlib/bigdecimal/util.rb +1 -0
  151. data/stdlib/bigdecimal.rb +2 -0
  152. data/stdlib/buffer/array.rb +2 -0
  153. data/stdlib/buffer/view.rb +2 -0
  154. data/stdlib/buffer.rb +2 -0
  155. data/stdlib/cgi.rb +14 -0
  156. data/stdlib/console.rb +2 -0
  157. data/stdlib/date/date_time.rb +2 -0
  158. data/stdlib/date.rb +2 -0
  159. data/stdlib/delegate.rb +2 -0
  160. data/stdlib/deno/base.rb +2 -0
  161. data/stdlib/deno/file.rb +2 -0
  162. data/stdlib/erb.rb +2 -0
  163. data/stdlib/gjs/io.rb +2 -0
  164. data/stdlib/gjs/kernel.rb +2 -0
  165. data/stdlib/headless_browser/base.rb +2 -0
  166. data/stdlib/headless_browser/file.rb +1 -0
  167. data/stdlib/headless_browser.rb +1 -0
  168. data/stdlib/js.rb +2 -0
  169. data/stdlib/json.rb +9 -15
  170. data/stdlib/logger.rb +2 -0
  171. data/stdlib/nashorn/file.rb +2 -0
  172. data/stdlib/nashorn/io.rb +2 -0
  173. data/stdlib/native.rb +48 -48
  174. data/stdlib/nodejs/base.rb +2 -0
  175. data/stdlib/nodejs/dir.rb +2 -0
  176. data/stdlib/nodejs/env.rb +2 -0
  177. data/stdlib/nodejs/file.rb +2 -0
  178. data/stdlib/nodejs/fileutils.rb +2 -0
  179. data/stdlib/nodejs/io.rb +2 -0
  180. data/stdlib/nodejs/js-yaml-3-6-1.js +1 -1
  181. data/stdlib/nodejs/kernel.rb +2 -0
  182. data/stdlib/nodejs/open-uri.rb +2 -0
  183. data/stdlib/nodejs/pathname.rb +2 -0
  184. data/stdlib/nodejs/require.rb +2 -0
  185. data/stdlib/nodejs/yaml.rb +9 -3
  186. data/stdlib/opal/miniracer.rb +2 -0
  187. data/stdlib/opal-parser.rb +8 -1
  188. data/stdlib/opal-platform.rb +2 -0
  189. data/stdlib/opal-replutils.rb +2 -0
  190. data/stdlib/open-uri.rb +4 -1
  191. data/stdlib/ostruct.rb +4 -2
  192. data/stdlib/pathname.rb +2 -0
  193. data/stdlib/pp.rb +1 -0
  194. data/stdlib/promise/v2.rb +2 -0
  195. data/stdlib/quickjs/io.rb +2 -0
  196. data/stdlib/quickjs/kernel.rb +2 -0
  197. data/stdlib/quickjs.rb +2 -0
  198. data/stdlib/securerandom.rb +2 -0
  199. data/stdlib/strscan.rb +2 -0
  200. data/stdlib/time.rb +2 -0
  201. data/stdlib/uri.rb +1 -0
  202. data/tasks/performance/optimization_status.rb +2 -0
  203. data/tasks/testing.rake +1 -0
  204. data/test/nodejs/test_await.rb +1 -0
  205. data/test/nodejs/test_dir.rb +2 -0
  206. data/test/nodejs/test_error.rb +2 -0
  207. data/test/nodejs/test_file.rb +2 -0
  208. data/test/nodejs/test_string.rb +2 -0
  209. data/test/nodejs/test_yaml.rb +20 -0
  210. metadata +22 -13
  211. data/spec/filters/bugs/openstruct.rb +0 -8
@@ -158,11 +158,15 @@ module Opal
158
158
  case value
159
159
  when ''
160
160
  push('/(?:)/')
161
- when /\(\?<=|\(\?<!/
161
+ when /\(\?[(<>#]|[*+?]\+/
162
162
  # Safari/WebKit will not execute javascript code if it contains a lookbehind literal RegExp
163
163
  # and they fail with "Syntax Error". This tricks their parser by disguising the literal RegExp
164
164
  # as string for the dynamic $regexp helper. Safari/Webkit will still fail to execute the RegExp,
165
165
  # but at least they will parse and run everything else.
166
+ #
167
+ # Also, let's compile a couple of more patterns into $regexp calls, as there are many syntax
168
+ # errors in RubySpec when ran in reverse, while there shouldn't be (they should be catchable
169
+ # errors) - at least since Node 17.
166
170
  static_as_dynamic(value)
167
171
  else
168
172
  push "#{Regexp.new(value).inspect}#{flags.join}"
@@ -6,6 +6,19 @@ module Opal
6
6
  handle :xstr
7
7
 
8
8
  def compile
9
+ if compiler.backtick_javascript_or_warn?
10
+ compile_javascript
11
+ else
12
+ compile_send
13
+ end
14
+ end
15
+
16
+ def compile_send
17
+ sexp = s(:send, nil, :`, s(:dstr, *children))
18
+ push process(sexp, @level)
19
+ end
20
+
21
+ def compile_javascript
9
22
  @should_add_semicolon = false
10
23
  unpacked_children = unpack_return(children)
11
24
  stripped_children = XStringNode.strip_empty_children(unpacked_children)
@@ -1,3 +1,4 @@
1
+ # backtick_javascript: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  if RUBY_ENGINE == 'opal'
@@ -34,40 +34,52 @@ module Opal
34
34
  # j = nil
35
35
  # [[1, 2], [3, 4]].each { |__jstmp| i, j = __jstmp }
36
36
  #
37
- def on_for(node)
38
- loop_variable, iterating_value, loop_body = *node
39
37
 
40
- iterating_lvars = LocalVariableAssigns.find(loop_variable) # [:i]
41
- lvars_declared_in_body = LocalVariableAssigns.find(loop_body) # [:j]
38
+ def on_for(node)
39
+ loop_variable, loop_range, loop_body = *node
42
40
 
43
- # i = nil; j = nil
44
- outer_assigns = (iterating_lvars + lvars_declared_in_body).map do |lvar_name|
45
- s(:lvdeclare, lvar_name)
46
- end
41
+ # Declare local variables used in the loop and the loop body at the outer scope
42
+ outer_assignments = generate_outer_assignments(loop_variable, loop_body)
47
43
 
48
- # :__jstmp
44
+ # Generate temporary loop variable
49
45
  tmp_loop_variable = self.class.next_tmp
50
46
  get_tmp_loop_variable = s(:js_tmp, tmp_loop_variable)
51
47
 
52
- loop_variable_assignment = case loop_variable.type
53
- when :mlhs # multiple left-hand statement like in "for i,j in [[1, 2], [3, 4]]"
54
- # i, j = __jstmp
55
- loop_variable.updated(:masgn, [loop_variable, get_tmp_loop_variable])
56
- else # single argument like "for i in (0..3)"
57
- # i = __jstmp
58
- loop_variable << get_tmp_loop_variable
59
- end
48
+ # Assign the loop variables in the loop body
49
+ loop_body = prepend_to_body(loop_body, assign_loop_variable(loop_variable, get_tmp_loop_variable))
50
+
51
+ # Transform the for-loop into each-loop with updated loop body
52
+ node = transform_for_to_each_loop(node, loop_range, tmp_loop_variable, loop_body)
53
+
54
+ node.updated(:begin, [*outer_assignments, node])
55
+ end
60
56
 
61
- loop_body = prepend_to_body(loop_body, loop_variable_assignment)
57
+ private
62
58
 
63
- node = node.updated(:send, [iterating_value, :each, # (0..3).each {
64
- node.updated(:iter, [s(:args, s(:arg, tmp_loop_variable)), # |__jstmp|
65
- process(loop_body)] # i = __jstmp; j = i + 1 }
66
- )]
67
- )
59
+ def generate_outer_assignments(loop_variable, loop_body)
60
+ loop_local_vars = LocalVariableAssigns.find(loop_variable)
61
+ body_local_vars = LocalVariableAssigns.find(loop_body)
62
+
63
+ (loop_local_vars + body_local_vars).map { |lvar_name| s(:lvdeclare, lvar_name) }
64
+ end
65
+
66
+ def assign_loop_variable(loop_variable, tmp_loop_variable)
67
+ case loop_variable.type
68
+ when :mlhs # multiple left-hand statement like in "for i,j in [[1, 2], [3, 4]]"
69
+ loop_variable.updated(:masgn, [loop_variable, tmp_loop_variable])
70
+ else # single argument like "for i in (0..3)"
71
+ loop_variable << tmp_loop_variable
72
+ end
73
+ end
68
74
 
69
- node.updated(:begin, [*outer_assigns, node])
75
+ # rubocop:disable Layout/MultilineMethodCallBraceLayout,Layout/MultilineArrayBraceLayout
76
+ def transform_for_to_each_loop(node, loop_range, tmp_loop_variable, loop_body)
77
+ node.updated(:send, [loop_range, :each, # (0..3).each {
78
+ node.updated(:iter, [s(:args, s(:arg, tmp_loop_variable)), # |__jstmp|
79
+ process(loop_body) # i = __jstmp; j = i + 1 }
80
+ ])])
70
81
  end
82
+ # rubocop:enable Layout/MultilineMethodCallBraceLayout,Layout/MultilineArrayBraceLayout
71
83
 
72
84
  class LocalVariableAssigns < Base
73
85
  attr_reader :result
@@ -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
@@ -134,7 +134,7 @@ class Opal::SourceMap::File
134
134
  absolute_mapping.map do |absolute_segment|
135
135
  segment = []
136
136
 
137
- segment[0] = absolute_segment[0] - reference_segment[0]
137
+ segment[0] = absolute_segment[0] - reference_segment[0]
138
138
  segment[1] = absolute_segment[1] - (reference_segment[1] || 0)
139
139
  segment[2] = absolute_segment[2] - (reference_segment[2] || 0)
140
140
  segment[3] = absolute_segment[3] - (reference_segment[3] || 0)
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.7.4'
6
+ VERSION = '1.8.0.alpha1'
7
7
  end
@@ -1,4 +1,5 @@
1
1
  # helpers: coerce_to
2
+ # backtick_javascript: true
2
3
 
3
4
  require 'corelib/pack_unpack/format_string_parser'
4
5
 
@@ -1,4 +1,5 @@
1
1
  # helpers: truthy, falsy, hash_ids, yield1, hash_get, hash_put, hash_delete, coerce_to, respond_to, deny_frozen_access, freeze
2
+ # backtick_javascript: true
2
3
 
3
4
  require 'corelib/enumerable'
4
5
  require 'corelib/numeric'
@@ -68,6 +69,13 @@ class ::Array < `Array`
68
69
 
69
70
  if (raised) throw raised;
70
71
  }
72
+
73
+ function convertToArray(array) {
74
+ if (!array.$$is_array) {
75
+ array = $coerce_to(array, #{::Array}, 'to_ary');
76
+ }
77
+ return #{`array`.to_a};
78
+ }
71
79
  }
72
80
 
73
81
  def self.[](*objects)
@@ -135,13 +143,13 @@ class ::Array < `Array`
135
143
  end
136
144
 
137
145
  def &(other)
138
- other = if ::Array === other
139
- other.to_a
140
- else
141
- `$coerce_to(other, #{::Array}, 'to_ary')`.to_a
142
- end
143
-
144
146
  %x{
147
+ other = convertToArray(other)
148
+
149
+ if (self.length === 0 || other.length === 0) {
150
+ return [];
151
+ }
152
+
145
153
  var result = [], hash = #{{}}, i, length, item;
146
154
 
147
155
  for (i = 0, length = other.length; i < length; i++) {
@@ -160,11 +168,7 @@ class ::Array < `Array`
160
168
  end
161
169
 
162
170
  def |(other)
163
- other = if ::Array === other
164
- other.to_a
165
- else
166
- `$coerce_to(other, #{::Array}, 'to_ary')`.to_a
167
- end
171
+ other = `convertToArray(other)`
168
172
 
169
173
  %x{
170
174
  var hash = #{{}}, i, length, item;
@@ -203,21 +207,13 @@ class ::Array < `Array`
203
207
  end
204
208
 
205
209
  def +(other)
206
- other = if ::Array === other
207
- other.to_a
208
- else
209
- `$coerce_to(other, #{::Array}, 'to_ary')`.to_a
210
- end
210
+ other = `convertToArray(other)`
211
211
 
212
212
  `self.concat(other)`
213
213
  end
214
214
 
215
215
  def -(other)
216
- other = if ::Array === other
217
- other.to_a
218
- else
219
- `$coerce_to(other, #{::Array}, 'to_ary')`.to_a
220
- end
216
+ other = `convertToArray(other)`
221
217
 
222
218
  return [] if `self.length === 0`
223
219
  return `self.slice()` if `other.length === 0`
@@ -696,11 +692,12 @@ class ::Array < `Array`
696
692
  return enum_for(:collect) { size } unless block_given?
697
693
 
698
694
  %x{
699
- var result = [];
695
+ var length = self.length;
696
+ var result = new Array(length);
700
697
 
701
- for (var i = 0, length = self.length; i < length; i++) {
698
+ for (var i = 0; i < length; i++) {
702
699
  var value = $yield1(block, self[i]);
703
- result.push(value);
700
+ result[i] = value;
704
701
  }
705
702
 
706
703
  return result;
@@ -849,11 +846,7 @@ class ::Array < `Array`
849
846
  `$deny_frozen_access(self)`
850
847
 
851
848
  others = others.map do |other|
852
- other = if ::Array === other
853
- other.to_a
854
- else
855
- `$coerce_to(other, #{::Array}, 'to_ary')`.to_a
856
- end
849
+ `other = convertToArray(other)`
857
850
 
858
851
  if other.equal?(self)
859
852
  other = other.dup
@@ -1410,11 +1403,54 @@ class ::Array < `Array`
1410
1403
  end
1411
1404
 
1412
1405
  def intersection(*arrays)
1413
- arrays.reduce(to_a.dup) { |a, b| a & b }
1406
+ %x{
1407
+ if (arrays.length === 0) {
1408
+ return #{to_a.dup};
1409
+ }
1410
+ arrays = arrays.map(convertToArray);
1411
+ if (self.length === 0) {
1412
+ return [];
1413
+ }
1414
+ }
1415
+
1416
+ arrays = arrays.sort_by(&:length)
1417
+ # When self is the smallest among the arrays
1418
+ if `self.length < arrays[0].length`
1419
+ return arrays.reduce(self, &:&)
1420
+ end
1421
+
1422
+ # First, calculate intersection of argument arrays.
1423
+ # Array#& is faster when the argument size is small.
1424
+ # So `largest & shortest & second_shortest & ...` would be the fastest.
1425
+ largest = `arrays.pop()`
1426
+ intersection_of_args = arrays.reduce(largest, &:&)
1427
+
1428
+ # self array must come last to maintain the order
1429
+ self & intersection_of_args
1414
1430
  end
1415
1431
 
1416
1432
  def intersect?(other)
1417
- !intersection(other).empty?
1433
+ %x{
1434
+ var small, large, hash = #{{}}, i, length;
1435
+ if (self.length < other.length) {
1436
+ small = self;
1437
+ large = other;
1438
+ } else {
1439
+ small = other;
1440
+ large = self;
1441
+ }
1442
+
1443
+ for (i = 0, length = small.length; i < length; i++) {
1444
+ $hash_put(hash, small[i], true);
1445
+ }
1446
+
1447
+ for (i = 0, length = large.length; i < length; i++) {
1448
+ if ($hash_get(hash, large[i])) {
1449
+ return true;
1450
+ }
1451
+ }
1452
+ return false;
1453
+ }
1418
1454
  end
1419
1455
 
1420
1456
  def join(sep = nil)
@@ -1762,11 +1798,7 @@ class ::Array < `Array`
1762
1798
  def replace(other)
1763
1799
  `$deny_frozen_access(self)`
1764
1800
 
1765
- other = if ::Array === other
1766
- other.to_a
1767
- else
1768
- `$coerce_to(other, #{::Array}, 'to_ary')`.to_a
1769
- end
1801
+ other = `convertToArray(other)`
1770
1802
 
1771
1803
  %x{
1772
1804
  self.splice(0, self.length);
@@ -2284,10 +2316,10 @@ class ::Array < `Array`
2284
2316
  for (i = 0; i < len; i++) {
2285
2317
  ary = #{::Opal.coerce_to?(`array[i]`, ::Array, :to_ary)};
2286
2318
  if (!ary.$$is_array) {
2287
- #{::Kernel.raise ::TypeError, "wrong element type #{`ary`.class} at #{`i`} (expected array)"}
2319
+ #{::Kernel.raise ::TypeError, "wrong element type #{`array[i]`.class} at #{`i`} (expected array)"}
2288
2320
  }
2289
2321
  if (ary.length !== 2) {
2290
- #{::Kernel.raise ::ArgumentError, "wrong array length at #{`i`} (expected 2, was #{`ary`.length})"}
2322
+ #{::Kernel.raise ::ArgumentError, "element has wrong array length at #{`i`} (expected 2, was #{`ary`.length})"}
2291
2323
  }
2292
2324
  key = ary[0];
2293
2325
  val = ary[1];
@@ -2305,11 +2337,7 @@ class ::Array < `Array`
2305
2337
  max = nil
2306
2338
 
2307
2339
  each do |row|
2308
- row = if ::Array === row
2309
- row.to_a
2310
- else
2311
- `$coerce_to(row, #{::Array}, 'to_ary')`.to_a
2312
- end
2340
+ `row = convertToArray(row)`
2313
2341
 
2314
2342
  max ||= `row.length`
2315
2343
 
@@ -1,4 +1,5 @@
1
1
  # use_strict: true
2
+ # backtick_javascript: true
2
3
 
3
4
  class ::BasicObject
4
5
  def initialize(*)
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  class ::Binding
2
4
  # @private
3
5
  def initialize(jseval, scope_variables = [], receiver = undefined, source_location = nil)
@@ -1,4 +1,5 @@
1
1
  # use_strict: true
2
+ # backtick_javascript: true
2
3
 
3
4
  class ::Boolean < `Boolean`
4
5
  `Opal.prop(self.$$prototype, '$$is_boolean', true)`
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  require 'corelib/module'
2
4
 
3
5
  class ::Class
@@ -1,4 +1,5 @@
1
1
  # helpers: truthy
2
+ # backtick_javascript: true
2
3
 
3
4
  module ::Comparable
4
5
  %x{
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  require 'corelib/numeric'
2
4
  require 'corelib/complex/base'
3
5
 
@@ -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.7.4'
5
- ::RUBY_RELEASE_DATE = '2023-09-14'
4
+ ::RUBY_ENGINE_VERSION = '1.8.0.alpha1'
5
+ ::RUBY_RELEASE_DATE = '2023-08-04'
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/dir.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  class ::Dir
2
4
  class << self
3
5
  def chdir(dir)
@@ -1,4 +1,5 @@
1
1
  # helpers: truthy, coerce_to, yield1, yieldX, deny_frozen_access
2
+ # backtick_javascript: true
2
3
 
3
4
  module ::Enumerable
4
5
  %x{
@@ -1251,10 +1252,10 @@ module ::Enumerable
1251
1252
  var param = #{::Opal.destructure(`arguments`)};
1252
1253
  var ary = #{::Opal.coerce_to?(`param`, ::Array, :to_ary)}, key, val;
1253
1254
  if (!ary.$$is_array) {
1254
- #{::Kernel.raise ::TypeError, "wrong element type #{`ary`.class} (expected array)"}
1255
+ #{::Kernel.raise ::TypeError, "wrong element type #{`param`.class} (expected array)"}
1255
1256
  }
1256
1257
  if (ary.length !== 2) {
1257
- #{::Kernel.raise ::ArgumentError, "wrong array length (expected 2, was #{`ary`.length})"}
1258
+ #{::Kernel.raise ::ArgumentError, "element has wrong array length (expected 2, was #{`ary`.length})"}
1258
1259
  }
1259
1260
  key = ary[0];
1260
1261
  val = ary[1];
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  class ::Enumerator
2
4
  class self::ArithmeticSequence < self
3
5
  `Opal.prop(self.$$prototype, '$$is_arithmetic_seq', true)`
@@ -1,4 +1,5 @@
1
1
  # helpers: deny_frozen_access
2
+ # backtick_javascript: true
2
3
 
3
4
  class ::Enumerator
4
5
  class self::Chain < self
@@ -1,4 +1,5 @@
1
1
  # helpers: deny_frozen_access
2
+ # backtick_javascript: true
2
3
 
3
4
  class Enumerator
4
5
  class Generator
@@ -1,4 +1,5 @@
1
1
  # helpers: truthy, coerce_to, yield1, yieldX, deny_frozen_access
2
+ # backtick_javascript: true
2
3
 
3
4
  class ::Enumerator
4
5
  class self::Lazy < self
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  class Enumerator
2
4
  class Yielder
3
5
  def initialize(&block)
@@ -1,4 +1,5 @@
1
1
  # helpers: slice, coerce_to, deny_frozen_access
2
+ # backtick_javascript: true
2
3
 
3
4
  require 'corelib/enumerable'
4
5
 
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  module ::Errno
2
4
  errors = [
3
5
  [:EINVAL, 'Invalid argument', 22],
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  class ::Exception < `Error`
2
4
  `Opal.prop(self.$$prototype, '$$is_exception', true)`
3
5
  `var stack_trace_limit`
@@ -36,6 +38,16 @@ class ::Exception < `Error`
36
38
  `self.message = (args.length > 0) ? args[0] : nil`
37
39
  end
38
40
 
41
+ # Those instance variables are not enumerable.
42
+ def copy_instance_variables(other)
43
+ super
44
+ %x{
45
+ self.message = other.message;
46
+ self.cause = other.cause;
47
+ self.stack = other.stack;
48
+ }
49
+ end
50
+
39
51
  %x{
40
52
  // Convert backtrace from any format to Ruby format
41
53
  function correct_backtrace(backtrace) {
data/opal/corelib/file.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # helpers: truthy
2
+ # backtick_javascript: true
2
3
 
3
4
  class ::File < ::IO
4
5
  Separator = SEPARATOR = '/'