opal 0.9.0.beta2 → 0.9.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/.jshintrc +2 -1
  3. data/.travis.yml +8 -4
  4. data/CHANGELOG.md +270 -251
  5. data/CONTRIBUTING.md +41 -0
  6. data/README.md +8 -8
  7. data/Rakefile +1 -1
  8. data/lib/opal/cli.rb +1 -0
  9. data/lib/opal/cli_options.rb +2 -2
  10. data/lib/opal/cli_runners.rb +1 -0
  11. data/lib/opal/cli_runners/nashorn.rb +58 -0
  12. data/lib/opal/cli_runners/phantom.js +11 -9
  13. data/lib/opal/compiler.rb +2 -0
  14. data/lib/opal/erb.rb +2 -1
  15. data/lib/opal/nodes/def.rb +15 -6
  16. data/lib/opal/nodes/helpers.rb +1 -1
  17. data/lib/opal/nodes/literal.rb +1 -1
  18. data/lib/opal/nodes/masgn.rb +79 -29
  19. data/lib/opal/nodes/module.rb +1 -1
  20. data/lib/opal/nodes/top.rb +6 -2
  21. data/lib/opal/parser.rb +1 -0
  22. data/lib/opal/parser/grammar.rb +3160 -3083
  23. data/lib/opal/parser/grammar.y +39 -11
  24. data/lib/opal/parser/lexer.rb +15 -13
  25. data/lib/opal/parser/sexp.rb +5 -0
  26. data/lib/opal/version.rb +1 -1
  27. data/opal/corelib/array.rb +21 -6
  28. data/opal/corelib/basic_object.rb +17 -4
  29. data/opal/corelib/class.rb +1 -1
  30. data/opal/corelib/constants.rb +2 -2
  31. data/opal/corelib/enumerator.rb +2 -0
  32. data/opal/corelib/hash.rb +50 -50
  33. data/opal/corelib/helpers.rb +1 -1
  34. data/opal/corelib/io.rb +9 -6
  35. data/opal/corelib/kernel.rb +37 -9
  36. data/opal/corelib/module.rb +6 -17
  37. data/opal/corelib/nil.rb +4 -0
  38. data/opal/corelib/number.rb +0 -4
  39. data/opal/corelib/runtime.js +637 -662
  40. data/opal/corelib/struct.rb +7 -3
  41. data/spec/filters/bugs/array.rb +4 -9
  42. data/spec/filters/bugs/basicobject.rb +1 -15
  43. data/spec/filters/bugs/date.rb +4 -26
  44. data/spec/filters/bugs/enumerable.rb +26 -1
  45. data/spec/filters/bugs/enumerator.rb +4 -4
  46. data/spec/filters/bugs/exception.rb +1 -7
  47. data/spec/filters/bugs/float.rb +14 -0
  48. data/spec/filters/bugs/hash.rb +0 -2
  49. data/spec/filters/bugs/integer.rb +1 -1
  50. data/spec/filters/bugs/kernel.rb +47 -66
  51. data/spec/filters/bugs/language.rb +1 -2
  52. data/spec/filters/bugs/module.rb +11 -14
  53. data/spec/filters/bugs/numeric.rb +3 -3
  54. data/spec/filters/bugs/proc.rb +0 -1
  55. data/spec/filters/bugs/range.rb +2 -3
  56. data/spec/filters/bugs/regexp.rb +15 -17
  57. data/spec/filters/bugs/set.rb +2 -2
  58. data/spec/filters/bugs/string.rb +29 -5
  59. data/spec/filters/bugs/{strscan.rb → stringscanner.rb} +9 -10
  60. data/spec/filters/bugs/struct.rb +0 -4
  61. data/spec/filters/bugs/time.rb +2 -3
  62. data/spec/filters/bugs/unboundmethod.rb +3 -0
  63. data/spec/filters/unsupported/freeze.rb +2 -1
  64. data/spec/filters/unsupported/taint.rb +2 -0
  65. data/spec/lib/parser/aref_spec.rb +10 -0
  66. data/spec/lib/parser/lambda_spec.rb +14 -0
  67. data/spec/lib/parser/op_asgn_spec.rb +17 -0
  68. data/spec/lib/parser/return_spec.rb +5 -0
  69. data/spec/lib/parser/unary_spec.rb +4 -0
  70. data/spec/lib/sprockets/erb_spec.rb +1 -1
  71. data/spec/mspec/opal/formatters.rb +159 -0
  72. data/{lib → spec}/mspec/opal/runner.rb +0 -160
  73. data/spec/opal/core/hash/internals_spec.rb +162 -162
  74. data/spec/opal/core/kernel/at_exit_spec.rb +70 -0
  75. data/spec/opal/core/kernel/extend_spec.rb +1 -1
  76. data/spec/opal/core/kernel/instance_variables_spec.rb +56 -0
  77. data/spec/opal/core/language/equal_spec.rb +8 -0
  78. data/spec/opal/core/language/predefined_spec.rb +1 -1
  79. data/spec/opal/core/language/ternary_operator_spec.rb +14 -0
  80. data/spec/opal/core/language/versions/{hash_1.9.rb → hash_1_9_spec.rb} +5 -0
  81. data/spec/opal/core/module/fixtures/classes.rb +11 -1
  82. data/spec/opal/core/module/method_lookup_spec.rb +13 -0
  83. data/spec/opal/core/runtime/super_spec.rb +10 -0
  84. data/spec/opal/stdlib/native/new_spec.rb +84 -0
  85. data/spec/opal/stdlib/strscan/scan_spec.rb +11 -0
  86. data/spec/rubyspecs +6 -9
  87. data/spec/spec_helper.rb +9 -21
  88. data/stdlib/date.rb +121 -1
  89. data/stdlib/js.rb +13 -5
  90. data/stdlib/json.rb +3 -3
  91. data/stdlib/nashorn.rb +5 -0
  92. data/stdlib/nashorn/file.rb +13 -0
  93. data/stdlib/nashorn/io.rb +2 -0
  94. data/stdlib/native.rb +12 -4
  95. data/stdlib/nodejs/io.rb +5 -2
  96. data/stdlib/opal/platform.rb +19 -0
  97. data/stdlib/phantomjs.rb +4 -0
  98. data/stdlib/strscan.rb +1 -1
  99. data/tasks/building.rake +2 -1
  100. data/tasks/testing.rake +29 -34
  101. data/tasks/testing/{phantomjs1-sprockets.js → sprockets-phantomjs.js} +2 -20
  102. data/vendored-minitest/minitest/test.rb +7 -15
  103. metadata +32 -9
  104. data/lib/mspec/opal/main.rb.erb +0 -9
@@ -112,5 +112,5 @@ module Opal
112
112
  end
113
113
 
114
114
  name
115
- end
115
+ end
116
116
  end
data/opal/corelib/io.rb CHANGED
@@ -18,7 +18,11 @@ class IO
18
18
  string.size
19
19
  end
20
20
 
21
- attr_accessor :sync
21
+ attr_accessor :sync, :tty
22
+
23
+ def flush
24
+ # noop
25
+ end
22
26
 
23
27
  module Writable
24
28
  def <<(string)
@@ -65,9 +69,8 @@ STDERR = $stderr = IO.new
65
69
  STDIN = $stdin = IO.new
66
70
  STDOUT = $stdout = IO.new
67
71
 
72
+ STDOUT.write_proc = `typeof(process) === 'object' ? function(s){process.stdout.write(s)} : function(s){console.log(s)}`
73
+ STDERR.write_proc = `typeof(process) === 'object' ? function(s){process.stderr.write(s)} : function(s){console.warn(s)}`
68
74
 
69
- $stdout.write_proc = `typeof(process) === 'object' ? function(s){process.stdout.write(s)} : function(s){console.log(s)}`
70
- $stderr.write_proc = `typeof(process) === 'object' ? function(s){process.stderr.write(s)} : function(s){console.warn(s)}`
71
-
72
- $stdout.extend(IO::Writable)
73
- $stderr.extend(IO::Writable)
75
+ STDOUT.extend(IO::Writable)
76
+ STDERR.extend(IO::Writable)
@@ -105,7 +105,7 @@ module Kernel
105
105
  def copy_instance_variables(other)
