opal 0.9.4 → 0.10.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (193) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +1 -0
  3. data/.gitignore +2 -3
  4. data/.gitmodules +5 -2
  5. data/.jshintrc +1 -8
  6. data/.rspec +1 -1
  7. data/.travis.yml +15 -23
  8. data/CHANGELOG.md +511 -326
  9. data/CODE_OF_CONDUCT.md +13 -15
  10. data/CONTRIBUTING.md +26 -216
  11. data/Gemfile +20 -12
  12. data/Guardfile +2 -2
  13. data/HACKING.md +230 -0
  14. data/README.md +6 -7
  15. data/bin/opal-mspec +1 -1
  16. data/config.ru +2 -2
  17. data/docs/faq.md +1 -1
  18. data/docs/source_maps.md +1 -1
  19. data/lib/opal.rb +1 -0
  20. data/lib/opal/builder.rb +1 -1
  21. data/lib/opal/cli.rb +30 -28
  22. data/lib/opal/cli_options.rb +3 -0
  23. data/lib/opal/cli_runners.rb +14 -1
  24. data/lib/opal/cli_runners/{apple_script.rb → applescript.rb} +3 -3
  25. data/lib/opal/cli_runners/nashorn.rb +2 -2
  26. data/lib/opal/cli_runners/nodejs.rb +2 -2
  27. data/lib/opal/cli_runners/phantom.js +24 -0
  28. data/lib/opal/cli_runners/phantomjs.rb +10 -10
  29. data/lib/opal/cli_runners/server.rb +3 -3
  30. data/lib/opal/compiler.rb +43 -4
  31. data/lib/opal/config.rb +3 -1
  32. data/lib/opal/errors.rb +13 -0
  33. data/lib/opal/fragment.rb +0 -13
  34. data/lib/opal/nodes.rb +10 -0
  35. data/lib/opal/nodes/args/initialize_kwargs.rb +28 -0
  36. data/lib/opal/nodes/args/kwarg.rb +29 -0
  37. data/lib/opal/nodes/args/kwoptarg.rb +29 -0
  38. data/lib/opal/nodes/args/kwrestarg.rb +39 -0
  39. data/lib/opal/nodes/args/mlhsarg.rb +79 -0
  40. data/lib/opal/nodes/args/normarg.rb +26 -0
  41. data/lib/opal/nodes/args/optarg.rb +27 -0
  42. data/lib/opal/nodes/args/post_args.rb +200 -0
  43. data/lib/opal/nodes/args/post_kwargs.rb +31 -0
  44. data/lib/opal/nodes/args/restarg.rb +33 -0
  45. data/lib/opal/nodes/base.rb +12 -0
  46. data/lib/opal/nodes/call.rb +92 -33
  47. data/lib/opal/nodes/def.rb +26 -169
  48. data/lib/opal/nodes/hash.rb +10 -4
  49. data/lib/opal/nodes/helpers.rb +6 -3
  50. data/lib/opal/nodes/inline_args.rb +61 -0
  51. data/lib/opal/nodes/iter.rb +73 -82
  52. data/lib/opal/nodes/logic.rb +12 -2
  53. data/lib/opal/nodes/masgn.rb +1 -2
  54. data/lib/opal/nodes/node_with_args.rb +141 -0
  55. data/lib/opal/nodes/rescue.rb +121 -43
  56. data/lib/opal/nodes/scope.rb +24 -5
  57. data/lib/opal/nodes/super.rb +122 -54
  58. data/lib/opal/nodes/top.rb +0 -12
  59. data/lib/opal/nodes/yield.rb +2 -13
  60. data/lib/opal/parser.rb +67 -39
  61. data/lib/opal/parser/grammar.rb +3319 -2961
  62. data/lib/opal/parser/grammar.y +234 -46
  63. data/lib/opal/parser/lexer.rb +105 -17
  64. data/lib/opal/parser/sexp.rb +4 -0
  65. data/lib/opal/paths.rb +4 -0
  66. data/lib/opal/regexp_anchors.rb +19 -1
  67. data/lib/opal/sprockets.rb +21 -18
  68. data/lib/opal/sprockets/environment.rb +0 -8
  69. data/lib/opal/sprockets/processor.rb +13 -16
  70. data/lib/opal/sprockets/server.rb +6 -12
  71. data/lib/opal/version.rb +1 -1
  72. data/opal.gemspec +1 -0
  73. data/opal/corelib/array.rb +209 -131
  74. data/opal/corelib/basic_object.rb +7 -3
  75. data/opal/corelib/class.rb +11 -17
  76. data/opal/corelib/constants.rb +2 -2
  77. data/opal/corelib/enumerable.rb +178 -355
  78. data/opal/corelib/enumerator.rb +3 -46
  79. data/opal/corelib/error.rb +2 -2
  80. data/opal/corelib/file.rb +13 -1
  81. data/opal/corelib/hash.rb +26 -56
  82. data/opal/corelib/helpers.rb +10 -0
  83. data/opal/corelib/kernel.rb +6 -3
  84. data/opal/corelib/module.rb +62 -31
  85. data/opal/corelib/number.rb +7 -16
  86. data/opal/corelib/proc.rb +24 -9
  87. data/opal/corelib/range.rb +4 -13
  88. data/opal/corelib/runtime.js +515 -378
  89. data/opal/corelib/string.rb +21 -49
  90. data/opal/corelib/struct.rb +50 -35
  91. data/opal/corelib/unsupported.rb +18 -30
  92. data/opal/opal.rb +0 -1
  93. data/opal/opal/mini.rb +1 -0
  94. data/spec/README.md +6 -4
  95. data/spec/filters/bugs/array.rb +0 -42
  96. data/spec/filters/bugs/basicobject.rb +0 -2
  97. data/spec/filters/bugs/bigdecimal.rb +160 -0
  98. data/spec/filters/bugs/class.rb +0 -5
  99. data/spec/filters/bugs/date.rb +1 -48
  100. data/spec/filters/bugs/enumerable.rb +4 -12
  101. data/spec/filters/bugs/enumerator.rb +0 -1
  102. data/spec/filters/bugs/exception.rb +4 -3
  103. data/spec/filters/bugs/float.rb +4 -2
  104. data/spec/filters/bugs/kernel.rb +25 -10
  105. data/spec/filters/bugs/language.rb +119 -68
  106. data/spec/filters/bugs/method.rb +135 -0
  107. data/spec/filters/bugs/module.rb +13 -28
  108. data/spec/filters/bugs/proc.rb +18 -8
  109. data/spec/filters/bugs/range.rb +0 -3
  110. data/spec/filters/bugs/rational.rb +4 -0
  111. data/spec/filters/bugs/regexp.rb +68 -36
  112. data/spec/filters/bugs/string.rb +1 -1
  113. data/spec/filters/bugs/struct.rb +0 -12
  114. data/spec/filters/bugs/time.rb +1 -0
  115. data/spec/filters/bugs/unboundmethod.rb +2 -1
  116. data/spec/filters/unsupported/freeze.rb +3 -1
  117. data/spec/filters/unsupported/language.rb +0 -7
  118. data/spec/filters/unsupported/privacy.rb +7 -6
  119. data/spec/filters/unsupported/string.rb +10 -0
  120. data/spec/filters/unsupported/struct.rb +3 -0
  121. data/spec/filters/unsupported/symbol.rb +9 -0
  122. data/spec/filters/unsupported/taint.rb +0 -3
  123. data/spec/filters/unsupported/thread.rb +1 -0
  124. data/spec/lib/cli_runners/phantomjs_spec.rb +39 -0
  125. data/spec/lib/cli_spec.rb +42 -1
  126. data/spec/lib/compiler/call_spec.rb +700 -0
  127. data/spec/lib/compiler_spec.rb +46 -28
  128. data/spec/lib/config_spec.rb +13 -0
  129. data/spec/lib/parser/call_spec.rb +18 -0
  130. data/spec/lib/parser/def_spec.rb +29 -0
  131. data/spec/lib/parser/iter_spec.rb +15 -15
  132. data/spec/lib/parser/lambda_spec.rb +153 -12
  133. data/spec/lib/parser/string_spec.rb +5 -0
  134. data/spec/lib/parser/undef_spec.rb +1 -1
  135. data/spec/lib/parser/variables_spec.rb +24 -0
  136. data/spec/lib/paths_spec.rb +12 -5
  137. data/spec/lib/spec_helper.rb +5 -0
  138. data/spec/lib/sprockets/processor_spec.rb +6 -5
  139. data/spec/lib/sprockets_spec.rb +8 -0
  140. data/spec/mspec-opal/formatters.rb +188 -0
  141. data/spec/mspec-opal/runner.rb +193 -0
  142. data/spec/opal/core/enumerator/with_index_spec.rb +6 -0
  143. data/spec/opal/core/kernel/define_singleton_method_spec.rb +1 -1
  144. data/spec/opal/core/kernel/instance_variables_spec.rb +14 -0
  145. data/spec/opal/core/kernel/loop_spec.rb +1 -1
  146. data/spec/opal/core/kernel/raise_spec.rb +1 -1
  147. data/spec/opal/core/language/heredoc_spec.rb +42 -0
  148. data/spec/opal/core/language/rescue_spec.rb +18 -0
  149. data/spec/opal/core/language_spec.rb +22 -0
  150. data/spec/opal/core/module/const_defined_spec.rb +1 -2
  151. data/spec/opal/core/module/name_spec.rb +6 -0
  152. data/spec/opal/core/runtime/bridged_classes_spec.rb +14 -2
  153. data/spec/opal/core/runtime/rescue_spec.rb +12 -2
  154. data/spec/opal/core/runtime/super_spec.rb +1 -0
  155. data/spec/opal/core/string_spec.rb +21 -0
  156. data/spec/opal/stdlib/js_spec.rb +1 -1
  157. data/spec/opal/stdlib/native/hash_spec.rb +7 -0
  158. data/spec/opal/stdlib/promise/always_spec.rb +24 -5
  159. data/spec/opal/stdlib/promise/rescue_spec.rb +15 -6
  160. data/spec/opal/stdlib/promise/then_spec.rb +13 -5
  161. data/spec/opal/stdlib/promise/trace_spec.rb +5 -6
  162. data/spec/opal/stdlib/strscan/scan_spec.rb +1 -1
  163. data/spec/ruby_specs +122 -0
  164. data/spec/spec_helper.rb +3 -15
  165. data/stdlib/base64.rb +51 -121
  166. data/stdlib/bigdecimal.rb +231 -0
  167. data/stdlib/bigdecimal/bignumber.js.rb +11 -0
  168. data/stdlib/bigdecimal/kernel.rb +5 -0
  169. data/stdlib/date.rb +252 -10
  170. data/stdlib/native.rb +38 -38
  171. data/stdlib/nodejs/dir.rb +8 -6
  172. data/stdlib/nodejs/file.rb +28 -3
  173. data/stdlib/nodejs/node_modules/.bin/js-yaml +1 -0
  174. data/stdlib/nodejs/node_modules/js-yaml/node_modules/.bin/esparse +1 -0
  175. data/stdlib/nodejs/node_modules/js-yaml/node_modules/.bin/esvalidate +1 -0
  176. data/stdlib/nodejs/require.rb +1 -1
  177. data/stdlib/nodejs/yaml.rb +3 -2
  178. data/stdlib/opal-parser.rb +7 -2
  179. data/stdlib/pathname.rb +23 -1
  180. data/stdlib/phantomjs.rb +10 -0
  181. data/stdlib/promise.rb +38 -23
  182. data/tasks/building.rake +3 -3
  183. data/tasks/testing.rake +27 -14
  184. data/tasks/testing/mspec_special_calls.rb +1 -1
  185. data/tasks/testing/sprockets-phantomjs.js +4 -0
  186. data/test/opal/test_keyword.rb +110 -110
  187. data/test/opal/unsupported_and_bugs.rb +30 -0
  188. data/vendored-minitest/minitest/assertions.rb +1 -1
  189. metadata +65 -15
  190. data/.spectator +0 -2
  191. data/.spectator-mspec +0 -3
  192. data/opal/corelib/array/inheritance.rb +0 -127
  193. data/spec/rubyspecs +0 -139
