opal 0.3.6 → 0.3.9
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +69 -97
- data/bin/opal +2 -2
- data/{lib/core → corelib}/array.rb +85 -56
- data/corelib/boolean.rb +20 -0
- data/corelib/class.rb +58 -0
- data/{lib → corelib}/core.rb +2 -50
- data/corelib/dir.rb +22 -0
- data/{lib/core → corelib}/enumerable.rb +0 -0
- data/corelib/error.rb +19 -0
- data/{lib/core → corelib}/file.rb +7 -9
- data/{lib/core → corelib}/hash.rb +104 -144
- data/{lib/core → corelib}/kernel.rb +38 -44
- data/corelib/load_order +21 -0
- data/{lib/core → corelib}/match_data.rb +0 -0
- data/{lib/core → corelib}/module.rb +12 -8
- data/{lib/core → corelib}/nil_class.rb +2 -2
- data/{lib/core → corelib}/numeric.rb +37 -100
- data/corelib/object.rb +37 -0
- data/{lib/core → corelib}/proc.rb +3 -3
- data/corelib/range.rb +27 -0
- data/{lib/core → corelib}/regexp.rb +1 -1
- data/{lib/core → corelib}/string.rb +16 -107
- data/{lib/core → corelib}/top_self.rb +0 -0
- data/lib/opal.rb +7 -0
- data/lib/opal/browserify.rb +34 -0
- data/{opal_lib → lib}/opal/builder.rb +70 -24
- data/lib/opal/command.rb +52 -0
- data/lib/opal/context.rb +197 -0
- data/{opal_lib/opal/ruby/parser.rb → lib/opal/lexer.rb} +20 -4
- data/{opal_lib/opal/ruby → lib/opal}/nodes.rb +238 -127
- data/lib/opal/parser.rb +4894 -0
- data/{opal_lib/opal/ruby/ruby_parser.y → lib/opal/parser.y} +38 -18
- data/lib/rbp.rb +2 -0
- data/lib/rbp/package.rb +49 -0
- data/runtime/class.js +216 -189
- data/runtime/fs.js +2 -2
- data/runtime/init.js +242 -244
- data/runtime/loader.js +78 -99
- data/runtime/module.js +34 -40
- data/runtime/post.js +2 -2
- data/runtime/pre.js +1 -1
- data/runtime/runtime.js +129 -135
- data/{lib → stdlib}/dev.rb +10 -10
- data/{lib → stdlib}/racc/parser.rb +0 -6
- data/{lib → stdlib}/strscan.rb +4 -4
- metadata +57 -105
- data/lib/core/basic_object.rb +0 -51
- data/lib/core/class.rb +0 -38
- data/lib/core/dir.rb +0 -26
- data/lib/core/error.rb +0 -75
- data/lib/core/false_class.rb +0 -81
- data/lib/core/object.rb +0 -6
- data/lib/core/range.rb +0 -27
- data/lib/core/symbol.rb +0 -42
- data/lib/core/true_class.rb +0 -41
- data/lib/ospec.rb +0 -7
- data/lib/ospec/autorun.rb +0 -8
- data/lib/ospec/dsl.rb +0 -15
- data/lib/ospec/example.rb +0 -11
- data/lib/ospec/example/before_and_after_hooks.rb +0 -56
- data/lib/ospec/example/errors.rb +0 -17
- data/lib/ospec/example/example_group.rb +0 -12
- data/lib/ospec/example/example_group_factory.rb +0 -18
- data/lib/ospec/example/example_group_hierarchy.rb +0 -21
- data/lib/ospec/example/example_group_methods.rb +0 -100
- data/lib/ospec/example/example_group_proxy.rb +0 -15
- data/lib/ospec/example/example_methods.rb +0 -46
- data/lib/ospec/example/example_proxy.rb +0 -18
- data/lib/ospec/expectations.rb +0 -19
- data/lib/ospec/expectations/errors.rb +0 -8
- data/lib/ospec/expectations/fail_with.rb +0 -9
- data/lib/ospec/expectations/handler.rb +0 -33
- data/lib/ospec/helpers/scratch.rb +0 -18
- data/lib/ospec/matchers.rb +0 -24
- data/lib/ospec/matchers/be.rb +0 -1
- data/lib/ospec/matchers/generated_descriptions.rb +0 -20
- data/lib/ospec/matchers/operator_matcher.rb +0 -54
- data/lib/ospec/matchers/raise_error.rb +0 -38
- data/lib/ospec/runner.rb +0 -90
- data/lib/ospec/runner/example_group_runner.rb +0 -41
- data/lib/ospec/runner/formatter/html_formatter.rb +0 -139
- data/lib/ospec/runner/formatter/terminal_formatter.rb +0 -48
- data/lib/ospec/runner/options.rb +0 -34
- data/lib/ospec/runner/reporter.rb +0 -82
- data/opal_lib/opal.rb +0 -16
- data/opal_lib/opal/build_methods.rb +0 -51
- data/opal_lib/opal/bundle.rb +0 -70
- data/opal_lib/opal/command.rb +0 -68
- data/opal_lib/opal/context.rb +0 -81
- data/opal_lib/opal/context/console.rb +0 -10
- data/opal_lib/opal/context/file_system.rb +0 -34
- data/opal_lib/opal/context/loader.rb +0 -135
- data/opal_lib/opal/gem.rb +0 -84
- data/opal_lib/opal/rake/builder_task.rb +0 -44
- data/opal_lib/opal/rake/spec_task.rb +0 -32
- data/opal_lib/opal/ruby/ruby_parser.rb +0 -4862
- data/opal_lib/opal/version.rb +0 -4
- data/runtime/debug.js +0 -84
data/runtime/loader.js
CHANGED
@@ -20,7 +20,7 @@ load_extensions['.rb'] = function(loader, path) {
|
|
20
20
|
@param {String} id lib path/name
|
21
21
|
@return {Boolean}
|
22
22
|
*/
|
23
|
-
var
|
23
|
+
var rb_require = Op.require = function(lib) {
|
24
24
|
var resolved = Op.loader.resolve_lib(lib);
|
25
25
|
var cached = Op.cache[resolved];
|
26
26
|
|
@@ -61,91 +61,94 @@ Op.run = function(body) {
|
|
61
61
|
var res = Qnil;
|
62
62
|
|
63
63
|
if (typeof body != 'function') {
|
64
|
-
|
64
|
+
rb_raise(rb_eException, "Expected body to be a function");
|
65
65
|
}
|
66
66
|
|
67
|
-
try {
|
68
|
-
res = body(Rt,
|
69
|
-
}
|
70
|
-
catch (
|
71
|
-
var
|
72
|
-
|
73
|
-
if (
|
74
|
-
puts(
|
75
|
-
}
|
76
|
-
else {
|
77
|
-
puts('
|
78
|
-
}
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
}
|
85
|
-
else if (stack = exc.stack) {
|
86
|
-
puts(stack);
|
87
|
-
}
|
88
|
-
}
|
67
|
+
// try {
|
68
|
+
res = body(Rt, rb_top_self, "(opal)");
|
69
|
+
// }
|
70
|
+
// catch (err) {
|
71
|
+
// var stack;
|
72
|
+
|
73
|
+
// if (err.$message) {
|
74
|
+
// puts(err.$k.__classid__ + ': ' + err.$message);
|
75
|
+
// }
|
76
|
+
// else if (err.message) {
|
77
|
+
// puts(err.$k.__classid__ + ': ' + err.message);
|
78
|
+
// }
|
79
|
+
// else {
|
80
|
+
// puts('NativeError: ' + err.message);
|
81
|
+
// console.log(err);
|
82
|
+
// }
|
83
|
+
// }
|
89
84
|
return res;
|
90
85
|
};
|
91
86
|
|
92
87
|
/**
|
93
|
-
Register a lib
|
94
|
-
|
95
|
-
of the gemspec for the gem. If the info is simply a function (or
|
96
|
-
string?) then a singular lib will be registerd with the function as
|
97
|
-
its body.
|
88
|
+
Register a simple lib file. This file is simply just put into the lib
|
89
|
+
"directory" so it is ready to load"
|
98
90
|
|
99
91
|
@param {String} name The lib/gem name
|
100
|
-
@param {
|
92
|
+
@param {String, Function} info
|
101
93
|
*/
|
102
|
-
Op.
|
103
|
-
// make sure name
|
94
|
+
Op.lib = function(name, info) {
|
95
|
+
// make sure name if useful
|
104
96
|
if (typeof name !== 'string') {
|
105
|
-
|
97
|
+
rb_raise(rb_eException, "Cannot register a lib without a proper name");
|
106
98
|
}
|
107
99
|
|
108
|
-
//
|
100
|
+
// make sure info is useful
|
109
101
|
if (typeof info === 'string' || typeof info === 'function') {
|
110
|
-
load_register_lib(name, info);
|
102
|
+
return load_register_lib(name, info);
|
111
103
|
}
|
112
|
-
|
113
|
-
|
114
|
-
|
104
|
+
|
105
|
+
// something went wrong..
|
106
|
+
rb_raise(rb_eException, "Invalid lib data for: " + name);
|
107
|
+
};
|
108
|
+
|
109
|
+
/**
|
110
|
+
External api for defining a package. This takes an object that defines
|
111
|
+
all the package info and files.
|
112
|
+
|
113
|
+
@param {Object} info Package info
|
114
|
+
*/
|
115
|
+
Op.package = function(info) {
|
116
|
+
if (typeof info === 'object') {
|
117
|
+
load_register_package(info);
|
115
118
|
}
|
116
|
-
// something has gone wrong..
|
117
119
|
else {
|
118
|
-
|
120
|
+
rb_raise(rb_eException, "Invalid package data");
|
119
121
|
}
|
120
122
|
};
|
121
123
|
|
122
124
|
/**
|
123
|
-
Actually register a predefined
|
124
|
-
where
|
125
|
+
Actually register a predefined package. This is for the browser context
|
126
|
+
where package can be serialized into JSON and defined before hand.
|
125
127
|
|
126
|
-
@param {String} name Gem name
|
127
128
|
@param {Object} info Serialized gemspec
|
128
129
|
*/
|
129
|
-
function
|
130
|
+
function load_register_package(info) {
|
130
131
|
var factories = Op.loader.factories,
|
131
|
-
paths = Op.loader.paths
|
132
|
+
paths = Op.loader.paths,
|
133
|
+
name = info.name;
|
132
134
|
|
133
135
|
// register all lib files
|
134
|
-
var
|
136
|
+
var libs = info.libs || {};
|
135
137
|
|
136
138
|
// root dir for gem is '/gem_name'
|
137
139
|
var root_dir = '/' + name;
|
138
140
|
|
139
141
|
// for now assume './lib' as dir for all libs (should be dynamic..)
|
140
|
-
var lib_dir = '
|
142
|
+
var lib_dir = '/' + name + '/lib/';
|
141
143
|
|
142
144
|
// add lib dir to paths
|
143
145
|
paths.unshift(fs_expand_path(fs_join(root_dir, lib_dir)));
|
144
146
|
|
145
|
-
for (var
|
146
|
-
if (
|
147
|
-
var file_path =
|
148
|
-
factories[file_path] =
|
147
|
+
for (var lib in libs) {
|
148
|
+
if (hasOwnProperty.call(libs, lib)) {
|
149
|
+
var file_path = lib_dir + lib;
|
150
|
+
Op.loader.factories[file_path] = libs[lib];
|
151
|
+
Op.loader.libs[lib] = file_path;
|
149
152
|
}
|
150
153
|
}
|
151
154
|
|
@@ -160,8 +163,9 @@ function load_register_gem(name, info) {
|
|
160
163
|
@param {Function, String} factory
|
161
164
|
*/
|
162
165
|
function load_register_lib(name, factory) {
|
163
|
-
var path = '/' + name;
|
166
|
+
var path = '/lib/' + name;
|
164
167
|
Op.loader.factories[path] = factory;
|
168
|
+
Op.loader.libs[name] = path;
|
165
169
|
}
|
166
170
|
|
167
171
|
/**
|
@@ -179,6 +183,7 @@ function Loader(opal) {
|
|
179
183
|
this.opal = opal;
|
180
184
|
this.paths = ['', '/lib'];
|
181
185
|
this.factories = {};
|
186
|
+
this.libs = {};
|
182
187
|
return this;
|
183
188
|
}
|
184
189
|
|
@@ -215,52 +220,31 @@ Lp.resolve_lib = function(lib) {
|
|
215
220
|
var resolved = this.find_lib(lib, this.paths);
|
216
221
|
|
217
222
|
if (!resolved) {
|
218
|
-
|
223
|
+
raise(eLoadError, "no such file to load -- " + lib);
|
219
224
|
}
|
220
225
|
|
221
226
|
return resolved;
|
222
227
|
};
|
223
228
|
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
@param {String} lib The lib path/file to look for
|
228
|
-
@param {Array} paths Load paths to use
|
229
|
-
@return {String} Located path
|
230
|
-
*/
|
231
|
-
Lp.find_lib = function(id, paths) {
|
232
|
-
var extensions = this.valid_extensions, factories = this.factories, candidate;
|
229
|
+
Lp.find_lib = function(id) {
|
230
|
+
var libs = this.libs;
|
231
|
+
var id_with_ext = id + '.rb';
|
233
232
|
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
if (factories[candidate]) {
|
239
|
-
return candidate;
|
240
|
-
}
|
241
|
-
}
|
233
|
+
// try to load a lib path first - i.e. something in our load path
|
234
|
+
if (libs[id_with_ext]) {
|
235
|
+
return libs[id_with_ext];
|
242
236
|
}
|
243
237
|
|
244
|
-
//
|
245
|
-
if (factories[id]) {
|
246
|
-
return id;
|
247
|
-
}
|
238
|
+
// go through full paths..
|
248
239
|
|
249
|
-
//
|
250
|
-
|
251
|
-
|
252
|
-
if (
|
253
|
-
return
|
254
|
-
}
|
255
|
-
}
|
256
|
-
|
257
|
-
// try each path with no extension (if id already has extension)
|
258
|
-
for (var i = 0; i < paths.length; i++) {
|
259
|
-
candidate = fs_join(paths[j], id);
|
260
|
-
|
261
|
-
if (factories[candidate]) {
|
262
|
-
return candidate;
|
240
|
+
// next, incase our require() has a ruby extension..
|
241
|
+
if (id.lastIndexOf('.rb') == id.length - 3) {
|
242
|
+
// id = id.substr(0, id.length - 3);
|
243
|
+
if (libs[id]) {
|
244
|
+
return libs[id];
|
263
245
|
}
|
246
|
+
// if not..
|
247
|
+
// return null;
|
264
248
|
}
|
265
249
|
|
266
250
|
return null;
|
@@ -292,7 +276,7 @@ function load_file(loader, path) {
|
|
292
276
|
var ext = load_extensions[PATH_RE.exec(path)[3] || '.js'];
|
293
277
|
|
294
278
|
if (!ext) {
|
295
|
-
|
279
|
+
rb_raise(rb_eException, "load_run_file - Bad extension for resolved path");
|
296
280
|
}
|
297
281
|
|
298
282
|
ext(loader, path);
|
@@ -310,7 +294,7 @@ function load_file(loader, path) {
|
|
310
294
|
@param {String} path
|
311
295
|
*/
|
312
296
|
function load_execute_file(loader, content, path) {
|
313
|
-
var args = [Rt,
|
297
|
+
var args = [Rt, rb_top_self, path];
|
314
298
|
|
315
299
|
if (typeof content === 'function') {
|
316
300
|
return content.apply(Op, args);
|
@@ -320,8 +304,7 @@ function load_execute_file(loader, content, path) {
|
|
320
304
|
return func.apply(Op, args);
|
321
305
|
|
322
306
|
} else {
|
323
|
-
|
324
|
-
"Loader.execute - bad content sent for '" + path + "'");
|
307
|
+
rb_raise(rb_eException, "Loader.execute - bad content for: " + path);
|
325
308
|
}
|
326
309
|
}
|
327
310
|
|
@@ -331,8 +314,8 @@ function load_execute_file(loader, content, path) {
|
|
331
314
|
@param {String} id The globals id being retrieved.
|
332
315
|
@return {Array} Load paths
|
333
316
|
*/
|
334
|
-
function
|
335
|
-
return
|
317
|
+
function rb_load_path_getter(id) {
|
318
|
+
return Op.loader.paths;
|
336
319
|
}
|
337
320
|
|
338
321
|
/**
|
@@ -341,11 +324,7 @@ function load_path_getter(id) {
|
|
341
324
|
@param {String} id Feature global id
|
342
325
|
@return {Array} Loaded features
|
343
326
|
*/
|
344
|
-
function
|
327
|
+
function rb_loaded_feature_getter(id) {
|
345
328
|
return loaded_features;
|
346
329
|
}
|
347
330
|
|
348
|
-
function obj_require(obj, path) {
|
349
|
-
return Rt.require(path) ? Qtrue : Qfalse;
|
350
|
-
}
|
351
|
-
|
data/runtime/module.js
CHANGED
@@ -2,49 +2,49 @@
|
|
2
2
|
/**
|
3
3
|
Define a top level module with the given id
|
4
4
|
*/
|
5
|
-
function
|
6
|
-
return
|
5
|
+
function rb_define_module(id) {
|
6
|
+
return rb_define_module_under(rb_cObject, id);
|
7
7
|
};
|
8
8
|
|
9
|
-
function
|
9
|
+
function rb_define_module_under(base, id) {
|
10
10
|
var module;
|
11
11
|
|
12
|
-
if (
|
13
|
-
module =
|
14
|
-
if (module.$
|
12
|
+
if (rb_const_defined(base, id)) {
|
13
|
+
module = rb_const_get(base, id);
|
14
|
+
if (module.$f & T_MODULE) {
|
15
15
|
return module;
|
16
16
|
}
|
17
17
|
|
18
|
-
|
18
|
+
rb_raise(rb_eException, id + " is not a module");
|
19
19
|
}
|
20
20
|
|
21
|
-
module =
|
21
|
+
module = rb_define_module_id(id);
|
22
22
|
|
23
|
-
if (base ==
|
24
|
-
|
23
|
+
if (base == rb_cObject) {
|
24
|
+
rb_name_class(module, id);
|
25
25
|
} else {
|
26
|
-
|
26
|
+
rb_name_class(module, base.__classid__ + '::' + id);
|
27
27
|
}
|
28
28
|
|
29
|
-
|
29
|
+
rb_const_set(base, id, module);
|
30
30
|
module.$parent = base;
|
31
31
|
return module;
|
32
32
|
};
|
33
33
|
|
34
|
-
function
|
35
|
-
var module =
|
36
|
-
|
34
|
+
function rb_define_module_id(id) {
|
35
|
+
var module = rb_class_create(rb_cModule);
|
36
|
+
rb_make_metaclass(module, rb_cModule);
|
37
37
|
|
38
|
-
module.$
|
38
|
+
module.$f = T_MODULE;
|
39
39
|
module.$included_in = [];
|
40
40
|
return module;
|
41
41
|
};
|
42
42
|
|
43
|
-
function
|
44
|
-
return
|
43
|
+
function rb_mod_create() {
|
44
|
+
return rb_class_boot(rb_cModule);
|
45
45
|
};
|
46
46
|
|
47
|
-
function
|
47
|
+
function rb_include_module(klass, module) {
|
48
48
|
|
49
49
|
if (!klass.$included_modules) {
|
50
50
|
klass.$included_modules = [];
|
@@ -61,24 +61,21 @@ function include_module(klass, module) {
|
|
61
61
|
|
62
62
|
module.$included_in.push(klass);
|
63
63
|
|
64
|
-
for (var method in module.$
|
65
|
-
if (module.$
|
66
|
-
|
67
|
-
module.$
|
68
|
-
module.$m_tbl['$' + method]);
|
64
|
+
for (var method in module.$m) {
|
65
|
+
if (hasOwnProperty.call(module.$m, method)) {
|
66
|
+
rb_define_raw_method(klass, method,
|
67
|
+
module.$a.prototype[method]);
|
69
68
|
}
|
70
69
|
}
|
71
70
|
|
72
|
-
for (var constant in module.$c) {
|
73
|
-
if (module.$c
|
74
|
-
const_set(klass, constant, module.$c[constant]);
|
75
|
-
}
|
76
|
-
}
|
71
|
+
// for (var constant in module.$c) {
|
72
|
+
// if (hasOwnProperty.call(module.$c, constant)) {
|
73
|
+
// const_set(klass, constant, module.$c[constant]);
|
74
|
+
// }
|
75
|
+
// }
|
77
76
|
};
|
78
77
|
|
79
|
-
|
80
|
-
|
81
|
-
function extend_module(klass, module) {
|
78
|
+
function rb_extend_module(klass, module) {
|
82
79
|
if (!klass.$extended_modules) {
|
83
80
|
klass.$extended_modules = [];
|
84
81
|
}
|
@@ -94,16 +91,13 @@ function extend_module(klass, module) {
|
|
94
91
|
|
95
92
|
module.$extended_in.push(klass);
|
96
93
|
|
97
|
-
var meta = klass.$
|
94
|
+
var meta = klass.$k;
|
98
95
|
|
99
|
-
for (var method in module
|
100
|
-
if (module
|
101
|
-
|
102
|
-
module
|
103
|
-
module.$m_tbl['$' + method]);
|
96
|
+
for (var method in module.o$m) {
|
97
|
+
if (hasOwnProperty.call(module.o$m, method)) {
|
98
|
+
rb_define_raw_method(meta, method,
|
99
|
+
module.o$a.prototype[method]);
|
104
100
|
}
|
105
101
|
}
|
106
102
|
};
|
107
103
|
|
108
|
-
Rt.extend_module = extend_module;
|
109
|
-
|
data/runtime/post.js
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
|
2
2
|
init();
|
3
3
|
|
4
|
-
})();
|
4
|
+
})(undefined);
|
5
5
|
|
6
6
|
// if in a commonjs system already (node etc), exports become our opal
|
7
7
|
// object. Otherwise, in the browser, we just get a top level opal var
|
8
8
|
if ((typeof require !== 'undefined') && (typeof module !== 'undefined')) {
|
9
|
-
module.exports =
|
9
|
+
module.exports = opalscript;
|
10
10
|
}
|
data/runtime/pre.js
CHANGED
data/runtime/runtime.js
CHANGED
@@ -2,56 +2,53 @@
|
|
2
2
|
All methods and properties available to ruby/js sources at runtime. These
|
3
3
|
are kept in their own namespace to keep the opal namespace clean.
|
4
4
|
*/
|
5
|
-
Op.runtime = {};
|
5
|
+
var Rt = Op.runtime = {};
|
6
6
|
|
7
|
-
// for minimizng
|
8
|
-
var Rt = Op.runtime;
|
9
7
|
Rt.opal = Op;
|
10
8
|
|
11
9
|
/**
|
12
10
|
Opal platform - this is overriden in gem context and nodejs context. These
|
13
11
|
are the default values used in the browser, `opal-browser'.
|
14
12
|
*/
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
13
|
+
var PLATFORM_PLATFORM = "opal";
|
14
|
+
var PLATFORM_ENGINE = "opal-browser";
|
15
|
+
var PLATFORM_VERSION = "1.9.2";
|
16
|
+
var PLATFORM_ARGV = [];
|
17
|
+
|
18
|
+
// Minimize js types
|
19
|
+
var ArrayProto = Array.prototype,
|
20
|
+
ObjectProto = Object.prototype,
|
21
|
+
|
22
|
+
ArraySlice = ArrayProto.slice,
|
23
|
+
|
24
|
+
hasOwnProperty = ObjectProto.hasOwnProperty;
|
21
25
|
|
22
26
|
/**
|
23
27
|
Core runtime classes, objects and literals.
|
24
28
|
*/
|
25
|
-
var
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
Qfalse, Qtrue,
|
29
|
+
var rb_cBasirb_cObject, rb_cObject, rb_cModule, rb_cClass,
|
30
|
+
rb_mKernel, rb_cNilClass, rb_cBoolean,
|
31
|
+
rb_cArray, rb_cNumeric,
|
32
|
+
rb_cRegexp, rb_cMatch, rb_top_self, Qnil,
|
30
33
|
|
31
|
-
|
34
|
+
rb_cDir;
|
32
35
|
|
33
36
|
/**
|
34
37
|
Core object type flags. Added as local variables, and onto runtime.
|
35
38
|
*/
|
36
|
-
var T_CLASS =
|
37
|
-
T_MODULE =
|
38
|
-
T_OBJECT =
|
39
|
-
T_BOOLEAN =
|
40
|
-
T_STRING =
|
41
|
-
T_ARRAY =
|
42
|
-
T_NUMBER =
|
43
|
-
T_PROC =
|
44
|
-
T_SYMBOL =
|
45
|
-
T_HASH =
|
46
|
-
T_RANGE =
|
47
|
-
T_ICLASS =
|
48
|
-
FL_SINGLETON =
|
49
|
-
|
50
|
-
/**
|
51
|
-
Method visibility modes
|
52
|
-
*/
|
53
|
-
var FL_PUBLIC = 0,
|
54
|
-
FL_PRIVATE = 1;
|
39
|
+
var T_CLASS = 1,
|
40
|
+
T_MODULE = 2,
|
41
|
+
T_OBJECT = 4,
|
42
|
+
T_BOOLEAN = 8,
|
43
|
+
T_STRING = 16,
|
44
|
+
T_ARRAY = 32,
|
45
|
+
T_NUMBER = 64,
|
46
|
+
T_PROC = 128,
|
47
|
+
T_SYMBOL = 256,
|
48
|
+
T_HASH = 512,
|
49
|
+
T_RANGE = 1024,
|
50
|
+
T_ICLASS = 2056,
|
51
|
+
FL_SINGLETON = 4112;
|
55
52
|
|
56
53
|
/**
|
57
54
|
Define classes. This is the public API for defining classes, shift classes
|
@@ -68,35 +65,32 @@ Rt.dc = function(base, super_class, id, body, flag) {
|
|
68
65
|
|
69
66
|
switch (flag) {
|
70
67
|
case 0:
|
71
|
-
if (base.$
|
72
|
-
base =
|
68
|
+
if (base.$f & T_OBJECT) {
|
69
|
+
base = rb_class_real(base.$k);
|
73
70
|
}
|
74
71
|
|
75
72
|
if (super_class == Qnil) {
|
76
|
-
super_class =
|
73
|
+
super_class = rb_cObject;
|
77
74
|
}
|
78
75
|
|
79
|
-
klass =
|
76
|
+
klass = rb_define_class_under(base, id, super_class);
|
80
77
|
break;
|
81
78
|
|
82
79
|
case 1:
|
83
|
-
klass =
|
80
|
+
klass = rb_singleton_class(base);
|
84
81
|
break;
|
85
82
|
|
86
83
|
case 2:
|
87
|
-
if (base.$
|
88
|
-
base =
|
84
|
+
if (base.$f & T_OBJECT) {
|
85
|
+
base = rb_class_real(base.$k);
|
89
86
|
}
|
90
|
-
klass =
|
87
|
+
klass = rb_define_module_under(base, id);
|
91
88
|
break;
|
92
89
|
|
93
90
|
default:
|
94
|
-
|
91
|
+
rb_raise(rb_eException, "define_class got a unknown flag " + flag);
|
95
92
|
}
|
96
93
|
|
97
|
-
// when reopening a class always set it back to public
|
98
|
-
klass.$mode = FL_PUBLIC;
|
99
|
-
|
100
94
|
var res = body(klass);
|
101
95
|
|
102
96
|
return res;
|
@@ -117,79 +111,38 @@ Rt.um = function(kls) {
|
|
117
111
|
for (var i = 0, ii = args.length; i < ii; i++) {
|
118
112
|
(function(mid) {
|
119
113
|
var func = function() {
|
120
|
-
|
114
|
+
rb_raise(rb_eNoMethodError, "undefined method `" + mid + "' for " + this.m$inspect());
|
121
115
|
};
|
122
116
|
|
123
|
-
kls.
|
117
|
+
kls.o$a.prototype['m$' + mid] = func;
|
124
118
|
|
125
|
-
if (kls.$bridge_prototype) {
|
126
|
-
kls.$bridge_prototype['m$' + mid] = func;
|
127
|
-
}
|
128
119
|
})(args[i].m$to_s());
|
129
120
|
}
|
130
121
|
|
131
122
|
return Qnil;
|
132
123
|
};
|
133
124
|
|
134
|
-
/**
|
135
|
-
Method missing support - used in debug mode (opt in).
|
136
|
-
*/
|
137
|
-
Rt.mm = function(method_ids) {
|
138
|
-
var prototype = cBasicObject.$m_tbl;
|
139
|
-
|
140
|
-
for (var i = 0, ii = method_ids.length; i < ii; i++) {
|
141
|
-
var mid = method_ids[i];
|
142
|
-
|
143
|
-
if (!prototype[mid]) {
|
144
|
-
var imp = (function(mid, method_id) {
|
145
|
-
return function(self) {
|
146
|
-
var args = [].slice.call(arguments, 0);
|
147
|
-
args.unshift(intern(method_id));
|
148
|
-
args.unshift(self);
|
149
|
-
return self.$m.method_missing.apply(null, args);
|
150
|
-
};
|
151
|
-
})(mid, method_ids[i]);
|
152
|
-
|
153
|
-
imp.$rbMM = true;
|
154
|
-
|
155
|
-
prototype[mid] = prototype['$' + mid] = imp;
|
156
|
-
}
|
157
|
-
}
|
158
|
-
};
|
159
|
-
|
160
125
|
/**
|
161
126
|
Define methods. Public method for defining a method on the given base.
|
162
127
|
|
163
128
|
@param {Object} klass The base to define method on
|
164
129
|
@param {String} name Ruby mid
|
165
|
-
@param {Function}
|
130
|
+
@param {Function} body The method implementation
|
166
131
|
@param {Number} arity Method arity
|
167
132
|
@return {Qnil}
|
168
133
|
*/
|
169
|
-
Rt.dm = function(klass, name,
|
170
|
-
if (klass.$
|
171
|
-
klass = klass.$
|
134
|
+
Rt.dm = function(klass, name, body, arity) {
|
135
|
+
if (klass.$f & T_OBJECT) {
|
136
|
+
klass = klass.$k;
|
172
137
|
}
|
173
138
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
if (mode == FL_PRIVATE) {
|
178
|
-
public_body = function() {
|
179
|
-
raise(eNoMethodError, "private method `" + name +
|
180
|
-
"' called for " + this.$m$inspect());
|
181
|
-
};
|
182
|
-
public_body.$arity = -1;
|
139
|
+
if (!body.$rbName) {
|
140
|
+
body.$rbName = name;
|
141
|
+
body.$arity = arity;
|
183
142
|
}
|
184
143
|
|
185
|
-
|
186
|
-
|
187
|
-
private_body.$rbArity = arity;
|
188
|
-
}
|
189
|
-
|
190
|
-
// FIXME: add to private/public methods
|
191
|
-
// klass.$methods.push(intern(name));
|
192
|
-
define_raw_method(klass, name, private_body, public_body);
|
144
|
+
rb_define_raw_method(klass, 'm$' + name, body);
|
145
|
+
klass.$methods.push(name);
|
193
146
|
|
194
147
|
return Qnil;
|
195
148
|
};
|
@@ -204,7 +157,7 @@ Rt.dm = function(klass, name, public_body, arity) {
|
|
204
157
|
@return {Qnil}
|
205
158
|
*/
|
206
159
|
Rt.ds = function(base, method_id, body, arity) {
|
207
|
-
return Rt.dm(
|
160
|
+
return Rt.dm(rb_singleton_class(base), method_id, body);
|
208
161
|
};
|
209
162
|
|
210
163
|
/**
|
@@ -215,44 +168,45 @@ Rt.ds = function(base, method_id, body, arity) {
|
|
215
168
|
This is actually done in super_find.
|
216
169
|
*/
|
217
170
|
Rt.S = function(callee, self, args) {
|
218
|
-
var mid = callee.$rbName;
|
219
|
-
var func =
|
171
|
+
var mid = 'm$' + callee.$rbName;
|
172
|
+
var func = rb_super_find(self.$k, callee, mid);
|
220
173
|
|
221
174
|
if (!func) {
|
222
|
-
|
175
|
+
rb_raise(rb_eNoMethodError, "super: no super class method `" + mid + "`" +
|
223
176
|
" for " + self.m$inspect());
|
224
177
|
}
|
225
178
|
|
226
|
-
var args_to_send = [self].concat(args);
|
179
|
+
// var args_to_send = [self].concat(args);
|
180
|
+
var args_to_send = [].concat(args);
|
227
181
|
return func.apply(self, args_to_send);
|
228
182
|
};
|
229
183
|
|
230
184
|
/**
|
231
185
|
Actually find super impl to call. Returns null if cannot find it.
|
232
186
|
*/
|
233
|
-
function
|
187
|
+
function rb_super_find(klass, callee, mid) {
|
234
188
|
var cur_method;
|
235
189
|
|
236
190
|
while (klass) {
|
237
|
-
if (klass.$
|
238
|
-
if (klass.$
|
239
|
-
cur_method = klass.$
|
191
|
+
if (klass.$m[mid]) {
|
192
|
+
if (klass.$m[mid] == callee) {
|
193
|
+
cur_method = klass.$m[mid];
|
240
194
|
break;
|
241
195
|
}
|
242
196
|
}
|
243
|
-
klass = klass.$
|
197
|
+
klass = klass.$s;
|
244
198
|
}
|
245
199
|
|
246
200
|
if (!(klass && cur_method)) { return null; }
|
247
201
|
|
248
|
-
klass = klass.$
|
202
|
+
klass = klass.$s;
|
249
203
|
|
250
204
|
while (klass) {
|
251
|
-
if (klass.$
|
252
|
-
return klass.$
|
205
|
+
if (klass.$m[mid]) {
|
206
|
+
return klass.$m[mid];
|
253
207
|
}
|
254
208
|
|
255
|
-
klass = klass.$
|
209
|
+
klass = klass.$s;
|
256
210
|
}
|
257
211
|
|
258
212
|
return null;
|
@@ -262,19 +216,19 @@ function super_find(klass, callee, mid) {
|
|
262
216
|
Exception classes. Some of these are used by runtime so they are here for
|
263
217
|
convenience.
|
264
218
|
*/
|
265
|
-
var
|
266
|
-
|
267
|
-
|
268
|
-
|
219
|
+
var rb_eException, rb_eStandardError, rb_eLocalJumpError, rb_eNameError,
|
220
|
+
rb_eNoMethodError, rb_eArgError, rb_eScriptError, rb_eLoadError,
|
221
|
+
rb_eRuntimeError, rb_eTypeError, rb_eIndexError, rb_eKeyError,
|
222
|
+
rb_eRangeError;
|
269
223
|
|
270
|
-
var
|
224
|
+
var rb_eExceptionInstance;
|
271
225
|
|
272
226
|
/**
|
273
227
|
Standard jump exceptions to save re-creating them everytime they are needed
|
274
228
|
*/
|
275
|
-
var
|
276
|
-
|
277
|
-
|
229
|
+
var rb_eReturnInstance,
|
230
|
+
rb_eBreakInstance,
|
231
|
+
rb_eNextInstance;
|
278
232
|
|
279
233
|
/**
|
280
234
|
Ruby break statement with the given value. When no break value is needed, nil
|
@@ -284,8 +238,8 @@ var eReturnInstance,
|
|
284
238
|
@param {RubyObject} value The break value.
|
285
239
|
*/
|
286
240
|
Rt.B = function(value) {
|
287
|
-
|
288
|
-
|
241
|
+
rb_eBreakInstance.$value = value;
|
242
|
+
rb_raise_exc(rb_eBreakInstance);
|
289
243
|
};
|
290
244
|
|
291
245
|
/**
|
@@ -293,53 +247,70 @@ Rt.B = function(value) {
|
|
293
247
|
represents the method that this statement must return from.
|
294
248
|
*/
|
295
249
|
Rt.R = function(value, func) {
|
296
|
-
|
297
|
-
|
298
|
-
throw
|
250
|
+
rb_eReturnInstance.$value = value;
|
251
|
+
rb_eReturnInstance.$func = func;
|
252
|
+
throw rb_eReturnInstance;
|
299
253
|
};
|
300
254
|
|
301
255
|
/**
|
302
256
|
Get the given constant name from the given base
|
303
257
|
*/
|
304
258
|
Rt.cg = function(base, id) {
|
305
|
-
if (base.$
|
306
|
-
base =
|
259
|
+
if (base.$f & T_OBJECT) {
|
260
|
+
base = rb_class_real(base.$k);
|
307
261
|
}
|
308
|
-
return
|
262
|
+
return rb_const_get(base, id);
|
309
263
|
};
|
310
264
|
|
311
265
|
/**
|
312
266
|
Set constant from runtime
|
313
267
|
*/
|
314
268
|
Rt.cs = function(base, id, val) {
|
315
|
-
if (base.$
|
316
|
-
base =
|
269
|
+
if (base.$f & T_OBJECT) {
|
270
|
+
base = rb_class_real(base.$k);
|
317
271
|
}
|
318
|
-
return
|
272
|
+
return rb_const_set(base, id, val);
|
319
273
|
};
|
320
274
|
|
321
275
|
/**
|
322
276
|
Get global by id
|
323
277
|
*/
|
324
278
|
Rt.gg = function(id) {
|
325
|
-
return
|
279
|
+
return rb_gvar_get(id);
|
326
280
|
};
|
327
281
|
|
328
282
|
/**
|
329
283
|
Set global by id
|
330
284
|
*/
|
331
285
|
Rt.gs = function(id, value) {
|
332
|
-
return
|
286
|
+
return rb_gvar_set(id, value);
|
287
|
+
};
|
288
|
+
|
289
|
+
/**
|
290
|
+
Class variables table
|
291
|
+
*/
|
292
|
+
var rb_class_variables = {};
|
293
|
+
|
294
|
+
Rt.cvg = function(id) {
|
295
|
+
var v = rb_class_variables[id];
|
296
|
+
|
297
|
+
if (v) return v;
|
298
|
+
|
299
|
+
return Qnil;
|
300
|
+
};
|
301
|
+
|
302
|
+
Rt.cvs = function(id, val) {
|
303
|
+
return rb_class_variables[id] = val;
|
333
304
|
};
|
334
305
|
|
335
|
-
function
|
306
|
+
function rb_regexp_match_getter(id) {
|
336
307
|
var matched = Rt.X;
|
337
308
|
|
338
309
|
if (matched) {
|
339
310
|
if (matched.$md) {
|
340
311
|
return matched.$md;
|
341
312
|
} else {
|
342
|
-
var res = new cMatch.
|
313
|
+
var res = new cMatch.o$a();
|
343
314
|
res.$data = matched;
|
344
315
|
matched.$md = res;
|
345
316
|
return res;
|
@@ -349,3 +320,26 @@ function regexp_match_getter(id) {
|
|
349
320
|
}
|
350
321
|
}
|
351
322
|
|
323
|
+
/**
|
324
|
+
An array of procs to call for at_exit()
|
325
|
+
|
326
|
+
@param {Function} proc implementation
|
327
|
+
*/
|
328
|
+
var rb_end_procs = [];
|
329
|
+
|
330
|
+
/**
|
331
|
+
Called upon exit: we need to run all of our registered procs
|
332
|
+
in reverse order: i.e. call last ones first.
|
333
|
+
|
334
|
+
FIXME: do we need to try/catch this??
|
335
|
+
*/
|
336
|
+
Rt.do_at_exit = function() {
|
337
|
+
var proc;
|
338
|
+
|
339
|
+
while (proc = rb_end_procs.pop()) {
|
340
|
+
proc.call(proc.$self);
|
341
|
+
}
|
342
|
+
|
343
|
+
return null;
|
344
|
+
};
|
345
|
+
|