opal 1.3.1 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (243) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.js +1 -0
  3. data/.github/workflows/build.yml +20 -21
  4. data/.rubocop.yml +5 -1
  5. data/CHANGELOG.md +119 -11
  6. data/UNRELEASED.md +4 -9
  7. data/benchmark-ips/bm_truthy.rb +30 -0
  8. data/bin/opal-mspec +1 -3
  9. data/bin/opal-repl +1 -2
  10. data/bin/remove-filters +1 -4
  11. data/docs/compiled_ruby.md +37 -22
  12. data/docs/faq.md +1 -1
  13. data/docs/headless_chrome.md +11 -21
  14. data/docs/jquery.md +1 -6
  15. data/docs/opal_parser.md +3 -1
  16. data/docs/promises.md +2 -0
  17. data/docs/releasing.md +3 -0
  18. data/docs/roda-sprockets.md +0 -1
  19. data/docs/source_maps.md +10 -11
  20. data/docs/static_applications.md +2 -2
  21. data/docs/unsupported_features.md +4 -0
  22. data/exe/opal-repl +1 -3
  23. data/lib/opal/ast/builder.rb +1 -1
  24. data/lib/opal/cli.rb +2 -2
  25. data/lib/opal/cli_runners/nodejs.rb +9 -2
  26. data/lib/opal/cli_runners/source-map-support-browser.js +80 -216
  27. data/lib/opal/cli_runners/source-map-support-node.js +80 -216
  28. data/lib/opal/cli_runners/source-map-support.js +5 -1
  29. data/lib/opal/cli_runners/system_runner.rb +10 -4
  30. data/lib/opal/compiler.rb +3 -5
  31. data/lib/opal/fragment.rb +5 -1
  32. data/lib/opal/nodes/args/extract_block_arg.rb +1 -8
  33. data/lib/opal/nodes/args/extract_kwoptarg.rb +1 -3
  34. data/lib/opal/nodes/args/extract_optarg.rb +1 -3
  35. data/lib/opal/nodes/args/extract_post_arg.rb +2 -5
  36. data/lib/opal/nodes/args/extract_post_optarg.rb +2 -7
  37. data/lib/opal/nodes/args/initialize_iterarg.rb +1 -3
  38. data/lib/opal/nodes/args/prepare_post_args.rb +5 -1
  39. data/lib/opal/nodes/base.rb +3 -2
  40. data/lib/opal/nodes/call.rb +20 -9
  41. data/lib/opal/nodes/call_special.rb +50 -0
  42. data/lib/opal/nodes/class.rb +24 -15
  43. data/lib/opal/nodes/constants.rb +23 -5
  44. data/lib/opal/nodes/def.rb +20 -23
  45. data/lib/opal/nodes/defined.rb +5 -5
  46. data/lib/opal/nodes/definitions.rb +2 -2
  47. data/lib/opal/nodes/defs.rb +2 -5
  48. data/lib/opal/nodes/helpers.rb +48 -18
  49. data/lib/opal/nodes/if.rb +113 -8
  50. data/lib/opal/nodes/iter.rb +23 -16
  51. data/lib/opal/nodes/literal.rb +18 -4
  52. data/lib/opal/nodes/logic.rb +2 -1
  53. data/lib/opal/nodes/masgn.rb +4 -9
  54. data/lib/opal/nodes/module.rb +29 -19
  55. data/lib/opal/nodes/node_with_args.rb +1 -7
  56. data/lib/opal/nodes/scope.rb +54 -15
  57. data/lib/opal/nodes/singleton_class.rb +5 -3
  58. data/lib/opal/nodes/super.rb +12 -12
  59. data/lib/opal/nodes/top.rb +34 -31
  60. data/lib/opal/nodes/variables.rb +2 -2
  61. data/lib/opal/nodes/x_string.rb +30 -28
  62. data/lib/opal/nodes.rb +0 -1
  63. data/lib/opal/parser/patch.rb +75 -0
  64. data/lib/opal/parser/with_ruby_lexer.rb +1 -1
  65. data/lib/opal/regexp_anchors.rb +7 -7
  66. data/lib/opal/requires.rb +19 -0
  67. data/lib/opal/rewriters/pattern_matching.rb +1 -1
  68. data/lib/opal/rewriters/returnable_logic.rb +102 -4
  69. data/lib/opal/util.rb +2 -2
  70. data/lib/opal/version.rb +1 -1
  71. data/lib/opal.rb +1 -17
  72. data/opal/corelib/array/pack.rb +11 -11
  73. data/opal/corelib/array.rb +193 -152
  74. data/opal/corelib/basic_object.rb +19 -15
  75. data/opal/corelib/binding.rb +7 -7
  76. data/opal/corelib/boolean.rb +12 -15
  77. data/opal/corelib/class.rb +23 -1
  78. data/opal/corelib/comparable.rb +8 -8
  79. data/opal/corelib/complex/base.rb +2 -2
  80. data/opal/corelib/complex.rb +79 -88
  81. data/opal/corelib/constants.rb +9 -9
  82. data/opal/corelib/dir.rb +4 -3
  83. data/opal/corelib/enumerable.rb +140 -127
  84. data/opal/corelib/enumerator/arithmetic_sequence.rb +177 -0
  85. data/opal/corelib/enumerator/chain.rb +42 -0
  86. data/opal/corelib/enumerator/generator.rb +35 -0
  87. data/opal/corelib/enumerator/lazy.rb +243 -0
  88. data/opal/corelib/enumerator/yielder.rb +36 -0
  89. data/opal/corelib/enumerator.rb +45 -300
  90. data/opal/corelib/error/errno.rb +47 -0
  91. data/opal/corelib/error.rb +62 -60
  92. data/opal/corelib/file.rb +26 -12
  93. data/opal/corelib/hash.rb +98 -107
  94. data/opal/corelib/helpers.rb +62 -13
  95. data/opal/corelib/io.rb +48 -35
  96. data/opal/corelib/kernel/format.rb +29 -29
  97. data/opal/corelib/kernel.rb +86 -83
  98. data/opal/corelib/main.rb +14 -12
  99. data/opal/corelib/marshal/read_buffer.rb +15 -15
  100. data/opal/corelib/marshal/write_buffer.rb +45 -44
  101. data/opal/corelib/marshal.rb +3 -3
  102. data/opal/corelib/math.rb +50 -50
  103. data/opal/corelib/method.rb +12 -8
  104. data/opal/corelib/module.rb +79 -75
  105. data/opal/corelib/nil.rb +9 -11
  106. data/opal/corelib/number.rb +113 -118
  107. data/opal/corelib/numeric.rb +37 -33
  108. data/opal/corelib/object_space.rb +11 -10
  109. data/opal/corelib/pack_unpack/format_string_parser.rb +3 -3
  110. data/opal/corelib/pattern_matching/base.rb +7 -7
  111. data/opal/corelib/pattern_matching.rb +1 -1
  112. data/opal/corelib/proc.rb +15 -16
  113. data/opal/corelib/process/base.rb +2 -2
  114. data/opal/corelib/process/status.rb +21 -0
  115. data/opal/corelib/process.rb +5 -5
  116. data/opal/corelib/random/formatter.rb +11 -11
  117. data/opal/corelib/random/math_random.js.rb +1 -1
  118. data/opal/corelib/random/mersenne_twister.rb +3 -3
  119. data/opal/corelib/random/seedrandom.js.rb +3 -3
  120. data/opal/corelib/random.rb +17 -17
  121. data/opal/corelib/range.rb +51 -35
  122. data/opal/corelib/rational/base.rb +4 -4
  123. data/opal/corelib/rational.rb +61 -62
  124. data/opal/corelib/regexp.rb +54 -45
  125. data/opal/corelib/runtime.js +247 -141
  126. data/opal/corelib/string/encoding.rb +21 -21
  127. data/opal/corelib/string/unpack.rb +19 -14
  128. data/opal/corelib/string.rb +137 -130
  129. data/opal/corelib/struct.rb +59 -46
  130. data/opal/corelib/time.rb +47 -57
  131. data/opal/corelib/trace_point.rb +2 -2
  132. data/opal/corelib/unsupported.rb +31 -120
  133. data/opal/corelib/variables.rb +3 -3
  134. data/opal/opal/base.rb +9 -8
  135. data/opal/opal/full.rb +8 -8
  136. data/opal/opal/mini.rb +17 -17
  137. data/opal/opal.rb +17 -18
  138. data/opal.gemspec +1 -1
  139. data/spec/filters/bugs/array.rb +4 -24
  140. data/spec/filters/bugs/basicobject.rb +0 -1
  141. data/spec/filters/bugs/bigdecimal.rb +0 -23
  142. data/spec/filters/bugs/binding.rb +0 -1
  143. data/spec/filters/bugs/boolean.rb +3 -0
  144. data/spec/filters/bugs/class.rb +2 -0
  145. data/spec/filters/bugs/date.rb +0 -5
  146. data/spec/filters/bugs/encoding.rb +8 -50
  147. data/spec/filters/bugs/enumerable.rb +4 -1
  148. data/spec/filters/bugs/enumerator.rb +3 -36
  149. data/spec/filters/bugs/exception.rb +0 -2
  150. data/spec/filters/bugs/file.rb +0 -2
  151. data/spec/filters/bugs/float.rb +0 -3
  152. data/spec/filters/bugs/hash.rb +5 -3
  153. data/spec/filters/bugs/integer.rb +2 -3
  154. data/spec/filters/bugs/kernel.rb +2 -31
  155. data/spec/filters/bugs/language.rb +29 -49
  156. data/spec/filters/bugs/main.rb +0 -2
  157. data/spec/filters/bugs/marshal.rb +2 -3
  158. data/spec/filters/bugs/matrix.rb +0 -36
  159. data/spec/filters/bugs/module.rb +7 -61
  160. data/spec/filters/bugs/numeric.rb +0 -7
  161. data/spec/filters/bugs/objectspace.rb +1 -1
  162. data/spec/filters/bugs/pack_unpack.rb +0 -4
  163. data/spec/filters/bugs/proc.rb +0 -9
  164. data/spec/filters/bugs/random.rb +0 -5
  165. data/spec/filters/bugs/range.rb +1 -6
  166. data/spec/filters/bugs/regexp.rb +0 -3
  167. data/spec/filters/bugs/set.rb +8 -1
  168. data/spec/filters/bugs/string.rb +9 -34
  169. data/spec/filters/bugs/stringscanner.rb +8 -7
  170. data/spec/filters/bugs/struct.rb +2 -3
  171. data/spec/filters/bugs/symbol.rb +0 -1
  172. data/spec/filters/bugs/time.rb +0 -8
  173. data/spec/filters/bugs/unboundmethod.rb +0 -8
  174. data/spec/filters/bugs/warnings.rb +1 -7
  175. data/spec/filters/unsupported/freeze.rb +24 -0
  176. data/spec/filters/unsupported/integer.rb +1 -0
  177. data/spec/filters/unsupported/kernel.rb +12 -0
  178. data/spec/filters/unsupported/privacy.rb +3 -0
  179. data/spec/filters/unsupported/string.rb +2 -0
  180. data/spec/lib/builder_spec.rb +2 -2
  181. data/spec/lib/cli_spec.rb +1 -1
  182. data/spec/lib/compiler_spec.rb +37 -37
  183. data/spec/lib/simple_server_spec.rb +2 -2
  184. data/spec/lib/source_map/file_spec.rb +1 -1
  185. data/spec/opal/compiler/irb_spec.rb +2 -2
  186. data/spec/opal/core/io/read_spec.rb +69 -0
  187. data/spec/opal/core/kernel/puts_spec.rb +90 -0
  188. data/spec/opal/core/language/super_spec.rb +21 -0
  189. data/spec/opal/core/language/xstring_spec.rb +13 -0
  190. data/spec/opal/core/language_spec.rb +14 -0
  191. data/spec/opal/core/string/gsub_spec.rb +8 -0
  192. data/spec/ruby_specs +4 -2
  193. data/spec/support/rewriters_helper.rb +1 -1
  194. data/stdlib/bigdecimal.rb +7 -11
  195. data/stdlib/buffer/view.rb +2 -2
  196. data/stdlib/buffer.rb +2 -2
  197. data/stdlib/date.rb +5 -6
  198. data/stdlib/erb.rb +1 -0
  199. data/stdlib/js.rb +2 -1
  200. data/stdlib/native.rb +7 -8
  201. data/stdlib/nodejs/argf.rb +4 -4
  202. data/stdlib/nodejs/base.rb +29 -0
  203. data/stdlib/nodejs/dir.rb +1 -1
  204. data/stdlib/nodejs/env.rb +6 -9
  205. data/stdlib/nodejs/file.rb +23 -17
  206. data/stdlib/nodejs/fileutils.rb +3 -3
  207. data/stdlib/nodejs/io.rb +2 -20
  208. data/stdlib/nodejs/irb.rb +0 -0
  209. data/stdlib/nodejs/kernel.rb +2 -37
  210. data/stdlib/nodejs.rb +1 -3
  211. data/stdlib/opal/miniracer.rb +2 -0
  212. data/stdlib/opal/platform.rb +6 -13
  213. data/stdlib/opal/replutils.rb +16 -5
  214. data/stdlib/opal-parser.rb +2 -2
  215. data/stdlib/optparse/ac.rb +54 -0
  216. data/stdlib/optparse/date.rb +14 -0
  217. data/stdlib/optparse/kwargs.rb +22 -0
  218. data/stdlib/optparse/shellwords.rb +7 -0
  219. data/stdlib/optparse/time.rb +15 -0
  220. data/stdlib/optparse/uri.rb +7 -0
  221. data/stdlib/optparse/version.rb +69 -0
  222. data/stdlib/optparse.rb +2279 -0
  223. data/stdlib/pathname.rb +5 -6
  224. data/stdlib/pp.rb +18 -2
  225. data/stdlib/promise/v2.rb +18 -29
  226. data/stdlib/promise.rb +15 -21
  227. data/stdlib/quickjs/io.rb +0 -2
  228. data/stdlib/quickjs/kernel.rb +0 -2
  229. data/stdlib/quickjs.rb +2 -0
  230. data/stdlib/set.rb +32 -32
  231. data/stdlib/shellwords.rb +240 -0
  232. data/stdlib/stringio.rb +3 -6
  233. data/stdlib/strscan.rb +5 -8
  234. data/stdlib/template.rb +2 -2
  235. data/stdlib/thread.rb +7 -9
  236. data/tasks/linting-parse-eslint-results.js +1 -0
  237. data/tasks/linting.rake +0 -10
  238. data/tasks/performance.rake +5 -2
  239. data/tasks/testing/mspec_special_calls.rb +0 -12
  240. data/tasks/testing.rake +55 -37
  241. data/test/nodejs/test_file.rb +11 -0
  242. metadata +55 -8
  243. data/lib/opal/nodes/case.rb +0 -114
