opal 0.3.20 → 0.3.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. data/.gitignore +2 -7
  2. data/.rspec +2 -0
  3. data/.travis.yml +11 -0
  4. data/Gemfile +8 -2
  5. data/LICENSE +2 -3
  6. data/README.md +106 -239
  7. data/Rakefile +58 -16
  8. data/bin/opal +1 -0
  9. data/core/array.rb +180 -160
  10. data/core/basic_object.rb +8 -4
  11. data/core/boolean.rb +6 -6
  12. data/core/class.rb +9 -15
  13. data/core/dir.rb +89 -0
  14. data/core/enumerable.rb +83 -86
  15. data/core/error.rb +9 -4
  16. data/core/file.rb +85 -0
  17. data/core/hash.rb +67 -67
  18. data/core/kernel.rb +38 -42
  19. data/core/module.rb +57 -54
  20. data/core/numeric.rb +41 -41
  21. data/core/proc.rb +1 -5
  22. data/core/range.rb +11 -11
  23. data/core/regexp.rb +27 -22
  24. data/core/runtime.js +152 -221
  25. data/core/string.rb +86 -73
  26. data/core/time.rb +22 -18
  27. data/docs/post.html +9 -0
  28. data/docs/pre.html +32 -0
  29. data/lib/opal.rb +43 -3
  30. data/lib/opal/builder.rb +9 -26
  31. data/lib/opal/grammar.rb +1 -1
  32. data/lib/opal/grammar.y +1 -1
  33. data/lib/opal/lexer.rb +21 -15
  34. data/lib/opal/parser.rb +100 -111
  35. data/lib/opal/rake_task.rb +66 -0
  36. data/lib/opal/scope.rb +13 -5
  37. data/lib/opal/version.rb +1 -1
  38. data/opal.gemspec +2 -0
  39. data/spec/browser_spec.rb +28 -0
  40. data/spec/builder/lib_name_for_spec.rb +1 -6
  41. data/spec/grammar/alias_spec.rb +1 -1
  42. data/spec/grammar/and_spec.rb +1 -1
  43. data/spec/grammar/array_spec.rb +1 -1
  44. data/spec/grammar/attrasgn_spec.rb +1 -1
  45. data/spec/grammar/begin_spec.rb +1 -1
  46. data/spec/grammar/block_spec.rb +1 -1
  47. data/spec/grammar/break_spec.rb +1 -1
  48. data/spec/grammar/call_spec.rb +1 -1
  49. data/spec/grammar/class_spec.rb +1 -1
  50. data/spec/grammar/const_spec.rb +1 -1
  51. data/spec/grammar/cvar_spec.rb +1 -1
  52. data/spec/grammar/def_spec.rb +1 -1
  53. data/spec/grammar/false_spec.rb +1 -1
  54. data/spec/grammar/file_spec.rb +1 -1
  55. data/spec/grammar/gvar_spec.rb +1 -1
  56. data/spec/grammar/hash_spec.rb +1 -1
  57. data/spec/grammar/iasgn_spec.rb +1 -1
  58. data/spec/grammar/if_spec.rb +1 -1
  59. data/spec/grammar/iter_spec.rb +1 -1
  60. data/spec/grammar/ivar_spec.rb +1 -1
  61. data/spec/grammar/lambda_spec.rb +1 -1
  62. data/spec/grammar/lasgn_spec.rb +1 -1
  63. data/spec/grammar/line_spec.rb +1 -1
  64. data/spec/grammar/lvar_spec.rb +1 -1
  65. data/spec/grammar/masgn_spec.rb +1 -1
  66. data/spec/grammar/module_spec.rb +1 -1
  67. data/spec/grammar/nil_spec.rb +1 -1
  68. data/spec/grammar/not_spec.rb +1 -1
  69. data/spec/grammar/op_asgn1_spec.rb +1 -1
  70. data/spec/grammar/op_asgn2_spec.rb +1 -1
  71. data/spec/grammar/or_spec.rb +1 -1
  72. data/spec/grammar/return_spec.rb +1 -1
  73. data/spec/grammar/sclass_spec.rb +1 -1
  74. data/spec/grammar/self_spec.rb +1 -1
  75. data/spec/grammar/str_spec.rb +1 -1
  76. data/spec/grammar/super_spec.rb +1 -1
  77. data/spec/grammar/true_spec.rb +1 -1
  78. data/spec/grammar/undef_spec.rb +1 -1
  79. data/spec/grammar/unless_spec.rb +1 -1
  80. data/spec/grammar/while_spec.rb +1 -1
  81. data/spec/grammar/xstr_spec.rb +1 -1
  82. data/spec/grammar/yield_spec.rb +1 -1
  83. data/spec/spec_helper.rb +6 -1
  84. data/test/core/array/minus_spec.rb +13 -0
  85. data/test/core/enumerable/drop_while_spec.rb +0 -5
  86. data/test/core/range/case_compare_spec.rb +0 -1
  87. data/test/index.html +1 -1
  88. data/test/index.min.html +12 -0
  89. data/test/language/alias_spec.rb +0 -4
  90. data/test/language/fixtures/next.rb +62 -0
  91. data/test/language/metaclass_spec.rb +4 -4
  92. data/test/language/next_spec.rb +0 -63
  93. data/test/language/send_spec.rb +0 -5
  94. data/test/language/singleton_class_spec.rb +4 -0
  95. data/test/opal/array/subclassing_spec.rb +1 -1
  96. data/test/opal/class/bridge_class_spec.rb +2 -2
  97. data/test/opal/runtime/class_hierarchy_spec.rb +1 -2
  98. data/test/opal/runtime/method_missing_spec.rb +17 -0
  99. data/test/spec_helper.rb +4 -1
  100. metadata +32 -28
  101. data/docs/CNAME +0 -1
  102. data/docs/Rakefile +0 -55
  103. data/docs/css/styles.css +0 -50
  104. data/docs/css/syntax.css +0 -63
  105. data/docs/layout/post.html +0 -3
  106. data/docs/layout/pre.html +0 -11
  107. data/examples/dependencies/.gitignore +0 -1
  108. data/examples/dependencies/Gemfile +0 -6
  109. data/examples/dependencies/README.md +0 -41
  110. data/examples/dependencies/Rakefile +0 -10
  111. data/examples/dependencies/app.rb +0 -19
  112. data/examples/dependencies/build/.gitkeep +0 -0
  113. data/examples/dependencies/index.html +0 -13
  114. data/examples/hello_world/.gitignore +0 -1
  115. data/examples/hello_world/Gemfile +0 -3
  116. data/examples/hello_world/README.md +0 -27
  117. data/examples/hello_world/Rakefile +0 -23
  118. data/examples/hello_world/app.rb +0 -7
  119. data/examples/hello_world/index.html +0 -12
  120. data/lib/opal/builder_task.rb +0 -91
  121. data/spec/builder/build_order_spec.rb +0 -20
  122. data/test/opal/runtime/_methods_spec.rb +0 -48
