opal 1.6.1 → 1.7.0

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 (212) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build.yml +17 -0
  3. data/CHANGELOG.md +35 -1
  4. data/Gemfile +1 -0
  5. data/HACKING.md +47 -26
  6. data/benchmark/benchmarks +415 -103
  7. data/benchmark/bm_call_overhead.yml +28 -0
  8. data/benchmark/run.rb +61 -40
  9. data/docs/cdp_common.json +3364 -0
  10. data/docs/cdp_common.md +18 -0
  11. data/docs/{headless_chrome.md → headless_browsers.md} +31 -12
  12. data/lib/opal/ast/builder.rb +1 -1
  13. data/lib/opal/builder.rb +6 -1
  14. data/lib/opal/builder_processors.rb +5 -3
  15. data/lib/opal/cache.rb +1 -7
  16. data/lib/opal/cli_options.rb +72 -58
  17. data/lib/opal/cli_runners/chrome.rb +47 -9
  18. data/lib/opal/cli_runners/chrome_cdp_interface.rb +238 -112
  19. data/lib/opal/cli_runners/compiler.rb +146 -13
  20. data/lib/opal/cli_runners/deno.rb +32 -0
  21. data/lib/opal/cli_runners/firefox.rb +350 -0
  22. data/lib/opal/cli_runners/firefox_cdp_interface.rb +212 -0
  23. data/lib/opal/cli_runners/node_modules/.bin/chrome-remote-interface.cmd +17 -0
  24. data/lib/opal/cli_runners/node_modules/.bin/chrome-remote-interface.ps1 +28 -0
  25. data/lib/opal/cli_runners/node_modules/.package-lock.json +41 -0
  26. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/LICENSE +1 -1
  27. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/README.md +322 -182
  28. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/bin/client.js +99 -114
  29. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/chrome-remote-interface.js +1 -11
  30. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/index.js +16 -11
  31. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/api.js +41 -33
  32. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/chrome.js +224 -214
  33. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/devtools.js +71 -191
  34. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/external-request.js +26 -6
  35. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/protocol.json +20788 -9049
  36. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/lib/websocket-wrapper.js +10 -3
  37. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/package.json +59 -123
  38. data/lib/opal/cli_runners/node_modules/chrome-remote-interface/webpack.config.js +25 -32
  39. data/lib/opal/cli_runners/node_modules/commander/History.md +298 -0
  40. data/lib/opal/cli_runners/node_modules/commander/LICENSE +22 -0
  41. data/lib/opal/cli_runners/node_modules/commander/Readme.md +217 -61
  42. data/lib/opal/cli_runners/node_modules/commander/index.js +431 -145
  43. data/lib/opal/cli_runners/node_modules/commander/package.json +16 -79
  44. data/lib/opal/cli_runners/node_modules/ws/README.md +334 -98
  45. data/lib/opal/cli_runners/node_modules/ws/browser.js +8 -0
  46. data/lib/opal/cli_runners/node_modules/ws/index.js +5 -10
  47. data/lib/opal/cli_runners/node_modules/ws/lib/buffer-util.js +129 -0
  48. data/lib/opal/cli_runners/node_modules/ws/lib/constants.js +10 -0
  49. data/lib/opal/cli_runners/node_modules/ws/lib/event-target.js +184 -0
  50. data/lib/opal/cli_runners/node_modules/ws/lib/extension.js +223 -0
  51. data/lib/opal/cli_runners/node_modules/ws/lib/limiter.js +55 -0
  52. data/lib/opal/cli_runners/node_modules/ws/lib/permessage-deflate.js +518 -0
  53. data/lib/opal/cli_runners/node_modules/ws/lib/receiver.js +607 -0
  54. data/lib/opal/cli_runners/node_modules/ws/lib/sender.js +409 -0
  55. data/lib/opal/cli_runners/node_modules/ws/lib/stream.js +180 -0
  56. data/lib/opal/cli_runners/node_modules/ws/lib/validation.js +104 -0
  57. data/lib/opal/cli_runners/node_modules/ws/lib/websocket-server.js +447 -0
  58. data/lib/opal/cli_runners/node_modules/ws/lib/websocket.js +1195 -0
  59. data/lib/opal/cli_runners/node_modules/ws/package.json +40 -106
  60. data/lib/opal/cli_runners/package-lock.json +62 -0
  61. data/lib/opal/cli_runners/package.json +1 -1
  62. data/lib/opal/cli_runners.rb +26 -4
  63. data/lib/opal/nodes/args/prepare_post_args.rb +2 -2
  64. data/lib/opal/nodes/def.rb +8 -8
  65. data/lib/opal/nodes/iter.rb +12 -12
  66. data/lib/opal/nodes/logic.rb +1 -1
  67. data/lib/opal/nodes/masgn.rb +2 -2
  68. data/lib/opal/parser/with_ruby_lexer.rb +1 -1
  69. data/lib/opal/paths.rb +14 -0
  70. data/lib/opal/rewriter.rb +2 -0
  71. data/lib/opal/rewriters/forward_args.rb +52 -4
  72. data/lib/opal/rewriters/targeted_patches.rb +94 -0
  73. data/lib/opal/version.rb +1 -1
  74. data/opal/corelib/basic_object.rb +1 -1
  75. data/opal/corelib/boolean.rb +2 -2
  76. data/opal/corelib/class.rb +11 -0
  77. data/opal/corelib/constants.rb +3 -3
  78. data/opal/corelib/enumerable.rb +4 -0
  79. data/opal/corelib/enumerator.rb +1 -1
  80. data/opal/corelib/hash.rb +2 -2
  81. data/opal/corelib/helpers.rb +1 -1
  82. data/opal/corelib/kernel.rb +3 -3
  83. data/opal/corelib/method.rb +1 -1
  84. data/opal/corelib/module.rb +29 -8
  85. data/opal/corelib/proc.rb +7 -5
  86. data/opal/corelib/runtime.js +141 -78
  87. data/opal/corelib/set.rb +252 -0
  88. data/opal/corelib/string.rb +2 -1
  89. data/opal/corelib/time.rb +2 -2
  90. data/opal/opal.rb +1 -0
  91. data/opal.gemspec +1 -0
  92. data/spec/filters/bugs/array.rb +22 -13
  93. data/spec/filters/bugs/base64.rb +5 -5
  94. data/spec/filters/bugs/basicobject.rb +16 -8
  95. data/spec/filters/bugs/bigdecimal.rb +161 -160
  96. data/spec/filters/bugs/binding.rb +10 -10
  97. data/spec/filters/bugs/class.rb +8 -8
  98. data/spec/filters/bugs/complex.rb +2 -1
  99. data/spec/filters/bugs/date.rb +79 -81
  100. data/spec/filters/bugs/datetime.rb +29 -29
  101. data/spec/filters/bugs/delegate.rb +1 -3
  102. data/spec/filters/bugs/encoding.rb +69 -69
  103. data/spec/filters/bugs/enumerable.rb +22 -20
  104. data/spec/filters/bugs/enumerator.rb +88 -85
  105. data/spec/filters/bugs/exception.rb +46 -40
  106. data/spec/filters/bugs/file.rb +32 -32
  107. data/spec/filters/bugs/float.rb +26 -21
  108. data/spec/filters/bugs/freeze.rb +88 -0
  109. data/spec/filters/bugs/hash.rb +39 -38
  110. data/spec/filters/bugs/integer.rb +57 -44
  111. data/spec/filters/bugs/io.rb +1 -1
  112. data/spec/filters/bugs/kernel.rb +349 -269
  113. data/spec/filters/bugs/language.rb +220 -188
  114. data/spec/filters/bugs/main.rb +5 -3
  115. data/spec/filters/bugs/marshal.rb +38 -38
  116. data/spec/filters/bugs/math.rb +2 -1
  117. data/spec/filters/bugs/method.rb +73 -62
  118. data/spec/filters/bugs/module.rb +163 -143
  119. data/spec/filters/bugs/numeric.rb +6 -6
  120. data/spec/filters/bugs/objectspace.rb +16 -16
  121. data/spec/filters/bugs/openstruct.rb +1 -1
  122. data/spec/filters/bugs/pack_unpack.rb +51 -51
  123. data/spec/filters/bugs/pathname.rb +7 -7
  124. data/spec/filters/bugs/proc.rb +63 -63
  125. data/spec/filters/bugs/random.rb +7 -6
  126. data/spec/filters/bugs/range.rb +12 -9
  127. data/spec/filters/bugs/rational.rb +8 -7
  128. data/spec/filters/bugs/regexp.rb +49 -48
  129. data/spec/filters/bugs/ruby-32.rb +56 -0
  130. data/spec/filters/bugs/set.rb +30 -30
  131. data/spec/filters/bugs/singleton.rb +4 -4
  132. data/spec/filters/bugs/string.rb +187 -99
  133. data/spec/filters/bugs/stringio.rb +7 -0
  134. data/spec/filters/bugs/stringscanner.rb +68 -68
  135. data/spec/filters/bugs/struct.rb +11 -9
  136. data/spec/filters/bugs/symbol.rb +1 -1
  137. data/spec/filters/bugs/time.rb +78 -63
  138. data/spec/filters/bugs/trace_point.rb +4 -4
  139. data/spec/filters/bugs/unboundmethod.rb +32 -17
  140. data/spec/filters/bugs/warnings.rb +8 -12
  141. data/spec/filters/unsupported/array.rb +24 -107
  142. data/spec/filters/unsupported/basicobject.rb +12 -12
  143. data/spec/filters/unsupported/bignum.rb +27 -52
  144. data/spec/filters/unsupported/class.rb +1 -2
  145. data/spec/filters/unsupported/delegator.rb +3 -3
  146. data/spec/filters/unsupported/enumerable.rb +2 -9
  147. data/spec/filters/unsupported/enumerator.rb +2 -11
  148. data/spec/filters/unsupported/file.rb +1 -1
  149. data/spec/filters/unsupported/float.rb +28 -47
  150. data/spec/filters/unsupported/hash.rb +8 -14
  151. data/spec/filters/unsupported/integer.rb +75 -91
  152. data/spec/filters/unsupported/kernel.rb +17 -35
  153. data/spec/filters/unsupported/language.rb +11 -19
  154. data/spec/filters/unsupported/marshal.rb +22 -41
  155. data/spec/filters/unsupported/matchdata.rb +28 -52
  156. data/spec/filters/unsupported/math.rb +1 -1
  157. data/spec/filters/unsupported/privacy.rb +229 -285
  158. data/spec/filters/unsupported/range.rb +1 -5
  159. data/spec/filters/unsupported/regexp.rb +40 -66
  160. data/spec/filters/unsupported/set.rb +2 -2
  161. data/spec/filters/unsupported/singleton.rb +4 -4
  162. data/spec/filters/unsupported/string.rb +305 -508
  163. data/spec/filters/unsupported/struct.rb +3 -4
  164. data/spec/filters/unsupported/symbol.rb +15 -18
  165. data/spec/filters/unsupported/thread.rb +1 -7
  166. data/spec/filters/unsupported/time.rb +159 -202
  167. data/spec/filters/unsupported/usage_of_files.rb +170 -259
  168. data/spec/lib/builder_spec.rb +4 -4
  169. data/spec/lib/rewriters/forward_args_spec.rb +32 -12
  170. data/spec/mspec-opal/runner.rb +2 -0
  171. data/spec/ruby_specs +4 -0
  172. data/stdlib/deno/base.rb +28 -0
  173. data/stdlib/deno/file.rb +340 -0
  174. data/stdlib/{headless_chrome.rb → headless_browser/base.rb} +1 -1
  175. data/stdlib/headless_browser/file.rb +15 -0
  176. data/stdlib/headless_browser.rb +4 -0
  177. data/stdlib/native.rb +1 -1
  178. data/stdlib/nodejs/file.rb +5 -0
  179. data/stdlib/opal/platform.rb +8 -6
  180. data/stdlib/opal-platform.rb +14 -8
  181. data/stdlib/set.rb +1 -258
  182. data/tasks/benchmarking.rake +62 -19
  183. data/tasks/performance.rake +1 -1
  184. data/tasks/testing.rake +5 -3
  185. data/test/nodejs/test_file.rb +29 -10
  186. data/test/opal/http_server.rb +28 -11
  187. data/test/opal/unsupported_and_bugs.rb +2 -1
  188. metadata +89 -50
  189. data/lib/opal/cli_runners/node_modules/ultron/LICENSE +0 -22
  190. data/lib/opal/cli_runners/node_modules/ultron/index.js +0 -138
  191. data/lib/opal/cli_runners/node_modules/ultron/package.json +0 -112
  192. data/lib/opal/cli_runners/node_modules/ws/SECURITY.md +0 -33
  193. data/lib/opal/cli_runners/node_modules/ws/lib/BufferUtil.fallback.js +0 -56
  194. data/lib/opal/cli_runners/node_modules/ws/lib/BufferUtil.js +0 -15
  195. data/lib/opal/cli_runners/node_modules/ws/lib/ErrorCodes.js +0 -28
  196. data/lib/opal/cli_runners/node_modules/ws/lib/EventTarget.js +0 -158
  197. data/lib/opal/cli_runners/node_modules/ws/lib/Extensions.js +0 -69
  198. data/lib/opal/cli_runners/node_modules/ws/lib/PerMessageDeflate.js +0 -339
  199. data/lib/opal/cli_runners/node_modules/ws/lib/Receiver.js +0 -520
  200. data/lib/opal/cli_runners/node_modules/ws/lib/Sender.js +0 -438
  201. data/lib/opal/cli_runners/node_modules/ws/lib/Validation.fallback.js +0 -9
  202. data/lib/opal/cli_runners/node_modules/ws/lib/Validation.js +0 -17
  203. data/lib/opal/cli_runners/node_modules/ws/lib/WebSocket.js +0 -705
  204. data/lib/opal/cli_runners/node_modules/ws/lib/WebSocketServer.js +0 -336
  205. data/spec/filters/bugs/boolean.rb +0 -3
  206. data/spec/filters/bugs/matrix.rb +0 -3
  207. data/spec/filters/unsupported/fixnum.rb +0 -15
  208. data/spec/filters/unsupported/freeze.rb +0 -102
  209. data/spec/filters/unsupported/pathname.rb +0 -4
  210. data/spec/filters/unsupported/proc.rb +0 -4
  211. data/spec/filters/unsupported/random.rb +0 -5
  212. data/spec/filters/unsupported/taint.rb +0 -162