106
106
  %x{
107
107
  for (var name in other) {
108
- if (name.charAt(0) !== '$') {
108
+ if (other.hasOwnProperty(name) && name.charAt(0) !== '$') {
109
109
  self[name] = other[name];
110
110
  }
111
111
  }
@@ -177,7 +177,12 @@ module Kernel
177
177
  end
178
178
 
179
179
  def exit(status = true)
180
- $__at_exit__.reverse.each(&:call) if $__at_exit__
180
+ $__at_exit__ ||= []
181
+ loop do
182
+ block = $__at_exit__.pop
183
+ block ? block.call : break
184
+ end
185
+
181
186
  status = 0 if `status === true` # it's in JS because it can be null/undef
182
187
  `Opal.exit(status);`
183
188
  nil
@@ -190,6 +195,10 @@ module Kernel
190
195
  for (var i = mods.length - 1; i >= 0; i--) {
191
196
  var mod = mods[i];
192
197
 
198
+ if (!mod.$$is_module) {
199
+ #{raise TypeError, "wrong argument type #{`mod`.class} (expected Module)"};
200
+ }
201
+
193
202
  #{`mod`.append_features `singleton`};
194
203
  #{`mod`.extended self};
195
204
  }
@@ -740,7 +749,7 @@ module Kernel
740
749
  end
741
750
 
742
751
  def hash
743
- "#{self.class}:#{self.class.__id__}:#{__id__}"
752
+ __id__
744
753
  end
745
754
 
746
755
  def initialize_copy(other)
@@ -770,7 +779,7 @@ module Kernel
770
779
  name = Opal.instance_variable_name!(name)
771
780
 
772
781
  %x{
773
- var ivar = self[name.substr(1)];
782
+ var ivar = self[Opal.ivar(name.substr(1))];
774
783
 
775
784
  return ivar == null ? nil : ivar;
776
785
  }
@@ -779,18 +788,37 @@ module Kernel
779
788
  def instance_variable_set(name, value)
780
789
  name = Opal.instance_variable_name!(name)
781
790
 
782
- `self[name.substr(1)] = value`
791
+ `self[Opal.ivar(name.substr(1))] = value`
792
+ end
793
+
794
+ def remove_instance_variable(name)
795
+ name = Opal.instance_variable_name!(name)
796
+
797
+ %x{
798
+ var key = Opal.ivar(name.substr(1)),
799
+ val;
800
+ if (self.hasOwnProperty(key)) {
801
+ val = self[key];
802
+ delete self[key];
803
+ return val;
804
+ }
805
+ }
806
+
807
+ raise NameError, "instance variable #{name} not defined"
783
808
  end
784
809
 
785
810
  def instance_variables
786
811
  %x{
787
- var result = [];
812
+ var result = [], ivar;
788
813
 
789
814
  for (var name in self) {
790
- if (name.charAt(0) !== '$') {
791
- if (name !== '$$class' && name !== '$$id') {
792
- result.push('@' + name);
815
+ if (self.hasOwnProperty(name) && name.charAt(0) !== '$') {
816
+ if (name.substr(-1) === '$') {
817
+ ivar = name.slice(0, name.length - 1);
818
+ } else {
819
+ ivar = name;
793
820
  }
821
+ result.push('@' + ivar);
794
822
  }
795
823
  }
796
824
 
@@ -1,8 +1,7 @@
1
1
  class Module
2
2
  def self.new(&block)
3
3
  %x{
4
- function AnonModule(){}
5
- var klass = Opal.boot(Opal.Module, AnonModule);
4
+ var klass = Opal.boot_module_object();
6
5
  klass.$$name = nil;
7
6
  klass.$$class = Opal.Module;
8
7
  klass.$$dep = []
@@ -67,21 +66,7 @@ class Module
67
66
  end
68
67
 
69
68
  def ancestors
70
- %x{
71
- var parent = self,
72
- result = [];
73
-
74
- while (parent) {
75
- result.push(parent);
76
- for (var i=0; i < parent.$$inc.length; i++) {
77
- result = result.concat(parent.$$inc[i].$ancestors());
78
- }
79
-
80
- parent = parent.$$is_class ? parent.$$super : null;
81
- }
82
-
83
- return result;
84
- }
69
+ `Opal.ancestors(self)`
85
70
  end
86
71
 
87
72
  def append_features(klass)
@@ -347,6 +332,10 @@ class Module
347
332
  continue;
348
333
  }
349
334
 
335
+ if (!mod.$$is_module) {
336
+ #{raise TypeError, "wrong argument type #{`mod`.class} (expected Module)"};
337
+ }
338
+
350
339
  #{`mod`.append_features self};
351
340
  #{`mod`.included self};
352
341
  }
data/opal/corelib/nil.rb CHANGED
@@ -71,6 +71,10 @@ class NilClass
71
71
  def to_r
72
72
  Rational(0, 1)
73
73
  end
74
+
75
+ def instance_variables
76
+ []
77
+ end
74
78
  end
75
79
 
76
80
  NIL = nil
@@ -392,10 +392,6 @@ class Number < Numeric
392
392
  [gcd, lcm]
393
393
  end
394
394
 
395
- def hash
396
- `'Numeric:'+self.toString()`
397
- end
398
-
399
395
  def integer?
400
396
  `self % 1 === 0`
401
397
  end
@@ -4,6 +4,36 @@
4
4
  return this.Opal;
5
5
  }
6
6
 
7
+ var nil;
8
+
9
+ // The actual class for BasicObject
10
+ var BasicObject;
11
+
12
+ // The actual Object class.
13
+ // The leading underscore is to avoid confusion with window.Object()
14
+ var _Object;
15
+
16
+ // The actual Module class
17
+ var Module;
18
+
19
+ // The actual Class class
20
+ var Class;
21
+
22
+ // Constructor for instances of BasicObject
23
+ function BasicObject_alloc(){}
24
+
25
+ // Constructor for instances of Object
26
+ function Object_alloc(){}
27
+
28
+ // Constructor for instances of Class
29
+ function Class_alloc(){}
30
+
31
+ // Constructor for instances of Module
32
+ function Module_alloc(){}
33
+
34
+ // Constructor for instances of NilClass (nil)
35
+ function NilClass_alloc(){}
36
+
7
37
  // The Opal object that is exposed globally
8
38
  var Opal = this.Opal = {};
9
39
 
@@ -51,26 +81,25 @@
51
81
  // Exit function, this should be replaced by platform specific implementation
52
82
  // (See nodejs and phantom for examples)
53
83
  Opal.exit = function(status) { if (Opal.gvars.DEBUG) console.log('Exited with status '+status); };
54
-
84
+
55
85
  // keeps track of exceptions for $!
56
86
  Opal.exceptions = [];
57
87
 
58
- /**
59
- Get a constant on the given scope. Every class and module in Opal has a
60
- scope used to store, and inherit, constants. For example, the top level
61
- `Object` in ruby has a scope accessible as `Opal.Object.$$scope`.
62
-
63
- To get the `Array` class using this scope, you could use:
64
-
65
- Opal.Object.$$scope.get("Array")
66
-
67
- If a constant with the given name cannot be found, then a dispatch to the
68
- class/module's `#const_method` is called, which by default will raise an
69
- error.
70
-
71
- @param [String] name the name of the constant to lookup
72
- @returns [RubyObject]
73
- */
88
+ // Get a constant on the given scope. Every class and module in Opal has a
89
+ // scope used to store, and inherit, constants. For example, the top level
90
+ // `Object` in ruby has a scope accessible as `Opal.Object.$$scope`.
91
+ //
92
+ // To get the `Array` class using this scope, you could use:
93
+ //
94
+ // Opal.Object.$$scope.get("Array")
95
+ //
96
+ // If a constant with the given name cannot be found, then a dispatch to the
97
+ // class/module's `#const_method` is called, which by default will raise an
98
+ // error.
99
+ //
100
+ // @param [String] name the name of the constant to lookup
101
+ // @return [RubyObject]
102
+ //
74
103
  Opal.get = function(name) {
75
104
  var constant = this[name];
76
105
 
@@ -81,12 +110,11 @@
81
110
  return constant;
82
111
  };
83
112
 
84
- /*
85
- * Create a new constants scope for the given class with the given
86
- * base. Constants are looked up through their parents, so the base
87
- * scope will be the outer scope of the new klass.
88
- */
89
- function create_scope(base, klass, id) {
113
+ // Create a new constants scope for the given class with the given
114
+ // base. Constants are looked up through their parents, so the base
115
+ // scope will be the outer scope of the new klass.
116
+ //
117
+ Opal.create_scope = function(base, klass, id) {
90
118
  var const_alloc = function() {};
91
119
  var const_scope = const_alloc.prototype = new base.constructor();
92
120
 
@@ -98,45 +126,51 @@
98
126
  const_scope.constants = [];
99
127
 
100
128
  if (id) {
101
- Opal.cdecl(base, id, klass)
129
+ Opal.cdecl(base, id, klass);
130
+ const_alloc.displayName = id+"_alloc";
102
131
  }
103
132
  }
104
133
 
105
- Opal.create_scope = create_scope;
106
-
107
- /*
108
- * A `class Foo; end` expression in ruby is compiled to call this runtime
109
- * method which either returns an existing class of the given name, or creates
110
- * a new class in the given `base` scope.
111
- *
112
- * If a constant with the given name exists, then we check to make sure that
113
- * it is a class and also that the superclasses match. If either of these
114
- * fail, then we raise a `TypeError`. Note, superklass may be null if one was
115
- * not specified in the ruby code.
116
- *
117
- * We pass a constructor to this method of the form `function ClassName() {}`
118
- * simply so that classes show up with nicely formatted names inside debuggers
119
- * in the web browser (or node/sprockets).
120
- *
121
- * The `base` is the current `self` value where the class is being created
122
- * from. We use this to get the scope for where the class should be created.
123
- * If `base` is an object (not a class/module), we simple get its class and
124
- * use that as the base instead.
125
- *
126
- * @param [Object] base where the class is being created
127
- * @param [Class] superklass superclass of the new class (may be null)
128
- * @param [String] id the name of the class to be created
129
- * @param [Function] constructor function to use as constructor
130
- * @return [Class] new or existing ruby class
131
- */
134
+ // A `class Foo; end` expression in ruby is compiled to call this runtime
135
+ // method which either returns an existing class of the given name, or creates
136
+ // a new class in the given `base` scope.
137
+ //
138
+ // If a constant with the given name exists, then we check to make sure that
139
+ // it is a class and also that the superclasses match. If either of these
140
+ // fail, then we raise a `TypeError`. Note, superklass may be null if one was
141
+ // not specified in the ruby code.
142
+ //
143
+ // We pass a constructor to this method of the form `function ClassName() {}`
144
+ // simply so that classes show up with nicely formatted names inside debuggers
145
+ // in the web browser (or node/sprockets).
146
+ //
147
+ // The `base` is the current `self` value where the class is being created
148
+ // from. We use this to get the scope for where the class should be created.
149
+ // If `base` is an object (not a class/module), we simple get its class and
150
+ // use that as the base instead.
151
+ //
152
+ // @param [Object] base where the class is being created
153
+ // @param [Class] superklass superclass of the new class (may be null)
154
+ // @param [String] id the name of the class to be created
155
+ // @param [Function] constructor function to use as constructor
156
+ // @return [Class] new or existing ruby class
157
+ //
132
158
  Opal.klass = function(base, superklass, id, constructor) {
159
+ var klass, bridged, alloc;
160
+
133
161
  // If base is an object, use its class
134
162
  if (!base.$$is_class && !base.$$is_module) {
135
163
  base = base.$$class;
136
164
  }
137
165
 
138
- var klass = base.$$scope[id],
139
- bridged = typeof(superklass) === 'function';
166
+ // If the superclass is a function then we're bridging a native JS class
167
+ if (typeof(superklass) === 'function') {
168
+ bridged = superklass;
169
+ superklass = _Object;
170
+ }
171
+
172
+ // Try to find the class in the current scope
173
+ klass = base.$$scope[id];
140
174
 
141
175
  // If the class exists in the scope, then we must use that
142
176
  if (klass && klass.$$orig_scope === base.$$scope) {
@@ -153,38 +187,42 @@
153
187
  return klass;
154
188
  }
155
189
 
190
+ // Class doesnt exist, create a new one with given superclass...
191
+
156
192
  // Not specifying a superclass means we can assume it to be Object
157
- if (superklass === null) {
158
- superklass = ObjectClass;
193
+ if (superklass == null) {
194
+ superklass = _Object;
159
195
  }
160
196
 
161
- // if class doesnt exist, create a new one with given superclass
162
- klass = bridged ?
163
- boot_class_object(ObjectClass, superklass) :
164
- boot_class(superklass, constructor);
197
+ // If bridged the JS class will also be the alloc function
198
+ alloc = bridged || boot_class_alloc(id, constructor, superklass);
165
199
 
166
- // name class using base (e.g. Foo or Foo::Baz)
200
+ // Create the class object (instance of Class)
201
+ klass = boot_class_object(id, superklass, alloc);
202
+
203
+ // Name the class
167
204
  klass.$$name = id;
205
+ klass.displayName = id;
168
206
 
169
- // mark the object as a class
207
+ // Mark the object as a class
170
208
  klass.$$is_class = true;
171
209
 
172
- // every class gets its own constant scope, inherited from current scope
173
- create_scope(base.$$scope, klass, id);
210
+ // Every class gets its own constant scope, inherited from current scope
211
+ Opal.create_scope(base.$$scope, klass, id);
174
212
 
175
213
  // Name new class directly onto current scope (Opal.Foo.Baz = klass)
176
214
  base[id] = base.$$scope[id] = klass;
177
215
 
178
216
  if (bridged) {
179
- Opal.bridge(klass, superklass);
217
+ Opal.bridge(klass, alloc);
180
218
  }
181
219
  else {
182
220
  // Copy all parent constants to child, unless parent is Object
183
- if (superklass !== ObjectClass && superklass !== BasicObjectClass) {
221
+ if (superklass !== _Object && superklass !== BasicObject) {
184
222
  donate_constants(superklass, klass);
185
223
  }
186
224
 
187
- // call .inherited() hook with new class on the superclass
225
+ // Call .inherited() hook with new class on the superclass
188
226
  if (superklass.$inherited) {
189
227
  superklass.$inherited(klass);
190
228
  }
@@ -194,33 +232,34 @@
194
232
  };
195
233
 
196
234
  // Create generic class with given superclass.
197
- function boot_class(superklass, constructor) {
235
+ Opal.boot_class = function(superklass, constructor) {
198
236
  var alloc = boot_class_alloc(null, constructor, superklass)
199
237
 
200
- return boot_class_object(superklass, alloc);
238
+ return boot_class_object(null, superklass, alloc);
201
239
  }
202
240
 
203
- // Make `boot_class` available to the JS-API
204
- Opal.boot = boot_class;
205
-
206
- /*
207
- * The class object itself (as in `Class.new`)
208
- *
209
- * @param [(Opal) Class] superklass Another class object (as in `Class.new`)
210
- * @param [constructor] alloc The constructor that holds the prototype
211
- * that will be used for instances of the
212
- * newly constructed class.
213
- */
214
- function boot_class_object(superklass, alloc) {
215
- var singleton_class = function() {};
216
- singleton_class.prototype = superklass.constructor.prototype;
241
+ // The class object itself (as in `Class.new`)
242
+ //
243
+ // @param superklass [(Opal) Class] Another class object (as in `Class.new`)
244
+ // @param alloc [constructor] The constructor that holds the prototype
245
+ // that will be used for instances of the
246
+ // newly constructed class.
247
+ function boot_class_object(id, superklass, alloc) {
248
+ // Grab the superclass prototype and use it to build an intermediary object
249
+ // in the prototype chain.
250
+ function Superclass_alloc_proxy() {};
251
+ Superclass_alloc_proxy.prototype = superklass.constructor.prototype;
252
+ function SingletonClass_alloc() {}
253
+ SingletonClass_alloc.prototype = new Superclass_alloc_proxy();
217
254
 
218
- function OpalClass() {}
219
- OpalClass.prototype = new singleton_class();
255
+ if (id) {
256
+ SingletonClass_alloc.displayName = "SingletonClass_alloc("+id+")";
257
+ }
220
258
 
221
- var klass = new OpalClass();
259
+ // The built class is the only instance of its singleton_class
260
+ var klass = new SingletonClass_alloc();
222
261
 
223
- setup_module_or_class_object(klass, OpalClass, superklass, alloc.prototype);
262
+ setup_module_or_class_object(klass, SingletonClass_alloc, superklass, alloc.prototype);
224
263
 
225
264
  // @property $$alloc This is the constructor of instances of the current
226
265
  // class. Its prototype will be used for method lookup
@@ -233,22 +272,21 @@
233
272
  return klass;
234
273
  }
235
274
 
236
- /*
237
- * Adds common/required properties to a module or class object
238
- * (as in `Module.new` / `Class.new`)
239
- *
240
- * @param module The module or class that needs to be prepared
241
- *
242
- * @param constructor The constructor of the module or class itself,
243
- * usually it's already assigned by using `new`. Some
244
- * ipothesis on why it's needed can be found below.
245
- *
246
- * @param superklass The superclass of the class/module object, for modules
247
- * is `Module` (of `ModuleClass` in JS context)
248
- *
249
- * @param prototype The prototype on which the class/module methods will
250
- * be stored.
251
- */
275
+ // Adds common/required properties to a module or class object
276
+ // (as in `Module.new` / `Class.new`)
277
+ //
278
+ // @param module The module or class that needs to be prepared
279
+ //
280
+ // @param constructor The constructor of the module or class itself,
281
+ // usually it's already assigned by using `new`. Some
282
+ // ipothesis on why it's needed can be found below.
283
+ //
284
+ // @param superklass The superclass of the class/module object, for modules
285
+ // is `Module` (of `Module` in JS context)
286
+ //
287
+ // @param prototype The prototype on which the class/module methods will
288
+ // be stored.
289
+ //
252
290
  function setup_module_or_class_object(module, constructor, superklass, prototype) {
253
291
  // @property $$id Each class is assigned a unique `id` that helps
254
292
  // comparation and implementation of `#object_id`
@@ -265,15 +303,15 @@
265
303
  // Maybe there are some browsers not abiding (IE6?)
266
304
  module.constructor = constructor;
267
305
 
268
- if (superklass === ModuleClass) {
306
+ if (superklass === Module) {
269
307
  // @property $$is_module Clearly mark this as a module
270
308
  module.$$is_module = true;
271
- module.$$class = ModuleClass;
309
+ module.$$class = Module;
272
310
  }
273
311
  else {
274
312
  // @property $$is_class Clearly mark this as a class
275
313
  module.$$is_class = true;
276
- module.$$class = ClassClass;
314
+ module.$$class = Class;
277
315
  }
278
316
 
279
317
  // @property $$super the superclass, doesn't get changed by module inclusions
@@ -288,26 +326,25 @@
288
326
  module.$$inc = [];
289
327
  }
290
328
 
291
- /**
292
- Define new module (or return existing module). The given `base` is basically
293
- the current `self` value the `module` statement was defined in. If this is
294
- a ruby module or class, then it is used, otherwise if the base is a ruby
295
- object then that objects real ruby class is used (e.g. if the base is the
296
- main object, then the top level `Object` class is used as the base).
297
-
298
- If a module of the given name is already defined in the base, then that
299
- instance is just returned.
300
-
301
- If there is a class of the given name in the base, then an error is
302
- generated instead (cannot have a class and module of same name in same base).
303
-
304
- Otherwise, a new module is created in the base with the given name, and that
305
- new instance is returned back (to be referenced at runtime).
306
-
307
- @param [RubyModule or Class] base class or module this definition is inside
308
- @param [String] id the name of the new (or existing) module
309
- @returns [RubyModule]
310
- */
329
+ // Define new module (or return existing module). The given `base` is basically
330
+ // the current `self` value the `module` statement was defined in. If this is
331
+ // a ruby module or class, then it is used, otherwise if the base is a ruby
332
+ // object then that objects real ruby class is used (e.g. if the base is the
333
+ // main object, then the top level `Object` class is used as the base).
334
+ //
335
+ // If a module of the given name is already defined in the base, then that
336
+ // instance is just returned.
337
+ //
338
+ // If there is a class of the given name in the base, then an error is
339
+ // generated instead (cannot have a class and module of same name in same base).
340
+ //
341
+ // Otherwise, a new module is created in the base with the given name, and that
342
+ // new instance is returned back (to be referenced at runtime).
343
+ //
344
+ // @param [RubyModule or Class] base class or module this definition is inside
345
+ // @param [String] id the name of the new (or existing) module
346
+ // @return [RubyModule]
347
+ //
311
348
  Opal.module = function(base, id) {
312
349
  var module;
313
350
 
@@ -318,7 +355,7 @@
318
355
  if ($hasOwn.call(base.$$scope, id)) {
319
356
  module = base.$$scope[id];
320
357
 
321
- if (!module.$$is_module && module !== ObjectClass) {
358
+ if (!module.$$is_module && module !== _Object) {
322
359
  throw Opal.TypeError.$new(id + " is not a module");
323
360
  }
324
361
  }
@@ -334,7 +371,7 @@
334
371
  // initialize dependency tracking
335
372
  module.$$dep = [];
336
373
 
337
- create_scope(base.$$scope, module, id);
374
+ Opal.create_scope(base.$$scope, module, id);
338
375
 
339
376
  // Name new module directly onto current scope (Opal.Foo.Baz = module)
340
377
  base[id] = base.$$scope[id] = module;
@@ -343,13 +380,12 @@
343
380
  return module;
344
381
  };
345
382
 
346
- /*
347
- * Internal function to create a new module instance. This simply sets up
348
- * the prototype hierarchy and method tables.
349
- */
383
+ // Internal function to create a new module instance. This simply sets up
384
+ // the prototype hierarchy and method tables.
385
+ //
350
386
  function boot_module_object() {
351
387
  var mtor = function() {};
352
- mtor.prototype = ModuleClass.constructor.prototype;
388
+ mtor.prototype = Module_alloc.prototype;
353
389
 
354
390
  function module_constructor() {}
355
391
  module_constructor.prototype = new mtor();
@@ -357,24 +393,26 @@
357
393
  var module = new module_constructor();
358
394
  var module_prototype = {};
359
395
 
360
- setup_module_or_class_object(module, module_constructor, ModuleClass, module_prototype);
396
+ setup_module_or_class_object(module, module_constructor, Module, module_prototype);
361
397
 
362
398
  return module;
363
399
  }
364
400
 
365
- /**
366
- Return the singleton class for the passed object.
367
-
368
- If the given object alredy has a singleton class, then it will be stored on
369
- the object as the `$$meta` property. If this exists, then it is simply
370
- returned back.
371
-
372
- Otherwise, a new singleton object for the class or object is created, set on
373
- the object at `$$meta` for future use, and then returned.
374
-
375
- @param [RubyObject] object the ruby object
376
- @returns [RubyClass] the singleton class for object
377
- */
401
+ // Make `boot_module_object` available to the JS-API
402
+ Opal.boot_module_object = boot_module_object;
403
+
404
+ // Return the singleton class for the passed object.
405
+ //
406
+ // If the given object alredy has a singleton class, then it will be stored on
407
+ // the object as the `$$meta` property. If this exists, then it is simply
408
+ // returned back.
409
+ //
410
+ // Otherwise, a new singleton object for the class or object is created, set on
411
+ // the object at `$$meta` for future use, and then returned.
412
+ //
413
+ // @param [RubyObject] object the ruby object
414
+ // @return [RubyClass] the singleton class for object
415
+ //
378
416
  Opal.get_singleton_class = function(object) {
379
417
  if (object.$$meta) {
380
418
  return object.$$meta;
@@ -387,15 +425,14 @@
387
425
  return build_object_singleton_class(object);
388
426
  };
389
427
 
390
- /**
391
- Build the singleton class for an existing class.
392
-
393
- NOTE: Actually in MRI a class' singleton class inherits from its
394
- superclass' singleton class which in turn inherits from Class.
395
-
396
- @param [RubyClass] klass
397
- @returns [RubyClass]
398
- */
428
+ // Build the singleton class for an existing class.
429
+ //
430
+ // NOTE: Actually in MRI a class' singleton class inherits from its
431
+ // superclass' singleton class which in turn inherits from Class.
432
+ //
433
+ // @param [RubyClass] klass
434
+ // @return [RubyClass]
435
+ //
399
436
  function build_class_singleton_class(klass) {
400
437
  var meta = new Opal.Class.$$alloc();
401
438
 
@@ -410,18 +447,17 @@
410
447
  return klass.$$meta = meta;
411
448
  }
412
449
 
413
- /**
414
- Build the singleton class for a Ruby (non class) Object.
415
-
416
- @param [RubyObject] object
417
- @returns [RubyClass]
418
- */
450
+ // Build the singleton class for a Ruby (non class) Object.
451
+ //
452
+ // @param [RubyObject] object
453
+ // @return [RubyClass]
454
+ //
419
455
  function build_object_singleton_class(object) {
420
456
  var orig_class = object.$$class,
421
457
  class_id = "#<Class:#<" + orig_class.$$name + ":" + orig_class.$$id + ">>";
422
458
 
423
- var Singleton = function () {};
424
- var meta = Opal.boot(orig_class, Singleton);
459
+ var Singleton = function() {};
460
+ var meta = Opal.boot_class(orig_class, Singleton);
425
461
  meta.$$name = class_id;
426
462
 
427
463
  meta.$$proto = object;
@@ -434,109 +470,85 @@
434
470
  return object.$$meta = meta;
435
471
  }
436
472
 
437
- /**
438
- The actual inclusion of a module into a class.
439
-
440
- ## Class `$$parent` and `iclass`
441
-
442
- To handle `super` calls, every class has a `$$parent`. This parent is
443
- used to resolve the next class for a super call. A normal class would
444
- have this point to its superclass. However, if a class includes a module
445
- then this would need to take into account the module. The module would
446
- also have to then point its `$$parent` to the actual superclass. We
447
- cannot modify modules like this, because it might be included in more
448
- then one class. To fix this, we actually insert an `iclass` as the class'
449
- `$$parent` which can then point to the superclass. The `iclass` acts as
450
- a proxy to the actual module, so the `super` chain can then search it for
451
- the required method.
452
-
453
- @param [RubyModule] module the module to include
454
- @param [RubyClass] klass the target class to include module into
455
- @returns [null]
456
- */
457
- function bridge() {
458
- var target, donator, from, name, body, ancestors, id, methods, method, i, ancestor, bridged, length;
459
-
460
- if (arguments.length === 4) {
461
- target = arguments[0];
462
- from = arguments[1];
463
- name = arguments[2];
464
- body = arguments[3];
465
- ancestors = target.$$bridge.$ancestors();
466
-
467
- // order important here, we have to check for method presence in
468
- // ancestors from the bridged class to the last ancestor
469
- for (i = 0, length = ancestors.length; i < length; i++) {
470
- ancestor = ancestors[i];
471
-
472
- if ($hasOwn.call(ancestor.$$proto, name) &&
473
- ancestor.$$proto[name] &&
474
- !ancestor.$$proto[name].$$donated &&
475
- !ancestor.$$proto[name].$$stub &&
476
- ancestor !== from) {
477
- break;
478
- }
473
+ // Bridges a single method.
474
+ function bridge_method(target, from, name, body) {
475
+ var ancestors, i, ancestor, length;
479
476
 
480
- if (ancestor === from) {
481
- target.prototype[name] = body
482
- break;
483
- }
477
+ ancestors = target.$$bridge.$ancestors();
478
+
479
+ // order important here, we have to check for method presence in
480
+ // ancestors from the bridged class to the last ancestor
481
+ for (i = 0, length = ancestors.length; i < length; i++) {
482
+ ancestor = ancestors[i];
483
+
484
+ if ($hasOwn.call(ancestor.$$proto, name) &&
485
+ ancestor.$$proto[name] &&
486
+ !ancestor.$$proto[name].$$donated &&
487
+ !ancestor.$$proto[name].$$stub &&
488
+ ancestor !== from) {
489
+ break;
490
+ }
491
+
492
+ if (ancestor === from) {
493
+ target.prototype[name] = body
494
+ break;
484
495
  }
485
496
  }
486
- else {
487
- target = arguments[0];
488
- donator = arguments[1];
489
497
 
490
- if (typeof(target) === "function") {
491
- id = donator.$__id__();
492
- methods = donator.$instance_methods();
498
+ }
493
499
 
494
- for (i = methods.length - 1; i >= 0; i--) {
495
- method = '$' + methods[i];
500
+ // Bridges from *donator* to a *target*.
501
+ function _bridge(target, donator) {
502
+ var id, methods, method, i, bridged;
496
503
 
497
- bridge(target, donator, method, donator.$$proto[method]);
498
- }
504
+ if (typeof(target) === "function") {
505
+ id = donator.$__id__();
506
+ methods = donator.$instance_methods();
499
507
 
500
- if (!bridges[id]) {
501
- bridges[id] = [];
502
- }
508
+ for (i = methods.length - 1; i >= 0; i--) {
509
+ method = '$' + methods[i];
503
510
 
504
- bridges[id].push(target);
511
+ bridge_method(target, donator, method, donator.$$proto[method]);
505
512
  }
506
- else {
507
- bridged = bridges[target.$__id__()];
508
513
 
509
- if (bridged) {
510
- for (i = bridged.length - 1; i >= 0; i--) {
511
- bridge(bridged[i], donator);
512
- }
514
+ if (!bridges[id]) {
515
+ bridges[id] = [];
516
+ }
513
517
 
514
- bridges[donator.$__id__()] = bridged.slice();
518
+ bridges[id].push(target);
519
+ }
520
+ else {
521
+ bridged = bridges[target.$__id__()];
522
+
523
+ if (bridged) {
524
+ for (i = bridged.length - 1; i >= 0; i--) {
525
+ _bridge(bridged[i], donator);
515
526
  }
527
+
528
+ bridges[donator.$__id__()] = bridged.slice();
516
529
  }
517
530
  }
518
531
  }
519
532
 
520
- /**
521
- The actual inclusion of a module into a class.
522
-
523
- ## Class `$$parent` and `iclass`
524
-
525
- To handle `super` calls, every class has a `$$parent`. This parent is
526
- used to resolve the next class for a super call. A normal class would
527
- have this point to its superclass. However, if a class includes a module
528
- then this would need to take into account the module. The module would
529
- also have to then point its `$$parent` to the actual superclass. We
530
- cannot modify modules like this, because it might be included in more
531
- then one class. To fix this, we actually insert an `iclass` as the class'
532
- `$$parent` which can then point to the superclass. The `iclass` acts as
533
- a proxy to the actual module, so the `super` chain can then search it for
534
- the required method.
535
-
536
- @param [RubyModule] module the module to include
537
- @param [RubyClass] klass the target class to include module into
538
- @returns [null]
539
- */
533
+ // The actual inclusion of a module into a class.
534
+ //
535
+ // ## Class `$$parent` and `iclass`
536
+ //
537
+ // To handle `super` calls, every class has a `$$parent`. This parent is
538
+ // used to resolve the next class for a super call. A normal class would
539
+ // have this point to its superclass. However, if a class includes a module
540
+ // then this would need to take into account the module. The module would
541
+ // also have to then point its `$$parent` to the actual superclass. We
542
+ // cannot modify modules like this, because it might be included in more
543
+ // then one class. To fix this, we actually insert an `iclass` as the class'
544
+ // `$$parent` which can then point to the superclass. The `iclass` acts as
545
+ // a proxy to the actual module, so the `super` chain can then search it for
546
+ // the required method.
547
+ //
548
+ // @param [RubyModule] module the module to include
549
+ // @param [RubyClass] klass the target class to include module into
550
+ // @return [null]
551
+ //
540
552
  Opal.append_features = function(module, klass) {
541
553
  var iclass, donator, prototype, methods, id, i;
542
554
 
@@ -549,7 +561,7 @@
549
561
 
550
562
  klass.$$inc.push(module);
551
563
  module.$$dep.push(klass);
552
- bridge(klass, module);
564
+ _bridge(klass, module);
553
565
 
554
566
  // iclass
555
567
  iclass = {
@@ -588,14 +600,13 @@
588
600
  // Boot a base class (makes instances).
589
601
  function boot_class_alloc(id, constructor, superklass) {
590
602
  if (superklass) {
591
- var ctor = function() {};
592
- ctor.prototype = superklass.$$proto || superklass.prototype;
593
-
594
- if (id) {
595
- ctor.displayName = id;
596
- }
603
+ var alloc_proxy = function() {};
604
+ alloc_proxy.prototype = superklass.$$proto || superklass.prototype;
605
+ constructor.prototype = new alloc_proxy();
606
+ }
597
607
 
598
- constructor.prototype = new ctor();
608
+ if (id) {
609
+ constructor.displayName = id+'_alloc';
599
610
  }
600
611
 
601
612
  constructor.prototype.constructor = constructor;
@@ -603,15 +614,14 @@
603
614
  return constructor;
604
615
  }
605
616
 
606
- /*
607
- * Builds the class object for core classes:
608
- * - make the class object have a singleton class
609
- * - make the singleton class inherit from its parent singleton class
610
- *
611
- * @param id [String] the name of the class
612
- * @param alloc [Function] the constructor for the core class instances
613
- * @param superclass [Class alloc] the constructor of the superclass
614
- */
617
+ // Builds the class object for core classes:
618
+ // - make the class object have a singleton class
619
+ // - make the singleton class inherit from its parent singleton class
620
+ //
621
+ // @param id [String] the name of the class
622
+ // @param alloc [Function] the constructor for the core class instances
623
+ // @param superclass [Class alloc] the constructor of the superclass
624
+ //
615
625
  function boot_core_class_object(id, alloc, superclass) {
616
626
  var superclass_constructor = function() {};
617
627
  superclass_constructor.prototype = superclass.prototype;
@@ -626,8 +636,9 @@
626
636
 
627
637
  setup_module_or_class_object(klass, singleton_class, superclass, alloc.prototype);
628
638
 
629
- klass.$$alloc = alloc;
630
- klass.$$name = id;
639
+ klass.$$alloc = alloc;
640
+ klass.$$name = id;
641
+ klass.displayName = id;
631
642
 
632
643
  // Give all instances a ref to their class
633
644
  alloc.prototype.$$class = klass;
@@ -638,24 +649,23 @@
638
649
  return klass;
639
650
  }
640
651
 
641
- /*
642
- * For performance, some core Ruby classes are toll-free bridged to their
643
- * native JavaScript counterparts (e.g. a Ruby Array is a JavaScript Array).
644
- *
645
- * This method is used to setup a native constructor (e.g. Array), to have
646
- * its prototype act like a normal Ruby class. Firstly, a new Ruby class is
647
- * created using the native constructor so that its prototype is set as the
648
- * target for th new class. Note: all bridged classes are set to inherit
649
- * from Object.
650
- *
651
- * Example:
652
- *
653
- * Opal.bridge(self, Function);
654
- *
655
- * @param [Class] klass the Ruby class to bridge
656
- * @param [Function] constructor native JavaScript constructor to use
657
- * @return [Class] returns the passed Ruby class
658
- */
652
+ // For performance, some core Ruby classes are toll-free bridged to their
653
+ // native JavaScript counterparts (e.g. a Ruby Array is a JavaScript Array).
654
+ //
655
+ // This method is used to setup a native constructor (e.g. Array), to have
656
+ // its prototype act like a normal Ruby class. Firstly, a new Ruby class is
657
+ // created using the native constructor so that its prototype is set as the
658
+ // target for th new class. Note: all bridged classes are set to inherit
659
+ // from Object.
660
+ //
661
+ // Example:
662
+ //
663
+ // Opal.bridge(self, Function);
664
+ //
665
+ // @param [Class] klass the Ruby class to bridge
666
+ // @param [Function] constructor native JavaScript constructor to use
667
+ // @return [Class] returns the passed Ruby class
668
+ //
659
669
  Opal.bridge = function(klass, constructor) {
660
670
  if (constructor.$$bridge) {
661
671
  throw Opal.ArgumentError.$new("already bridged");
@@ -671,11 +681,11 @@
671
681
  // order important here, we have to bridge from the last ancestor to the
672
682
  // bridged class
673
683
  for (var i = ancestors.length - 1; i >= 0; i--) {
674
- bridge(constructor, ancestors[i]);
684
+ _bridge(constructor, ancestors[i]);
675
685
  }
676
686
 
677
- for (var name in BasicObject.prototype) {
678
- var method = BasicObject.prototype[method];
687
+ for (var name in BasicObject_alloc.prototype) {
688
+ var method = BasicObject_alloc.prototype[method];
679
689
 
680
690
  if (method && method.$$stub && !(name in constructor.prototype)) {
681
691
  constructor.prototype[name] = method;
@@ -686,9 +696,8 @@
686
696
  }
687
697
 
688
698
 
689
- /*
690
- * constant assign
691
- */
699
+ // constant assign
700
+ //
692
701
  Opal.casgn = function(base_module, name, value) {
693
702
  function update(klass, name) {
694
703
  klass.$$name = name;
@@ -705,8 +714,8 @@
705
714
  var scope = base_module.$$scope;
706
715
 
707
716
  if (value.$$is_class || value.$$is_module) {
708
- // only checking ObjectClass prevents setting a const on an anonymous class that has a superclass that's not Object
709
- if (value.$$is_class || value.$$base_module === ObjectClass) {
717
+ // only checking _Object prevents setting a const on an anonymous class that has a superclass that's not Object
718
+ if (value.$$is_class || value.$$base_module === _Object) {
710
719
  value.$$base_module = base_module;
711
720
  }
712
721
 
@@ -719,9 +728,7 @@
719
728
  return scope[name] = value;
720
729
  };
721
730
 
722
- /*
723
- * constant decl
724
- */
731
+ // constant decl
725
732
  Opal.cdecl = function(base_scope, name, value) {
726
733
  if ((value.$$is_class || value.$$is_module) && value.$$orig_scope == null) {
727
734
  value.$$name = name;
@@ -733,10 +740,9 @@
733
740
  return base_scope[name] = value;
734
741
  };
735
742
 
736
- /*
737
- * When a source module is included into the target module, we must also copy
738
- * its constants to the target.
739
- */
743
+ // When a source module is included into the target module, we must also copy
744
+ // its constants to the target.
745
+ //
740
746
  function donate_constants(source_mod, target_mod) {
741
747
  var source_constants = source_mod.$$scope.constants,
742
748
  target_scope = target_mod.$$scope,
@@ -748,9 +754,7 @@
748
754
  }
749
755
  };
750
756
 
751
- /*
752
- * Donate methods for a module.
753
- */
757
+ // Donate methods for a module.
754
758
  function donate(module, jsid) {
755
759
  var included_in = module.$$dep,
756
760
  body = module.$$proto[jsid],
@@ -802,34 +806,33 @@
802
806
  }
803
807
  };
804
808
 
805
- /*
806
- * Methods stubs are used to facilitate method_missing in opal. A stub is a
807
- * placeholder function which just calls `method_missing` on the receiver.
808
- * If no method with the given name is actually defined on an object, then it
809
- * is obvious to say that the stub will be called instead, and then in turn
810
- * method_missing will be called.
811
- *
812
- * When a file in ruby gets compiled to javascript, it includes a call to
813
- * this function which adds stubs for every method name in the compiled file.
814
- * It should then be safe to assume that method_missing will work for any
815
- * method call detected.
816
- *
817
- * Method stubs are added to the BasicObject prototype, which every other
818
- * ruby object inherits, so all objects should handle method missing. A stub
819
- * is only added if the given property name (method name) is not already
820
- * defined.
821
- *
822
- * Note: all ruby methods have a `$` prefix in javascript, so all stubs will
823
- * have this prefix as well (to make this method more performant).
824
- *
825
- * Opal.add_stubs(["$foo", "$bar", "$baz="]);
826
- *
827
- * All stub functions will have a private `$$stub` property set to true so
828
- * that other internal methods can detect if a method is just a stub or not.
829
- * `Kernel#respond_to?` uses this property to detect a methods presence.
830
- *
831
- * @param [Array] stubs an array of method stubs to add
832
- */
809
+ // Methods stubs are used to facilitate method_missing in opal. A stub is a
810
+ // placeholder function which just calls `method_missing` on the receiver.
811
+ // If no method with the given name is actually defined on an object, then it
812
+ // is obvious to say that the stub will be called instead, and then in turn
813
+ // method_missing will be called.
814
+ //
815
+ // When a file in ruby gets compiled to javascript, it includes a call to
816
+ // this function which adds stubs for every method name in the compiled file.
817
+ // It should then be safe to assume that method_missing will work for any
818
+ // method call detected.
819
+ //
820
+ // Method stubs are added to the BasicObject prototype, which every other
821
+ // ruby object inherits, so all objects should handle method missing. A stub
822
+ // is only added if the given property name (method name) is not already
823
+ // defined.
824
+ //
825
+ // Note: all ruby methods have a `$` prefix in javascript, so all stubs will
826
+ // have this prefix as well (to make this method more performant).
827
+ //
828
+ // Opal.add_stubs(["$foo", "$bar", "$baz="]);
829
+ //
830
+ // All stub functions will have a private `$$stub` property set to true so
831
+ // that other internal methods can detect if a method is just a stub or not.
832
+ // `Kernel#respond_to?` uses this property to detect a methods presence.
833
+ //
834
+ // @param [Array] stubs an array of method stubs to add
835
+ //
833
836
  Opal.add_stubs = function(stubs) {
834
837
  var subscriber, subscribers = Opal.stub_subscribers,
835
838
  i, ilength = stubs.length,
@@ -850,30 +853,27 @@
850
853
  }
851
854
  };
852
855
 
853
- /*
854
- * Keep a list of prototypes that want method_missing stubs to be added.
855
- *
856
- * @default [Prototype List] BasicObject.prototype
857
- */
858
- Opal.stub_subscribers = [BasicObject.prototype];
859
-
860
- /*
861
- * Add a method_missing stub function to the given prototype for the
862
- * given name.
863
- *
864
- * @param [Prototype] prototype the target prototype
865
- * @param [String] stub stub name to add (e.g. "$foo")
866
- */
867
- function add_stub_for(prototype, stub) {
856
+ // Keep a list of prototypes that want method_missing stubs to be added.
857
+ //
858
+ // @default [Prototype List] BasicObject_alloc.prototype
859
+ //
860
+ Opal.stub_subscribers = [BasicObject_alloc.prototype];
861
+
862
+ // Add a method_missing stub function to the given prototype for the
863
+ // given name.
864
+ //
865
+ // @param [Prototype] prototype the target prototype
866
+ // @param [String] stub stub name to add (e.g. "$foo")
867
+ //
868
+ Opal.add_stub_for = function(prototype, stub) {
868
869
  var method_missing_stub = stub_for(stub);
869
870
  prototype[stub] = method_missing_stub;
870
871
  }
871
872
 
872
- /*
873
- * Generate the method_missing stub for a given method name.
874
- *
875
- * @param [String] method_name The js-name of the method to stub (e.g. "$foo")
876
- */
873
+ // Generate the method_missing stub for a given method name.
874
+ //
875
+ // @param [String] method_name The js-name of the method to stub (e.g. "$foo")
876
+ //
877
877
  function stub_for(method_name) {
878
878
  function method_missing_stub() {
879
879
  // Copy any given block onto the method_missing dispatcher
@@ -891,9 +891,6 @@
891
891
  return method_missing_stub;
892
892
  }
893
893
 
894
- // Expose for other parts of Opal to use
895
- Opal.add_stub_for = add_stub_for;
896
-
897
894
  // Arity count error dispatcher
898
895
  Opal.ac = function(actual, expected, object, meth) {
899
896
  var inspect = '';
@@ -908,6 +905,23 @@
908
905
  throw Opal.ArgumentError.$new('[' + inspect + '] wrong number of arguments(' + actual + ' for ' + expected + ')');
909
906
  };
910
907
 
908
+ // The Array of ancestors for a given module/class
909
+ Opal.ancestors = function(module_or_class) {
910
+ var parent = module_or_class,
911
+ result = [];
912
+
913
+ while (parent) {
914
+ result.push(parent);
915
+ for (var i=0; i < parent.$$inc.length; i++) {
916
+ result = result.concat(Opal.ancestors(parent.$$inc[i]));
917
+ }
918
+
919
+ parent = parent.$$is_class ? parent.$$super : null;
920
+ }
921
+
922
+ return result;
923
+ }
924
+
911
925
  // Super dispatcher
912
926
  Opal.find_super_dispatcher = function(obj, jsid, current_func, iter, defs) {
913
927
  var dispatcher;
@@ -980,14 +994,13 @@
980
994
  return klass.$$proto;
981
995
  };
982
996
 
983
- /*
984
- * Used to return as an expression. Sometimes, we can't simply return from
985
- * a javascript function as if we were a method, as the return is used as
986
- * an expression, or even inside a block which must "return" to the outer
987
- * method. This helper simply throws an error which is then caught by the
988
- * method. This approach is expensive, so it is only used when absolutely
989
- * needed.
990
- */
997
+ // Used to return as an expression. Sometimes, we can't simply return from
998
+ // a javascript function as if we were a method, as the return is used as
999
+ // an expression, or even inside a block which must "return" to the outer
1000
+ // method. This helper simply throws an error which is then caught by the
1001
+ // method. This approach is expensive, so it is only used when absolutely
1002
+ // needed.
1003
+ //
991
1004
  Opal.ret = function(val) {
992
1005
  Opal.returner.$v = val;
993
1006
  throw Opal.returner;
@@ -1071,13 +1084,28 @@
1071
1084
  return false;
1072
1085
  };
1073
1086
 
1074
- // Helper to convert the given object to an array
1087
+ // Helpers for implementing multiple assignment
1088
+ // Our code for extracting the values and assigning them only works if the
1089
+ // return value is a JS array
1090
+ // So if we get an Array subclass, extract the wrapped JS array from it
1091
+
1075
1092
  Opal.to_ary = function(value) {
1093
+ // Used for: a, b = something (no splat)
1076
1094
  if (value.$$is_array) {
1077
- return value;
1095
+ return (value.constructor === Array) ? value : value.literal;
1078
1096
  }
1079
- else if (value.$to_ary && !value.$to_ary.$$stub) {
1080
- return value.$to_ary();
1097
+ else if (value['$respond_to?']('to_ary', true)) {
1098
+ var ary = value.$to_ary();
1099
+ if (ary === nil) {
1100
+ return [value];
1101
+ }
1102
+ else if (ary.$$is_array) {
1103
+ return (ary.constructor === Array) ? ary : ary.literal;
1104
+ }
1105
+ else {
1106
+ throw Opal.TypeError.$new("Can't convert " + value.$$class +
1107
+ " to Array (" + value.$$class + "#to_ary gives " + ary.$$class + ")");
1108
+ }
1081
1109
  }
1082
1110
  else {
1083
1111
  return [value];
@@ -1085,34 +1113,45 @@
1085
1113
  };
1086
1114
 
1087
1115
  Opal.to_a = function(value) {
1088
- if (value == null || value === nil) {
1089
- return [];
1116
+ // Used for: a, b = *something (with splat)
1117
+ if (value.$$is_array) {
1118
+ // A splatted array must be copied
1119
+ return (value.constructor === Array) ? value.slice() : value.literal.slice();
1090
1120
  }
1091
- else if (value.$to_a && !value.$to_a.$$stub) {
1092
- return value.$to_a();
1121
+ else if (value['$respond_to?']('to_a', true)) {
1122
+ var ary = value.$to_a();
1123
+ if (ary === nil) {
1124
+ return [value];
1125
+ }
1126
+ else if (ary.$$is_array) {
1127
+ return (ary.constructor === Array) ? ary : ary.literal;
1128
+ }
1129
+ else {
1130
+ throw Opal.TypeError.$new("Can't convert " + value.$$class +
1131
+ " to Array (" + value.$$class + "#to_a gives " + ary.$$class + ")");
1132
+ }
1093
1133
  }
1094
1134
  else {
1095
1135
  return [value];
1096
1136
  }
1097
1137
  };
1098
1138
 
1099
- /**
1100
- Used to get a list of rest keyword arguments. Method takes the given
1101
- keyword args, i.e. the hash literal passed to the method containing all
1102
- keyword arguemnts passed to method, as well as the used args which are
1103
- the names of required and optional arguments defined. This method then
1104
- just returns all key/value pairs which have not been used, in a new
1105
- hash literal.
1106
-
1107
- @param given_args [Hash] all kwargs given to method
1108
- @param used_args [Object<String: true>] all keys used as named kwargs
1109
- @return [Hash]
1110
- */
1139
+ // Used to get a list of rest keyword arguments. Method takes the given
1140
+ // keyword args, i.e. the hash literal passed to the method containing all
1141
+ // keyword arguemnts passed to method, as well as the used args which are
1142
+ // the names of required and optional arguments defined. This method then
1143
+ // just returns all key/value pairs which have not been used, in a new
1144
+ // hash literal.
1145
+ //
1146
+ // @param given_args [Hash] all kwargs given to method
1147
+ // @param used_args [Object<String: true>] all keys used as named kwargs
1148
+ // @return [Hash]
1149
+ //
1111
1150
  Opal.kwrestargs = function(given_args, used_args) {
1112
1151
  var keys = [],
1113
1152
  map = {},
1114
1153
  key = null,
1115
- given_map = given_args.smap;
1154
+ given_map = given_args.$$smap;
1116
1155
 
1117
1156
  for (key in given_map) {
1118
1157
  if (!used_args[key]) {
@@ -1124,21 +1163,20 @@
1124
1163
  return Opal.hash2(keys, map);
1125
1164
  };
1126
1165
 
1127
- /*
1128
- * Call a ruby method on a ruby object with some arguments:
1129
- *
1130
- * var my_array = [1, 2, 3, 4]
1131
- * Opal.send(my_array, 'length') # => 4
1132
- * Opal.send(my_array, 'reverse!') # => [4, 3, 2, 1]
1133
- *
1134
- * A missing method will be forwarded to the object via
1135
- * method_missing.
1136
- *
1137
- * The result of either call with be returned.
1138
- *
1139
- * @param [Object] recv the ruby object
1140
- * @param [String] mid ruby method to call
1141
- */
1166
+ // Call a ruby method on a ruby object with some arguments:
1167
+ //
1168
+ // var my_array = [1, 2, 3, 4]
1169
+ // Opal.send(my_array, 'length') # => 4
1170
+ // Opal.send(my_array, 'reverse!') # => [4, 3, 2, 1]
1171
+ //
1172
+ // A missing method will be forwarded to the object via
1173
+ // method_missing.
1174
+ //
1175
+ // The result of either call with be returned.
1176
+ //
1177
+ // @param [Object] recv the ruby object
1178
+ // @param [String] mid ruby method to call
1179
+ //
1142
1180
  Opal.send = function(recv, mid) {
1143
1181
  var args = $slice.call(arguments, 2),
1144
1182
  func = recv['$' + mid];
@@ -1162,43 +1200,42 @@
1162
1200
  return recv.$method_missing.apply(recv, [mid].concat(args));
1163
1201
  };
1164
1202
 
1165
- /**
1166
- Used to define methods on an object. This is a helper method, used by the
1167
- compiled source to define methods on special case objects when the compiler
1168
- can not determine the destination object, or the object is a Module
1169
- instance. This can get called by `Module#define_method` as well.
1170
-
1171
- ## Modules
1172
-
1173
- Any method defined on a module will come through this runtime helper.
1174
- The method is added to the module body, and the owner of the method is
1175
- set to be the module itself. This is used later when choosing which
1176
- method should show on a class if more than 1 included modules define
1177
- the same method. Finally, if the module is in `module_function` mode,
1178
- then the method is also defined onto the module itself.
1179
-
1180
- ## Classes
1181
-
1182
- This helper will only be called for classes when a method is being
1183
- defined indirectly; either through `Module#define_method`, or by a
1184
- literal `def` method inside an `instance_eval` or `class_eval` body. In
1185
- either case, the method is simply added to the class' prototype. A special
1186
- exception exists for `BasicObject` and `Object`. These two classes are
1187
- special because they are used in toll-free bridged classes. In each of
1188
- these two cases, extra work is required to define the methods on toll-free
1189
- bridged class' prototypes as well.
1190
-
1191
- ## Objects
1192
-
1193
- If a simple ruby object is the object, then the method is simply just
1194
- defined on the object as a singleton method. This would be the case when
1195
- a method is defined inside an `instance_eval` block.
1196
-
1197
- @param [RubyObject or Class] obj the actual obj to define method for
1198
- @param [String] jsid the javascript friendly method name (e.g. '$foo')
1199
- @param [Function] body the literal javascript function used as method
1200
- @returns [null]
1201
- */
1203
+ // Used to define methods on an object. This is a helper method, used by the
1204
+ // compiled source to define methods on special case objects when the compiler
1205
+ // can not determine the destination object, or the object is a Module
1206
+ // instance. This can get called by `Module#define_method` as well.
1207
+ //
1208
+ // ## Modules
1209
+ //
1210
+ // Any method defined on a module will come through this runtime helper.
1211
+ // The method is added to the module body, and the owner of the method is
1212
+ // set to be the module itself. This is used later when choosing which
1213
+ // method should show on a class if more than 1 included modules define
1214
+ // the same method. Finally, if the module is in `module_function` mode,
1215
+ // then the method is also defined onto the module itself.
1216
+ //
1217
+ // ## Classes
1218
+ //
1219
+ // This helper will only be called for classes when a method is being
1220
+ // defined indirectly; either through `Module#define_method`, or by a
1221
+ // literal `def` method inside an `instance_eval` or `class_eval` body. In
1222
+ // either case, the method is simply added to the class' prototype. A special
1223
+ // exception exists for `BasicObject` and `Object`. These two classes are
1224
+ // special because they are used in toll-free bridged classes. In each of
1225
+ // these two cases, extra work is required to define the methods on toll-free
1226
+ // bridged class' prototypes as well.
1227
+ //
1228
+ // ## Objects
1229
+ //
1230
+ // If a simple ruby object is the object, then the method is simply just
1231
+ // defined on the object as a singleton method. This would be the case when
1232
+ // a method is defined inside an `instance_eval` block.
1233
+ //
1234
+ // @param [RubyObject or Class] obj the actual obj to define method for
1235
+ // @param [String] jsid the javascript friendly method name (e.g. '$foo')
1236
+ // @param [Function] body the literal javascript function used as method
1237
+ // @return [null]
1238
+ //
1202
1239
  Opal.defn = function(obj, jsid, body) {
1203
1240
  obj.$$proto[jsid] = body;
1204
1241
 
@@ -1215,7 +1252,7 @@
1215
1252
 
1216
1253
  if (bridged) {
1217
1254
  for (var i = bridged.length - 1; i >= 0; i--) {
1218
- bridge(bridged[i], obj, jsid, body);
1255
+ bridge_method(bridged[i], obj, jsid, body);
1219
1256
  }
1220
1257
  }
1221
1258
  }
@@ -1232,9 +1269,8 @@
1232
1269
  return nil;
1233
1270
  };
1234
1271
 
1235
- /*
1236
- * Define a singleton method on the given object.
1237
- */
1272
+
1273
+ // Define a singleton method on the given object.
1238
1274
  Opal.defs = function(obj, jsid, body) {
1239
1275
  Opal.defn(Opal.get_singleton_class(obj), jsid, body)
1240
1276
  };
@@ -1249,9 +1285,7 @@
1249
1285
  }
1250
1286
  };
1251
1287
 
1252
- /*
1253
- * Called from #remove_method.
1254
- */
1288
+ // Called from #remove_method.
1255
1289
  Opal.rdef = function(obj, jsid) {
1256
1290
  // TODO: remove from bridges as well
1257
1291
 
@@ -1273,9 +1307,7 @@
1273
1307
  }
1274
1308
  };
1275
1309
 
1276
- /*
1277
- * Called from #undef_method.
1278
- */
1310
+ // Called from #undef_method.
1279
1311
  Opal.udef = function(obj, jsid) {
1280
1312
  if (!obj.$$proto[jsid] || obj.$$proto[jsid].$$stub) {
1281
1313
  throw Opal.NameError.$new("method '" + jsid.substr(1) + "' not defined in " + obj.$name());
@@ -1295,33 +1327,11 @@
1295
1327
  }
1296
1328
  };
1297
1329
 
1298
- // This black magic is required to avoid clashes of internal special fields,
1299
- // like $$donated.
1300
- function wrap(body) {
1301
- function alias() {
1302
- body.$$p = alias.$$p;
1303
- body.$$s = alias.$$s;
1304
-
1305
- try {
1306
- return body.apply(this, $slice.call(arguments));
1307
- }
1308
- finally {
1309
- alias.$$s = null;
1310
- alias.$$p = null;
1311
- }
1312
- }
1313
-
1314
- alias.$$target = body;
1315
- alias.$$arity = body.length;
1316
-
1317
- return alias;
1318
- }
1319
-
1320
1330
  Opal.alias = function(obj, name, old) {
1321
1331
  var id = '$' + name,
1322
1332
  old_id = '$' + old,
1323
1333
  body = obj.$$proto['$' + old];
1324
-
1334
+
1325
1335
  // instance_eval is being run on a class/module, so that need to alias class methods
1326
1336
  if (obj.$$eval) {
1327
1337
  return Opal.alias(Opal.get_singleton_class(obj), name, old);
@@ -1340,7 +1350,7 @@
1340
1350
  }
1341
1351
  }
1342
1352
 
1343
- Opal.defn(obj, id, wrap(body));
1353
+ Opal.defn(obj, id, body);
1344
1354
 
1345
1355
  return obj;
1346
1356
  };
@@ -1353,26 +1363,26 @@
1353
1363
  throw Opal.NameError.$new("undefined native method `" + native_name + "' for class `" + obj.$name() + "'")
1354
1364
  }
1355
1365
 
1356
- Opal.defn(obj, id, wrap(body));
1366
+ Opal.defn(obj, id, body);
1357
1367
 
1358
1368
  return obj;
1359
1369
  };
1360
1370
 
1361
- Opal.hash_init = function (hash) {
1362
- hash.map = {};
1363
- hash.smap = {};
1364
- hash.keys = [];
1371
+ Opal.hash_init = function(hash) {
1372
+ hash.$$map = {};
1373
+ hash.$$smap = {};
1374
+ hash.$$keys = [];
1365
1375
  };
1366
1376
 
1367
- Opal.hash_clone = function (from_hash, to_hash) {
1377
+ Opal.hash_clone = function(from_hash, to_hash) {
1368
1378
  to_hash.none = from_hash.none;
1369
1379
  to_hash.proc = from_hash.proc;
1370
1380
 
1371
- for (var i = 0, keys = from_hash.keys, length = keys.length, key, value; i < length; i++) {
1372
- key = from_hash.keys[i];
1381
+ for (var i = 0, keys = from_hash.$$keys, length = keys.length, key, value; i < length; i++) {
1382
+ key = from_hash.$$keys[i];
1373
1383
 
1374
1384
  if (key.$$is_string) {
1375
- value = from_hash.smap[key];
1385
+ value = from_hash.$$smap[key];
1376
1386
  } else {
1377
1387
  value = key.value;
1378
1388
  key = key.key;
@@ -1382,25 +1392,25 @@
1382
1392
  }
1383
1393
  };
1384
1394
 
1385
- Opal.hash_put = function (hash, key, value) {
1395
+ Opal.hash_put = function(hash, key, value) {
1386
1396
  if (key.$$is_string) {
1387
- if (!hash.smap.hasOwnProperty(key)) {
1388
- hash.keys.push(key);
1397
+ if (!hash.$$smap.hasOwnProperty(key)) {
1398
+ hash.$$keys.push(key);
1389
1399
  }
1390
- hash.smap[key] = value;
1400
+ hash.$$smap[key] = value;
1391
1401
  return;
1392
1402
  }
1393
1403
 
1394
1404
  var key_hash = key.$hash(), bucket, last_bucket;
1395
1405
 
1396
- if (!hash.map.hasOwnProperty(key_hash)) {
1406
+ if (!hash.$$map.hasOwnProperty(key_hash)) {
1397
1407
  bucket = {key: key, key_hash: key_hash, value: value};
1398
- hash.keys.push(bucket);
1399
- hash.map[key_hash] = bucket;
1408
+ hash.$$keys.push(bucket);
1409
+ hash.$$map[key_hash] = bucket;
1400
1410
  return;
1401
1411
  }
1402
1412
 
1403
- bucket = hash.map[key_hash];
1413
+ bucket = hash.$$map[key_hash];
1404
1414
 
1405
1415
  while (bucket) {
1406
1416
  if (key === bucket.key || key['$eql?'](bucket.key)) {
@@ -1414,23 +1424,23 @@
1414
1424
 
1415
1425
  if (last_bucket) {
1416
1426
  bucket = {key: key, key_hash: key_hash, value: value};
1417
- hash.keys.push(bucket);
1427
+ hash.$$keys.push(bucket);
1418
1428
  last_bucket.next = bucket;
1419
1429
  }
1420
1430
  };
1421
1431
 
1422
- Opal.hash_get = function (hash, key) {
1432
+ Opal.hash_get = function(hash, key) {
1423
1433
  if (key.$$is_string) {
1424
- if (hash.smap.hasOwnProperty(key)) {
1425
- return hash.smap[key];
1434
+ if (hash.$$smap.hasOwnProperty(key)) {
1435
+ return hash.$$smap[key];
1426
1436
  }
1427
1437
  return;
1428
1438
  }
1429
1439
 
1430
1440
  var key_hash = key.$hash(), bucket;
1431
1441
 
1432
- if (hash.map.hasOwnProperty(key_hash)) {
1433
- bucket = hash.map[key_hash];
1442
+ if (hash.$$map.hasOwnProperty(key_hash)) {
1443
+ bucket = hash.$$map[key_hash];
1434
1444
 
1435
1445
  while (bucket) {
1436
1446
  if (key === bucket.key || key['$eql?'](bucket.key)) {
@@ -1441,11 +1451,11 @@
1441
1451
  }
1442
1452
  };
1443
1453
 
1444
- Opal.hash_delete = function (hash, key) {
1445
- var i, keys = hash.keys, length = keys.length, value;
1454
+ Opal.hash_delete = function(hash, key) {
1455
+ var i, keys = hash.$$keys, length = keys.length, value;
1446
1456
 
1447
1457
  if (key.$$is_string) {
1448
- if (!hash.smap.hasOwnProperty(key)) {
1458
+ if (!hash.$$smap.hasOwnProperty(key)) {
1449
1459
  return;
1450
1460
  }
1451
1461
 
@@ -1456,18 +1466,18 @@
1456
1466
  }
1457
1467
  }
1458
1468
 
1459
- value = hash.smap[key];
1460
- delete hash.smap[key];
1469
+ value = hash.$$smap[key];
1470
+ delete hash.$$smap[key];
1461
1471
  return value;
1462
1472
  }
1463
1473
 
1464
1474
  var key_hash = key.$hash();
1465
1475
 
1466
- if (!hash.map.hasOwnProperty(key_hash)) {
1476
+ if (!hash.$$map.hasOwnProperty(key_hash)) {
1467
1477
  return;
1468
1478
  }
1469
1479
 
1470
- var bucket = hash.map[key_hash], last_bucket;
1480
+ var bucket = hash.$$map[key_hash], last_bucket;
1471
1481
 
1472
1482
  while (bucket) {
1473
1483
  if (key === bucket.key || key['$eql?'](bucket.key)) {
@@ -1487,10 +1497,10 @@
1487
1497
  delete last_bucket.next;
1488
1498
  }
1489
1499
  else if (bucket.next) {
1490
- hash.map[key_hash] = bucket.next;
1500
+ hash.$$map[key_hash] = bucket.next;
1491
1501
  }
1492
1502
  else {
1493
- delete hash.map[key_hash];
1503
+ delete hash.$$map[key_hash];
1494
1504
  }
1495
1505
 
1496
1506
  return value;
@@ -1500,24 +1510,24 @@
1500
1510
  }
1501
1511
  };
1502
1512
 
1503
- Opal.hash_rehash = function (hash) {
1504
- for (var i = 0, length = hash.keys.length, key_hash, bucket, last_bucket; i < length; i++) {
1513
+ Opal.hash_rehash = function(hash) {
1514
+ for (var i = 0, length = hash.$$keys.length, key_hash, bucket, last_bucket; i < length; i++) {
1505
1515
 
1506
- if (hash.keys[i].$$is_string) {
1516
+ if (hash.$$keys[i].$$is_string) {
1507
1517
  continue;
1508
1518
  }
1509
1519
 
1510
- key_hash = hash.keys[i].key.$hash();
1520
+ key_hash = hash.$$keys[i].key.$hash();
1511
1521
 
1512
- if (key_hash === hash.keys[i].key_hash) {
1522
+ if (key_hash === hash.$$keys[i].key_hash) {
1513
1523
  continue;
1514
1524
  }
1515
1525
 
1516
- bucket = hash.map[hash.keys[i].key_hash];
1526
+ bucket = hash.$$map[hash.$$keys[i].key_hash];
1517
1527
  last_bucket = undefined;
1518
1528
 
1519
1529
  while (bucket) {
1520
- if (bucket === hash.keys[i]) {
1530
+ if (bucket === hash.$$keys[i]) {
1521
1531
  if (last_bucket && bucket.next) {
1522
1532
  last_bucket.next = bucket.next;
1523
1533
  }
@@ -1525,10 +1535,10 @@
1525
1535
  delete last_bucket.next;
1526
1536
  }
1527
1537
  else if (bucket.next) {
1528
- hash.map[hash.keys[i].key_hash] = bucket.next;
1538
+ hash.$$map[hash.$$keys[i].key_hash] = bucket.next;
1529
1539
  }
1530
1540
  else {
1531
- delete hash.map[hash.keys[i].key_hash];
1541
+ delete hash.$$map[hash.$$keys[i].key_hash];
1532
1542
  }
1533
1543
  break;
1534
1544
  }
@@ -1536,18 +1546,18 @@
1536
1546
  bucket = bucket.next;
1537
1547
  }
1538
1548
 
1539
- hash.keys[i].key_hash = key_hash;
1549
+ hash.$$keys[i].key_hash = key_hash;
1540
1550
 
1541
- if (!hash.map.hasOwnProperty(key_hash)) {
1542
- hash.map[key_hash] = hash.keys[i];
1551
+ if (!hash.$$map.hasOwnProperty(key_hash)) {
1552
+ hash.$$map[key_hash] = hash.$$keys[i];
1543
1553
  continue;
1544
1554
  }
1545
1555
 
1546
- bucket = hash.map[key_hash];
1556
+ bucket = hash.$$map[key_hash];
1547
1557
  last_bucket = undefined;
1548
1558
 
1549
1559
  while (bucket) {
1550
- if (bucket === hash.keys[i]) {
1560
+ if (bucket === hash.$$keys[i]) {
1551
1561
  last_bucket = undefined;
1552
1562
  break;
1553
1563
  }
@@ -1556,7 +1566,7 @@
1556
1566
  }
1557
1567
 
1558
1568
  if (last_bucket) {
1559
- last_bucket.next = hash.keys[i];
1569
+ last_bucket.next = hash.$$keys[i];
1560
1570
  }
1561
1571
  }
1562
1572
  };
@@ -1616,26 +1626,24 @@
1616
1626
  return hash;
1617
1627
  };
1618
1628
 
1619
- /*
1620
- * hash2 is a faster creator for hashes that just use symbols and
1621
- * strings as keys. The map and keys array can be constructed at
1622
- * compile time, so they are just added here by the constructor
1623
- * function
1624
- */
1629
+ // hash2 is a faster creator for hashes that just use symbols and
1630
+ // strings as keys. The map and keys array can be constructed at
1631
+ // compile time, so they are just added here by the constructor
1632
+ // function
1633
+ //
1625
1634
  Opal.hash2 = function(keys, smap) {
1626
1635
  var hash = new Opal.Hash.$$alloc();
1627
1636
 
1628
- hash.map = {};
1629
- hash.keys = keys;
1630
- hash.smap = smap;
1637
+ hash.$$map = {};
1638
+ hash.$$keys = keys;
1639
+ hash.$$smap = smap;
1631
1640
 
1632
1641
  return hash;
1633
1642
  };
1634
1643
 
1635
- /*
1636
- * Create a new range instance with first and last values, and whether the
1637
- * range excludes the last value.
1638
- */
1644
+ // Create a new range instance with first and last values, and whether the
1645
+ // range excludes the last value.
1646
+ //
1639
1647
  Opal.range = function(first, last, exc) {
1640
1648
  var range = new Opal.Range.$$alloc();
1641
1649
  range.begin = first;
@@ -1646,17 +1654,19 @@
1646
1654
  };
1647
1655
 
1648
1656
  Opal.ivar = function(name) {
1649
- if (name === "constructor" ||
1650
- name === "__proto__" ||
1651
- name === "__parent__" ||
1657
+ if (
1658
+ // properties
1659
+ name === "constructor" ||
1660
+ name === "displayName" ||
1661
+ name === "__count__" ||
1652
1662
  name === "__noSuchMethod__" ||
1653
- name === "__count__")
1654
- {
1655
- return name + "$";
1656
- }
1663
+ name === "__parent__" ||
1664
+ name === "__proto__" ||
1657
1665
 
1658
- if (name === "hasOwnProperty" ||
1659
- name === "valueOf")
1666
+ // methods
1667
+ name === "hasOwnProperty" ||
1668
+ name === "valueOf"
1669
+ )
1660
1670
  {
1661
1671
  return name + "$";
1662
1672
  }
@@ -1666,169 +1676,133 @@
1666
1676
 
1667
1677
  // Require system
1668
1678
  // --------------
1669
- (function(Opal) {
1670
- var loaded_features = ['corelib/runtime'],
1671
- require_table = {'corelib/runtime': true},
1672
- modules = {};
1673
1679
 
1674
- var current_dir = '.';
1680
+ Opal.modules = {};
1681
+ Opal.loaded_features = ['corelib/runtime'];
1682
+ Opal.current_dir = '.'
1683
+ Opal.require_table = {'corelib/runtime': true};
1675
1684
 
1676
- function normalize(path) {
1677
- var parts, part, new_parts = [], SEPARATOR = '/';
1685
+ function normalize(path) {
1686
+ var parts, part, new_parts = [], SEPARATOR = '/';
1678
1687
 
1679
- if (current_dir !== '.') {
1680
- path = current_dir.replace(/\/*$/, '/') + path;
1681
- }
1682
-
1683
- path = path.replace(/\.(rb|opal|js)$/, '');
1684
- parts = path.split(SEPARATOR);
1688
+ if (Opal.current_dir !== '.') {
1689
+ path = Opal.current_dir.replace(/\/*$/, '/') + path;
1690
+ }
1685
1691
 
1686
- for (var i = 0, ii = parts.length; i < ii; i++) {
1687
- part = parts[i];
1688
- if (part === '') continue;
1689
- (part === '..') ? new_parts.pop() : new_parts.push(part)
1690
- }
1692
+ path = path.replace(/\.(rb|opal|js)$/, '');
1693
+ parts = path.split(SEPARATOR);
1691
1694
 
1692
- return new_parts.join(SEPARATOR);
1695
+ for (var i = 0, ii = parts.length; i < ii; i++) {
1696
+ part = parts[i];
1697
+ if (part === '') continue;
1698
+ (part === '..') ? new_parts.pop() : new_parts.push(part)
1693
1699
  }
1694
1700
 
1695
- function loaded(paths) {
1696
- var i, l, path;
1701
+ return new_parts.join(SEPARATOR);
1702
+ }
1697
1703
 
1698
- for (i = 0, l = paths.length; i < l; i++) {
1699
- path = normalize(paths[i]);
1704
+ Opal.loaded = function(paths) {
1705
+ var i, l, path;
1700
1706
 
1701
- if (require_table[path]) {
1702
- return;
1703
- }
1707
+ for (i = 0, l = paths.length; i < l; i++) {
1708
+ path = normalize(paths[i]);
1704
1709
 
1705
- loaded_features.push(path);
1706
- require_table[path] = true;
1710
+ if (Opal.require_table[path]) {
1711
+ return;
1707
1712
  }
1713
+
1714
+ Opal.loaded_features.push(path);
1715
+ Opal.require_table[path] = true;
1708
1716
  }
1717
+ }
1709
1718
 
1710
- function load(path) {
1711
- path = normalize(path);
1719
+ Opal.load = function(path) {
1720
+ path = normalize(path);
1712
1721
 
1713
- loaded([path]);
1722
+ Opal.loaded([path]);
1714
1723
 
1715
- var module = modules[path];
1724
+ var module = Opal.modules[path];
1716
1725
 
1717
- if (module) {
1718
- module(Opal);
1719
- }
1720
- else {
1721
- var severity = Opal.dynamic_require_severity || 'warning';
1722
- var message = 'cannot load such file -- ' + path;
1726
+ if (module) {
1727
+ module(Opal);
1728
+ }
1729
+ else {
1730
+ var severity = Opal.dynamic_require_severity || 'warning';
1731
+ var message = 'cannot load such file -- ' + path;
1723
1732
 
1724
- if (severity === "error") {
1725
- Opal.LoadError ? Opal.LoadError.$new(message) : function(){throw message}();
1726
- }
1727
- else if (severity === "warning") {
1728
- console.warn('WARNING: LoadError: ' + message);
1729
- }
1733
+ if (severity === "error") {
1734
+ Opal.LoadError ? Opal.LoadError.$new(message) : function(){throw message}();
1735
+ }
1736
+ else if (severity === "warning") {
1737
+ console.warn('WARNING: LoadError: ' + message);
1730
1738
  }
1731
-
1732
- return true;
1733
1739
  }
1734
1740
 
1735
- function require(path) {
1736
- path = normalize(path);
1741
+ return true;
1742
+ }
1737
1743
 
1738
- if (require_table[path]) {
1739
- return false;
1740
- }
1744
+ Opal.require = function(path) {
1745
+ path = normalize(path);
1741
1746
 
1742
- return load(path);
1747
+ if (Opal.require_table[path]) {
1748
+ return false;
1743
1749
  }
1744
1750
 
1745
- Opal.modules = modules;
1746
- Opal.loaded_features = loaded_features;
1747
- Opal.loaded = loaded;
1748
-
1749
- Opal.load = load;
1750
- Opal.require = require;
1751
- })(Opal);
1751
+ return Opal.load(path);
1752
+ }
1752
1753
 
1753
1754
  // Initialization
1754
1755
  // --------------
1755
1756
 
1756
- // The actual class for BasicObject
1757
- var BasicObjectClass;
1758
-
1759
- // The actual Object class
1760
- var ObjectClass;
1761
-
1762
- // The actual Module class
1763
- var ModuleClass;
1764
-
1765
- // The actual Class class
1766
- var ClassClass;
1767
-
1768
- // Constructor for instances of BasicObject
1769
- function BasicObject(){}
1770
-
1771
- // Constructor for instances of Object
1772
- function Object(){}
1773
-
1774
- // Constructor for instances of Class
1775
- function Class(){}
1776
-
1777
- // Constructor for instances of Module
1778
- function Module(){}
1779
-
1780
- // Constructor for instances of NilClass (nil)
1781
- function NilClass(){}
1782
-
1783
1757
  // Constructors for *instances* of core objects
1784
- boot_class_alloc('BasicObject', BasicObject);
1785
- boot_class_alloc('Object', Object, BasicObject);
1786
- boot_class_alloc('Module', Module, Object);
1787
- boot_class_alloc('Class', Class, Module);
1758
+ boot_class_alloc('BasicObject', BasicObject_alloc);
1759
+ boot_class_alloc('Object', Object_alloc, BasicObject_alloc);
1760
+ boot_class_alloc('Module', Module_alloc, Object_alloc);
1761
+ boot_class_alloc('Class', Class_alloc, Module_alloc);
1788
1762
 
1789
1763
  // Constructors for *classes* of core objects
1790
- BasicObjectClass = boot_core_class_object('BasicObject', BasicObject, Class);
1791
- ObjectClass = boot_core_class_object('Object', Object, BasicObjectClass.constructor);
1792
- ModuleClass = boot_core_class_object('Module', Module, ObjectClass.constructor);
1793
- ClassClass = boot_core_class_object('Class', Class, ModuleClass.constructor);
1764
+ BasicObject = boot_core_class_object('BasicObject', BasicObject_alloc, Class_alloc);
1765
+ _Object = boot_core_class_object('Object', Object_alloc, BasicObject.constructor);
1766
+ Module = boot_core_class_object('Module', Module_alloc, _Object.constructor);
1767
+ Class = boot_core_class_object('Class', Class_alloc, Module.constructor);
1794
1768
 
1795
1769
  // Fix booted classes to use their metaclass
1796
- BasicObjectClass.$$class = ClassClass;
1797
- ObjectClass.$$class = ClassClass;
1798
- ModuleClass.$$class = ClassClass;
1799
- ClassClass.$$class = ClassClass;
1770
+ BasicObject.$$class = Class;
1771
+ _Object.$$class = Class;
1772
+ Module.$$class = Class;
1773
+ Class.$$class = Class;
1800
1774
 
1801
1775
  // Fix superclasses of booted classes
1802
- BasicObjectClass.$$super = null;
1803
- ObjectClass.$$super = BasicObjectClass;
1804
- ModuleClass.$$super = ObjectClass;
1805
- ClassClass.$$super = ModuleClass;
1806
-
1807
- BasicObjectClass.$$parent = null;
1808
- ObjectClass.$$parent = BasicObjectClass;
1809
- ModuleClass.$$parent = ObjectClass;
1810
- ClassClass.$$parent = ModuleClass;
1811
-
1812
- Opal.base = ObjectClass;
1813
- BasicObjectClass.$$scope = ObjectClass.$$scope = Opal;
1814
- BasicObjectClass.$$orig_scope = ObjectClass.$$orig_scope = Opal;
1815
-
1816
- ModuleClass.$$scope = ObjectClass.$$scope;
1817
- ModuleClass.$$orig_scope = ObjectClass.$$orig_scope;
1818
- ClassClass.$$scope = ObjectClass.$$scope;
1819
- ClassClass.$$orig_scope = ObjectClass.$$orig_scope;
1820
-
1821
- ObjectClass.$$proto.toString = function() {
1776
+ BasicObject.$$super = null;
1777
+ _Object.$$super = BasicObject;
1778
+ Module.$$super = _Object;
1779
+ Class.$$super = Module;
1780
+
1781
+ BasicObject.$$parent = null;
1782
+ _Object.$$parent = BasicObject;
1783
+ Module.$$parent = _Object;
1784
+ Class.$$parent = Module;
1785
+
1786
+ Opal.base = _Object;
1787
+ BasicObject.$$scope = _Object.$$scope = Opal;
1788
+ BasicObject.$$orig_scope = _Object.$$orig_scope = Opal;
1789
+
1790
+ Module.$$scope = _Object.$$scope;
1791
+ Module.$$orig_scope = _Object.$$orig_scope;
1792
+ Class.$$scope = _Object.$$scope;
1793
+ Class.$$orig_scope = _Object.$$orig_scope;
1794
+
1795
+ _Object.$$proto.toString = function() {
1822
1796
  return this.$to_s();
1823
1797
  };
1824
1798
 
1825
- ObjectClass.$$proto.$require = Opal.require;
1799
+ _Object.$$proto.$require = Opal.require;
1826
1800
 
1827
- Opal.top = new ObjectClass.$$alloc();
1801
+ Opal.top = new _Object.$$alloc();
1828
1802
 
1829
1803
  // Nil
1830
- Opal.klass(ObjectClass, ObjectClass, 'NilClass', NilClass);
1831
- var nil = Opal.nil = new NilClass();
1804
+ Opal.klass(_Object, _Object, 'NilClass', NilClass_alloc);
1805
+ nil = Opal.nil = new NilClass_alloc();
1832
1806
  nil.$$id = nil_id;
1833
1807
  nil.call = nil.apply = function() { throw Opal.LocalJumpError.$new('no block given'); };
1834
1808
 
@@ -1842,6 +1816,7 @@ if (typeof(global) !== 'undefined') {
1842
1816
  global.Opal = this.Opal;
1843
1817
  Opal.global = global;
1844
1818
  }
1819
+
1845
1820
  if (typeof(window) !== 'undefined') {
1846
1821
  window.Opal = this.Opal;
1847
1822
  Opal.global = window;