@@ -14,17 +14,13 @@ class Proc < `Function`
14
14
  end
15
15
 
16
16
  def call(*args)
17
- `this.apply(this._s, #{args})`
17
+ `#{self}.apply(null, [#{self}._s].concat(#{args}))`
18
18
  end
19
19
 
20
20
  def to_proc
21
21
  self
22
22
  end
23
23
 
24
- def to_s
25
- "#<Proc:0x0000000>"
26
- end
27
-
28
24
  def lambda?
29
25
  `!!this.$lambda`
30
26
  end
@@ -2,7 +2,7 @@ class Range
2
2
  include Enumerable
3
3
 
4
4
  %x{
5
- Range.prototype._isRange = true;
5
+ Range_prototype._isRange = true;
6
6
 
7
7
  Opal.range = function(beg, end, exc) {
8
8
  var range = new Range;
@@ -23,20 +23,20 @@ class Range
23
23
  def ==(other)
24
24
  return false unless Range === other
25
25
 
26
- exclude_end? == other.exclude_end? && `this.begin` == other.begin && `this.end` == other.end
26
+ exclude_end? == other.exclude_end? && `#{self}.begin` == other.begin && `#{self}.end` == other.end
27
27
  end
28
28
 
29
29
  # FIXME: currently hardcoded to assume range holds numerics
30
30
  def ===(obj)
31
- `return obj >= this.begin && obj <= this.end`
31
+ `return obj >= #{self}.begin && (#{self}.exclude ? obj < #{self}.end : obj <= #{self}.end)`
32
32
  end
33
33
 
34
34
  def begin
35
- `this.begin`
35
+ `#{self}.begin`
36
36
  end
37
37
 
38
38
  def cover?(value)
39
- `this.begin` <= value && value <= (exclude_end? ? `this.end` - 1 : `this.end`)
39
+ `#{self}.begin` <= value && value <= (exclude_end? ? `#{self}.end` - 1 : `#{self}.end`)
40
40
  end
41
41
 
42
42
  def each
@@ -56,22 +56,22 @@ class Range
56
56
  end
57
57
 
58
58
  def end
59
- `this.end`
59
+ `#{self}.end`
60
60
  end
61
61
 
62
62
  def eql?(other)
63
63
  return false unless Range === other
64
64
 
65
- exclude_end? == other.exclude_end? && `this.begin`.eql?(other.begin) && `this.end`.eql?(other.end)
65
+ exclude_end? == other.exclude_end? && `#{self}.begin`.eql?(other.begin) && `#{self}.end`.eql?(other.end)
66
66
  end
67
67
 
68
68
  def exclude_end?
69
- `this.exclude`
69
+ `#{self}.exclude`
70
70
  end
71
71
 
72
72
  # FIXME: currently hardcoded to assume range holds numerics
73
73
  def include?(val)
74
- `return obj >= this.begin && obj <= this.end`
74
+ `return obj >= #{self}.begin && obj <= #{self}.end`
75
75
  end
76
76
 
77
77
  alias max end
@@ -87,10 +87,10 @@ class Range
87
87
  end
88
88
 
89
89
  def to_s
90
- `this.begin + (this.exclude ? '...' : '..') + this.end`
90
+ `#{self}.begin + (#{self}.exclude ? '...' : '..') + #{self}.end`
91
91
  end
92
92
 
93
93
  def inspect
94
- `this.begin + (this.exclude ? '...' : '..') + this.end`
94
+ `#{self}.begin + (#{self}.exclude ? '...' : '..') + #{self}.end`
95
95
  end
96
96
  end
@@ -8,21 +8,21 @@ class Regexp < `RegExp`
8
8
  end
9
9
 
10
10
  def ==(other)
11
- `other.constructor == RegExp && this.toString() === other.toString()`
11
+ `other.constructor == RegExp && #{self}.toString() === other.toString()`
12
12
  end
13
13
 
14
14
  def ===(obj)
15
- `this.test(obj)`
15
+ `#{self}.test(obj)`
16
16
  end
17
17
 
18
18
  def =~(string)
19
19
  %x{
20
- var result = this.exec(string);
20
+ var result = #{self}.exec(string);
21
21
 
22
22
  if (result) {
23
- result.$to_s = match_to_s;
24
- result.$inspect = match_inspect;
25
- result._real = result._klass = #{ MatchData };
23
+ var matchdata = #{MatchData};
24
+ result.$k = matchdata;
25
+ result.$m = matchdata.$m_tbl;
26
26
 
27
27
  #{$~ = `result`};
28
28
  }
@@ -37,17 +37,17 @@ class Regexp < `RegExp`
37
37
  alias eql? ==
38
38
 
39
39
  def inspect
40
- `this.toString()`
40
+ `#{self}.toString()`
41
41
  end
42
42
 
43
43
  def match(pattern)
44
44
  %x{
45
- var result = this.exec(pattern);
45
+ var result = #{self}.exec(pattern);
46
46
 
47
47
  if (result) {
48
- result.$to_s = match_to_s;
49
- result.$inspect = match_inspect;
50
- result._real = result._klass = #{ MatchData };
48
+ var matchdata = #{MatchData};
49
+ result.$k = matchdata;
50
+ result.$m = matchdata.$m_tbl;
51
51
 
52
52
  return #{$~ = `result`};
53
53
  }
@@ -58,19 +58,24 @@ class Regexp < `RegExp`
58
58
  end
59
59
 
60
60
  def to_s
61
- `this.source`
61
+ `#{self}.source`
62
62
  end
63
-
64
- %x{
65
- function match_inspect() {
66
- return "<#MatchData " + this[0].$inspect() + ">";
67
- }
68
-
69
- function match_to_s() {
70
- return this[0];
71
- }
72
- }
73
63
  end
74
64
 
75
65
  class MatchData
66
+ def [](idx)
67
+ `#{self}[idx]`
68
+ end
69
+
70
+ def inspect
71
+ "#<MatchData #{self[0].inspect}>"
72
+ end
73
+
74
+ def to_a
75
+ `#{self}.slice()`
76
+ end
77
+
78
+ def to_s
79
+ self[0]
80
+ end
76
81
  end
@@ -28,6 +28,12 @@ Opal.alloc = TopScope;
28
28
  // This is a useful reference to global object inside ruby files
29
29
  Opal.global = this;
30
30
 
31
+ // Root method table (BasicObject inherits from this)
32
+ function RootMethodTableConstructor() {}
33
+
34
+ // The prototype (actual table) for root
35
+ var RootMethodTable = RootMethodTableConstructor.prototype;
36
+
31
37
  // Minify common function calls
32
38
  var __hasOwn = Opal.hasOwnProperty;
33
39
  var __slice = Opal.slice = Array.prototype.slice;
@@ -41,6 +47,34 @@ Opal.cvars = {};
41
47
  // Globals table
42
48
  Opal.gvars = {};
43
49
 
50
+ var method_missing_mid = '';
51
+
52
+ function method_missing_handler(self) {
53
+ var args = __slice.call(arguments, 1);
54
+ return self.$m.method_missing.apply(null, [self, method_missing_mid].concat(args));
55
+ }
56
+
57
+ Opal.mm = function(mid) {
58
+ method_missing_mid = mid;
59
+ return method_missing_handler;
60
+ };
61
+
62
+ Opal.send = function(recv, mid) {
63
+ var args = __slice.call(arguments, 2);
64
+ return (recv.$m[mid] || Opal.mm(mid)).apply(null, [recv].concat(args));
65
+ };
66
+
67
+ // define singleton method
68
+ Opal.defs = function(obj, name, method) {
69
+ var singleton;
70
+
71
+ if (!(singleton = obj._singleton)) {
72
+ singleton = Opal.send(obj, 'singleton_class');
73
+ }
74
+
75
+ singleton.$m_tbl[name] = method;
76
+ };
77
+
44
78
  // Runtime method used to either define a new class, or re-open an old
45
79
  // class. The base may be an object (rather than a class), which is
46
80
  // always the case when defining classes in the top level as the top
@@ -76,7 +110,7 @@ Opal.gvars = {};
76
110
  Opal.klass = function(base, superklass, id, constructor) {
77
111
  var klass;
78
112
  if (base._isObject) {
79
- base = base._real;
113
+ base = base.$k;
80
114
  }
81
115
 
82
116
  if (superklass === null) {
@@ -87,15 +121,14 @@ Opal.klass = function(base, superklass, id, constructor) {
87
121
  klass = base._scope[id];
88
122
  }
89
123
  else {
90
- if (!superklass._methods) {
124
+ if (!superklass.$m_tbl) {
91
125
  var bridged = superklass;
92
126
  superklass = Object;
93
- klass = bridge_class(bridged);
94
- }
95
- else {
96
- klass = boot_class(superklass, constructor);
127
+ constructor = bridged;
97
128
  }
98
129
 
130
+ klass = boot_class(superklass, constructor, bridged);
131
+
99
132
  klass._name = (base === Object ? id : base._name + '::' + id);
100
133
 
101
134
  var const_alloc = function() {};
@@ -105,8 +138,8 @@ Opal.klass = function(base, superklass, id, constructor) {
105
138
 
106
139
  base[id] = base._scope[id] = klass;
107
140
 
108
- if (superklass.$inherited) {
109
- superklass.$inherited(klass);
141
+ if (superklass.$m.inherited) {
142
+ superklass.$m.inherited(superklass, klass);
110
143
  }
111
144
  }
112
145
 
@@ -117,14 +150,14 @@ Opal.klass = function(base, superklass, id, constructor) {
117
150
  Opal.module = function(base, id, constructor) {
118
151
  var klass;
119
152
  if (base._isObject) {
120
- base = base._real;
153
+ base = base.$k;
121
154
  }
122
155
 
123
156
  if (__hasOwn.call(base._scope, id)) {
124
157
  klass = base._scope[id];
125
158
  }
126
159
  else {
127
- klass = boot_module(constructor, id);
160
+ klass = boot_module(constructor);
128
161
  klass._name = (base === Object ? id : base._name + '::' + id);
129
162
 
130
163
  klass._isModule = true;
@@ -141,21 +174,11 @@ Opal.module = function(base, id, constructor) {
141
174
  return klass;
142
175
  }
143
176
 
144
- // Convert a ruby method name into a javascript identifier
145
- var mid_to_jsid = function(mid) {
146
- return method_names[mid] ||
147
- ('$' + mid.replace('!', '$b').replace('?', '$p').replace('=', '$e'));
148
- };
149
-
150
177
  // Utility function to raise a "no block given" error
151
178
  var no_block_given = function() {
152
179
  throw new Error('no block given');
153
180
  };
154
181
 
155
- // An array of all classes inside Opal. Used for donating methods from
156
- // Module and Class.
157
- var classes = Opal.classes = [];
158
-
159
182
  // Boot a base class (makes instances).
160
183
  var boot_defclass = function(id, constructor, superklass) {
161
184
  if (superklass) {
@@ -165,192 +188,140 @@ var boot_defclass = function(id, constructor, superklass) {
165
188
  constructor.prototype = new ctor();
166
189
  }
167
190
 
168
- var prototype = constructor.prototype;
169
-
170
- prototype.constructor = constructor;
171
- prototype._isObject = true;
172
- prototype._klass = constructor;
173
- prototype._real = constructor;
174
-
175
- constructor._included_in = [];
176
- constructor._isClass = true;
177
- constructor._name = id;
178
- constructor._super = superklass;
179
- constructor._methods = [];
180
- constructor._smethods = [];
181
- constructor._isObject = false;
182
- constructor._subclasses = [];
183
-
184
- constructor._donate = __donate;
185
- constructor._sdonate = __sdonate;
186
-
187
- Opal[id] = constructor;
188
-
189
- classes.push(constructor);
191
+ // method table constructor;
192
+ var m_ctr = function() {};
190
193
 
191
- return constructor;
192
- };
194
+ if (superklass) {
195
+ // not BasicObject
196
+ m_ctr.prototype = new superklass.$m_ctr;
197
+ }
198
+ else {
199
+ // BasicObject
200
+ m_ctr.prototype = RootMethodTable;
201
+ }
193
202
 
194
- // Create generic class with given superclass.
195
- var boot_class = function(superklass, constructor) {
196
- var ctor = function() {};
197
- ctor.prototype = superklass.prototype;
203
+ var m_tbl = m_ctr.prototype;
204
+ m_tbl.constructor = m_ctr;
198
205
 
199
- constructor.prototype = new ctor();
200
206
  var prototype = constructor.prototype;
201
207
 
202
- prototype._klass = constructor;
203
- prototype._real = constructor;
204
208
  prototype.constructor = constructor;
209
+ prototype._isObject = true;
210
+ prototype.$k = constructor;
205
211
 
206
- constructor._included_in = [];
207
- constructor._isClass = true;
208
- constructor._super = superklass;
209
- constructor._methods = [];
210
- constructor._isObject = false;
211
- constructor._klass = Class;
212
- constructor._real = Class;
213
- constructor._donate = __donate
214
- constructor._sdonate = __sdonate;
215
- constructor._subclasses = [];
212
+ // method table of instances
213
+ prototype.$m = m_tbl;
216
214
 
217
- constructor.$eqq$ = module_eqq;
215
+ // constructor._included_in = [];
216
+ // constructor._isClass = true;
217
+ // constructor._name = id;
218
+ // constructor._super = superklass;
219
+ // constructor._methods = [];
220
+ // constructor._smethods = [];
221
+ constructor._isObject = false;
218
222
 
219
- superklass._subclasses.push(constructor);
223
+ // method table for class methods
224
+ // constructor.$m = c_tbl;
225
+ // method table of instances
226
+ constructor.$m_tbl = m_tbl;
227
+ // method table constructor of instances
228
+ constructor.$m_ctr = m_ctr;
220
229
 
221
- var smethods;
230
+ constructor.$s = superklass;
222
231
 
223
- smethods = superklass._smethods.slice();
232
+ constructor._name = id;
224
233
 
225
- constructor._smethods = smethods;
226
- for (var i = 0, length = smethods.length; i < length; i++) {
227
- var m = smethods[i];
228
- constructor[m] = superklass[m];
229
- }
234
+ constructor._donate = __donate;
230
235
 
231
- classes.push(constructor);
236
+ Opal[id] = constructor;
232
237
 
233
238
  return constructor;
234
239
  };
235
240
 
236
- var boot_module = function(constructor, id) {
237
- var ctor = function() {};
238
- ctor.prototype = Module.prototype;
241
+ var boot_defmeta = function(constructor, parent_m_tbl) {
242
+ var m_ctr = function(){};
243
+ m_ctr.prototype = new parent_m_tbl;
239
244
 
240
- constructor.prototype = new ctor();
241
- var prototype = constructor.prototype;
242
-
243
- prototype.constructor = constructor;
245
+ var m_tbl = m_ctr.prototype;
246
+ m_tbl.constructor = m_ctr;
244
247
 
245
- constructor._isModule = true;
246
- constructor._name = id;
247
- constructor._methods = [];
248
- constructor._smethods = [];
249
- constructor._klass = Module;
250
- constructor._donate = __donate;
251
- constructor._sdonate = function(){};
252
-
253
- classes.push(constructor);
254
-
255
- var smethods = constructor._smethods = Module._methods.slice();
256
- for (var i = 0, length = smethods.length; i < length; i++) {
257
- var m = smethods[i];
258
- constructor[m] = Object[m];
259
- }
248
+ constructor.$m = m_tbl;
260
249
 
261
250
  return constructor;
262
251
  };
263
252
 
264
- var bridge_class = function(constructor) {
265
- constructor.prototype._klass = constructor;
266
- constructor.prototype._real = constructor;
267
-
268
- constructor._included_in = [];
269
- constructor._isClass = true;
270
- constructor._super = Object;
271
- constructor._klass = Class;
272
- constructor._methods = [];
273
- constructor._smethods = [];
274
- constructor._isObject = false;
275
- constructor._subclasses = [];
276
-
277
- constructor._donate = function(){};
278
- constructor._sdonate = __sdonate;
253
+ // Create generic class with given superclass.
254
+ var boot_class = function(superklass, constructor, bridged) {
255
+ // method table constructor
256
+ function m_ctr(){};
257
+ m_ctr.prototype = new superklass.$m_tbl.constructor;
258
+
259
+ // method table itself
260
+ var m_tbl = m_ctr.prototype;
261
+ m_tbl.constructor = m_ctr;
279
262
 
280
- constructor.$eqq$ = module_eqq;
263
+ var prototype = constructor.prototype;
281
264
 
282
- var smethods = constructor._smethods = Module._methods.slice();
283
- for (var i = 0, length = smethods.length; i < length; i++) {
284
- var m = smethods[i];
285
- constructor[m] = Object[m];
265
+ if (!bridged) {
266
+ constructor.prototype = new superklass;
267
+ prototype = constructor.prototype;
268
+ prototype.constructor = constructor;
286
269
  }
287
270
 
288
- bridgedClasses.push(constructor);
289
- classes.push(constructor);
271
+ prototype.$k = constructor; // instances need to know their class
272
+ prototype.$m = m_tbl; // all instances get method table
290
273
 
291
- var allocator = function(initializer) {
292
- var result, kls = this, methods = kls._methods, proto = kls.prototype;
274
+ prototype._isObject = true;
293
275
 
294
- if (initializer == null) {
295
- result = new constructor
296
- }
297
- else {
298
- result = new constructor(initializer);
299
- }
276
+ constructor.$m_ctr = m_ctr;
277
+ constructor.$m_tbl = m_tbl;
300
278
 
301
- if (kls === constructor) {
302
- return result;
303
- }
279
+ // FIXME: need c_ctr
280
+ var c_ctr = function(){};
281
+ c_ctr.prototype = new superklass.$m.constructor;
304
282
 
305
- result._klass = kls;
306
- result._real = kls;
283
+ var c_tbl = c_ctr.prototype;
284
+ c_tbl.constructor = c_ctr;
285
+ constructor.$m = c_tbl;
307
286
 
308
- for (var i = 0, length = methods.length; i < length; i++) {
309
- var method = methods[i];
310
- result[method] = proto[method];
311
- }
312
287
 
313
- return result;
314
- };
288
+ constructor.$k = Class;
289
+ constructor.$s = superklass;
315
290
 
316
- var table = Object.prototype, methods = Object._methods;
291
+ constructor._donate = __donate
292
+ // constructor._included_in = [];
293
+ // constructor._isClass = true;
294
+ // constructor._super = superklass;
295
+ // constructor._methods = [];
296
+ constructor._isObject = false;
297
+ // constructor._klass = Class;
298
+
299
+ return constructor;
300
+ };
317
301
 
318
- for (var i = 0, length = methods.length; i < length; i++) {
319
- var m = methods[i];
320
- constructor.prototype[m] = table[m];
321
- }
302
+ var boot_module = function(constructor) {
303
+ // constructor.$m_ctr = m_ctr;
304
+ constructor.$m_tbl = {}; // simple method table for modules
322
305
 
323
- constructor.$allocate = allocator;
306
+ // FIXME: need c_ctr
307
+ var c_ctr = function(){};
308
+ c_ctr.prototype = new Module.$m.constructor;
309
+
310
+ var c_tbl = c_ctr.prototype;
311
+ constructor.$m = c_tbl;
324
312
 
325
- constructor._smethods.push('$allocate');
326
313
 
327
- return constructor;
328
- };
314
+ constructor.$k = Class;
329
315
 
330
- // An IClass is a fake class created when a module is included into a
331
- // class or another module. It is a "copy" of the module that is then
332
- // injected into the hierarchy so it appears internally that the iclass
333
- // is the super of the class instead of the old super class. This is
334
- // actually hidden from the ruby side of things, but allows internal
335
- // features such as super() etc to work. All useful properties from the
336
- // module are copied onto this iclass.
337
- //
338
- // @param [RubyClass] klass the klass which is including the module
339
- // @param [RubyModule] module the module which is being included
340
- // @return [RubyIClass] returns newly created iclass
341
- var define_iclass = function(klass, module) {
342
- var iclass = {
343
- _proto: module._proto,
344
- _super: klass._super,
345
- _isIClass: true,
346
- _klass: module,
347
- _name: module._name,
348
- _methods: module._methods
349
- };
350
-
351
- klass._super = iclass;
352
-
353
- return iclass;
316
+ constructor._donate = __donate
317
+ // constructor._included_in = [];
318
+ // constructor._isClass = true;
319
+ // constructor._super = superklass;
320
+ // constructor._methods = [];
321
+ constructor._isObject = false;
322
+ // constructor._klass = Class;
323
+
324
+ return constructor;
354
325
  };
355
326
 
356
327
  // Initialization
@@ -360,79 +331,39 @@ boot_defclass('BasicObject', BasicObject);
360
331
  boot_defclass('Object', Object, BasicObject);
361
332
  boot_defclass('Class', Class, Object);
362
333
 
363
- Class.prototype = Function.prototype;
364
-
365
- BasicObject._klass = Object._klass = Class._klass = Class;
366
-
367
- Module._donate = function(defined) {
368
- // ...
369
- };
370
-
371
- // Implementation of Module#===
372
- function module_eqq(object) {
373
- if (object == null) {
374
- return false;
375
- }
376
-
377
- var search = object._klass;
334
+ boot_defmeta(BasicObject, Class.$m_tbl.constructor);
335
+ boot_defmeta(Object, BasicObject.$m.constructor);
336
+ boot_defmeta(Class, Object.$m.constructor);
378
337
 
379
- while (search) {
380
- if (search === this) {
381
- return true;
382
- }
383
-
384
- search = search._super;
385
- }
386
-
387
- return false;
388
- }
338
+ BasicObject.$k = Object.$k = Class.$k = Class;
389
339
 
390
340
  // Donator for all 'normal' classes and modules
391
- function __donate(defined, indirect) {
392
- var methods = this._methods, included_in = this.$included_in;
393
-
394
- if (!indirect) {
395
- this._methods = methods.concat(defined);
396
- }
341
+ function __donate(defined) {
342
+ var included_in = this.$included_in, m_tbl = this.$m_tbl;
397
343
 
398
344
  if (included_in) {
399
345
  for (var i = 0, length = included_in.length; i < length; i++) {
400
346
  var includee = included_in[i];
401
- var dest = includee.prototype;
347
+ var dest = includee.$m_tbl;
402
348
 
403
- for (var j = 0, jj = defined.length; j < jj; j++) {
404
- var method = defined[j];
405
- dest[method] = this.prototype[method];
349
+ for (var idx = 0, jj = defined.length; idx < jj; idx++) {
350
+ var method = defined[idx];
351
+ dest[method] = m_tbl[method];
406
352
  }
407
353
 
408
354
  if (includee.$included_in) {
409
- includee._donate(defined, true);
355
+ // includee._donate(defined, true);
410
356
  }
411
357
  }
412
358
 
413
359
  }
414
360
  }
415
361
 
416
- // Donator for singleton (class) methods
417
- function __sdonate(defined) {
418
- var smethods = this._smethods, subclasses = this._subclasses;
419
-
420
- this._smethods = smethods.concat(defined);
421
-
422
- for (var i = 0, length = subclasses.length; i < length; i++) {
423
- var s = subclasses[i];
424
-
425
- for (var j = 0, jj = defined.length; j < jj; j++) {
426
- }
427
- }
428
- }
429
-
430
- var bridgedClasses = Object.$included_in = [];
431
- BasicObject.$included_in = bridgedClasses;
362
+ var bridged_classes = Object.$included_in = [];
363
+ BasicObject.$included_in = bridged_classes;
432
364
 
433
365
  BasicObject._scope = Object._scope = Opal;
434
366
  Opal.Module = Opal.Class;
435
- Opal.Kernel = Object;
436
367
 
437
368
  var class_const_alloc = function(){};
438
369
  var class_const_scope = new TopScope();
@@ -440,7 +371,7 @@ class_const_scope.alloc = class_const_alloc;
440
371
  Class._scope = class_const_scope;
441
372
 
442
373
  Object.prototype.toString = function() {
443
- return this.$to_s();
374
+ return this.$m.to_s(this, 'to_s');
444
375
  };
445
376
 
446
377
  Opal.top = new Object;