opal 1.7.4 → 1.8.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
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 = '/'