@@ -54,6 +54,12 @@
54
54
  // The actual Class class
55
55
  var Class;
56
56
 
57
+ // The Opal.Opal class (helpers etc.)
58
+ var _Opal;
59
+
60
+ // The Kernel module
61
+ var Kernel;
62
+
57
63
  // The Opal object that is exposed globally
58
64
  var Opal = global_object.Opal = {};
59
65
 
@@ -95,7 +101,7 @@
95
101
  if (obj.$$id != null) {
96
102
  return obj.$$id;
97
103
  }
98
- $defineProperty(obj, '$$id', Opal.uid());
104
+ $prop(obj, '$$id', Opal.uid());
99
105
  return obj.$$id;
100
106
  };
101
107
 
@@ -122,23 +128,7 @@
122
128
  }
123
129
  };
124
130
 
125
- // Inspect any kind of object, including non Ruby ones
126
- Opal.inspect = function(obj) {
127
- if (obj === undefined) {
128
- return "undefined";
129
- }
130
- else if (obj === null) {
131
- return "null";
132
- }
133
- else if (!obj.$$class) {
134
- return obj.toString();
135
- }
136
- else {
137
- return obj.$inspect();
138
- }
139
- };
140
-
141
- function $defineProperty(object, name, initialValue) {
131
+ function $prop(object, name, initialValue) {
142
132
  if (typeof(object) === "string") {
143
133
  // Special case for:
144
134
  // s = "string"
@@ -158,7 +148,10 @@
158
148
  }
159
149
  }
160
150
 
161
- Opal.defineProperty = $defineProperty;
151
+ Opal.prop = $prop;
152
+
153
+ // @deprecated
154
+ Opal.defineProperty = Opal.prop;
162
155
 
163
156
  Opal.slice = $slice;
164
157
 
@@ -166,12 +159,12 @@
166
159
  // Helpers
167
160
  // -----
168
161
 
169
- Opal.truthy = function(val) {
170
- return (val !== nil && val != null && (!val.$$is_boolean || val == true));
162
+ var $truthy = Opal.truthy = function(val) {
163
+ return false !== val && nil !== val && undefined !== val && null !== val && (!(val instanceof Boolean) || true === val.valueOf());
171
164
  };
172
165
 
173
166
  Opal.falsy = function(val) {
174
- return (val === nil || val == null || (val.$$is_boolean && val == false))
167
+ return !$truthy(val);
175
168
  };
176
169
 
177
170
  Opal.type_error = function(object, type, method, coerced) {
@@ -207,9 +200,10 @@
207
200
  var body = obj[jsid];
208
201
 
209
202
  if (obj['$respond_to?'].$$pristine) {
210
- if (obj['$respond_to_missing?'].$$pristine) {
211
- return typeof(body) === "function" && !body.$$stub;
212
- } else {
203
+ if (typeof(body) === "function" && !body.$$stub) {
204
+ return true;
205
+ }
206
+ if (!obj['$respond_to_missing?'].$$pristine) {
213
207
  return Opal.send(obj, obj['$respond_to_missing?'], [jsid.substr(1), include_all]);
214
208
  }
215
209
  } else {
@@ -244,7 +238,7 @@
244
238
  throw e;
245
239
  }
246
240
  cref.$$autoload[name].required = true;
247
- if (cref.$$const[name]) {
241
+ if (cref.$$const[name] != null) {
248
242
  cref.$$autoload[name].success = true;
249
243
  return cref.$$const[name];
250
244
  }
@@ -268,7 +262,7 @@
268
262
  // Get the constant in the scope of the current cref
269
263
  function const_get_name(cref, name) {
270
264
  if (cref) {
271
- if (cref.$$const[name]) { return cref.$$const[name]; }
265
+ if (cref.$$const[name] != null) { return cref.$$const[name]; }
272
266
  if (cref.$$autoload && cref.$$autoload[name]) {
273
267
  return handle_autoload(cref, name);
274
268
  }
@@ -346,6 +340,14 @@
346
340
  Opal.const_get_qualified = function(cref, name, skip_missing) {
347
341
  var result, cache, cached, current_version = Opal.const_cache_version;
348
342
 
343
+ if (name == null) {
344
+ // A shortpath for calls like ::String => $$$("String")
345
+ result = const_get_name(_Object, cref);
346
+
347
+ if (result != null) return result;
348
+ return Opal.const_get_qualified(_Object, cref, skip_missing);
349
+ }
350
+
349
351
  if (cref == null) return;
350
352
 
351
353
  if (cref === '::') cref = _Object;
@@ -355,7 +357,7 @@
355
357
  }
356
358
 
357
359
  if ((cache = cref.$$const_cache) == null) {
358
- $defineProperty(cref, '$$const_cache', Object.create(null));
360
+ $prop(cref, '$$const_cache', Object.create(null));
359
361
  cache = cref.$$const_cache;
360
362
  }
361
363
  cached = cache[name];
@@ -380,7 +382,7 @@
380
382
  var cref = nesting[0], result, current_version = Opal.const_cache_version, cache, cached;
381
383
 
382
384
  if ((cache = nesting.$$const_cache) == null) {
383
- $defineProperty(nesting, '$$const_cache', Object.create(null));
385
+ $prop(nesting, '$$const_cache', Object.create(null));
384
386
  cache = nesting.$$const_cache;
385
387
  }
386
388
  cached = cache[name];
@@ -401,7 +403,7 @@
401
403
 
402
404
  // Register the constant on a cref and opportunistically set the name of
403
405
  // unnamed classes/modules.
404
- Opal.const_set = function(cref, name, value) {
406
+ function $const_set(cref, name, value) {
405
407
  if (cref == null || cref === '::') cref = _Object;
406
408
 
407
409
  if (value.$$is_a_module) {
@@ -423,11 +425,13 @@
423
425
  if (cref === _Object) Opal[name] = value;
424
426
 
425
427
  // Name new class directly onto current scope (Opal.Foo.Baz = klass)
426
- $defineProperty(cref, name, value);
428
+ $prop(cref, name, value);
427
429
 
428
430
  return value;
429
431
  };
430
432
 
433
+ Opal.const_set = $const_set;
434
+
431
435
  // Get all the constants reachable from a given cref, by default will include
432
436
  // inherited constants.
433
437
  Opal.constants = function(cref, inherit) {
@@ -475,10 +479,17 @@
475
479
  throw Opal.NameError.$new("constant "+cref+"::"+cref.$name()+" not defined");
476
480
  };
477
481
 
482
+ // Generates a function that is a curried const_get_relative.
483
+ Opal.const_get_relative_factory = function(nesting) {
484
+ return function(name, skip_missing) {
485
+ return Opal.$$(nesting, name, skip_missing);
486
+ }
487
+ }
488
+
478
489
  // Setup some shortcuts to reduce compiled size
479
490
  Opal.$$ = Opal.const_get_relative;
480
491
  Opal.$$$ = Opal.const_get_qualified;
481
-
492
+ Opal.$r = Opal.const_get_relative_factory;
482
493
 
483
494
  // Modules & Classes
484
495
  // -----------------
@@ -502,13 +513,13 @@
502
513
  // use that as the scope instead.
503
514
  //
504
515
  // @param scope [Object] where the class is being created
505
- // @param superclass [Class,null] superclass of the new class (may be null)
506
- // @param id [String] the name of the class to be created
507
- // @param constructor [JS.Function] function to use as constructor
516
+ // @param superclass [Class,null] superclass of the new class (may be null)
517
+ // @param singleton [Boolean,null] a true value denotes we want to allocate
518
+ // a singleton
508
519
  //
509
520
  // @return new [Class] or existing ruby class
510
521
  //
511
- Opal.allocate_class = function(name, superclass) {
522
+ Opal.allocate_class = function(name, superclass, singleton) {
512
523
  var klass, constructor;
513
524
 
514
525
  if (superclass != null && superclass.$$bridge) {
@@ -526,26 +537,27 @@
526
537
  constructor = function(){};
527
538
  }
528
539
 
529
- if (name) {
530
- $defineProperty(constructor, 'displayName', '::'+name);
540
+ if (name && name !== nil) {
541
+ $prop(constructor, 'displayName', '::'+name);
531
542
  }
532
543
 
533
544
  klass = constructor;
534
545
 
535
- $defineProperty(klass, '$$name', name);
536
- $defineProperty(klass, '$$constructor', constructor);
537
- $defineProperty(klass, '$$prototype', constructor.prototype);
538
- $defineProperty(klass, '$$const', {});
539
- $defineProperty(klass, '$$is_class', true);
540
- $defineProperty(klass, '$$is_a_module', true);
541
- $defineProperty(klass, '$$super', superclass);
542
- $defineProperty(klass, '$$cvars', {});
543
- $defineProperty(klass, '$$own_included_modules', []);
544
- $defineProperty(klass, '$$own_prepended_modules', []);
545
- $defineProperty(klass, '$$ancestors', []);
546
- $defineProperty(klass, '$$ancestors_cache_version', null);
547
-
548
- $defineProperty(klass.$$prototype, '$$class', klass);
546
+ $prop(klass, '$$name', name);
547
+ $prop(klass, '$$constructor', constructor);
548
+ $prop(klass, '$$prototype', constructor.prototype);
549
+ $prop(klass, '$$const', {});
550
+ $prop(klass, '$$is_class', true);
551
+ $prop(klass, '$$is_a_module', true);
552
+ $prop(klass, '$$super', superclass);
553
+ $prop(klass, '$$cvars', {});
554
+ $prop(klass, '$$own_included_modules', []);
555
+ $prop(klass, '$$own_prepended_modules', []);
556
+ $prop(klass, '$$ancestors', []);
557
+ $prop(klass, '$$ancestors_cache_version', null);
558
+ $prop(klass, '$$subclasses', []);
559
+
560
+ $prop(klass.$$prototype, '$$class', klass);
549
561
 
550
562
  // By default if there are no singleton class methods
551
563
  // __proto__ is Class.prototype
@@ -558,6 +570,27 @@
558
570
  if (superclass != null) {
559
571
  $set_proto(klass.$$prototype, superclass.$$prototype);
560
572
 
573
+ if (singleton !== true) {
574
+ // Let's not forbid GC from cleaning up our
575
+ // subclasses.
576
+ if (typeof WeakRef !== 'undefined') {
577
+ // First, let's clean up our array from empty objects.
578
+ var i, subclass, rebuilt_subclasses = [];
579
+ for (i = 0; i < superclass.$$subclasses.length; i++) {
580
+ subclass = superclass.$$subclasses[i];
581
+ if (subclass.deref() !== undefined) {
582
+ rebuilt_subclasses.push(subclass);
583
+ }
584
+ }
585
+ // Now, let's add our class.
586
+ rebuilt_subclasses.push(new WeakRef(klass));
587
+ superclass.$$subclasses = rebuilt_subclasses;
588
+ }
589
+ else {
590
+ superclass.$$subclasses.push(klass);
591
+ }
592
+ }
593
+
561
594
  if (superclass.$$meta) {
562
595
  // If superclass has metaclass then we have explicitely inherit it.
563
596
  Opal.build_class_singleton_class(klass);
@@ -639,7 +672,7 @@
639
672
 
640
673
  // Create the class object (instance of Class)
641
674
  klass = Opal.allocate_class(name, superclass);
642
- Opal.const_set(scope, name, klass);
675
+ $const_set(scope, name, klass);
643
676
 
644
677
  // Call .inherited() hook with new class on the superclass
645
678
  if (superclass.$inherited) {
@@ -677,25 +710,25 @@
677
710
  Opal.allocate_module = function(name) {
678
711
  var constructor = function(){};
679
712
  if (name) {
680
- $defineProperty(constructor, 'displayName', name+'.$$constructor');
713
+ $prop(constructor, 'displayName', name+'.$$constructor');
681
714
  }
682
715
 
683
716
  var module = constructor;
684
717
 
685
718
  if (name)
686
- $defineProperty(constructor, 'displayName', name+'.constructor');
687
-
688
- $defineProperty(module, '$$name', name);
689
- $defineProperty(module, '$$prototype', constructor.prototype);
690
- $defineProperty(module, '$$const', {});
691
- $defineProperty(module, '$$is_module', true);
692
- $defineProperty(module, '$$is_a_module', true);
693
- $defineProperty(module, '$$cvars', {});
694
- $defineProperty(module, '$$iclasses', []);
695
- $defineProperty(module, '$$own_included_modules', []);
696
- $defineProperty(module, '$$own_prepended_modules', []);
697
- $defineProperty(module, '$$ancestors', [module]);
698
- $defineProperty(module, '$$ancestors_cache_version', null);
719
+ $prop(constructor, 'displayName', name+'.constructor');
720
+
721
+ $prop(module, '$$name', name);
722
+ $prop(module, '$$prototype', constructor.prototype);
723
+ $prop(module, '$$const', {});
724
+ $prop(module, '$$is_module', true);
725
+ $prop(module, '$$is_a_module', true);
726
+ $prop(module, '$$cvars', {});
727
+ $prop(module, '$$iclasses', []);
728
+ $prop(module, '$$own_included_modules', []);
729
+ $prop(module, '$$own_prepended_modules', []);
730
+ $prop(module, '$$ancestors', [module]);
731
+ $prop(module, '$$ancestors_cache_version', null);
699
732
 
700
733
  $set_proto(module, Opal.Module.prototype);
701
734
 
@@ -737,7 +770,7 @@
737
770
 
738
771
  // Module doesnt exist, create a new one...
739
772
  module = Opal.allocate_module(name);
740
- Opal.const_set(scope, name, module);
773
+ $const_set(scope, name, module);
741
774
 
742
775
  if (Opal.trace_class) { invoke_tracers_for_class(module); }
743
776
 
@@ -790,14 +823,14 @@
790
823
  // fallback on `Class`.
791
824
  superclass = klass === BasicObject ? Class : Opal.get_singleton_class(klass.$$super);
792
825
 
793
- meta = Opal.allocate_class(null, superclass, function(){});
826
+ meta = Opal.allocate_class(null, superclass, true);
794
827
 
795
- $defineProperty(meta, '$$is_singleton', true);
796
- $defineProperty(meta, '$$singleton_of', klass);
797
- $defineProperty(klass, '$$meta', meta);
828
+ $prop(meta, '$$is_singleton', true);
829
+ $prop(meta, '$$singleton_of', klass);
830
+ $prop(klass, '$$meta', meta);
798
831
  $set_proto(klass, meta.$$prototype);
799
832
  // Restoring ClassName.class
800
- $defineProperty(klass, '$$class', Opal.Class);
833
+ $prop(klass, '$$class', Opal.Class);
801
834
 
802
835
  return meta;
803
836
  };
@@ -807,14 +840,14 @@
807
840
  return mod.$$meta;
808
841
  }
809
842
 
810
- var meta = Opal.allocate_class(null, Opal.Module, function(){});
843
+ var meta = Opal.allocate_class(null, Opal.Module, true);
811
844
 
812
- $defineProperty(meta, '$$is_singleton', true);
813
- $defineProperty(meta, '$$singleton_of', mod);
814
- $defineProperty(mod, '$$meta', meta);
845
+ $prop(meta, '$$is_singleton', true);
846
+ $prop(meta, '$$singleton_of', mod);
847
+ $prop(mod, '$$meta', meta);
815
848
  $set_proto(mod, meta.$$prototype);
816
849
  // Restoring ModuleName.class
817
- $defineProperty(mod, '$$class', Opal.Module);
850
+ $prop(mod, '$$class', Opal.Module);
818
851
 
819
852
  return meta;
820
853
  };
@@ -825,14 +858,14 @@
825
858
  // @return [Class]
826
859
  Opal.build_object_singleton_class = function(object) {
827
860
  var superclass = object.$$class,
828
- klass = Opal.allocate_class(nil, superclass, function(){});
861
+ klass = Opal.allocate_class(nil, superclass, true);
829
862
 
830
- $defineProperty(klass, '$$is_singleton', true);
831
- $defineProperty(klass, '$$singleton_of', object);
863
+ $prop(klass, '$$is_singleton', true);
864
+ $prop(klass, '$$singleton_of', object);
832
865
 
833
866
  delete klass.$$prototype.$$class;
834
867
 
835
- $defineProperty(object, '$$meta', klass);
868
+ $prop(object, '$$meta', klass);
836
869
 
837
870
  $set_proto(object, object.$$meta.$$prototype);
838
871
 
@@ -904,11 +937,16 @@
904
937
  };
905
938
 
906
939
  Opal.methods = function(obj) {
907
- return Opal.instance_methods(Opal.get_singleton_class(obj));
940
+ return Opal.instance_methods(obj.$$meta || obj.$$class);
908
941
  };
909
942
 
910
943
  Opal.own_methods = function(obj) {
911
- return Opal.own_instance_methods(Opal.get_singleton_class(obj));
944
+ if (obj.$$meta) {
945
+ return Opal.own_instance_methods(obj.$$meta);
946
+ }
947
+ else {
948
+ return [];
949
+ }
912
950
  };
913
951
 
914
952
  Opal.receiver_methods = function(obj) {
@@ -1061,7 +1099,7 @@
1061
1099
 
1062
1100
  for (var i = 0, length = module_ancestors.length; i < length; i++) {
1063
1101
  var ancestor = module_ancestors[i], iclass = create_iclass(ancestor);
1064
- $defineProperty(iclass, '$$included', true);
1102
+ $prop(iclass, '$$included', true);
1065
1103
  iclasses.push(iclass);
1066
1104
  }
1067
1105
  var includer_ancestors = Opal.ancestors(includer),
@@ -1166,7 +1204,7 @@
1166
1204
 
1167
1205
  for (var i = 0, length = module_ancestors.length; i < length; i++) {
1168
1206
  var ancestor = module_ancestors[i], iclass = create_iclass(ancestor);
1169
- $defineProperty(iclass, '$$prepended', true);
1207
+ $prop(iclass, '$$prepended', true);
1170
1208
  iclasses.push(iclass);
1171
1209
  }
1172
1210
 
@@ -1185,8 +1223,8 @@
1185
1223
  // Making the module "dummy"
1186
1224
  prepender_iclass = create_dummy_iclass(prepender);
1187
1225
  flush_methods_in(prepender);
1188
- $defineProperty(dummy_prepender, '$$dummy', true);
1189
- $defineProperty(dummy_prepender, '$$define_methods_on', prepender_iclass);
1226
+ $prop(dummy_prepender, '$$dummy', true);
1227
+ $prop(dummy_prepender, '$$define_methods_on', prepender_iclass);
1190
1228
 
1191
1229
  // Converting
1192
1230
  // dummy(prepender) -> previous_parent
@@ -1265,11 +1303,11 @@
1265
1303
 
1266
1304
  for (i = 0; i < length; i++) {
1267
1305
  var prop = props[i];
1268
- $defineProperty(iclass, prop, proto[prop]);
1306
+ $prop(iclass, prop, proto[prop]);
1269
1307
  }
1270
1308
 
1271
- $defineProperty(iclass, '$$iclass', true);
1272
- $defineProperty(iclass, '$$module', module);
1309
+ $prop(iclass, '$$iclass', true);
1310
+ $prop(iclass, '$$module', module);
1273
1311
 
1274
1312
  return iclass;
1275
1313
  }
@@ -1277,7 +1315,7 @@
1277
1315
  function chain_iclasses(iclasses) {
1278
1316
  var length = iclasses.length, first = iclasses[0];
1279
1317
 
1280
- $defineProperty(first, '$$root', true);
1318
+ $prop(first, '$$root', true);
1281
1319
 
1282
1320
  if (length === 1) {
1283
1321
  return { first: first, last: first };
@@ -1332,13 +1370,13 @@
1332
1370
  // - super (window.Object)
1333
1371
  // - null
1334
1372
  //
1335
- $defineProperty(native_klass, '$$bridge', klass);
1373
+ $prop(native_klass, '$$bridge', klass);
1336
1374
  $set_proto(native_klass.prototype, (klass.$$super || Opal.Object).$$prototype);
1337
- $defineProperty(klass, '$$prototype', native_klass.prototype);
1375
+ $prop(klass, '$$prototype', native_klass.prototype);
1338
1376
 
1339
- $defineProperty(klass.$$prototype, '$$class', klass);
1340
- $defineProperty(klass, '$$constructor', native_klass);
1341
- $defineProperty(klass, '$$bridge', true);
1377
+ $prop(klass.$$prototype, '$$class', klass);
1378
+ $prop(klass, '$$constructor', native_klass);
1379
+ $prop(klass, '$$bridge', true);
1342
1380
  };
1343
1381
 
1344
1382
  function protoToModule(proto) {
@@ -1417,7 +1455,7 @@
1417
1455
  // Note: all ruby methods have a `$` prefix in javascript, so all stubs will
1418
1456
  // have this prefix as well (to make this method more performant).
1419
1457
  //
1420
- // Opal.add_stubs(["$foo", "$bar", "$baz="]);
1458
+ // Opal.add_stubs("foo,bar,baz=");
1421
1459
  //
1422
1460
  // All stub functions will have a private `$$stub` property set to true so
1423
1461
  // that other internal methods can detect if a method is just a stub or not.
@@ -1428,9 +1466,10 @@
1428
1466
  Opal.add_stubs = function(stubs) {
1429
1467
  var proto = Opal.BasicObject.$$prototype;
1430
1468
  var stub, existing_method;
1469
+ stubs = stubs.split(',');
1431
1470
 
1432
1471
  for (var i = 0, length = stubs.length; i < length; i++) {
1433
- stub = stubs[i], existing_method = proto[stub];
1472
+ stub = '$'+stubs[i], existing_method = proto[stub];
1434
1473
 
1435
1474
  if (existing_method == null || existing_method.$$stub) {
1436
1475
  Opal.add_stub_for(proto, stub);
@@ -1446,7 +1485,7 @@
1446
1485
  // @return [undefined]
1447
1486
  Opal.add_stub_for = function(prototype, stub) {
1448
1487
  // Opal.stub_for(stub) is the method_missing_stub
1449
- $defineProperty(prototype, stub, Opal.stub_for(stub));
1488
+ $prop(prototype, stub, Opal.stub_for(stub));
1450
1489
  };
1451
1490
 
1452
1491
  // Generate the method_missing stub for a given method name.
@@ -1460,7 +1499,7 @@
1460
1499
  this.$method_missing.$$p = method_missing_stub.$$p;
1461
1500
 
1462
1501
  // Set block property to null ready for the next call (stop false-positives)
1463
- method_missing_stub.$$p = null;
1502
+ delete method_missing_stub.$$p;
1464
1503
 
1465
1504
  // call method missing with correct args (remove '$' prefix on method name)
1466
1505
  var args_ary = new Array(arguments.length);
@@ -1495,7 +1534,7 @@
1495
1534
  }
1496
1535
  inspect += meth;
1497
1536
 
1498
- throw Opal.ArgumentError.$new('[' + inspect + '] wrong number of arguments(' + actual + ' for ' + expected + ')');
1537
+ throw Opal.ArgumentError.$new('[' + inspect + '] wrong number of arguments (given ' + actual + ', expected ' + expected + ')');
1499
1538
  };
1500
1539
 
1501
1540
  // Arity count error dispatcher for blocks
@@ -1507,7 +1546,7 @@
1507
1546
  Opal.block_ac = function(actual, expected, context) {
1508
1547
  var inspect = "`block in " + context + "'";
1509
1548
 
1510
- throw Opal.ArgumentError.$new(inspect + ': wrong number of arguments (' + actual + ' for ' + expected + ')');
1549
+ throw Opal.ArgumentError.$new(inspect + ': wrong number of arguments (given ' + actual + ', expected ' + expected + ')');
1511
1550
  };
1512
1551
 
1513
1552
  // Super dispatcher
@@ -1560,7 +1599,7 @@
1560
1599
  call_jsid = current_func.$$jsid;
1561
1600
  }
1562
1601
 
1563
- return Opal.find_super_dispatcher(obj, call_jsid, current_func, defcheck);
1602
+ return Opal.find_super(obj, call_jsid, current_func, defcheck);
1564
1603
  };
1565
1604
 
1566
1605
  // @deprecated
@@ -1763,7 +1802,7 @@
1763
1802
  Opal.extract_kwargs = function(parameters) {
1764
1803
  var kwargs = parameters[parameters.length - 1];
1765
1804
  if (kwargs != null && Opal.respond_to(kwargs, '$to_hash', true)) {
1766
- $splice.call(parameters, parameters.length - 1, 1);
1805
+ $splice.call(parameters, parameters.length - 1);
1767
1806
  return kwargs.$to_hash();
1768
1807
  }
1769
1808
  else {
@@ -1798,6 +1837,15 @@
1798
1837
  return Opal.hash2(keys, map);
1799
1838
  };
1800
1839
 
1840
+ function apply_blockopts(block, blockopts) {
1841
+ if (typeof(blockopts) === 'number') {
1842
+ block.$$arity = blockopts;
1843
+ }
1844
+ else if (typeof(blockopts) === 'object') {
1845
+ Object.assign(block, blockopts);
1846
+ }
1847
+ }
1848
+
1801
1849
  // Calls passed method on a ruby object with arguments and block:
1802
1850
  //
1803
1851
  // Can take a method or a method name.
@@ -1821,10 +1869,13 @@
1821
1869
  // @param method [Function, String] method body or name of the method
1822
1870
  // @param args [Array] arguments that will be passed to the method call
1823
1871
  // @param block [Function] ruby block
1872
+ // @param blockopts [Object, Number] optional properties to set on the block
1824
1873
  // @return [Object] returning value of the method call
1825
- Opal.send = function(recv, method, args, block) {
1874
+ Opal.send = function(recv, method, args, block, blockopts) {
1826
1875
  var body;
1827
1876
 
1877
+ apply_blockopts(block, blockopts);
1878
+
1828
1879
  if (typeof(method) === 'function') {
1829
1880
  body = method;
1830
1881
  method = null;
@@ -1837,17 +1888,19 @@
1837
1888
  return Opal.send2(recv, body, method, args, block);
1838
1889
  };
1839
1890
 
1840
- Opal.send2 = function(recv, body, method, args, block) {
1891
+ Opal.send2 = function(recv, body, method, args, block, blockopts) {
1841
1892
  if (body == null && method != null && recv.$method_missing) {
1842
1893
  body = recv.$method_missing;
1843
1894
  args = [method].concat(args);
1844
1895
  }
1845
1896
 
1897
+ apply_blockopts(block, blockopts);
1898
+
1846
1899
  if (typeof block === 'function') body.$$p = block;
1847
1900
  return body.apply(recv, args);
1848
1901
  };
1849
1902
 
1850
- Opal.refined_send = function(refinement_groups, recv, method, args, block) {
1903
+ Opal.refined_send = function(refinement_groups, recv, method, args, block, blockopts) {
1851
1904
  var i, j, k, ancestors, ancestor, refinements, refinement, refine_modules, refine_module, body;
1852
1905
 
1853
1906
  if (recv.hasOwnProperty('$$meta')) {
@@ -1856,6 +1909,8 @@
1856
1909
  ancestors = Opal.ancestors(recv.$$class);
1857
1910
  }
1858
1911
 
1912
+ apply_blockopts(block, blockopts);
1913
+
1859
1914
  // For all ancestors that there are, starting from the closest to the furthest...
1860
1915
  for (i = 0; i < ancestors.length; i++) {
1861
1916
  ancestor = Opal.id(ancestors[i]);
@@ -1885,8 +1940,11 @@
1885
1940
  return Opal.send(recv, method, args, block);
1886
1941
  };
1887
1942
 
1888
- Opal.lambda = function(block) {
1943
+ Opal.lambda = function(block, blockopts) {
1889
1944
  block.$$is_lambda = true;
1945
+
1946
+ apply_blockopts(block, blockopts);
1947
+
1890
1948
  return block;
1891
1949
  };
1892
1950
 
@@ -1924,20 +1982,23 @@
1924
1982
  // @param obj [Object, Class] the actual obj to define method for
1925
1983
  // @param jsid [String] the JavaScript friendly method name (e.g. '$foo')
1926
1984
  // @param body [JS.Function] the literal JavaScript function used as method
1985
+ // @param blockopts [Object, Number] optional properties to set on the body
1927
1986
  // @return [null]
1928
1987
  //
1929
- Opal.def = function(obj, jsid, body) {
1988
+ Opal.def = function(obj, jsid, body, blockopts) {
1989
+ apply_blockopts(body, blockopts);
1990
+
1930
1991
  // Special case for a method definition in the
1931
1992
  // top-level namespace
1932
1993
  if (obj === Opal.top) {
1933
- Opal.defn(Opal.Object, jsid, body)
1994
+ return Opal.defn(Opal.Object, jsid, body);
1934
1995
  }
1935
1996
  // if instance_eval is invoked on a module/class, it sets inst_eval_mod
1936
1997
  else if (!obj.$$eval && obj.$$is_a_module) {
1937
- Opal.defn(obj, jsid, body);
1998
+ return Opal.defn(obj, jsid, body);
1938
1999
  }
1939
2000
  else {
1940
- Opal.defs(obj, jsid, body);
2001
+ return Opal.defs(obj, jsid, body);
1941
2002
  }
1942
2003
  };
1943
2004
 
@@ -1946,11 +2007,13 @@
1946
2007
  body.displayName = jsid;
1947
2008
  body.$$owner = module;
1948
2009
 
2010
+ var name = jsid.substr(1);
2011
+
1949
2012
  var proto = module.$$prototype;
1950
2013
  if (proto.hasOwnProperty('$$dummy')) {
1951
2014
  proto = proto.$$define_methods_on;
1952
2015
  }
1953
- $defineProperty(proto, jsid, body);
2016
+ $prop(proto, jsid, body);
1954
2017
 
1955
2018
  if (module.$$is_module) {
1956
2019
  if (module.$$module_function) {
@@ -1959,25 +2022,29 @@
1959
2022
 
1960
2023
  for (var i = 0, iclasses = module.$$iclasses, length = iclasses.length; i < length; i++) {
1961
2024
  var iclass = iclasses[i];
1962
- $defineProperty(iclass, jsid, body);
2025
+ $prop(iclass, jsid, body);
1963
2026
  }
1964
2027
  }
1965
2028
 
1966
2029
  var singleton_of = module.$$singleton_of;
1967
2030
  if (module.$method_added && !module.$method_added.$$stub && !singleton_of) {
1968
- module.$method_added(jsid.substr(1));
2031
+ module.$method_added(name);
1969
2032
  }
1970
2033
  else if (singleton_of && singleton_of.$singleton_method_added && !singleton_of.$singleton_method_added.$$stub) {
1971
- singleton_of.$singleton_method_added(jsid.substr(1));
2034
+ singleton_of.$singleton_method_added(name);
1972
2035
  }
2036
+
2037
+ return name;
1973
2038
  };
1974
2039
 
1975
2040
  // Define a singleton method on the given object (see Opal.def).
1976
- Opal.defs = function(obj, jsid, body) {
2041
+ Opal.defs = function(obj, jsid, body, blockopts) {
2042
+ apply_blockopts(body, blockopts);
2043
+
1977
2044
  if (obj.$$is_string || obj.$$is_number) {
1978
2045
  throw Opal.TypeError.$new("can't define singleton");
1979
2046
  }
1980
- Opal.defn(Opal.get_singleton_class(obj), jsid, body)
2047
+ return Opal.defn(Opal.get_singleton_class(obj), jsid, body);
1981
2048
  };
1982
2049
 
1983
2050
  // Called from #remove_method.
@@ -2074,7 +2141,7 @@
2074
2141
  args[i] = arguments[i];
2075
2142
  }
2076
2143
 
2077
- if (block != null) { alias.$$p = null }
2144
+ delete alias.$$p;
2078
2145
 
2079
2146
  return Opal.send(this, body, args, block);
2080
2147
  };
@@ -2698,18 +2765,55 @@
2698
2765
  }
2699
2766
  }
2700
2767
 
2768
+ // Operator helpers
2769
+ // ----------------
2770
+ Opal.rb_plus = function(l,r) { return (typeof(l) === 'number' && typeof(r) === 'number') ? l + r : l['$+'](r); }
2771
+ Opal.rb_minus = function(l,r) { return (typeof(l) === 'number' && typeof(r) === 'number') ? l - r : l['$-'](r); }
2772
+ Opal.rb_times = function(l,r) { return (typeof(l) === 'number' && typeof(r) === 'number') ? l * r : l['$*'](r); }
2773
+ Opal.rb_divide = function(l,r) { return (typeof(l) === 'number' && typeof(r) === 'number') ? l / r : l['$/'](r); }
2774
+ Opal.rb_lt = function(l,r) { return (typeof(l) === 'number' && typeof(r) === 'number') ? l < r : l['$<'](r); }
2775
+ Opal.rb_gt = function(l,r) { return (typeof(l) === 'number' && typeof(r) === 'number') ? l > r : l['$>'](r); }
2776
+ Opal.rb_le = function(l,r) { return (typeof(l) === 'number' && typeof(r) === 'number') ? l <= r : l['$<='](r); }
2777
+ Opal.rb_ge = function(l,r) { return (typeof(l) === 'number' && typeof(r) === 'number') ? l >= r : l['$>='](r); }
2778
+
2779
+ // Optimized helpers for calls like $truthy((a)['$==='](b)) -> $eqeqeq(a, b)
2780
+ Opal.eqeq = function(lhs, rhs) {
2781
+ if ((typeof lhs === 'number' && typeof rhs === 'number') ||
2782
+ (typeof lhs === 'string' && typeof rhs === 'string')) {
2783
+ return lhs === rhs;
2784
+ }
2785
+ return $truthy((lhs)['$=='](rhs));
2786
+ };
2787
+ Opal.eqeqeq = function(lhs, rhs) {
2788
+ if ((typeof lhs === 'number' && typeof rhs === 'number') ||
2789
+ (typeof lhs === 'string' && typeof rhs === 'string')) {
2790
+ return lhs === rhs;
2791
+ }
2792
+ return $truthy((lhs)['$==='](rhs));
2793
+ };
2794
+ Opal.neqeq = function(lhs, rhs) {
2795
+ if ((typeof lhs === 'number' && typeof rhs === 'number') ||
2796
+ (typeof lhs === 'string' && typeof rhs === 'string')) {
2797
+ return lhs !== rhs;
2798
+ }
2799
+ return $truthy((lhs)['$!='](rhs));
2800
+ };
2801
+ Opal.not = function(arg) {
2802
+ if (true === arg) return false;
2803
+ if (undefined === arg || null === arg || false === arg || nil === arg) return true;
2804
+ return $truthy(arg['$!']());
2805
+ }
2806
+
2807
+
2701
2808
 
2702
2809
  // Initialization
2703
2810
  // --------------
2704
- function $BasicObject() {}
2705
- function $Object() {}
2706
- function $Module() {}
2707
- function $Class() {}
2708
-
2709
- Opal.BasicObject = BasicObject = Opal.allocate_class('BasicObject', null, $BasicObject);
2710
- Opal.Object = _Object = Opal.allocate_class('Object', Opal.BasicObject, $Object);
2711
- Opal.Module = Module = Opal.allocate_class('Module', Opal.Object, $Module);
2712
- Opal.Class = Class = Opal.allocate_class('Class', Opal.Module, $Class);
2811
+ Opal.BasicObject = BasicObject = Opal.allocate_class('BasicObject', null);
2812
+ Opal.Object = _Object = Opal.allocate_class('Object', Opal.BasicObject);
2813
+ Opal.Module = Module = Opal.allocate_class('Module', Opal.Object);
2814
+ Opal.Class = Class = Opal.allocate_class('Class', Opal.Module);
2815
+ Opal.Opal = _Opal = Opal.allocate_module('Opal');
2816
+ Opal.Kernel = Kernel = Opal.allocate_module('Kernel');
2713
2817
 
2714
2818
  $set_proto(Opal.BasicObject, Opal.Class.$$prototype);
2715
2819
  $set_proto(Opal.Object, Opal.Class.$$prototype);
@@ -2720,19 +2824,23 @@
2720
2824
  BasicObject.$$const["BasicObject"] = BasicObject;
2721
2825
 
2722
2826
  // Assign basic constants
2723
- Opal.const_set(_Object, "BasicObject", BasicObject);
2724
- Opal.const_set(_Object, "Object", _Object);
2725
- Opal.const_set(_Object, "Module", Module);
2726
- Opal.const_set(_Object, "Class", Class);
2827
+ $const_set(_Object, "BasicObject", BasicObject);
2828
+ $const_set(_Object, "Object", _Object);
2829
+ $const_set(_Object, "Module", Module);
2830
+ $const_set(_Object, "Class", Class);
2831
+ $const_set(_Object, "Opal", _Opal);
2832
+ $const_set(_Object, "Kernel", Kernel);
2727
2833
 
2728
2834
  // Fix booted classes to have correct .class value
2729
2835
  BasicObject.$$class = Class;
2730
2836
  _Object.$$class = Class;
2731
2837
  Module.$$class = Class;
2732
2838
  Class.$$class = Class;
2839
+ _Opal.$$class = Module;
2840
+ Kernel.$$class = Module;
2733
2841
 
2734
2842
  // Forward .toString() to #to_s
2735
- $defineProperty(_Object.$$prototype, 'toString', function() {
2843
+ $prop(_Object.$$prototype, 'toString', function() {
2736
2844
  var to_s = this.$to_s();
2737
2845
  if (to_s.$$is_string && typeof(to_s) === 'object') {
2738
2846
  // a string created using new String('string')
@@ -2744,7 +2852,7 @@
2744
2852
 
2745
2853
  // Make Kernel#require immediately available as it's needed to require all the
2746
2854
  // other corelib files.
2747
- $defineProperty(_Object.$$prototype, '$require', Opal.require);
2855
+ $prop(_Object.$$prototype, '$require', Opal.require);
2748
2856
 
2749
2857
  // Instantiate the main object
2750
2858
  Opal.top = new _Object();
@@ -2753,17 +2861,15 @@
2753
2861
 
2754
2862
  // Foward calls to define_method on the top object to Object
2755
2863
  function top_define_method() {
2756
- var args = Opal.slice.call(arguments, 0, arguments.length);
2864
+ var args = Opal.slice.call(arguments);
2757
2865
  var block = top_define_method.$$p;
2758
- top_define_method.$$p = null;
2866
+ delete top_define_method.$$p;
2759
2867
  return Opal.send(_Object, 'define_method', args, block)
2760
2868
  };
2761
2869
 
2762
-
2763
2870
  // Nil
2764
- function $NilClass() {}
2765
- Opal.NilClass = Opal.allocate_class('NilClass', Opal.Object, $NilClass);
2766
- Opal.const_set(_Object, 'NilClass', Opal.NilClass);
2871
+ Opal.NilClass = Opal.allocate_class('NilClass', Opal.Object);
2872
+ $const_set(_Object, 'NilClass', Opal.NilClass);
2767
2873
  nil = Opal.nil = new Opal.NilClass();
2768
2874
  nil.$$id = nil_id;
2769
2875
  nil.call = nil.apply = function() { throw Opal.LocalJumpError.$new('no block given'); };