@@ -209,16 +209,13 @@ class Number < Numeric
209
209
  bit = Opal.coerce_to! bit, Integer, :to_int
210
210
 
211
211
  %x{
212
- if (#{bit} < #{Integer::MIN} || #{bit} > #{Integer::MAX}) {
212
+ if (#{bit} < 0) {
213
213
  return 0;
214
214
  }
215
-
216
- if (self < 0) {
217
- return (((~self) + 1) >> #{bit}) % 2;
218
- }
219
- else {
220
- return (self >> #{bit}) % 2;
215
+ if (#{bit} >= 32) {
216
+ return #{ self } < 0 ? 1 : 0;
221
217
  }
218
+ return (self >> #{bit}) & 1;
222
219
  }
223
220
  end
224
221
 
@@ -345,9 +342,7 @@ class Number < Numeric
345
342
  #{raise ArgumentError, "comparison of #{self.class} with #{stop.class} failed"}
346
343
  }
347
344
  for (var i = self; i >= stop; i--) {
348
- if (block(i) === $breaker) {
349
- return $breaker.$v;
350
- }
345
+ block(i);
351
346
  }
352
347
  }
353
348
 
@@ -595,9 +590,7 @@ class Number < Numeric
595
590
 
596
591
  %x{
597
592
  for (var i = 0; i < self; i++) {
598
- if (block(i) === $breaker) {
599
- return $breaker.$v;
600
- }
593
+ block(i);
601
594
  }
602
595
  }
603
596
 
@@ -659,9 +652,7 @@ class Number < Numeric
659
652
  #{raise ArgumentError, "comparison of #{self.class} with #{stop.class} failed"}
660
653
  }
661
654
  for (var i = self; i <= stop; i++) {
662
- if (block(i) === $breaker) {
663
- return $breaker.$v;
664
- }
655
+ block(i);
665
656
  }
666
657
  }
667
658
 
data/opal/corelib/proc.rb CHANGED
@@ -16,17 +16,32 @@ class Proc < `Function`
16
16
  self.$$p = block;
17
17
  }
18
18
 