@@ -77,11 +77,12 @@
77
77
  };
78
78
 
79
79
  // Minify common function calls
80
- var $has_own = Object.hasOwnProperty;
80
+ var $call = Function.prototype.call;
81
81
  var $bind = Function.prototype.bind;
82
+ var $has_own = Object.hasOwn || $call.bind(Object.prototype.hasOwnProperty);
82
83
  var $set_proto = Object.setPrototypeOf;
83
- var $slice = Array.prototype.slice;
84
- var $splice = Array.prototype.splice;
84
+ var $slice = $call.bind(Array.prototype.slice);
85
+ var $splice = $call.bind(Array.prototype.splice);
85
86
 
86
87
  // Nil object id is always 4
87
88
  var nil_id = 4;
@@ -129,6 +130,28 @@
129
130
  }
130
131
  };
131
132
 
133
+ // A helper function for raising things, that gracefully degrades if necessary
134
+ // functionality is not yet loaded.
135
+ function $raise(klass, message) {
136
+ // Raise Exception, so we can know that something wrong is going on.
137
+ if (!klass) klass = Opal.Exception || Error;
138
+
139
+ if (Kernel && Kernel.$raise) {
140
+ if (arguments.length > 2) {
141
+ Kernel.$raise(klass.$new.apply(klass, $slice(arguments, 1)));
142
+ }
143
+ else {
144
+ Kernel.$raise(klass, message);
145
+ }
146
+ }
147
+ else if (!klass.$new) {
148
+ throw new klass(message);
149
+ }
150
+ else {
151
+ throw klass.$new(message);
152
+ }
153
+ }
154
+
132
155
  function $prop(object, name, initialValue) {
133
156
  if (typeof(object) === "string") {
134
157
  // Special case for:
@@ -156,7 +179,6 @@
156
179
 
157
180
  Opal.slice = $slice;
158
181
 
159
-
160
182
  // Helpers
161
183
  // -----
162
184
 
@@ -173,12 +195,12 @@
173
195
 
174
196
  if (coerced && method) {
175
197
  coerced = coerced.$$class;
176
- return Opal.TypeError.$new(
198
+ $raise(Opal.TypeError,
177
199
  "can't convert " + object + " into " + type +
178
200
  " (" + object + "#" + method + " gives " + coerced + ")"
179
201
  )
180
202
  } else {
181
- return Opal.TypeError.$new(
203
+ $raise(Opal.TypeError,
182
204
  "no implicit conversion of " + object + " into " + type
183
205
  )
184
206
  }
@@ -197,13 +219,13 @@
197
219
 
198
220
  // Fast path for the most common situation
199
221
  if (object['$respond_to?'].$$pristine && object.$method_missing.$$pristine) {
200
- body = object['$' + method];
201
- if (body == null || body.$$stub) throw Opal.type_error(object, type);
222
+ body = object[$jsid(method)];
223
+ if (body == null || body.$$stub) Opal.type_error(object, type);
202
224
  return body.apply(object, args);
203
225
  }
204
226
 
205
227
  if (!object['$respond_to?'](method)) {
206
- throw Opal.type_error(object, type);
228
+ Opal.type_error(object, type);
207
229
  }
208
230
 
209
231
  if (args == null) args = [];
@@ -312,7 +334,7 @@
312
334
  ancestors = $ancestors(cref);
313
335
 
314
336
  for (i = 0, ii = ancestors.length; i < ii; i++) {
315
- if (ancestors[i].$$const && $has_own.call(ancestors[i].$$const, name)) {
337
+ if (ancestors[i].$$const && $has_own(ancestors[i].$$const, name)) {
316
338
  return ancestors[i].$$const[name];
317
339
  } else if (ancestors[i].$$autoload && ancestors[i].$$autoload[name]) {
318
340
  return handle_autoload(ancestors[i], name);
@@ -342,7 +364,7 @@
342
364
  if (cref === '::') cref = _Object;
343
365
 
344
366
  if (!cref.$$is_module && !cref.$$is_class) {
345
- throw new Opal.TypeError(cref.toString() + " is not a class/module");
367
+ $raise(Opal.TypeError, cref.toString() + " is not a class/module");
346
368
  }
347
369
 
348
370
  result = const_get_name(cref, name);
@@ -367,7 +389,7 @@
367
389
  if (cref === '::') cref = _Object;
368
390
 
369
391
  if (!cref.$$is_module && !cref.$$is_class) {
370
- throw new Opal.TypeError(cref.toString() + " is not a class/module");
392
+ $raise(Opal.TypeError, cref.toString() + " is not a class/module");
371
393
  }
372
394
 
373
395
  if ((cache = cref.$$const_cache) == null) {
@@ -418,6 +440,8 @@
418
440
  // Register the constant on a cref and opportunistically set the name of
419
441
  // unnamed classes/modules.
420
442
  function $const_set(cref, name, value) {
443
+ var new_const = true;
444
+
421
445
  if (cref == null || cref === '::') cref = _Object;
422
446
 
423
447
  if (value.$$is_a_module) {
@@ -426,6 +450,11 @@
426
450
  }
427
451
 
428
452
  cref.$$const = (cref.$$const || Object.create(null));
453
+
454
+ if (name in cref.$$const || ("$$autoload" in cref && name in cref.$$autoload)) {
455
+ new_const = false;
456
+ }
457
+
429
458
  cref.$$const[name] = value;
430
459
 
431
460
  // Add a short helper to navigate constants manually.
@@ -441,6 +470,10 @@
441
470
  // Name new class directly onto current scope (Opal.Foo.Baz = klass)
442
471
  $prop(cref, name, value);
443
472
 
473
+ if (new_const && cref.$const_added && !cref.$const_added.$$pristine) {
474
+ cref.$const_added(name);
475
+ }
476
+
444
477
  return value;
445
478
  };
446
479
 
@@ -490,7 +523,7 @@
490
523
  return nil;
491
524
  }
492
525
 
493
- throw Opal.NameError.$new("constant "+cref+"::"+cref.$name()+" not defined");
526
+ $raise(Opal.NameError, "constant "+cref+"::"+cref.$name()+" not defined");
494
527
  };
495
528
 
496
529
  // Generates a function that is a curried const_get_relative.
@@ -540,7 +573,7 @@
540
573
  // Inheritance from bridged classes requires
541
574
  // calling original JS constructors
542
575
  klass = function() {
543
- var args = $slice.call(arguments),
576
+ var args = $slice(arguments),
544
577
  self = new ($bind.apply(superclass.$$constructor, [null].concat(args)))();
545
578
 
546
579
  // and replacing a __proto__ manually
@@ -622,7 +655,7 @@
622
655
  if (klass) {
623
656
  // Make sure the existing constant is a class, or raise error
624
657
  if (!klass.$$is_class) {
625
- throw Opal.TypeError.$new(name + " is not a class");
658
+ $raise(Opal.TypeError, name + " is not a class");
626
659
  }
627
660
 
628
661
  return klass;
@@ -631,7 +664,7 @@
631
664
 
632
665
  function ensureSuperclassMatch(klass, superclass) {
633
666
  if (klass.$$super !== superclass) {
634
- throw Opal.TypeError.$new("superclass mismatch for class " + klass.$$name);
667
+ $raise(Opal.TypeError, "superclass mismatch for class " + klass.$$name);
635
668
  }
636
669
  }
637
670
 
@@ -656,7 +689,7 @@
656
689
  bridged = superclass;
657
690
  superclass = _Object;
658
691
  } else {
659
- throw Opal.TypeError.$new("superclass must be a Class (" + (
692
+ $raise(Opal.TypeError, "superclass must be a Class (" + (
660
693
  (superclass.constructor && (superclass.constructor.name || superclass.constructor.$$name)) ||
661
694
  typeof(superclass)
662
695
  ) + " given)");
@@ -748,7 +781,7 @@
748
781
 
749
782
  if (module) {
750
783
  if (!module.$$is_module && module !== _Object) {
751
- throw Opal.TypeError.$new(name + " is not a module");
784
+ $raise(Opal.TypeError, name + " is not a module");
752
785
  }
753
786
  }
754
787
 
@@ -999,7 +1032,7 @@
999
1032
  for (i = length - 2; i >= 0; i--) {
1000
1033
  var ancestor = ancestors[i];
1001
1034
 
1002
- if ($has_own.call(ancestor.$$cvars, name)) {
1035
+ if ($has_own(ancestor.$$cvars, name)) {
1003
1036
  ancestor.$$cvars[name] = value;
1004
1037
  return value;
1005
1038
  }
@@ -1015,7 +1048,7 @@
1015
1048
  // @param module [Module]
1016
1049
  // @param name [String]
1017
1050
  Opal.class_variable_get = function(module, name, tolerant) {
1018
- if ($has_own.call(module.$$cvars, name))
1051
+ if ($has_own(module.$$cvars, name))
1019
1052
  return module.$$cvars[name];
1020
1053
 
1021
1054
  var ancestors = $ancestors(module),
@@ -1024,13 +1057,13 @@
1024
1057
  for (i = 0; i < length; i++) {
1025
1058
  var ancestor = ancestors[i];
1026
1059
 
1027
- if ($has_own.call(ancestor.$$cvars, name)) {
1060
+ if ($has_own(ancestor.$$cvars, name)) {
1028
1061
  return ancestor.$$cvars[name];
1029
1062
  }
1030
1063
  }
1031
1064
 
1032
1065
  if (!tolerant)
1033
- throw Opal.NameError.$new('uninitialized class variable '+name+' in '+module.$name());
1066
+ $raise(Opal.NameError, 'uninitialized class variable '+name+' in '+module.$name());
1034
1067
 
1035
1068
  return nil;
1036
1069
  }
@@ -1102,7 +1135,7 @@
1102
1135
  var iclasses = [];
1103
1136
 
1104
1137
  if (module_ancestors.indexOf(includer) !== -1) {
1105
- throw Opal.ArgumentError.$new('cyclic include detected');
1138
+ $raise(Opal.ArgumentError, 'cyclic include detected');
1106
1139
  }
1107
1140
 
1108
1141
  for (var i = 0, length = module_ancestors.length; i < length; i++) {
@@ -1207,7 +1240,7 @@
1207
1240
  var iclasses = [];
1208
1241
 
1209
1242
  if (module_ancestors.indexOf(prepender) !== -1) {
1210
- throw Opal.ArgumentError.$new('cyclic prepend detected');
1243
+ $raise(Opal.ArgumentError, 'cyclic prepend detected');
1211
1244
  }
1212
1245
 
1213
1246
  for (var i = 0, length = module_ancestors.length; i < length; i++) {
@@ -1263,7 +1296,7 @@
1263
1296
  end_chain_on = Object.getPrototypeOf(end_chain_on);
1264
1297
  }
1265
1298
  } else {
1266
- throw Opal.RuntimeError.$new("Prepending a module multiple times is not supported");
1299
+ $raise(Opal.RuntimeError, "Prepending a module multiple times is not supported");
1267
1300
  }
1268
1301
 
1269
1302
  $set_proto(start_chain_after, chain.first);
@@ -1360,7 +1393,7 @@
1360
1393
  //
1361
1394
  Opal.bridge = function(native_klass, klass) {
1362
1395
  if (native_klass.hasOwnProperty('$$bridge')) {
1363
- throw Opal.ArgumentError.$new("already bridged");
1396
+ $raise(Opal.ArgumentError, "already bridged");
1364
1397
  }
1365
1398
 
1366
1399
  // constructor is a JS function with a prototype chain like:
@@ -1478,7 +1511,7 @@
1478
1511
  stubs = stubs.split(',');
1479
1512
 
1480
1513
  for (var i = 0, length = stubs.length; i < length; i++) {
1481
- stub = '$'+stubs[i], existing_method = proto[stub];
1514
+ stub = $jsid(stubs[i]), existing_method = proto[stub];
1482
1515
 
1483
1516
  if (existing_method == null || existing_method.$$stub) {
1484
1517
  Opal.add_stub_for(proto, stub);
@@ -1543,7 +1576,7 @@
1543
1576
  }
1544
1577
  inspect += meth;
1545
1578
 
1546
- throw Opal.ArgumentError.$new('[' + inspect + '] wrong number of arguments (given ' + actual + ', expected ' + expected + ')');
1579
+ $raise(Opal.ArgumentError, '[' + inspect + '] wrong number of arguments (given ' + actual + ', expected ' + expected + ')');
1547
1580
  };
1548
1581
 
1549
1582
  // Arity count error dispatcher for blocks
@@ -1555,7 +1588,7 @@
1555
1588
  Opal.block_ac = function(actual, expected, context) {
1556
1589
  var inspect = "`block in " + context + "'";
1557
1590
 
1558
- throw Opal.ArgumentError.$new(inspect + ': wrong number of arguments (given ' + actual + ', expected ' + expected + ')');
1591
+ $raise(Opal.ArgumentError, inspect + ': wrong number of arguments (given ' + actual + ', expected ' + expected + ')');
1559
1592
  };
1560
1593
 
1561
1594
  function get_ancestors(obj) {
@@ -1568,7 +1601,7 @@
1568
1601
 
1569
1602
  // Super dispatcher
1570
1603
  Opal.find_super = function(obj, mid, current_func, defcheck, allow_stubs) {
1571
- var jsid = '$' + mid, ancestors, super_method;
1604
+ var jsid = $jsid(mid), ancestors, super_method;
1572
1605
 
1573
1606
  ancestors = get_ancestors(obj);
1574
1607
 
@@ -1590,7 +1623,7 @@
1590
1623
 
1591
1624
  if (!defcheck && super_method && super_method.$$stub && obj.$method_missing.$$pristine) {
1592
1625
  // method_missing hasn't been explicitly defined
1593
- throw Opal.NoMethodError.$new('super: no superclass method `'+mid+"' for "+obj, mid);
1626
+ $raise(Opal.NoMethodError, 'super: no superclass method `'+mid+"' for "+obj, mid);
1594
1627
  }
1595
1628
 
1596
1629
  return (super_method.$$stub && !allow_stubs) ? null : super_method;
@@ -1601,11 +1634,11 @@
1601
1634
  var call_jsid = jsid;
1602
1635
 
1603
1636
  if (!current_func) {
1604
- throw Opal.RuntimeError.$new("super called outside of method");
1637
+ $raise(Opal.RuntimeError, "super called outside of method");
1605
1638
  }
1606
1639
 
1607
1640
  if (implicit && current_func.$$define_meth) {
1608
- throw Opal.RuntimeError.$new(
1641
+ $raise(Opal.RuntimeError,
1609
1642
  "implicit argument passing of super from method defined by define_method() is not supported. " +
1610
1643
  "Specify all arguments explicitly"
1611
1644
  );
@@ -1627,7 +1660,7 @@
1627
1660
  // handles yield calls for 1 yielded arg
1628
1661
  Opal.yield1 = function(block, arg) {
1629
1662
  if (typeof(block) !== "function") {
1630
- throw Opal.LocalJumpError.$new("no block given");
1663
+ $raise(Opal.LocalJumpError, "no block given");
1631
1664
  }
1632
1665
 
1633
1666
  var has_mlhs = block.$$has_top_level_mlhs_arg,
@@ -1648,7 +1681,7 @@
1648
1681
  // handles yield for > 1 yielded arg
1649
1682
  Opal.yieldX = function(block, args) {
1650
1683
  if (typeof(block) !== "function") {
1651
- throw Opal.LocalJumpError.$new("no block given");
1684
+ $raise(Opal.LocalJumpError, "no block given");
1652
1685
  }
1653
1686
 
1654
1687
  if (block.length > 1 && args.length === 1) {
@@ -1714,12 +1747,12 @@
1714
1747
  return hash;
1715
1748
  }
1716
1749
  else {
1717
- throw Opal.TypeError.$new("Can't convert " + value.$$class +
1750
+ $raise(Opal.TypeError, "Can't convert " + value.$$class +
1718
1751
  " to Hash (" + value.$$class + "#to_hash gives " + hash.$$class + ")");
1719
1752
  }
1720
1753
  }
1721
1754
  else {
1722
- throw Opal.TypeError.$new("no implicit conversion of " + value.$$class + " into Hash");
1755
+ $raise(Opal.TypeError, "no implicit conversion of " + value.$$class + " into Hash");
1723
1756
  }
1724
1757
  };
1725
1758
 
@@ -1742,7 +1775,7 @@
1742
1775
  return ary;
1743
1776
  }
1744
1777
  else {
1745
- throw Opal.TypeError.$new("Can't convert " + value.$$class +
1778
+ $raise(Opal.TypeError, "Can't convert " + value.$$class +
1746
1779
  " to Array (" + value.$$class + "#to_ary gives " + ary.$$class + ")");
1747
1780
  }
1748
1781
  }
@@ -1766,7 +1799,7 @@
1766
1799
  return ary;
1767
1800
  }
1768
1801
  else {
1769
- throw Opal.TypeError.$new("Can't convert " + value.$$class +
1802
+ $raise(Opal.TypeError, "Can't convert " + value.$$class +
1770
1803
  " to Array (" + value.$$class + "#to_a gives " + ary.$$class + ")");
1771
1804
  }
1772
1805
  }
@@ -1785,7 +1818,7 @@
1785
1818
  Opal.extract_kwargs = function(parameters) {
1786
1819
  var kwargs = parameters[parameters.length - 1];
1787
1820
  if (kwargs != null && Opal.respond_to(kwargs, '$to_hash', true)) {
1788
- $splice.call(parameters, parameters.length - 1);
1821
+ $splice(parameters, parameters.length - 1);
1789
1822
  return kwargs;
1790
1823
  }
1791
1824
  };
@@ -1826,6 +1859,13 @@
1826
1859
  }
1827
1860
  }
1828
1861
 
1862
+ // Optimization for a costly operation of prepending '$' to method names
1863
+ var jsid_cache = {}
1864
+ function $jsid(name) {
1865
+ return jsid_cache[name] || (jsid_cache[name] = '$' + name);
1866
+ }
1867
+ Opal.jsid = $jsid;
1868
+
1829
1869
  // Calls passed method on a ruby object with arguments and block:
1830
1870
  //
1831
1871
  // Can take a method or a method name.
@@ -1858,9 +1898,9 @@
1858
1898
  body = method;
1859
1899
  method = null;
1860
1900
  } else if (typeof(method) === 'string') {
1861
- body = recv['$'+method];
1901
+ body = recv[$jsid(method)];
1862
1902
  } else {
1863
- throw Opal.NameError.$new("Passed method should be a string or a function");
1903
+ $raise(Opal.NameError, "Passed method should be a string or a function");
1864
1904
  }
1865
1905
 
1866
1906
  return Opal.send2(recv, body, method, args, block, blockopts);
@@ -1905,8 +1945,8 @@
1905
1945
  refine_module = refine_modules[ancestor];
1906
1946
 
1907
1947
  // Does this module define a method we want to call?
1908
- if (typeof refine_module.$$prototype['$'+method] !== 'undefined') {
1909
- body = refine_module.$$prototype['$'+method];
1948
+ if (typeof refine_module.$$prototype[$jsid(method)] !== 'undefined') {
1949
+ body = refine_module.$$prototype[$jsid(method)];
1910
1950
  return Opal.send2(recv, body, method, args, block, blockopts);
1911
1951
  }
1912
1952
  }
@@ -2020,15 +2060,15 @@
2020
2060
  apply_blockopts(body, blockopts);
2021
2061
 
2022
2062
  if (obj.$$is_string || obj.$$is_number) {
2023
- throw Opal.TypeError.$new("can't define singleton");
2063
+ $raise(Opal.TypeError, "can't define singleton");
2024
2064
  }
2025
2065
  return Opal.defn(Opal.get_singleton_class(obj), jsid, body);
2026
2066
  };
2027
2067
 
2028
2068
  // Called from #remove_method.
2029
2069
  Opal.rdef = function(obj, jsid) {
2030
- if (!$has_own.call(obj.$$prototype, jsid)) {
2031
- throw Opal.NameError.$new("method '" + jsid.substr(1) + "' not defined in " + obj.$name());
2070
+ if (!$has_own(obj.$$prototype, jsid)) {
2071
+ $raise(Opal.NameError, "method '" + jsid.substr(1) + "' not defined in " + obj.$name());
2032
2072
  }
2033
2073
 
2034
2074
  delete obj.$$prototype[jsid];
@@ -2048,7 +2088,7 @@
2048
2088
  // Called from #undef_method.
2049
2089
  Opal.udef = function(obj, jsid) {
2050
2090
  if (!obj.$$prototype[jsid] || obj.$$prototype[jsid].$$stub) {
2051
- throw Opal.NameError.$new("method '" + jsid.substr(1) + "' not defined in " + obj.$name());
2091
+ $raise(Opal.NameError, "method '" + jsid.substr(1) + "' not defined in " + obj.$name());
2052
2092
  }
2053
2093
 
2054
2094
  Opal.add_stub_for(obj.$$prototype, jsid);
@@ -2070,8 +2110,8 @@
2070
2110
  }
2071
2111
 
2072
2112
  Opal.alias = function(obj, name, old) {
2073
- var id = '$' + name,
2074
- old_id = '$' + old,
2113
+ var id = $jsid(name),
2114
+ old_id = $jsid(old),
2075
2115
  body,
2076
2116
  alias;
2077
2117
 
@@ -2080,7 +2120,7 @@
2080
2120
  obj = Opal.Object;
2081
2121
  }
2082
2122
 
2083
- body = obj.$$prototype['$' + old];
2123
+ body = obj.$$prototype[old_id];
2084
2124
 
2085
2125
  // When running inside #instance_eval the alias refers to class methods.
2086
2126
  if (obj.$$eval) {
@@ -2101,7 +2141,7 @@
2101
2141
  }
2102
2142
 
2103
2143
  if (!is_method_body(body)) {
2104
- throw Opal.NameError.$new("undefined method `" + old + "' for class `" + obj.$name() + "'")
2144
+ $raise(Opal.NameError, "undefined method `" + old + "' for class `" + obj.$name() + "'")
2105
2145
  }
2106
2146
  }
2107
2147
 
@@ -2135,7 +2175,7 @@
2135
2175
  // Try to make the browser pick the right name
2136
2176
  alias.displayName = name;
2137
2177
 
2138
- alias.$$arity = body.$$arity;
2178
+ alias.$$arity = body.$$arity == null ? body.length : body.$$arity;
2139
2179
  alias.$$parameters = body.$$parameters;
2140
2180
  alias.$$source_location = body.$$source_location;
2141
2181
  alias.$$alias_of = body;
@@ -2161,11 +2201,11 @@
2161
2201
  }
2162
2202
 
2163
2203
  Opal.alias_native = function(obj, name, native_name) {
2164
- var id = '$' + name,
2204
+ var id = $jsid(name),
2165
2205
  body = obj.$$prototype[native_name];
2166
2206
 
2167
2207
  if (typeof(body) !== "function" || body.$$stub) {
2168
- throw Opal.NameError.$new("undefined native method `" + native_name + "' for class `" + obj.$name() + "'")
2208
+ $raise(Opal.NameError, "undefined native method `" + native_name + "' for class `" + obj.$name() + "'")
2169
2209
  }
2170
2210
 
2171
2211
  Opal.defn(obj, id, body);
@@ -2203,7 +2243,7 @@
2203
2243
 
2204
2244
  Opal.hash_put = function(hash, key, value) {
2205
2245
  if (key.$$is_string) {
2206
- if (!$has_own.call(hash.$$smap, key)) {
2246
+ if (!$has_own(hash.$$smap, key)) {
2207
2247
  hash.$$keys.push(key);
2208
2248
  }
2209
2249
  hash.$$smap[key] = value;
@@ -2213,7 +2253,7 @@
2213
2253
  var key_hash, bucket, last_bucket;
2214
2254
  key_hash = hash.$$by_identity ? Opal.id(key) : key.$hash();
2215
2255
 
2216
- if (!$has_own.call(hash.$$map, key_hash)) {
2256
+ if (!$has_own(hash.$$map, key_hash)) {
2217
2257
  bucket = {key: key, key_hash: key_hash, value: value};
2218
2258
  hash.$$keys.push(bucket);
2219
2259
  hash.$$map[key_hash] = bucket;
@@ -2241,7 +2281,7 @@
2241
2281
 
2242
2282
  Opal.hash_get = function(hash, key) {
2243
2283
  if (key.$$is_string) {
2244
- if ($has_own.call(hash.$$smap, key)) {
2284
+ if ($has_own(hash.$$smap, key)) {
2245
2285
  return hash.$$smap[key];
2246
2286
  }
2247
2287
  return;
@@ -2250,7 +2290,7 @@
2250
2290
  var key_hash, bucket;
2251
2291
  key_hash = hash.$$by_identity ? Opal.id(key) : key.$hash();
2252
2292
 
2253
- if ($has_own.call(hash.$$map, key_hash)) {
2293
+ if ($has_own(hash.$$map, key_hash)) {
2254
2294
  bucket = hash.$$map[key_hash];
2255
2295
 
2256
2296
  while (bucket) {
@@ -2268,7 +2308,7 @@
2268
2308
  if (key.$$is_string) {
2269
2309
  if (typeof key !== "string") key = key.valueOf();
2270
2310
 
2271
- if (!$has_own.call(hash.$$smap, key)) {
2311
+ if (!$has_own(hash.$$smap, key)) {
2272
2312
  return;
2273
2313
  }
2274
2314
 
@@ -2292,7 +2332,7 @@
2292
2332
 
2293
2333
  var key_hash = key.$hash();
2294
2334
 
2295
- if (!$has_own.call(hash.$$map, key_hash)) {
2335
+ if (!$has_own(hash.$$map, key_hash)) {
2296
2336
  return;
2297
2337
  }
2298
2338
 
@@ -2367,7 +2407,7 @@
2367
2407
 
2368
2408
  hash.$$keys[i].key_hash = key_hash;
2369
2409
 
2370
- if (!$has_own.call(hash.$$map, key_hash)) {
2410
+ if (!$has_own(hash.$$map, key_hash)) {
2371
2411
  hash.$$map[key_hash] = hash.$$keys[i];
2372
2412
  continue;
2373
2413
  }
@@ -2408,7 +2448,7 @@
2408
2448
 
2409
2449
  for (i = 0; i < length; i++) {
2410
2450
  if (args[i].length !== 2) {
2411
- throw Opal.ArgumentError.$new("value not of length 2: " + args[i].$inspect());
2451
+ $raise(Opal.ArgumentError, "value not of length 2: " + args[i].$inspect());
2412
2452
  }
2413
2453
 
2414
2454
  key = args[i][0];
@@ -2422,7 +2462,7 @@
2422
2462
  else {
2423
2463
  args = arguments[0];
2424
2464
  for (key in args) {
2425
- if ($has_own.call(args, key)) {
2465
+ if ($has_own(args, key)) {
2426
2466
  value = args[key];
2427
2467
 
2428
2468
  Opal.hash_put(hash, key, value);
@@ -2434,7 +2474,7 @@
2434
2474
  }
2435
2475
 
2436
2476
  if (arguments_length % 2 !== 0) {
2437
- throw Opal.ArgumentError.$new("odd number of arguments for Hash");
2477
+ $raise(Opal.ArgumentError, "odd number of arguments for Hash");
2438
2478
  }
2439
2479
 
2440
2480
  for (i = 0; i < arguments_length; i += 2) {
@@ -2499,7 +2539,7 @@
2499
2539
  // helper that can be used from methods
2500
2540
  function $deny_frozen_access(obj) {
2501
2541
  if (obj.$$frozen) {
2502
- throw Opal.FrozenError.$new("can't modify frozen " + (obj.$class()) + ": " + (obj), Opal.hash2(["receiver"], {"receiver": obj}));
2542
+ $raise(Opal.FrozenError, "can't modify frozen " + (obj.$class()) + ": " + (obj), Opal.hash2(["receiver"], {"receiver": obj}));
2503
2543
  }
2504
2544
  };
2505
2545
  Opal.deny_frozen_access = $deny_frozen_access;
@@ -2701,11 +2741,7 @@
2701
2741
  var message = 'cannot load such file -- ' + path;
2702
2742
 
2703
2743
  if (severity === "error") {
2704
- if (Opal.LoadError) {
2705
- throw Opal.LoadError.$new(message)
2706
- } else {
2707
- throw message
2708
- }
2744
+ $raise(Opal.LoadError, message);
2709
2745
  }
2710
2746
  else if (severity === "warning") {
2711
2747
  console.warn('WARNING: LoadError: ' + message);
@@ -2746,7 +2782,7 @@
2746
2782
  Opal.set_encoding = function(str, name, type) {
2747
2783
  if (typeof type === "undefined") type = "encoding";
2748
2784
  if (typeof str === 'string' || str.$$frozen === true)
2749
- throw Opal.FrozenError.$new("can't modify frozen String");
2785
+ $raise(Opal.FrozenError, "can't modify frozen String");
2750
2786
 
2751
2787
  var encoding = Opal.find_encoding(name);
2752
2788
 
@@ -2761,7 +2797,7 @@
2761
2797
  Opal.find_encoding = function(name) {
2762
2798
  var register = Opal.encodings;
2763
2799
  var encoding = register[name] || register[name.toUpperCase()];
2764
- if (!encoding) throw Opal.ArgumentError.$new("unknown encoding name - " + name);
2800
+ if (!encoding) $raise(Opal.ArgumentError, "unknown encoding name - " + name);
2765
2801
  return encoding;
2766
2802
  }
2767
2803
 
@@ -2883,17 +2919,44 @@
2883
2919
  } else if (kwargs.$$is_hash) {
2884
2920
  return kwargs;
2885
2921
  } else {
2886
- throw Opal.ArgumentError.$new('expected kwargs');
2922
+ $raise(Opal.ArgumentError, 'expected kwargs');
2887
2923
  }
2888
2924
  }
2889
2925
 
2890
2926
  Opal.get_kwarg = function(kwargs, key) {
2891
- if (!$has_own.call(kwargs.$$smap, key)) {
2892
- throw Opal.ArgumentError.$new('missing keyword: '+key);
2927
+ if (!$has_own(kwargs.$$smap, key)) {
2928
+ $raise(Opal.ArgumentError, 'missing keyword: '+key);
2893
2929
  }
2894
2930
  return kwargs.$$smap[key];
2895
2931
  }
2896
2932
 
2933
+ // Arrays of size > 32 elements that contain only strings,
2934
+ // symbols, integers and nils are compiled as a self-extracting
2935
+ // string.
2936
+ Opal.large_array_unpack = function(str) {
2937
+ var array = str.split(","), length = array.length, i;
2938
+ for (i = 0; i < length; i++) {
2939
+ switch(array[i][0]) {
2940
+ case undefined:
2941
+ array[i] = nil
2942
+ break;
2943
+ case '-':
2944
+ case '0':
2945
+ case '1':
2946
+ case '2':
2947
+ case '3':
2948
+ case '4':
2949
+ case '5':
2950
+ case '6':
2951
+ case '7':
2952
+ case '8':
2953
+ case '9':
2954
+ array[i] = +array[i];
2955
+ }
2956
+ }
2957
+ return array;
2958
+ }
2959
+
2897
2960
  // Initialization
2898
2961
  // --------------
2899
2962
  Opal.BasicObject = BasicObject = $allocate_class('BasicObject', null);
@@ -2949,7 +3012,7 @@
2949
3012
 
2950
3013
  // Foward calls to define_method on the top object to Object
2951
3014
  function top_define_method() {
2952
- var args = Opal.slice.call(arguments);
3015
+ var args = $slice(arguments);
2953
3016
  var block = top_define_method.$$p;
2954
3017
  top_define_method.$$p = null;
2955
3018
  return Opal.send(_Object, 'define_method', args, block)
@@ -2960,7 +3023,7 @@
2960
3023
  $const_set(_Object, 'NilClass', Opal.NilClass);
2961
3024
  nil = Opal.nil = new Opal.NilClass();
2962
3025
  nil.$$id = nil_id;
2963
- nil.call = nil.apply = function() { throw Opal.LocalJumpError.$new('no block given'); };
3026
+ nil.call = nil.apply = function() { $raise(Opal.LocalJumpError, 'no block given'); };
2964
3027
  nil.$$frozen = true;
2965
3028
  nil.$$comparable = false;
2966
3029
  Object.seal(nil);