19
- var result;
20
-
21
- if (self.$$is_lambda) {
22
- result = self.apply(null, args);
19
+ var result, $brk = self.$$brk;
20
+
21
+ if ($brk) {
22
+ try {
23
+ if (self.$$is_lambda) {
24
+ result = self.apply(null, args);
25
+ }
26
+ else {
27
+ result = Opal.yieldX(self, args);
28
+ }
29
+ } catch (err) {
30
+ if (err === $brk) {
31
+ return $brk.$v
32
+ }
33
+ else {
34
+ throw err
35
+ }
36
+ }
23
37
  }
24
38
  else {
25
- result = Opal.yieldX(self, args);
26
- }
27
-
28
- if (result === $breaker) {
29
- return $breaker.$v;
39
+ if (self.$$is_lambda) {
40
+ result = self.apply(null, args);
41
+ }
42
+ else {
43
+ result = Opal.yieldX(self, args);
44
+ }
30
45
  }
31
46
 
32
47
  return result;
@@ -39,7 +39,7 @@ class Range
39
39
  return enum_for :each unless block_given?
40
40
 
41
41
  %x{
42
- var i, limit, value;
42
+ var i, limit;
43
43
 
44
44
  if (#@begin.$$is_number && #@end.$$is_number) {
45
45
  if (#@begin % 1 !== 0 || #@end % 1 !== 0) {
@@ -47,24 +47,15 @@ class Range
47
47
  }
48
48
 
49
49
  for (i = #@begin, limit = #@end + #{@exclude ? 0 : 1}; i < limit; i++) {
50
- value = block(i);
51
- if (value === $breaker) { return $breaker.$v; }
50
+ block(i);
52
51
  }
53
52
 
54
53
  return self;
55
54
  }
56
55
 
57
56
  if (#@begin.$$is_string && #@end.$$is_string) {
58
- value = #{@begin.upto(@end, @exclude, &block)};
59
-
60
- // The following is a bit hackish: we know that
61
- // String#upto normally returns self, but may
62
- // return a different value if there's a `break`
63
- // statement in the supplied block. We need to
64
- // propagate this `break` value here, so we
65
- // test for equality with `@begin` string to
66
- // determine the return value:
67
- return value === #@begin ? self : value;
57
+ #{@begin.upto(@end, @exclude, &block)}
58
+ return self;
68
59
  }
69
60
  }
70
61
 
@@ -1,4 +1,18 @@
1
1
  (function(undefined) {
2
+ // @note
3
+ // A few conventions for the documentation of this file:
4
+ // 1. Always use "//" (in contrast with "/**/")
5
+ // 2. The syntax used is Yardoc (yardoc.org), which is intended for Ruby (se below)
6
+ // 3. `@param` and `@return` types should be preceded by `JS.` when referring to
7
+ // JavaScript constructors (e.g. `JS.Function`) otherwise Ruby is assumed.
8
+ // 4. `nil` and `null` being unambiguous refer to the respective
9
+ // objects/values in Ruby and JavaScript
10
+ // 5. This is still WIP :) so please give feedback and suggestions on how
11
+ // to improve or for alternative solutions
12
+ //
13
+ // The way the code is digested before going through Yardoc is a secret kept
14
+ // in the docs repo (https://github.com/opal/docs/tree/master).
15
+
2
16
  if (typeof(this.Opal) !== 'undefined') {
3
17
  console.warn('Opal already loaded. Loading twice can cause troubles, please fix your setup.');
4
18
  return this.Opal;
@@ -55,6 +69,12 @@
55
69
  // This is a useful reference to global object inside ruby files
56
70
  Opal.global = this;
57
71
 
72
+ // Configure runtime behavior with regards to require and unsupported fearures
73
+ Opal.config = {
74
+ missing_require_severity: 'error', // error, warning, ignore
75
+ unsupported_features_severity: 'warning' // error, warning, ignore
76
+ }
77
+
58
78
  // Minify common function calls
59
79
  var $hasOwn = Opal.hasOwnProperty;
60
80
  var $slice = Opal.slice = Array.prototype.slice;
@@ -85,6 +105,16 @@
85
105
  // keeps track of exceptions for $!
86
106
  Opal.exceptions = [];
87
107
 
108
+ // @private
109
+ // Pops an exception from the stack and updates `$!`.
110
+ Opal.pop_exception = function() {
111
+ Opal.gvars["!"] = Opal.exceptions.pop() || nil;
112
+ }
113
+
114
+
115
+ // Constants
116
+ // ---------
117
+
88
118
  // Get a constant on the given scope. Every class and module in Opal has a
89
119
  // scope used to store, and inherit, constants. For example, the top level
90
120
  // `Object` in ruby has a scope accessible as `Opal.Object.$$scope`.
@@ -97,8 +127,8 @@
97
127
  // class/module's `#const_method` is called, which by default will raise an
98
128
  // error.
99
129
  //
100
- // @param [String] name the name of the constant to lookup
101
- // @return [RubyObject]
130
+ // @param name [String] the name of the constant to lookup
131
+ // @return [Object]
102
132
  //
103
133
  Opal.get = function(name) {
104
134
  var constant = this[name];
@@ -133,7 +163,88 @@
133
163
  Opal.cdecl(base_scope, id, klass);
134
164
  const_alloc.displayName = id+"_scope_alloc";
135
165
  }
136
- }
166
+ };
167
+
168
+ // Constant assignment, see also `Opal.cdecl`
169
+ //
170
+ // @param base_module [Module, Class] the constant namespace
171
+ // @param name [String] the name of the constant
172
+ // @param value [Object] the value of the constant
173
+ //
174
+ // @example Assigning a namespaced constant
175
+ // self::FOO = 'bar'
176
+ //
177
+ // @example Assigning with Module#const_set
178
+ // Foo.const_set :BAR, 123
179
+ //
180
+ Opal.casgn = function(base_module, name, value) {
181
+ function update(klass, name) {
182
+ klass.$$name = name;
183
+
184
+ for (name in klass.$$scope) {
185
+ var value = klass.$$scope[name];
186
+
187
+ if (value.$$name === nil && (value.$$is_class || value.$$is_module)) {
188
+ update(value, name)
189
+ }
190
+ }
191
+ }
192
+
193
+ var scope = base_module.$$scope;
194
+
195
+ if (value.$$is_class || value.$$is_module) {
196
+ // Only checking _Object prevents setting a const on an anonymous class
197
+ // that has a superclass that's not Object
198
+ if (value.$$is_class || value.$$base_module === _Object) {
199
+ value.$$base_module = base_module;
200
+ }
201
+
202
+ if (value.$$name === nil && value.$$base_module.$$name !== nil) {
203
+ update(value, name);
204
+ }
205
+ }
206
+
207
+ scope.constants.push(name);
208
+ scope[name] = value;
209
+
210
+ // If we dynamically declare a constant in a module,
211
+ // we should populate all the classes that include this module
212
+ // with the same constant
213
+ if (base_module.$$is_module && base_module.$$dep) {
214
+ for (var i = 0; i < base_module.$$dep.length; i++) {
215
+ var dep = base_module.$$dep[i];
216
+ Opal.casgn(dep, name, value);
217
+ }
218
+ }
219
+
220
+ return value;
221
+ };
222
+
223
+ // Constant declaration
224
+ //
225
+ // @example
226
+ // FOO = :bar
227
+ //
228
+ // @param base_scope [$$scope] the current scope
229
+ // @param name [String] the name of the constant
230
+ // @param value [Object] the value of the constant
231
+ Opal.cdecl = function(base_scope, name, value) {
232
+ if ((value.$$is_class || value.$$is_module) && value.$$orig_scope == null) {
233
+ value.$$name = name;
234
+ value.$$orig_scope = base_scope;
235
+ // Here we should explicitly set a base module
236
+ // (a module where the constant was initially defined)
237
+ value.$$base_module = base_scope.base;
238
+ base_scope.constructor[name] = value;
239
+ }
240
+
241
+ base_scope.constants.push(name);
242
+ return base_scope[name] = value;
243
+ };
244
+
245
+
246
+ // Modules & Classes
247
+ // -----------------
137
248
 
138
249
  // A `class Foo; end` expression in ruby is compiled to call this runtime
139
250
  // method which either returns an existing class of the given name, or creates
@@ -141,8 +252,8 @@
141
252
  //
142
253
  // If a constant with the given name exists, then we check to make sure that
143
254
  // it is a class and also that the superclasses match. If either of these
144
- // fail, then we raise a `TypeError`. Note, superklass may be null if one was
145
- // not specified in the ruby code.
255
+ // fail, then we raise a `TypeError`. Note, `superclass` may be null if one
256
+ // was not specified in the ruby code.
146
257
  //
147
258
  // We pass a constructor to this method of the form `function ClassName() {}`
148
259
  // simply so that classes show up with nicely formatted names inside debuggers
@@ -154,13 +265,13 @@
154
265
  // use that as the base instead.
155
266
  //
156
267
  // @param base [Object] where the class is being created
157
- // @param superklass [Class,null] superclass of the new class (may be null)
268
+ // @param superclass [Class,null] superclass of the new class (may be null)
158
269
  // @param id [String] the name of the class to be created
159
- // @param constructor [Function] function to use as constructor
270
+ // @param constructor [JS.Function] function to use as constructor
160
271
  //
161
272
  // @return new [Class] or existing ruby class
162
273
  //
163
- Opal.klass = function(base, superklass, id, constructor) {
274
+ Opal.klass = function(base, superclass, name, constructor) {
164
275
  var klass, bridged, alloc;
165
276
 
166
277
  // If base is an object, use its class
@@ -169,24 +280,24 @@
169
280
  }
170
281
 
171
282
  // If the superclass is a function then we're bridging a native JS class
172
- if (typeof(superklass) === 'function') {
173
- bridged = superklass;
174
- superklass = _Object;
283
+ if (typeof(superclass) === 'function') {
284
+ bridged = superclass;
285
+ superclass = _Object;
175
286
  }
176
287
 
177
288
  // Try to find the class in the current scope
178
- klass = base.$$scope[id];
289
+ klass = base.$$scope[name];
179
290
 
180
291
  // If the class exists in the scope, then we must use that
181
292
  if (klass && klass.$$orig_scope === base.$$scope) {
182
293
  // Make sure the existing constant is a class, or raise error
183
294
  if (!klass.$$is_class) {
184
- throw Opal.TypeError.$new(id + " is not a class");
295
+ throw Opal.TypeError.$new(name + " is not a class");
185
296
  }
186
297
 
187
298
  // Make sure existing class has same superclass
188
- if (superklass && klass.$$super !== superklass) {
189
- throw Opal.TypeError.$new("superclass mismatch for class " + id);
299
+ if (superclass && klass.$$super !== superclass) {
300
+ throw Opal.TypeError.$new("superclass mismatch for class " + name);
190
301
  }
191
302
 
192
303
  return klass;
@@ -195,141 +306,134 @@
195
306
  // Class doesnt exist, create a new one with given superclass...
196
307
 
197
308
  // Not specifying a superclass means we can assume it to be Object
198
- if (superklass == null) {
199
- superklass = _Object;
309
+ if (superclass == null) {
310
+ superclass = _Object;
200
311
  }
201
312
 
202
313
  // If bridged the JS class will also be the alloc function
203
- alloc = bridged || boot_class_alloc(id, constructor, superklass);
314
+ alloc = bridged || Opal.boot_class_alloc(name, constructor, superclass);
204
315
 
205
316
  // Create the class object (instance of Class)
206
- klass = boot_class_object(id, superklass, alloc);
317
+ klass = Opal.setup_class_object(name, alloc, superclass.$$name, superclass.constructor);
207
318
 
208
- // Name the class
209
- klass.$$name = id;
210
- klass.displayName = id;
319
+ // @property $$super the superclass, doesn't get changed by module inclusions
320
+ klass.$$super = superclass;
211
321
 
212
- // Mark the object as a class
213
- klass.$$is_class = true;
322
+ // @property $$parent direct parent class
323
+ // starts with the superclass, after klass inclusion is
324
+ // the last included klass
325
+ klass.$$parent = superclass;
214
326
 
215
327
  // Every class gets its own constant scope, inherited from current scope
216
- Opal.create_scope(base.$$scope, klass, id);
217
-
218
- // Name new class directly onto current scope (Opal.Foo.Baz = klass)
219
- base[id] = base.$$scope[id] = klass;
328
+ Opal.create_scope(base.$$scope, klass, name);
220
329
 
221
330
  if (bridged) {
222
331
  Opal.bridge(klass, alloc);
223
332
  }
224
333
  else {
225
334
  // Copy all parent constants to child, unless parent is Object
226
- if (superklass !== _Object && superklass !== BasicObject) {
227
- donate_constants(superklass, klass);
335
+ if (superclass !== _Object && superclass !== BasicObject) {
336
+ Opal.donate_constants(superclass, klass);
228
337
  }
229
338
 
230
339
  // Call .inherited() hook with new class on the superclass
231
- if (superklass.$inherited) {
232
- superklass.$inherited(klass);
340
+ if (superclass.$inherited) {
341
+ superclass.$inherited(klass);
233
342
  }
234
343
  }
235
344
 
236
345
  return klass;
237
346
  };
238
347
 
239
- // Create generic class with given superclass.
240
- Opal.boot_class = function(superklass, constructor) {
241
- var alloc = boot_class_alloc(null, constructor, superklass)
348
+ // Boot a base class (makes instances).
349
+ //
350
+ // @param name [String,null] the class name
351
+ // @param constructor [JS.Function] the class' instances constructor/alloc function
352
+ // @param superclass [Class,null] the superclass object
353
+ // @return [JS.Function] the consturctor holding the prototype for the class' instances
354
+ Opal.boot_class_alloc = function(name, constructor, superclass) {
355
+ if (superclass) {
356
+ var alloc_proxy = function() {};
357
+ alloc_proxy.prototype = superclass.$$proto || superclass.prototype;
358
+ constructor.prototype = new alloc_proxy();
359
+ }
360
+
361
+ if (name) {
362
+ constructor.displayName = name+'_alloc';
363
+ }
242
364
 
243
- return boot_class_object(null, superklass, alloc);
244
- }
365
+ constructor.prototype.constructor = constructor;
245
366
 
246
- // The class object itself (as in `Class.new`)
367
+ return constructor;
368
+ };
369
+
370
+ // Adds common/required properties to class object (as in `Class.new`)
371
+ //
372
+ // @param name [String,null] The name of the class
373
+ //
374
+ // @param alloc [JS.Function] The constructor of the class' instances
375
+ //
376
+ // @param superclass_name [String,null]
377
+ // The name of the super class, this is
378
+ // usefule to build the `.displayName` of the singleton class
247
379
  //
248
- // @param superklass [(Opal) Class] Another class object (as in `Class.new`)
249
- // @param alloc [constructor] The constructor that holds the prototype
250
- // that will be used for instances of the
251
- // newly constructed class.
252
- function boot_class_object(id, superklass, alloc) {
380
+ // @param superclass_alloc [JS.Function]
381
+ // The constructor of the superclass from which the singleton_class is
382
+ // derived.
383
+ //
384
+ // @return [Class]
385
+ Opal.setup_class_object = function(name, alloc, superclass_name, superclass_alloc) {
253
386
  // Grab the superclass prototype and use it to build an intermediary object
254
387
  // in the prototype chain.
255
- function Superclass_alloc_proxy() {};
256
- Superclass_alloc_proxy.prototype = superklass.constructor.prototype;
257
- function SingletonClass_alloc() {}
258
- SingletonClass_alloc.prototype = new Superclass_alloc_proxy();
388
+ var superclass_alloc_proxy = function() {};
389
+ superclass_alloc_proxy.prototype = superclass_alloc.prototype;
390
+ superclass_alloc_proxy.displayName = superclass_name;
259
391
 
260
- if (id) {
261
- SingletonClass_alloc.displayName = "SingletonClass_alloc("+id+")";
262
- }
392
+ var singleton_class_alloc = function() {}
393
+ singleton_class_alloc.prototype = new superclass_alloc_proxy();
263
394
 
264
395
  // The built class is the only instance of its singleton_class
265
- var klass = new SingletonClass_alloc();
266
-
267
- setup_module_or_class_object(klass, SingletonClass_alloc, superklass, alloc.prototype);
396
+ var klass = new singleton_class_alloc();
268
397
 
269
398
  // @property $$alloc This is the constructor of instances of the current
270
399
  // class. Its prototype will be used for method lookup
271
400
  klass.$$alloc = alloc;
272
401
 
273
- // @property $$proto.$$class Make available to instances a reference to the
274
- // class they belong to.
275
- klass.$$proto.$$class = klass;
402
+ klass.$$name = name || nil;
276
403
 
277
- return klass;
278
- }
279
-
280
- // Adds common/required properties to a module or class object
281
- // (as in `Module.new` / `Class.new`)
282
- //
283
- // @param module The module or class that needs to be prepared
284
- //
285
- // @param constructor The constructor of the module or class itself,
286
- // usually it's already assigned by using `new`. Some
287
- // ipothesis on why it's needed can be found below.
288
- //
289
- // @param superklass The superclass of the class/module object, for modules
290
- // is `Module` (of `Module` in JS context)
291
- //
292
- // @param prototype The prototype on which the class/module methods will
293
- // be stored.
294
- //
295
- function setup_module_or_class_object(module, constructor, superklass, prototype) {
296
404
  // @property $$id Each class is assigned a unique `id` that helps
297
405
  // comparation and implementation of `#object_id`
298
- module.$$id = Opal.uid();
406
+ klass.$$id = Opal.uid();
407
+
408
+ // Set a displayName for the singleton_class
409
+ singleton_class_alloc.displayName = "#<Class:"+(name || ("#<Class:"+klass.$$id+">"))+">";
299
410
 
300
411
  // @property $$proto This is the prototype on which methods will be defined
301
- module.$$proto = prototype;
412
+ klass.$$proto = alloc.prototype;
413
+
414
+ // @property $$proto.$$class Make available to instances a reference to the
415
+ // class they belong to.
416
+ klass.$$proto.$$class = klass;
302
417
 
303
418
  // @property constructor keeps a ref to the constructor, but apparently the
304
419
  // constructor is already set on:
305
420
  //
306
- // `var module = new constructor` is called.
421
+ // `var klass = new constructor` is called.
307
422
  //
308
423
  // Maybe there are some browsers not abiding (IE6?)
309
- module.constructor = constructor;
310
-
311
- if (superklass === Module) {
312
- // @property $$is_module Clearly mark this as a module
313
- module.$$is_module = true;
314
- module.$$class = Module;
315
- }
316
- else {
317
- // @property $$is_class Clearly mark this as a class
318
- module.$$is_class = true;
319
- module.$$class = Class;
320
- }
424
+ klass.constructor = singleton_class_alloc;
321
425
 
322
- // @property $$super the superclass, doesn't get changed by module inclusions
323
- module.$$super = superklass;
426
+ // @property $$is_class Clearly mark this as a class
427
+ klass.$$is_class = true;
324
428
 
325
- // @property $$parent direct parent class or module
326
- // starts with the superclass, after module inclusion is
327
- // the last included module
328
- module.$$parent = superklass;
429
+ // @property $$class Classes are instances of the class Class
430
+ klass.$$class = Class;
329
431
 
330
432
  // @property $$inc included modules
331
- module.$$inc = [];
332
- }
433
+ klass.$$inc = [];
434
+
435
+ return klass;
436
+ };
333
437
 
334
438
  // Define new module (or return existing module). The given `base` is basically
335
439
  // the current `self` value the `module` statement was defined in. If this is
@@ -347,48 +451,49 @@
347
451
  // new instance is returned back (to be referenced at runtime).
348
452
  //
349
453
  // @param base [Module, Class] class or module this definition is inside
350
- // @param id [String] the name of the new (or existing) module
351
- // @return [Module]
454
+ // @param id [String] the name of the new (or existing) module
352
455
  //
353
- Opal.module = function(base, id) {
456
+ // @return [Module]
457
+ Opal.module = function(base, name) {
354
458
  var module;
355
459
 
356
460
  if (!base.$$is_class && !base.$$is_module) {
357
461
  base = base.$$class;
358
462
  }
359
463
 
360
- if ($hasOwn.call(base.$$scope, id)) {
361
- module = base.$$scope[id];
464
+ if ($hasOwn.call(base.$$scope, name)) {
465
+ module = base.$$scope[name];
362
466
 
363
467
  if (!module.$$is_module && module !== _Object) {
364
- throw Opal.TypeError.$new(id + " is not a module");
468
+ throw Opal.TypeError.$new(name + " is not a module");
365
469
  }
366
470
  }
367
471
  else {
368
- module = boot_module_object();
369
-
370
- // name module using base (e.g. Foo or Foo::Baz)
371
- module.$$name = id;
372
-
373
- // mark the object as a module
374
- module.$$is_module = true;
375
-
376
- // initialize dependency tracking
377
- module.$$dep = [];
378
-
379
- Opal.create_scope(base.$$scope, module, id);
380
-
381
- // Name new module directly onto current scope (Opal.Foo.Baz = module)
382
- base[id] = base.$$scope[id] = module;
472
+ module = Opal.module_allocate();
473
+ Opal.create_scope(base.$$scope, module, name);
383
474
  }
384
475
 
385
476
  return module;
386
477
  };
387
478
 
479
+ // The implementation for Module#initialize
480
+ // @param module [Module]
481
+ // @param block [Proc,nil]
482
+ // @return nil
483
+ Opal.module_initialize = function(module, block) {
484
+ if (block !== nil) {
485
+ var block_self = block.$$s;
486
+ block.$$s = null;
487
+ block.call(module);
488
+ block.$$s = block_self;
489
+ }
490
+ return nil;
491
+ };
492
+
388
493
  // Internal function to create a new module instance. This simply sets up
389
494
  // the prototype hierarchy and method tables.
390
495
  //
391
- function boot_module_object() {
496
+ Opal.module_allocate = function() {
392
497
  var mtor = function() {};
393
498
  mtor.prototype = Module_alloc.prototype;
394
499
 
@@ -397,14 +502,55 @@
397
502
 
398
503
  var module = new module_constructor();
399
504
  var module_prototype = {};
505
+ var superclass = Module;
506
+
507
+ // @property $$id Each class is assigned a unique `id` that helps
508
+ // comparation and implementation of `#object_id`
509
+ module.$$id = Opal.uid();
400
510
 
401
- setup_module_or_class_object(module, module_constructor, Module, module_prototype);
511
+ // Set the display name of the singleton prototype holder
512
+ module_constructor.displayName = "#<Class:#<Module:"+module.$$id+">>"
402
513
 
403
- return module;
404
- }
514
+ // @property $$proto This is the prototype on which methods will be defined
515
+ module.$$proto = module_prototype;
516
+
517
+ // @property constructor
518
+ // keeps a ref to the constructor, but apparently the
519
+ // constructor is already set on:
520
+ //
521
+ // `var module = new constructor` is called.
522
+ //
523
+ // Maybe there are some browsers not abiding (IE6?)
524
+ module.constructor = module_constructor;
525
+
526
+ // @property $$is_module Clearly mark this as a module
527
+ module.$$is_module = true;
528
+ module.$$class = Module;
529
+
530
+ // @property $$super
531
+ // the superclass, doesn't get changed by module inclusions
532
+ module.$$super = superclass;
405
533
 
406
- // Make `boot_module_object` available to the JS-API
407
- Opal.boot_module_object = boot_module_object;
534
+ // @property $$parent
535
+ // direct parent class or module
536
+ // starts with the superclass, after module inclusion is
537
+ // the last included module
538
+ module.$$parent = superclass;
539
+
540
+ // @property $$inc included modules
541
+ module.$$inc = [];
542
+
543
+ // mark the object as a module
544
+ module.$$is_module = true;
545
+
546
+ // initialize dependency tracking
547
+ module.$$dep = [];
548
+
549
+ // initialize the name with nil
550
+ module.$$name = nil;
551
+
552
+ return module;
553
+ };
408
554
 
409
555
  // Return the singleton class for the passed object.
410
556
  //
@@ -415,68 +561,83 @@
415
561
  // Otherwise, a new singleton object for the class or object is created, set on
416
562
  // the object at `$$meta` for future use, and then returned.
417
563
  //
418
- // @param [RubyObject] object the ruby object
419
- // @return [RubyClass] the singleton class for object
420
- //
564
+ // @param object [Object] the ruby object
565
+ // @return [Class] the singleton class for object
421
566
  Opal.get_singleton_class = function(object) {
422
567
  if (object.$$meta) {
423
568
  return object.$$meta;
424
569
  }
425
570
 
426
571
  if (object.$$is_class || object.$$is_module) {
427
- return build_class_singleton_class(object);
572
+ return Opal.build_class_singleton_class(object);
428
573
  }
429
574
 
430
- return build_object_singleton_class(object);
575
+ return Opal.build_object_singleton_class(object);
431
576
  };
432
577
 
433
- // Build the singleton class for an existing class.
578
+ // Build the singleton class for an existing class. Class object are built
579
+ // with their singleton class already in the prototype chain and inheriting
580
+ // from their superclass object (up to `Class` itself).
434
581
  //
435
582
  // NOTE: Actually in MRI a class' singleton class inherits from its
436
583
  // superclass' singleton class which in turn inherits from Class.
437
584
  //
438
- // @param [RubyClass] klass
439
- // @return [RubyClass]
440
- //
441
- function build_class_singleton_class(klass) {
442
- var meta = new Opal.Class.$$alloc();
585
+ // @param klass [Class]
586
+ // @return [Class]
587
+ Opal.build_class_singleton_class = function(object) {
588
+ var alloc, superclass, klass;
443
589
 
444
- meta.$$class = Opal.Class;
445
- meta.$$proto = klass.constructor.prototype;
590
+ if (object.$$meta) {
591
+ return object.$$meta;
592
+ }
446
593
 
447
- meta.$$is_singleton = true;
448
- meta.$$singleton_of = klass;
449
- meta.$$inc = [];
450
- meta.$$scope = klass.$$scope;
594
+ // The constructor and prototype of the singleton_class instances is the
595
+ // current class constructor and prototype.
596
+ alloc = object.constructor;
451
597
 
452
- return klass.$$meta = meta;
453
- }
598
+ // The singleton_class superclass is the singleton_class of its superclass;
599
+ // but BasicObject has no superclass (its `$$super` is null), thus we
600
+ // fallback on `Class`.
601
+ superclass = object === BasicObject ? Class : Opal.build_class_singleton_class(object.$$super);
602
+
603
+ klass = Opal.setup_class_object(null, alloc, superclass.$$name, superclass.constructor);
604
+ klass.$$super = superclass;
605
+ klass.$$parent = superclass;
606
+
607
+ // The singleton_class retains the same scope as the original class
608
+ Opal.create_scope(object.$$scope, klass);
609
+
610
+ klass.$$is_singleton = true;
611
+ klass.$$singleton_of = object;
612
+
613
+ return object.$$meta = klass;
614
+ };
454
615
 
455
616
  // Build the singleton class for a Ruby (non class) Object.
456
617
  //
457
- // @param [RubyObject] object
458
- // @return [RubyClass]
459
- //
460
- function build_object_singleton_class(object) {
461
- var orig_class = object.$$class,
462
- class_id = "#<Class:#<" + orig_class.$$name + ":" + orig_class.$$id + ">>";
618
+ // @param object [Object]
619
+ // @return [Class]
620
+ Opal.build_object_singleton_class = function(object) {
621
+ var superclass = object.$$class,
622
+ name = "#<Class:#<" + superclass.$$name + ":" + superclass.$$id + ">>";
463
623
 
464
- var Singleton = function() {};
465
- var meta = Opal.boot_class(orig_class, Singleton);
466
- meta.$$name = class_id;
624
+ var alloc = Opal.boot_class_alloc(name, function(){}, superclass)
625
+ var klass = Opal.setup_class_object(name, alloc, superclass.$$name, superclass.constructor);
467
626
 
468
- meta.$$proto = object;
469
- meta.$$class = orig_class.$$class;
470
- meta.$$scope = orig_class.$$scope;
471
- meta.$$parent = orig_class;
472
- meta.$$is_singleton = true;
473
- meta.$$singleton_of = object;
627
+ klass.$$super = superclass;
628
+ klass.$$parent = superclass;
629
+ klass.$$class = superclass.$$class;
630
+ klass.$$scope = superclass.$$scope;
631
+ klass.$$proto = object;
474
632
 
475
- return object.$$meta = meta;
476
- }
633
+ klass.$$is_singleton = true;
634
+ klass.$$singleton_of = object;
635
+
636
+ return object.$$meta = klass;
637
+ };
477
638
 
478
639
  // Bridges a single method.
479
- function bridge_method(target, from, name, body) {
640
+ Opal.bridge_method = function(target, from, name, body) {
480
641
  var ancestors, i, ancestor, length;
481
642
 
482
643
  ancestors = target.$$bridge.$ancestors();
@@ -500,10 +661,10 @@
500
661
  }
501
662
  }
502
663
 
503
- }
664
+ };
504
665
 
505
666
  // Bridges from *donator* to a *target*.
506
- function _bridge(target, donator) {
667
+ Opal._bridge = function(target, donator) {
507
668
  var id, methods, method, i, bridged;
508
669
 
509
670
  if (typeof(target) === "function") {
@@ -513,7 +674,7 @@
513
674
  for (i = methods.length - 1; i >= 0; i--) {
514
675
  method = '$' + methods[i];
515
676
 
516
- bridge_method(target, donator, method, donator.$$proto[method]);
677
+ Opal.bridge_method(target, donator, method, donator.$$proto[method]);
517
678
  }
518
679
 
519
680
  if (!bridges[id]) {
@@ -527,13 +688,13 @@
527
688
 
528
689
  if (bridged) {
529
690
  for (i = bridged.length - 1; i >= 0; i--) {
530
- _bridge(bridged[i], donator);
691
+ Opal._bridge(bridged[i], donator);
531
692
  }
532
693
 
533
694
  bridges[donator.$__id__()] = bridged.slice();
534
695
  }
535
696
  }
536
- }
697
+ };
537
698
 
538
699
  // The actual inclusion of a module into a class.
539
700
  //
@@ -550,10 +711,9 @@
550
711
  // a proxy to the actual module, so the `super` chain can then search it for
551
712
  // the required method.
552
713
  //
553
- // @param [RubyModule] module the module to include
554
- // @param [RubyClass] klass the target class to include module into
714
+ // @param module [Module] the module to include
715
+ // @param klass [Class] the target class to include module into
555
716
  // @return [null]
556
- //
557
717
  Opal.append_features = function(module, klass) {
558
718
  var iclass, donator, prototype, methods, id, i;
559
719
 
@@ -566,7 +726,7 @@
566
726
 
567
727
  klass.$$inc.push(module);
568
728
  module.$$dep.push(klass);
569
- _bridge(klass, module);
729
+ Opal._bridge(klass, module);
570
730
 
571
731
  // iclass
572
732
  iclass = {
@@ -599,60 +759,12 @@
599
759
  prototype[id].$$donated = module;
600
760
  }
601
761
 
602
- donate_constants(module, klass);
762
+ Opal.donate_constants(module, klass);
603
763
  };
604
764
 
605
- // Boot a base class (makes instances).
606
- function boot_class_alloc(id, constructor, superklass) {
607
- if (superklass) {
608
- var alloc_proxy = function() {};
609
- alloc_proxy.prototype = superklass.$$proto || superklass.prototype;
610
- constructor.prototype = new alloc_proxy();
611
- }
612
-
613
- if (id) {
614
- constructor.displayName = id+'_alloc';
615
- }
616
-
617
- constructor.prototype.constructor = constructor;
618
-
619
- return constructor;
620
- }
621
-
622
- // Builds the class object for core classes:
623
- // - make the class object have a singleton class
624
- // - make the singleton class inherit from its parent singleton class
625
- //
626
- // @param id [String] the name of the class
627
- // @param alloc [Function] the constructor for the core class instances
628
- // @param superclass [Class alloc] the constructor of the superclass
629
- //
630
- function boot_core_class_object(id, alloc, superclass) {
631
- var superclass_constructor = function() {};
632
- superclass_constructor.prototype = superclass.prototype;
633
-
634
- var singleton_class = function() {};
635
- singleton_class.prototype = new superclass_constructor();
636
-
637
- singleton_class.displayName = "#<Class:"+id+">";
638
-
639
- // the singleton_class acts as the class object constructor
640
- var klass = new singleton_class();
641
-
642
- setup_module_or_class_object(klass, singleton_class, superclass, alloc.prototype);
643
-
644
- klass.$$alloc = alloc;
645
- klass.$$name = id;
646
- klass.displayName = id;
647
-
648
- // Give all instances a ref to their class
649
- alloc.prototype.$$class = klass;
650
-
651
- Opal[id] = klass;
652
- Opal.constants.push(id);
653
-
654
- return klass;
655
- }
765
+ // Table that holds all methods that have been defined on all objects
766
+ // It is used for defining method stubs for new coming native classes
767
+ Opal.stubs = {};
656
768
 
657
769
  // For performance, some core Ruby classes are toll-free bridged to their
658
770
  // native JavaScript counterparts (e.g. a Ruby Array is a JavaScript Array).
@@ -667,8 +779,8 @@
667
779
  //
668
780
  // Opal.bridge(self, Function);
669
781
  //
670
- // @param [Class] klass the Ruby class to bridge
671
- // @param [Function] constructor native JavaScript constructor to use
782
+ // @param klass [Class] the Ruby class to bridge
783
+ // @param constructor [JS.Function] native JavaScript constructor to use
672
784
  // @return [Class] returns the passed Ruby class
673
785
  //
674
786
  Opal.bridge = function(klass, constructor) {
@@ -678,6 +790,13 @@
678
790
 
679
791
  Opal.stub_subscribers.push(constructor.prototype);
680
792
 
793
+ // Populate constructor with previously stored stubs
794
+ for (var method_name in Opal.stubs) {
795
+ if (!(method_name in constructor.prototype)) {
796
+ constructor.prototype[method_name] = Opal.stub_for(method_name);
797
+ }
798
+ }
799
+
681
800
  constructor.prototype.$$class = klass;
682
801
  constructor.$$bridge = klass;
683
802
 
@@ -686,7 +805,7 @@
686
805
  // order important here, we have to bridge from the last ancestor to the
687
806
  // bridged class
688
807
  for (var i = ancestors.length - 1; i >= 0; i--) {
689
- _bridge(constructor, ancestors[i]);
808
+ Opal._bridge(constructor, ancestors[i]);
690
809
  }
691
810
 
692
811
  for (var name in BasicObject_alloc.prototype) {
@@ -698,68 +817,12 @@
698
817
  }
699
818
 
700
819
  return klass;
701
- }
702
-
703
-
704
- // Constant assignment, see also `Opal.cdecl`
705
- //
706
- // @param base_module [Module, Class] the constant namespace
707
- // @param name [String] the name of the constant
708
- // @param value [Object] the value of the constant
709
- //
710
- // @example Assigning a namespaced constant
711
- // self::FOO = 'bar'
712
- //
713
- // @example Assigning with Module#const_set
714
- // Foo.const_set :BAR, 123
715
- //
716
- Opal.casgn = function(base_module, name, value) {
717
- function update(klass, name) {
718
- klass.$$name = name;
719
-
720
- for (name in klass.$$scope) {
721
- var value = klass.$$scope[name];
722
-
723
- if (value.$$name === nil && (value.$$is_class || value.$$is_module)) {
724
- update(value, name)
725
- }
726
- }
727
- }
728
-
729
- var scope = base_module.$$scope;
730
-
731
- if (value.$$is_class || value.$$is_module) {
732
- // Only checking _Object prevents setting a const on an anonymous class
733
- // that has a superclass that's not Object
734
- if (value.$$is_class || value.$$base_module === _Object) {
735
- value.$$base_module = base_module;
736
- }
737
-
738
- if (value.$$name === nil && value.$$base_module.$$name !== nil) {
739
- update(value, name);
740
- }
741
- }
742
-
743
- scope.constants.push(name);
744
- return scope[name] = value;
745
- };
746
-
747
- // constant decl
748
- Opal.cdecl = function(base_scope, name, value) {
749
- if ((value.$$is_class || value.$$is_module) && value.$$orig_scope == null) {
750
- value.$$name = name;
751
- value.$$orig_scope = base_scope;
752
- base_scope.constructor[name] = value;
753
- }
754
-
755
- base_scope.constants.push(name);
756
- return base_scope[name] = value;
757
820
  };
758
821
 
759
822
  // When a source module is included into the target module, we must also copy
760
823
  // its constants to the target.
761
824
  //
762
- function donate_constants(source_mod, target_mod) {
825
+ Opal.donate_constants = function(source_mod, target_mod) {
763
826
  var source_constants = source_mod.$$scope.constants,
764
827
  target_scope = target_mod.$$scope,
765
828
  target_constants = target_scope.constants;
@@ -771,7 +834,7 @@
771
834
  };
772
835
 
773
836
  // Donate methods for a module.
774
- function donate(module, jsid) {
837
+ Opal.donate = function(module, jsid) {
775
838
  var included_in = module.$$dep,
776
839
  body = module.$$proto[jsid],
777
840
  i, length, includee, dest, current,
@@ -817,11 +880,37 @@
817
880
  }
818
881
 
819
882
  if (includee.$$dep) {
820
- donate(includee, jsid);
883
+ Opal.donate(includee, jsid);
884
+ }
885
+ }
886
+ };
887
+
888
+ // The Array of ancestors for a given module/class
889
+ Opal.ancestors = function(module_or_class) {
890
+ var parent = module_or_class,
891
+ result = [],
892
+ modules;
893
+
894
+ while (parent) {
895
+ result.push(parent);
896
+ for (var i=0; i < parent.$$inc.length; i++) {
897
+ modules = Opal.ancestors(parent.$$inc[i]);
898
+
899
+ for(var j = 0; j < modules.length; j++) {
900
+ result.push(modules[j]);
901
+ }
821
902
  }
903
+
904
+ parent = parent.$$is_class ? parent.$$super : null;
822
905
  }
906
+
907
+ return result;
823
908
  };
824
909
 
910
+
911
+ // Method Missing
912
+ // --------------
913
+
825
914
  // Methods stubs are used to facilitate method_missing in opal. A stub is a
826
915
  // placeholder function which just calls `method_missing` on the receiver.
827
916
  // If no method with the given name is actually defined on an object, then it
@@ -847,8 +936,8 @@
847
936
  // that other internal methods can detect if a method is just a stub or not.
848
937
  // `Kernel#respond_to?` uses this property to detect a methods presence.
849
938
  //
850
- // @param [Array] stubs an array of method stubs to add
851
- //
939
+ // @param stubs [Array] an array of method stubs to add
940
+ // @return [undefined]
852
941
  Opal.add_stubs = function(stubs) {
853
942
  var subscriber, subscribers = Opal.stub_subscribers,
854
943
  i, ilength = stubs.length,
@@ -857,7 +946,9 @@
857
946
 
858
947
  for (i = 0; i < ilength; i++) {
859
948
  method_name = stubs[i];
860
- stub = stub_for(method_name);
949
+ // Save method name to populate other subscribers with this stub
950
+ Opal.stubs[method_name] = true;
951
+ stub = Opal.stub_for(method_name);
861
952
 
862
953
  for (j = 0; j < jlength; j++) {
863
954
  subscriber = subscribers[j];
@@ -878,19 +969,19 @@
878
969
  // Add a method_missing stub function to the given prototype for the
879
970
  // given name.
880
971
  //
881
- // @param [Prototype] prototype the target prototype
882
- // @param [String] stub stub name to add (e.g. "$foo")
883
- //
972
+ // @param prototype [Prototype] the target prototype
973
+ // @param stub [String] stub name to add (e.g. "$foo")
974
+ // @return [undefined]
884
975
  Opal.add_stub_for = function(prototype, stub) {
885
- var method_missing_stub = stub_for(stub);
976
+ var method_missing_stub = Opal.stub_for(stub);
886
977
  prototype[stub] = method_missing_stub;
887
- }
978
+ };
888
979
 
889
980
  // Generate the method_missing stub for a given method name.
890
981
  //
891
- // @param [String] method_name The js-name of the method to stub (e.g. "$foo")
892
- //
893
- function stub_for(method_name) {
982
+ // @param method_name [String] The js-name of the method to stub (e.g. "$foo")
983
+ // @return [undefined]
984
+ Opal.stub_for = function(method_name) {
894
985
  function method_missing_stub() {
895
986
  // Copy any given block onto the method_missing dispatcher
896
987
  this.$method_missing.$$p = method_missing_stub.$$p;
@@ -905,7 +996,11 @@
905
996
  method_missing_stub.$$stub = true;
906
997
 
907
998
  return method_missing_stub;
908
- }
999
+ };
1000
+
1001
+
1002
+ // Methods
1003
+ // -------
909
1004
 
910
1005
  // Arity count error dispatcher
911
1006
  Opal.ac = function(actual, expected, object, meth) {
@@ -921,25 +1016,8 @@
921
1016
  throw Opal.ArgumentError.$new('[' + inspect + '] wrong number of arguments(' + actual + ' for ' + expected + ')');
922
1017
  };
923
1018
 
924
- // The Array of ancestors for a given module/class
925
- Opal.ancestors = function(module_or_class) {
926
- var parent = module_or_class,
927
- result = [];
928
-
929
- while (parent) {
930
- result.push(parent);
931
- for (var i=0; i < parent.$$inc.length; i++) {
932
- result = result.concat(Opal.ancestors(parent.$$inc[i]));
933
- }
934
-
935
- parent = parent.$$is_class ? parent.$$super : null;
936
- }
937
-
938
- return result;
939
- }
940
-
941
1019
  // Super dispatcher
942
- Opal.find_super_dispatcher = function(obj, jsid, current_func, iter, defs) {
1020
+ Opal.find_super_dispatcher = function(obj, jsid, current_func, defcheck, defs) {
943
1021
  var dispatcher;
944
1022
 
945
1023
  if (defs) {
@@ -955,33 +1033,47 @@
955
1033
  dispatcher = obj.$$super;
956
1034
  }
957
1035
  else {
958
- dispatcher = find_obj_super_dispatcher(obj, jsid, current_func);
1036
+ dispatcher = Opal.find_obj_super_dispatcher(obj, jsid, current_func);
959
1037
  }
960
1038
  }
961
1039
 
962
1040
  dispatcher = dispatcher['$' + jsid];
963
- dispatcher.$$p = iter;
1041
+
1042
+ if (!defcheck && dispatcher.$$stub && Opal.Kernel.$method_missing === obj.$method_missing) {
1043
+ // method_missing hasn't been explicitly defined
1044
+ throw Opal.NoMethodError.$new('super: no superclass method `'+jsid+"' for "+obj, jsid);
1045
+ }
964
1046
 
965
1047
  return dispatcher;
966
1048
  };
967
1049
 
968
1050
  // Iter dispatcher for super in a block
969
- Opal.find_iter_super_dispatcher = function(obj, jsid, current_func, iter, defs) {
970
- if (current_func.$$def) {
971
- return Opal.find_super_dispatcher(obj, current_func.$$jsid, current_func, iter, defs);
1051
+ Opal.find_iter_super_dispatcher = function(obj, jsid, current_func, defcheck, implicit) {
1052
+ var call_jsid = jsid;
1053
+
1054
+ if (!current_func) {
1055
+ throw Opal.RuntimeError.$new("super called outside of method");
972
1056
  }
973
- else {
974
- return Opal.find_super_dispatcher(obj, jsid, current_func, iter, defs);
1057
+
1058
+ if (implicit && current_func.$$define_meth) {
1059
+ throw Opal.RuntimeError.$new("implicit argument passing of super from method defined by define_method() is not supported. Specify all arguments explicitly");
975
1060
  }
1061
+
1062
+ if (current_func.$$def) {
1063
+ call_jsid = current_func.$$jsid;
1064
+ }
1065
+
1066
+ return Opal.find_super_dispatcher(obj, call_jsid, current_func, defcheck);
976
1067
  };
977
1068
 
978
- function find_obj_super_dispatcher(obj, jsid, current_func) {
1069
+ Opal.find_obj_super_dispatcher = function(obj, jsid, current_func) {
979
1070
  var klass = obj.$$meta || obj.$$class;
980
1071
  jsid = '$' + jsid;
981
1072
 
1073
+ // first we need to find the class/module current_func is defined/donated on
982
1074
  while (klass) {
983
- if (klass.$$proto[jsid] === current_func) {
984
- // ok
1075
+ // when a module has been included in a class, look for that
1076
+ if ((klass.$$iclass && klass.$$module === current_func.$$owner) || klass === current_func.$$owner) {
985
1077
  break;
986
1078
  }
987
1079
 
@@ -995,7 +1087,7 @@
995
1087
 
996
1088
  klass = klass.$$parent;
997
1089
 
998
- // else, let's find the next one
1090
+ // now we can find the super
999
1091
  while (klass) {
1000
1092
  var working = klass.$$proto[jsid];
1001
1093
 
@@ -1022,6 +1114,18 @@
1022
1114
  throw Opal.returner;
1023
1115
  };
1024
1116
 
1117
+ // Used to break out of a block.
1118
+ Opal.brk = function(val, breaker) {
1119
+ breaker.$v = val;
1120
+ throw breaker;
1121
+ };
1122
+
1123
+ // Builds a new unique breaker, this is to avoid multiple nested breaks to get
1124
+ // in the way of each other.
1125
+ Opal.new_brk = function() {
1126
+ return new Error('unexpected break');
1127
+ };
1128
+
1025
1129
  // handles yield calls for 1 yielded arg
1026
1130
  Opal.yield1 = function(block, arg) {
1027
1131
  if (typeof(block) !== "function") {
@@ -1081,20 +1185,20 @@
1081
1185
  return true;
1082
1186
  }
1083
1187
 
1084
- var search = object.$$class;
1188
+ var i, length, ancestors = Opal.ancestors(object.$$class);
1085
1189
 
1086
- while (search) {
1087
- if (search === klass) {
1190
+ for (i = 0, length = ancestors.length; i < length; i++) {
1191
+ if (ancestors[i] === klass) {
1088
1192
  return true;
1089
1193
  }
1194
+ }
1090
1195
 
1091
- for (var i = 0, length = search.$$inc.length; i < length; i++) {
1092
- if (search.$$inc[i] === klass) {
1093
- return true;
1094
- }
1095
- }
1196
+ ancestors = Opal.ancestors(object.$$meta);
1096
1197
 
1097
- search = search.$$super;
1198
+ for (i = 0, length = ancestors.length; i < length; i++) {
1199
+ if (ancestors[i] === klass) {
1200
+ return true;
1201
+ }
1098
1202
  }
1099
1203
 
1100
1204
  return false;
@@ -1102,13 +1206,13 @@
1102
1206
 
1103
1207
  // Helpers for implementing multiple assignment
1104
1208
  // Our code for extracting the values and assigning them only works if the
1105
- // return value is a JS array
1209
+ // return value is a JS array.
1106
1210
  // So if we get an Array subclass, extract the wrapped JS array from it
1107
1211
 
1212
+ // Used for: a, b = something (no splat)
1108
1213
  Opal.to_ary = function(value) {
1109
- // Used for: a, b = something (no splat)
1110
1214
  if (value.$$is_array) {
1111
- return (value.constructor === Array) ? value : value.literal;
1215
+ return value;
1112
1216
  }
1113
1217
  else if (value['$respond_to?']('to_ary', true)) {
1114
1218
  var ary = value.$to_ary();
@@ -1116,7 +1220,7 @@
1116
1220
  return [value];
1117
1221
  }
1118
1222
  else if (ary.$$is_array) {
1119
- return (ary.constructor === Array) ? ary : ary.literal;
1223
+ return ary;
1120
1224
  }
1121
1225
  else {
1122
1226
  throw Opal.TypeError.$new("Can't convert " + value.$$class +
@@ -1128,11 +1232,11 @@
1128
1232
  }
1129
1233
  };
1130
1234
 
1235
+ // Used for: a, b = *something (with splat)
1131
1236
  Opal.to_a = function(value) {
1132
- // Used for: a, b = *something (with splat)
1133
1237
  if (value.$$is_array) {
1134
1238
  // A splatted array must be copied
1135
- return (value.constructor === Array) ? value.slice() : value.literal.slice();
1239
+ return value.slice();
1136
1240
  }
1137
1241
  else if (value['$respond_to?']('to_a', true)) {
1138
1242
  var ary = value.$to_a();
@@ -1140,7 +1244,7 @@
1140
1244
  return [value];
1141
1245
  }
1142
1246
  else if (ary.$$is_array) {
1143
- return (ary.constructor === Array) ? ary : ary.literal;
1247
+ return ary;
1144
1248
  }
1145
1249
  else {
1146
1250
  throw Opal.TypeError.$new("Can't convert " + value.$$class +
@@ -1152,6 +1256,24 @@
1152
1256
  }
1153
1257
  };
1154
1258
 
1259
+ // Used for extracting keyword arguments from arguments passed to
1260
+ // JS function. If provided +arguments+ list doesn't have a Hash
1261
+ // as a last item, returns a blank Hash.
1262
+ //
1263
+ // @param parameters [Array]
1264
+ // @return [Hash]
1265
+ //
1266
+ Opal.extract_kwargs = function(parameters) {
1267
+ var kwargs = parameters[parameters.length - 1];
1268
+ if (kwargs != null && kwargs['$respond_to?']('to_hash', true)) {
1269
+ Array.prototype.splice.call(parameters, parameters.length - 1, 1);
1270
+ return kwargs.$to_hash();
1271
+ }
1272
+ else {
1273
+ return Opal.hash2([], {});
1274
+ }
1275
+ }
1276
+
1155
1277
  // Used to get a list of rest keyword arguments. Method takes the given
1156
1278
  // keyword args, i.e. the hash literal passed to the method containing all
1157
1279
  // keyword arguemnts passed to method, as well as the used args which are
@@ -1181,6 +1303,7 @@
1181
1303
 
1182
1304
  // Call a ruby method on a ruby object with some arguments:
1183
1305
  //
1306
+ // @example
1184
1307
  // var my_array = [1, 2, 3, 4]
1185
1308
  // Opal.send(my_array, 'length') # => 4
1186
1309
  // Opal.send(my_array, 'reverse!') # => [4, 3, 2, 1]
@@ -1190,9 +1313,9 @@
1190
1313
  //
1191
1314
  // The result of either call with be returned.
1192
1315
  //
1193
- // @param [Object] recv the ruby object
1194
- // @param [String] mid ruby method to call
1195
- //
1316
+ // @param recv [Object] the ruby object
1317
+ // @param mid [String] ruby method to call
1318
+ // @return [Object] forwards the return value of the method (or of method_missing)
1196
1319
  Opal.send = function(recv, mid) {
1197
1320
  var args = $slice.call(arguments, 2),
1198
1321
  func = recv['$' + mid];
@@ -1247,16 +1370,18 @@
1247
1370
  // defined on the object as a singleton method. This would be the case when
1248
1371
  // a method is defined inside an `instance_eval` block.
1249
1372
  //
1250
- // @param [RubyObject or Class] obj the actual obj to define method for
1251
- // @param [String] jsid the javascript friendly method name (e.g. '$foo')
1252
- // @param [Function] body the literal javascript function used as method
1373
+ // @param obj [Object, Class] the actual obj to define method for
1374
+ // @param jsid [String] the javascript friendly method name (e.g. '$foo')
1375
+ // @param body [JS.Function] the literal javascript function used as method
1253
1376
  // @return [null]
1254
1377
  //
1255
1378
  Opal.defn = function(obj, jsid, body) {
1256
1379
  obj.$$proto[jsid] = body;
1380
+ // for super dispatcher, etc.
1381
+ body.$$owner = obj;
1257
1382
 
1258
1383
  if (obj.$$is_module) {
1259
- donate(obj, jsid);
1384
+ Opal.donate(obj, jsid);
1260
1385
 
1261
1386
  if (obj.$$module_function) {
1262
1387
  Opal.defs(obj, jsid, body);
@@ -1268,24 +1393,22 @@
1268
1393
 
1269
1394
  if (bridged) {
1270
1395
  for (var i = bridged.length - 1; i >= 0; i--) {
1271
- bridge_method(bridged[i], obj, jsid, body);
1396
+ Opal.bridge_method(bridged[i], obj, jsid, body);
1272
1397
  }
1273
1398
  }
1274
1399
  }
1275
1400
 
1276
- if (obj.$method_added && !obj.$method_added.$$stub) {
1401
+ var singleton_of = obj.$$singleton_of;
1402
+ if (obj.$method_added && !obj.$method_added.$$stub && !singleton_of) {
1277
1403
  obj.$method_added(jsid.substr(1));
1278
1404
  }
1279
-
1280
- var singleton_of = obj.$$singleton_of;
1281
- if (singleton_of && singleton_of.$singleton_method_added && !singleton_of.$singleton_method_added.$$stub) {
1405
+ else if (singleton_of && singleton_of.$singleton_method_added && !singleton_of.$singleton_method_added.$$stub) {
1282
1406
  singleton_of.$singleton_method_added(jsid.substr(1));
1283
1407
  }
1284
1408
 
1285
1409
  return nil;
1286
1410
  };
1287
1411
 
1288
-
1289
1412
  // Define a singleton method on the given object.
1290
1413
  Opal.defs = function(obj, jsid, body) {
1291
1414
  Opal.defn(Opal.get_singleton_class(obj), jsid, body)
@@ -1384,15 +1507,19 @@
1384
1507
  return obj;
1385
1508
  };
1386
1509
 
1510
+
1511
+ // Hashes
1512
+ // ------
1513
+
1387
1514
  Opal.hash_init = function(hash) {
1388
- hash.$$map = {};
1389
1515
  hash.$$smap = {};
1516
+ hash.$$map = {};
1390
1517
  hash.$$keys = [];
1391
1518
  };
1392
1519
 
1393
1520
  Opal.hash_clone = function(from_hash, to_hash) {
1394
- to_hash.none = from_hash.none;
1395
- to_hash.proc = from_hash.proc;
1521
+ to_hash.$$none = from_hash.$$none;
1522
+ to_hash.$$proc = from_hash.$$proc;
1396
1523
 
1397
1524
  for (var i = 0, keys = from_hash.$$keys, length = keys.length, key, value; i < length; i++) {
1398
1525
  key = from_hash.$$keys[i];
@@ -1650,9 +1777,9 @@
1650
1777
  Opal.hash2 = function(keys, smap) {
1651
1778
  var hash = new Opal.Hash.$$alloc();
1652
1779
 
1780
+ hash.$$smap = smap;
1653
1781
  hash.$$map = {};
1654
1782
  hash.$$keys = keys;
1655
- hash.$$smap = smap;
1656
1783
 
1657
1784
  return hash;
1658
1785
  };
@@ -1690,6 +1817,7 @@
1690
1817
  return name;
1691
1818
  };
1692
1819
 
1820
+
1693
1821
  // Require system
1694
1822
  // --------------
1695
1823
 
@@ -1698,7 +1826,7 @@
1698
1826
  Opal.current_dir = '.'
1699
1827
  Opal.require_table = {'corelib/runtime': true};
1700
1828
 
1701
- function normalize(path) {
1829
+ Opal.normalize = function(path) {
1702
1830
  var parts, part, new_parts = [], SEPARATOR = '/';
1703
1831
 
1704
1832
  if (Opal.current_dir !== '.') {
@@ -1715,13 +1843,13 @@
1715
1843
  }
1716
1844
 
1717
1845
  return new_parts.join(SEPARATOR);
1718
- }
1846
+ };
1719
1847
 
1720
1848
  Opal.loaded = function(paths) {
1721
1849
  var i, l, path;
1722
1850
 
1723
1851
  for (i = 0, l = paths.length; i < l; i++) {
1724
- path = normalize(paths[i]);
1852
+ path = Opal.normalize(paths[i]);
1725
1853
 
1726
1854
  if (Opal.require_table[path]) {
1727
1855
  return;
@@ -1730,10 +1858,10 @@
1730
1858
  Opal.loaded_features.push(path);
1731
1859
  Opal.require_table[path] = true;
1732
1860
  }
1733
- }
1861
+ };
1734
1862
 
1735
1863
  Opal.load = function(path) {
1736
- path = normalize(path);
1864
+ path = Opal.normalize(path);
1737
1865
 
1738
1866
  Opal.loaded([path]);
1739
1867
 
@@ -1743,7 +1871,7 @@
1743
1871
  module(Opal);
1744
1872
  }
1745
1873
  else {
1746
- var severity = Opal.dynamic_require_severity || 'warning';
1874
+ var severity = Opal.config.missing_require_severity;
1747
1875
  var message = 'cannot load such file -- ' + path;
1748
1876
 
1749
1877
  if (severity === "error") {
@@ -1755,32 +1883,38 @@
1755
1883
  }
1756
1884
 
1757
1885
  return true;
1758
- }
1886
+ };
1759
1887
 
1760
1888
  Opal.require = function(path) {
1761
- path = normalize(path);
1889
+ path = Opal.normalize(path);
1762
1890
 
1763
1891
  if (Opal.require_table[path]) {
1764
1892
  return false;
1765
1893
  }
1766
1894
 
1767
1895
  return Opal.load(path);
1768
- }
1896
+ };
1897
+
1769
1898
 
1770
1899
  // Initialization
1771
1900
  // --------------
1772
1901
 
1773
1902
  // Constructors for *instances* of core objects
1774
- boot_class_alloc('BasicObject', BasicObject_alloc);
1775
- boot_class_alloc('Object', Object_alloc, BasicObject_alloc);
1776
- boot_class_alloc('Module', Module_alloc, Object_alloc);
1777
- boot_class_alloc('Class', Class_alloc, Module_alloc);
1903
+ Opal.boot_class_alloc('BasicObject', BasicObject_alloc);
1904
+ Opal.boot_class_alloc('Object', Object_alloc, BasicObject_alloc);
1905
+ Opal.boot_class_alloc('Module', Module_alloc, Object_alloc);
1906
+ Opal.boot_class_alloc('Class', Class_alloc, Module_alloc);
1778
1907
 
1779
1908
  // Constructors for *classes* of core objects
1780
- BasicObject = boot_core_class_object('BasicObject', BasicObject_alloc, Class_alloc);
1781
- _Object = boot_core_class_object('Object', Object_alloc, BasicObject.constructor);
1782
- Module = boot_core_class_object('Module', Module_alloc, _Object.constructor);
1783
- Class = boot_core_class_object('Class', Class_alloc, Module.constructor);
1909
+ Opal.BasicObject = BasicObject = Opal.setup_class_object('BasicObject', BasicObject_alloc, 'Class', Class_alloc);
1910
+ Opal.Object = _Object = Opal.setup_class_object('Object', Object_alloc, 'BasicObject', BasicObject.constructor);
1911
+ Opal.Module = Module = Opal.setup_class_object('Module', Module_alloc, 'Object', _Object.constructor);
1912
+ Opal.Class = Class = Opal.setup_class_object('Class', Class_alloc, 'Module', Module.constructor);
1913
+
1914
+ Opal.constants.push("BasicObject");
1915
+ Opal.constants.push("Object");
1916
+ Opal.constants.push("Module");
1917
+ Opal.constants.push("Class");
1784
1918
 
1785
1919
  // Fix booted classes to use their metaclass
1786
1920
  BasicObject.$$class = Class;
@@ -1808,12 +1942,16 @@
1808
1942
  Class.$$scope = _Object.$$scope;
1809
1943
  Class.$$orig_scope = _Object.$$orig_scope;
1810
1944
 
1945
+ // Forward .toString() to #to_s
1811
1946
  _Object.$$proto.toString = function() {
1812
1947
  return this.$to_s();
1813
1948
  };
1814
1949
 
1950
+ // Make Kernel#require immediately available as it's needed to require all the
1951
+ // other corelib files.
1815
1952
  _Object.$$proto.$require = Opal.require;
1816
1953
 
1954
+ // Instantiate the top object
1817
1955
  Opal.top = new _Object.$$alloc();
1818
1956
 
1819
1957
  // Nil
@@ -1821,8 +1959,7 @@
1821
1959
  nil = Opal.nil = new NilClass_alloc();
1822
1960
  nil.$$id = nil_id;
1823
1961
  nil.call = nil.apply = function() { throw Opal.LocalJumpError.$new('no block given'); };
1824
-
1825
- Opal.breaker = new Error('unexpected break');
1962
+ Opal.breaker = new Error('unexpected break (old)');
1826
1963
  Opal.returner = new Error('unexpected return');
1827
1964
 
1828
1965
  TypeError.$$super = Error;