opal 1.5.1 → 1.6.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/build.yml +4 -1
- data/HACKING.md +23 -0
- data/UNRELEASED.md +42 -0
- data/benchmark/run.rb +1 -0
- data/docs/compiled_ruby.md +8 -0
- data/docs/compiler.md +1 -1
- data/docs/compiler_directives.md +1 -1
- data/docs/getting_started.md +17 -0
- data/docs/headless_chrome.md +1 -1
- data/docs/index.md +123 -0
- data/docs/templates.md +37 -37
- data/docs/unsupported_features.md +0 -4
- data/lib/opal/builder.rb +59 -39
- data/lib/opal/builder_scheduler/prefork.rb +259 -0
- data/lib/opal/builder_scheduler/sequential.rb +13 -0
- data/lib/opal/builder_scheduler.rb +29 -0
- data/lib/opal/cache/file_cache.rb +5 -0
- data/lib/opal/cli.rb +22 -18
- data/lib/opal/cli_options.rb +4 -0
- data/lib/opal/cli_runners/chrome.rb +13 -9
- data/lib/opal/cli_runners/chrome_cdp_interface.rb +19 -2
- data/lib/opal/cli_runners/compiler.rb +1 -1
- data/lib/opal/cli_runners/gjs.rb +3 -1
- data/lib/opal/cli_runners/mini_racer.rb +5 -3
- data/lib/opal/cli_runners/nodejs.rb +3 -3
- data/lib/opal/cli_runners/server.rb +13 -28
- data/lib/opal/cli_runners/system_runner.rb +5 -3
- data/lib/opal/cli_runners.rb +7 -6
- data/lib/opal/compiler.rb +25 -2
- data/lib/opal/config.rb +10 -0
- data/lib/opal/nodes/args/ensure_kwargs_are_kwargs.rb +2 -6
- data/lib/opal/nodes/args/extract_kwarg.rb +3 -4
- data/lib/opal/nodes/args/extract_kwargs.rb +3 -1
- data/lib/opal/nodes/args/extract_kwoptarg.rb +1 -1
- data/lib/opal/nodes/args/extract_kwrestarg.rb +4 -1
- data/lib/opal/nodes/args/extract_optarg.rb +1 -1
- data/lib/opal/nodes/args/extract_post_arg.rb +1 -1
- data/lib/opal/nodes/args/extract_post_optarg.rb +1 -1
- data/lib/opal/nodes/args/extract_restarg.rb +2 -2
- data/lib/opal/nodes/args/initialize_iterarg.rb +1 -1
- data/lib/opal/nodes/args/initialize_shadowarg.rb +1 -1
- data/lib/opal/nodes/args/prepare_post_args.rb +4 -2
- data/lib/opal/nodes/base.rb +14 -3
- data/lib/opal/nodes/call.rb +10 -14
- data/lib/opal/nodes/class.rb +3 -1
- data/lib/opal/nodes/closure.rb +250 -0
- data/lib/opal/nodes/def.rb +7 -11
- data/lib/opal/nodes/definitions.rb +4 -2
- data/lib/opal/nodes/if.rb +12 -2
- data/lib/opal/nodes/iter.rb +11 -17
- data/lib/opal/nodes/logic.rb +15 -63
- data/lib/opal/nodes/module.rb +3 -1
- data/lib/opal/nodes/rescue.rb +23 -15
- data/lib/opal/nodes/scope.rb +7 -1
- data/lib/opal/nodes/top.rb +27 -4
- data/lib/opal/nodes/while.rb +42 -26
- data/lib/opal/nodes.rb +1 -0
- data/lib/opal/os.rb +59 -0
- data/lib/opal/rewriter.rb +2 -0
- data/lib/opal/rewriters/returnable_logic.rb +14 -0
- data/lib/opal/rewriters/thrower_finder.rb +90 -0
- data/lib/opal/simple_server.rb +12 -6
- data/lib/opal/source_map/file.rb +1 -1
- data/lib/opal/source_map/map.rb +9 -1
- data/lib/opal/util.rb +1 -1
- data/lib/opal/version.rb +1 -1
- data/opal/corelib/array.rb +68 -3
- data/opal/corelib/basic_object.rb +1 -0
- data/opal/corelib/comparable.rb +1 -1
- data/opal/corelib/complex.rb +1 -0
- data/opal/corelib/constants.rb +2 -2
- data/opal/corelib/enumerable.rb +4 -2
- data/opal/corelib/enumerator/chain.rb +4 -0
- data/opal/corelib/enumerator/generator.rb +5 -3
- data/opal/corelib/enumerator/lazy.rb +3 -1
- data/opal/corelib/enumerator/yielder.rb +2 -4
- data/opal/corelib/enumerator.rb +3 -1
- data/opal/corelib/error/errno.rb +2 -1
- data/opal/corelib/error.rb +13 -2
- data/opal/corelib/hash.rb +39 -1
- data/opal/corelib/kernel.rb +56 -5
- data/opal/corelib/module.rb +60 -4
- data/opal/corelib/proc.rb +8 -5
- data/opal/corelib/rational.rb +1 -0
- data/opal/corelib/regexp.rb +15 -1
- data/opal/corelib/runtime.js +307 -238
- data/opal/corelib/string/encoding.rb +0 -6
- data/opal/corelib/string.rb +28 -7
- data/opal/corelib/time.rb +5 -2
- data/opal/corelib/unsupported.rb +2 -14
- data/spec/filters/bugs/delegate.rb +11 -0
- data/spec/filters/bugs/kernel.rb +1 -3
- data/spec/filters/bugs/language.rb +3 -23
- data/spec/filters/bugs/method.rb +0 -1
- data/spec/filters/bugs/module.rb +0 -3
- data/spec/filters/bugs/proc.rb +0 -3
- data/spec/filters/bugs/set.rb +4 -16
- data/spec/filters/bugs/unboundmethod.rb +0 -2
- data/spec/filters/unsupported/array.rb +0 -58
- data/spec/filters/unsupported/freeze.rb +8 -192
- data/spec/filters/unsupported/hash.rb +0 -25
- data/spec/filters/unsupported/kernel.rb +0 -1
- data/spec/filters/unsupported/privacy.rb +17 -0
- data/spec/lib/builder_spec.rb +14 -0
- data/spec/lib/cli_runners/server_spec.rb +2 -3
- data/spec/lib/cli_spec.rb +1 -1
- data/spec/lib/compiler_spec.rb +1 -1
- data/spec/opal/core/language/if_spec.rb +13 -0
- data/spec/opal/core/module_spec.rb +8 -0
- data/spec/ruby_specs +2 -1
- data/stdlib/await.rb +44 -7
- data/stdlib/delegate.rb +427 -6
- data/stdlib/headless_chrome.rb +6 -2
- data/stdlib/nodejs/file.rb +2 -1
- data/stdlib/opal-parser.rb +1 -1
- data/stdlib/opal-platform.rb +1 -1
- data/stdlib/opal-replutils.rb +5 -3
- data/stdlib/promise.rb +3 -0
- data/stdlib/rbconfig.rb +4 -1
- data/stdlib/ruby2_keywords.rb +60 -0
- data/stdlib/set.rb +21 -0
- data/tasks/performance.rake +41 -35
- data/tasks/releasing.rake +1 -0
- data/tasks/testing/mspec_special_calls.rb +1 -0
- data/tasks/testing.rake +5 -5
- data/test/nodejs/test_await.rb +39 -1
- metadata +27 -14
- data/docs/faq.md +0 -17
- data/lib/opal/rewriters/break_finder.rb +0 -36
- data/spec/opal/core/kernel/freeze_spec.rb +0 -15
data/opal/corelib/runtime.js
CHANGED
@@ -23,10 +23,12 @@
|
|
23
23
|
else if (typeof(window) !== 'undefined') { global_object = window; }
|
24
24
|
|
25
25
|
// Setup a dummy console object if missing
|
26
|
+
if (global_object.console == null) {
|
27
|
+
global_object.console = {};
|
28
|
+
}
|
29
|
+
|
26
30
|
if (typeof(global_object.console) === 'object') {
|
27
31
|
console = global_object.console;
|
28
|
-
} else if (global_object.console == null) {
|
29
|
-
console = global_object.console = {};
|
30
32
|
} else {
|
31
33
|
console = {};
|
32
34
|
}
|
@@ -65,7 +67,6 @@
|
|
65
67
|
|
66
68
|
// This is a useful reference to global object inside ruby files
|
67
69
|
Opal.global = global_object;
|
68
|
-
global_object.Opal = Opal;
|
69
70
|
|
70
71
|
// Configure runtime behavior with regards to require and unsupported features
|
71
72
|
Opal.config = {
|
@@ -90,27 +91,27 @@
|
|
90
91
|
var unique_id = nil_id;
|
91
92
|
|
92
93
|
// Return next unique id
|
93
|
-
|
94
|
+
function $uid() {
|
94
95
|
unique_id += 2;
|
95
96
|
return unique_id;
|
96
97
|
};
|
98
|
+
Opal.uid = $uid;
|
97
99
|
|
98
100
|
// Retrieve or assign the id of an object
|
99
101
|
Opal.id = function(obj) {
|
100
102
|
if (obj.$$is_number) return (obj * 2)+1;
|
101
|
-
if (obj.$$id
|
102
|
-
|
103
|
+
if (obj.$$id == null) {
|
104
|
+
$prop(obj, '$$id', $uid());
|
103
105
|
}
|
104
|
-
$prop(obj, '$$id', Opal.uid());
|
105
106
|
return obj.$$id;
|
106
107
|
};
|
107
108
|
|
108
109
|
// Globals table
|
109
|
-
Opal.gvars = {};
|
110
|
+
var $gvars = Opal.gvars = {};
|
110
111
|
|
111
112
|
// Exit function, this should be replaced by platform specific implementation
|
112
113
|
// (See nodejs and chrome for examples)
|
113
|
-
Opal.exit = function(status) { if (
|
114
|
+
Opal.exit = function(status) { if ($gvars.DEBUG) console.log('Exited with status '+status); };
|
114
115
|
|
115
116
|
// keeps track of exceptions for $!
|
116
117
|
Opal.exceptions = [];
|
@@ -120,11 +121,11 @@
|
|
120
121
|
Opal.pop_exception = function() {
|
121
122
|
var exception = Opal.exceptions.pop();
|
122
123
|
if (exception) {
|
123
|
-
|
124
|
-
|
124
|
+
$gvars["!"] = exception;
|
125
|
+
$gvars["@"] = exception.$backtrace();
|
125
126
|
}
|
126
127
|
else {
|
127
|
-
|
128
|
+
$gvars["!"] = $gvars["@"] = nil;
|
128
129
|
}
|
129
130
|
};
|
130
131
|
|
@@ -308,7 +309,7 @@
|
|
308
309
|
|
309
310
|
if (cref == null) return;
|
310
311
|
|
311
|
-
ancestors =
|
312
|
+
ancestors = $ancestors(cref);
|
312
313
|
|
313
314
|
for (i = 0, ii = ancestors.length; i < ii; i++) {
|
314
315
|
if (ancestors[i].$$const && $has_own.call(ancestors[i].$$const, name)) {
|
@@ -328,10 +329,8 @@
|
|
328
329
|
}
|
329
330
|
|
330
331
|
// Call const_missing if nothing else worked
|
331
|
-
function const_missing(cref, name
|
332
|
-
|
333
|
-
return (cref || _Object).$const_missing(name);
|
334
|
-
}
|
332
|
+
function const_missing(cref, name) {
|
333
|
+
return (cref || _Object).$const_missing(name);
|
335
334
|
}
|
336
335
|
|
337
336
|
// Look for the constant just in the current cref or call `#const_missing`
|
@@ -346,8 +345,8 @@
|
|
346
345
|
throw new Opal.TypeError(cref.toString() + " is not a class/module");
|
347
346
|
}
|
348
347
|
|
349
|
-
result = const_get_name(cref, name);
|
350
|
-
result
|
348
|
+
result = const_get_name(cref, name);
|
349
|
+
return result != null || skip_missing ? result : const_missing(cref, name);
|
351
350
|
};
|
352
351
|
|
353
352
|
// Look for the constant relative to a cref or call `#const_missing` (when the
|
@@ -385,7 +384,7 @@
|
|
385
384
|
result = cached[1];
|
386
385
|
}
|
387
386
|
|
388
|
-
return result != null ? result : const_missing(cref, name
|
387
|
+
return result != null || skip_missing ? result : const_missing(cref, name);
|
389
388
|
};
|
390
389
|
|
391
390
|
// Initialize the top level constant cache generation counter
|
@@ -413,7 +412,7 @@
|
|
413
412
|
result = cached[1];
|
414
413
|
}
|
415
414
|
|
416
|
-
return result != null ? result : const_missing(cref, name
|
415
|
+
return result != null || skip_missing ? result : const_missing(cref, name);
|
417
416
|
};
|
418
417
|
|
419
418
|
// Register the constant on a cref and opportunistically set the name of
|
@@ -454,8 +453,8 @@
|
|
454
453
|
|
455
454
|
var module, modules = [cref], i, ii, constants = {}, constant;
|
456
455
|
|
457
|
-
if (inherit) modules = modules.concat(
|
458
|
-
if (inherit && cref.$$is_module) modules = modules.concat([Opal.Object]).concat(
|
456
|
+
if (inherit) modules = modules.concat($ancestors(cref));
|
457
|
+
if (inherit && cref.$$is_module) modules = modules.concat([Opal.Object]).concat($ancestors(Opal.Object));
|
459
458
|
|
460
459
|
for (i = 0, ii = modules.length; i < ii; i++) {
|
461
460
|
module = modules[i];
|
@@ -534,13 +533,13 @@
|
|
534
533
|
//
|
535
534
|
// @return new [Class] or existing ruby class
|
536
535
|
//
|
537
|
-
|
538
|
-
var klass
|
536
|
+
function $allocate_class(name, superclass, singleton) {
|
537
|
+
var klass;
|
539
538
|
|
540
539
|
if (superclass != null && superclass.$$bridge) {
|
541
540
|
// Inheritance from bridged classes requires
|
542
541
|
// calling original JS constructors
|
543
|
-
|
542
|
+
klass = function() {
|
544
543
|
var args = $slice.call(arguments),
|
545
544
|
self = new ($bind.apply(superclass.$$constructor, [null].concat(args)))();
|
546
545
|
|
@@ -549,18 +548,16 @@
|
|
549
548
|
return self;
|
550
549
|
}
|
551
550
|
} else {
|
552
|
-
|
551
|
+
klass = function(){};
|
553
552
|
}
|
554
553
|
|
555
554
|
if (name && name !== nil) {
|
556
|
-
$prop(
|
555
|
+
$prop(klass, 'displayName', '::'+name);
|
557
556
|
}
|
558
557
|
|
559
|
-
klass = constructor;
|
560
|
-
|
561
558
|
$prop(klass, '$$name', name);
|
562
|
-
$prop(klass, '$$constructor',
|
563
|
-
$prop(klass, '$$prototype',
|
559
|
+
$prop(klass, '$$constructor', klass);
|
560
|
+
$prop(klass, '$$prototype', klass.prototype);
|
564
561
|
$prop(klass, '$$const', {});
|
565
562
|
$prop(klass, '$$is_class', true);
|
566
563
|
$prop(klass, '$$is_a_module', true);
|
@@ -614,6 +611,7 @@
|
|
614
611
|
|
615
612
|
return klass;
|
616
613
|
};
|
614
|
+
Opal.allocate_class = $allocate_class;
|
617
615
|
|
618
616
|
|
619
617
|
function find_existing_class(scope, name) {
|
@@ -667,35 +665,32 @@
|
|
667
665
|
|
668
666
|
var klass = find_existing_class(scope, name);
|
669
667
|
|
670
|
-
if (klass) {
|
668
|
+
if (klass != null) {
|
671
669
|
if (superclass) {
|
672
670
|
// Make sure existing class has same superclass
|
673
671
|
ensureSuperclassMatch(klass, superclass);
|
674
672
|
}
|
675
|
-
|
676
|
-
if (Opal.trace_class) { invoke_tracers_for_class(klass); }
|
677
|
-
|
678
|
-
return klass;
|
679
673
|
}
|
674
|
+
else {
|
675
|
+
// Class doesn't exist, create a new one with given superclass...
|
680
676
|
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
superclass = _Object;
|
686
|
-
}
|
677
|
+
// Not specifying a superclass means we can assume it to be Object
|
678
|
+
if (superclass == null) {
|
679
|
+
superclass = _Object;
|
680
|
+
}
|
687
681
|
|
688
|
-
|
689
|
-
|
690
|
-
|
682
|
+
// Create the class object (instance of Class)
|
683
|
+
klass = $allocate_class(name, superclass);
|
684
|
+
$const_set(scope, name, klass);
|
691
685
|
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
686
|
+
// Call .inherited() hook with new class on the superclass
|
687
|
+
if (superclass.$inherited) {
|
688
|
+
superclass.$inherited(klass);
|
689
|
+
}
|
696
690
|
|
697
|
-
|
698
|
-
|
691
|
+
if (bridged) {
|
692
|
+
Opal.bridge(bridged, klass);
|
693
|
+
}
|
699
694
|
}
|
700
695
|
|
701
696
|
if (Opal.trace_class) { invoke_tracers_for_class(klass); }
|
@@ -722,12 +717,8 @@
|
|
722
717
|
// @param id [String] the name of the new (or existing) module
|
723
718
|
//
|
724
719
|
// @return [Module]
|
725
|
-
|
720
|
+
function $allocate_module(name) {
|
726
721
|
var constructor = function(){};
|
727
|
-
if (name) {
|
728
|
-
$prop(constructor, 'displayName', name+'.$$constructor');
|
729
|
-
}
|
730
|
-
|
731
722
|
var module = constructor;
|
732
723
|
|
733
724
|
if (name)
|
@@ -749,6 +740,7 @@
|
|
749
740
|
|
750
741
|
return module;
|
751
742
|
};
|
743
|
+
Opal.allocate_module = $allocate_module;
|
752
744
|
|
753
745
|
function find_existing_module(scope, name) {
|
754
746
|
var module = const_get_name(scope, name);
|
@@ -776,17 +768,12 @@
|
|
776
768
|
|
777
769
|
module = find_existing_module(scope, name);
|
778
770
|
|
779
|
-
if (module) {
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
return module;
|
771
|
+
if (module == null) {
|
772
|
+
// Module doesnt exist, create a new one...
|
773
|
+
module = $allocate_module(name);
|
774
|
+
$const_set(scope, name, module);
|
784
775
|
}
|
785
776
|
|
786
|
-
// Module doesnt exist, create a new one...
|
787
|
-
module = Opal.allocate_module(name);
|
788
|
-
$const_set(scope, name, module);
|
789
|
-
|
790
777
|
if (Opal.trace_class) { invoke_tracers_for_class(module); }
|
791
778
|
|
792
779
|
return module;
|
@@ -817,6 +804,23 @@
|
|
817
804
|
}
|
818
805
|
};
|
819
806
|
|
807
|
+
// helper to set $$meta on klass, module or instance
|
808
|
+
function set_meta(obj, meta) {
|
809
|
+
if (obj.hasOwnProperty('$$meta')) {
|
810
|
+
obj.$$meta = meta;
|
811
|
+
} else {
|
812
|
+
$prop(obj, '$$meta', meta);
|
813
|
+
}
|
814
|
+
if (obj.$$frozen) {
|
815
|
+
// If a object is frozen (sealed), freeze $$meta too.
|
816
|
+
// No need to inject $$meta.$$prototype in the prototype chain,
|
817
|
+
// as $$meta cannot be modified anyway.
|
818
|
+
obj.$$meta.$freeze();
|
819
|
+
} else {
|
820
|
+
$set_proto(obj, meta.$$prototype);
|
821
|
+
}
|
822
|
+
};
|
823
|
+
|
820
824
|
// Build the singleton class for an existing class. Class object are built
|
821
825
|
// with their singleton class already in the prototype chain and inheriting
|
822
826
|
// from their superclass object (up to `Class` itself).
|
@@ -827,8 +831,6 @@
|
|
827
831
|
// @param klass [Class]
|
828
832
|
// @return [Class]
|
829
833
|
Opal.build_class_singleton_class = function(klass) {
|
830
|
-
var superclass, meta;
|
831
|
-
|
832
834
|
if (klass.$$meta) {
|
833
835
|
return klass.$$meta;
|
834
836
|
}
|
@@ -836,14 +838,13 @@
|
|
836
838
|
// The singleton_class superclass is the singleton_class of its superclass;
|
837
839
|
// but BasicObject has no superclass (its `$$super` is null), thus we
|
838
840
|
// fallback on `Class`.
|
839
|
-
superclass = klass === BasicObject ? Class : Opal.get_singleton_class(klass.$$super);
|
841
|
+
var superclass = klass === BasicObject ? Class : Opal.get_singleton_class(klass.$$super);
|
840
842
|
|
841
|
-
meta =
|
843
|
+
var meta = $allocate_class(null, superclass, true);
|
842
844
|
|
843
845
|
$prop(meta, '$$is_singleton', true);
|
844
846
|
$prop(meta, '$$singleton_of', klass);
|
845
|
-
|
846
|
-
$set_proto(klass, meta.$$prototype);
|
847
|
+
set_meta(klass, meta);
|
847
848
|
// Restoring ClassName.class
|
848
849
|
$prop(klass, '$$class', Opal.Class);
|
849
850
|
|
@@ -855,12 +856,11 @@
|
|
855
856
|
return mod.$$meta;
|
856
857
|
}
|
857
858
|
|
858
|
-
var meta =
|
859
|
+
var meta = $allocate_class(null, Opal.Module, true);
|
859
860
|
|
860
861
|
$prop(meta, '$$is_singleton', true);
|
861
862
|
$prop(meta, '$$singleton_of', mod);
|
862
|
-
|
863
|
-
$set_proto(mod, meta.$$prototype);
|
863
|
+
set_meta(mod, meta);
|
864
864
|
// Restoring ModuleName.class
|
865
865
|
$prop(mod, '$$class', Opal.Module);
|
866
866
|
|
@@ -873,16 +873,14 @@
|
|
873
873
|
// @return [Class]
|
874
874
|
Opal.build_object_singleton_class = function(object) {
|
875
875
|
var superclass = object.$$class,
|
876
|
-
klass =
|
876
|
+
klass = $allocate_class(nil, superclass, true);
|
877
877
|
|
878
878
|
$prop(klass, '$$is_singleton', true);
|
879
879
|
$prop(klass, '$$singleton_of', object);
|
880
880
|
|
881
881
|
delete klass.$$prototype.$$class;
|
882
882
|
|
883
|
-
|
884
|
-
|
885
|
-
$set_proto(object, object.$$meta.$$prototype);
|
883
|
+
set_meta(object, klass);
|
886
884
|
|
887
885
|
return klass;
|
888
886
|
};
|
@@ -892,7 +890,7 @@
|
|
892
890
|
};
|
893
891
|
|
894
892
|
Opal.instance_methods = function(mod) {
|
895
|
-
var exclude = [], results = [], ancestors =
|
893
|
+
var exclude = [], results = [], ancestors = $ancestors(mod);
|
896
894
|
|
897
895
|
for (var i = 0, l = ancestors.length; i < l; i++) {
|
898
896
|
var ancestor = ancestors[i],
|
@@ -956,12 +954,7 @@
|
|
956
954
|
};
|
957
955
|
|
958
956
|
Opal.own_methods = function(obj) {
|
959
|
-
|
960
|
-
return Opal.own_instance_methods(obj.$$meta);
|
961
|
-
}
|
962
|
-
else {
|
963
|
-
return [];
|
964
|
-
}
|
957
|
+
return obj.$$meta ? Opal.own_instance_methods(obj.$$meta) : [];
|
965
958
|
};
|
966
959
|
|
967
960
|
Opal.receiver_methods = function(obj) {
|
@@ -978,7 +971,7 @@
|
|
978
971
|
// @param module [Module]
|
979
972
|
// @return [Object]
|
980
973
|
Opal.class_variables = function(module) {
|
981
|
-
var ancestors =
|
974
|
+
var ancestors = $ancestors(module),
|
982
975
|
i, length = ancestors.length,
|
983
976
|
result = {};
|
984
977
|
|
@@ -1000,7 +993,7 @@
|
|
1000
993
|
// @param name [String]
|
1001
994
|
// @param value [Object]
|
1002
995
|
Opal.class_variable_set = function(module, name, value) {
|
1003
|
-
var ancestors =
|
996
|
+
var ancestors = $ancestors(module),
|
1004
997
|
i, length = ancestors.length;
|
1005
998
|
|
1006
999
|
for (i = length - 2; i >= 0; i--) {
|
@@ -1025,7 +1018,7 @@
|
|
1025
1018
|
if ($has_own.call(module.$$cvars, name))
|
1026
1019
|
return module.$$cvars[name];
|
1027
1020
|
|
1028
|
-
var ancestors =
|
1021
|
+
var ancestors = $ancestors(module),
|
1029
1022
|
i, length = ancestors.length;
|
1030
1023
|
|
1031
1024
|
for (i = 0; i < length; i++) {
|
@@ -1105,7 +1098,7 @@
|
|
1105
1098
|
// @param includer [Module] the target class to include module into
|
1106
1099
|
// @return [null]
|
1107
1100
|
Opal.append_features = function(module, includer) {
|
1108
|
-
var module_ancestors =
|
1101
|
+
var module_ancestors = $ancestors(module);
|
1109
1102
|
var iclasses = [];
|
1110
1103
|
|
1111
1104
|
if (module_ancestors.indexOf(includer) !== -1) {
|
@@ -1117,7 +1110,7 @@
|
|
1117
1110
|
$prop(iclass, '$$included', true);
|
1118
1111
|
iclasses.push(iclass);
|
1119
1112
|
}
|
1120
|
-
var includer_ancestors =
|
1113
|
+
var includer_ancestors = $ancestors(includer),
|
1121
1114
|
chain = chain_iclasses(iclasses),
|
1122
1115
|
start_chain_after,
|
1123
1116
|
end_chain_on;
|
@@ -1210,7 +1203,7 @@
|
|
1210
1203
|
// iclass(prepender)
|
1211
1204
|
// |
|
1212
1205
|
// parent
|
1213
|
-
var module_ancestors =
|
1206
|
+
var module_ancestors = $ancestors(module);
|
1214
1207
|
var iclasses = [];
|
1215
1208
|
|
1216
1209
|
if (module_ancestors.indexOf(prepender) !== -1) {
|
@@ -1249,7 +1242,7 @@
|
|
1249
1242
|
$set_proto(prepender_iclass, previous_parent);
|
1250
1243
|
}
|
1251
1244
|
|
1252
|
-
var prepender_ancestors =
|
1245
|
+
var prepender_ancestors = $ancestors(prepender);
|
1253
1246
|
|
1254
1247
|
if (prepender_ancestors.indexOf(module) === -1) {
|
1255
1248
|
// first time prepend
|
@@ -1409,7 +1402,7 @@
|
|
1409
1402
|
}
|
1410
1403
|
|
1411
1404
|
// The Array of ancestors for a given module/class
|
1412
|
-
|
1405
|
+
function $ancestors(module) {
|
1413
1406
|
if (!module) { return []; }
|
1414
1407
|
|
1415
1408
|
if (module.$$ancestors_cache_version === Opal.const_cache_version) {
|
@@ -1423,7 +1416,7 @@
|
|
1423
1416
|
}
|
1424
1417
|
|
1425
1418
|
if (module.$$super) {
|
1426
|
-
for (i = 0, mods =
|
1419
|
+
for (i = 0, mods = $ancestors(module.$$super), length = mods.length; i < length; i++) {
|
1427
1420
|
result.push(mods[i]);
|
1428
1421
|
}
|
1429
1422
|
}
|
@@ -1433,6 +1426,7 @@
|
|
1433
1426
|
|
1434
1427
|
return result;
|
1435
1428
|
};
|
1429
|
+
Opal.ancestors = $ancestors;
|
1436
1430
|
|
1437
1431
|
Opal.included_modules = function(module) {
|
1438
1432
|
var result = [], mod = null, proto = Object.getPrototypeOf(module.$$prototype);
|
@@ -1514,7 +1508,7 @@
|
|
1514
1508
|
this.$method_missing.$$p = method_missing_stub.$$p;
|
1515
1509
|
|
1516
1510
|
// Set block property to null ready for the next call (stop false-positives)
|
1517
|
-
|
1511
|
+
method_missing_stub.$$p = null;
|
1518
1512
|
|
1519
1513
|
// call method missing with correct args (remove '$' prefix on method name)
|
1520
1514
|
var args_ary = new Array(arguments.length);
|
@@ -1564,15 +1558,19 @@
|
|
1564
1558
|
throw Opal.ArgumentError.$new(inspect + ': wrong number of arguments (given ' + actual + ', expected ' + expected + ')');
|
1565
1559
|
};
|
1566
1560
|
|
1561
|
+
function get_ancestors(obj) {
|
1562
|
+
if (obj.hasOwnProperty('$$meta') && obj.$$meta !== null) {
|
1563
|
+
return $ancestors(obj.$$meta);
|
1564
|
+
} else {
|
1565
|
+
return $ancestors(obj.$$class);
|
1566
|
+
}
|
1567
|
+
};
|
1568
|
+
|
1567
1569
|
// Super dispatcher
|
1568
1570
|
Opal.find_super = function(obj, mid, current_func, defcheck, allow_stubs) {
|
1569
1571
|
var jsid = '$' + mid, ancestors, super_method;
|
1570
1572
|
|
1571
|
-
|
1572
|
-
ancestors = Opal.ancestors(obj.$$meta);
|
1573
|
-
} else {
|
1574
|
-
ancestors = Opal.ancestors(obj.$$class);
|
1575
|
-
}
|
1573
|
+
ancestors = get_ancestors(obj);
|
1576
1574
|
|
1577
1575
|
var current_index = ancestors.indexOf(current_func.$$owner);
|
1578
1576
|
|
@@ -1626,30 +1624,6 @@
|
|
1626
1624
|
// @deprecated
|
1627
1625
|
Opal.find_iter_super_dispatcher = Opal.find_block_super;
|
1628
1626
|
|
1629
|
-
// Used to return as an expression. Sometimes, we can't simply return from
|
1630
|
-
// a javascript function as if we were a method, as the return is used as
|
1631
|
-
// an expression, or even inside a block which must "return" to the outer
|
1632
|
-
// method. This helper simply throws an error which is then caught by the
|
1633
|
-
// method. This approach is expensive, so it is only used when absolutely
|
1634
|
-
// needed.
|
1635
|
-
//
|
1636
|
-
Opal.ret = function(val) {
|
1637
|
-
Opal.returner.$v = val;
|
1638
|
-
throw Opal.returner;
|
1639
|
-
};
|
1640
|
-
|
1641
|
-
// Used to break out of a block.
|
1642
|
-
Opal.brk = function(val, breaker) {
|
1643
|
-
breaker.$v = val;
|
1644
|
-
throw breaker;
|
1645
|
-
};
|
1646
|
-
|
1647
|
-
// Builds a new unique breaker, this is to avoid multiple nested breaks to get
|
1648
|
-
// in the way of each other.
|
1649
|
-
Opal.new_brk = function() {
|
1650
|
-
return new Error('unexpected break');
|
1651
|
-
};
|
1652
|
-
|
1653
1627
|
// handles yield calls for 1 yielded arg
|
1654
1628
|
Opal.yield1 = function(block, arg) {
|
1655
1629
|
if (typeof(block) !== "function") {
|
@@ -1706,10 +1680,7 @@
|
|
1706
1680
|
return result;
|
1707
1681
|
}
|
1708
1682
|
}
|
1709
|
-
else if (candidate === Opal.JS.Error) {
|
1710
|
-
return candidate;
|
1711
|
-
}
|
1712
|
-
else if (candidate['$==='](exception)) {
|
1683
|
+
else if (candidate === Opal.JS.Error || candidate['$==='](exception)) {
|
1713
1684
|
return candidate;
|
1714
1685
|
}
|
1715
1686
|
}
|
@@ -1726,7 +1697,7 @@
|
|
1726
1697
|
return (klass.$$is_integer_class) ? (object % 1) === 0 : true;
|
1727
1698
|
}
|
1728
1699
|
|
1729
|
-
var ancestors =
|
1700
|
+
var ancestors = $ancestors(object.$$is_class ? Opal.get_singleton_class(object) : (object.$$meta || object.$$class));
|
1730
1701
|
|
1731
1702
|
return ancestors.indexOf(klass) !== -1;
|
1732
1703
|
};
|
@@ -1815,10 +1786,7 @@
|
|
1815
1786
|
var kwargs = parameters[parameters.length - 1];
|
1816
1787
|
if (kwargs != null && Opal.respond_to(kwargs, '$to_hash', true)) {
|
1817
1788
|
$splice.call(parameters, parameters.length - 1);
|
1818
|
-
return kwargs
|
1819
|
-
}
|
1820
|
-
else {
|
1821
|
-
return Opal.hash2([], {});
|
1789
|
+
return kwargs;
|
1822
1790
|
}
|
1823
1791
|
};
|
1824
1792
|
|
@@ -1913,33 +1881,33 @@
|
|
1913
1881
|
Opal.refined_send = function(refinement_groups, recv, method, args, block, blockopts) {
|
1914
1882
|
var i, j, k, ancestors, ancestor, refinements, refinement, refine_modules, refine_module, body;
|
1915
1883
|
|
1916
|
-
|
1917
|
-
ancestors = Opal.ancestors(recv.$$meta);
|
1918
|
-
} else {
|
1919
|
-
ancestors = Opal.ancestors(recv.$$class);
|
1920
|
-
}
|
1884
|
+
ancestors = get_ancestors(recv);
|
1921
1885
|
|
1922
1886
|
// For all ancestors that there are, starting from the closest to the furthest...
|
1923
1887
|
for (i = 0; i < ancestors.length; i++) {
|
1924
1888
|
ancestor = Opal.id(ancestors[i]);
|
1889
|
+
|
1925
1890
|
// For all refinement groups there are, starting from the closest scope to the furthest...
|
1926
1891
|
for (j = 0; j < refinement_groups.length; j++) {
|
1927
1892
|
refinements = refinement_groups[j];
|
1893
|
+
|
1928
1894
|
// For all refinements there are, starting from the last `using` call to the furthest...
|
1929
1895
|
for (k = refinements.length - 1; k >= 0; k--) {
|
1930
1896
|
refinement = refinements[k];
|
1931
1897
|
if (typeof refinement.$$refine_modules === 'undefined') continue;
|
1898
|
+
|
1932
1899
|
// A single module being given as an argument of the `using` call contains multiple
|
1933
1900
|
// refinement modules
|
1934
1901
|
refine_modules = refinement.$$refine_modules;
|
1902
|
+
|
1935
1903
|
// Does this module refine a given call for a given ancestor module?
|
1936
|
-
if (typeof refine_modules[ancestor]
|
1937
|
-
|
1938
|
-
|
1939
|
-
|
1940
|
-
|
1941
|
-
|
1942
|
-
|
1904
|
+
if (typeof refine_modules[ancestor] === 'undefined') continue;
|
1905
|
+
refine_module = refine_modules[ancestor];
|
1906
|
+
|
1907
|
+
// Does this module define a method we want to call?
|
1908
|
+
if (typeof refine_module.$$prototype['$'+method] !== 'undefined') {
|
1909
|
+
body = refine_module.$$prototype['$'+method];
|
1910
|
+
return Opal.send2(recv, body, method, args, block, blockopts);
|
1943
1911
|
}
|
1944
1912
|
}
|
1945
1913
|
}
|
@@ -2012,6 +1980,8 @@
|
|
2012
1980
|
|
2013
1981
|
// Define method on a module or class (see Opal.def).
|
2014
1982
|
Opal.defn = function(module, jsid, body) {
|
1983
|
+
$deny_frozen_access(module);
|
1984
|
+
|
2015
1985
|
body.displayName = jsid;
|
2016
1986
|
body.$$owner = module;
|
2017
1987
|
|
@@ -2149,7 +2119,7 @@
|
|
2149
2119
|
args[i] = arguments[i];
|
2150
2120
|
}
|
2151
2121
|
|
2152
|
-
|
2122
|
+
alias.$$p = null;
|
2153
2123
|
|
2154
2124
|
return Opal.send(this, body, args, block);
|
2155
2125
|
};
|
@@ -2177,14 +2147,14 @@
|
|
2177
2147
|
};
|
2178
2148
|
|
2179
2149
|
Opal.alias_gvar = function(new_name, old_name) {
|
2180
|
-
Object.defineProperty(
|
2150
|
+
Object.defineProperty($gvars, new_name, {
|
2181
2151
|
configurable: true,
|
2182
2152
|
enumerable: true,
|
2183
2153
|
get: function() {
|
2184
|
-
return
|
2154
|
+
return $gvars[old_name];
|
2185
2155
|
},
|
2186
2156
|
set: function(new_value) {
|
2187
|
-
|
2157
|
+
$gvars[old_name] = new_value;
|
2188
2158
|
}
|
2189
2159
|
});
|
2190
2160
|
return nil;
|
@@ -2430,35 +2400,37 @@
|
|
2430
2400
|
hash = new Opal.Hash();
|
2431
2401
|
Opal.hash_init(hash);
|
2432
2402
|
|
2433
|
-
if (arguments_length === 1
|
2403
|
+
if (arguments_length === 1) {
|
2434
2404
|
args = arguments[0];
|
2435
|
-
length = args.length;
|
2436
2405
|
|
2437
|
-
|
2438
|
-
|
2439
|
-
throw Opal.ArgumentError.$new("value not of length 2: " + args[i].$inspect());
|
2440
|
-
}
|
2441
|
-
|
2442
|
-
key = args[i][0];
|
2443
|
-
value = args[i][1];
|
2444
|
-
|
2445
|
-
Opal.hash_put(hash, key, value);
|
2446
|
-
}
|
2406
|
+
if (arguments[0].$$is_array) {
|
2407
|
+
length = args.length;
|
2447
2408
|
|
2448
|
-
|
2449
|
-
|
2409
|
+
for (i = 0; i < length; i++) {
|
2410
|
+
if (args[i].length !== 2) {
|
2411
|
+
throw Opal.ArgumentError.$new("value not of length 2: " + args[i].$inspect());
|
2412
|
+
}
|
2450
2413
|
|
2451
|
-
|
2452
|
-
|
2453
|
-
for (key in args) {
|
2454
|
-
if ($has_own.call(args, key)) {
|
2455
|
-
value = args[key];
|
2414
|
+
key = args[i][0];
|
2415
|
+
value = args[i][1];
|
2456
2416
|
|
2457
2417
|
Opal.hash_put(hash, key, value);
|
2458
2418
|
}
|
2419
|
+
|
2420
|
+
return hash;
|
2459
2421
|
}
|
2422
|
+
else {
|
2423
|
+
args = arguments[0];
|
2424
|
+
for (key in args) {
|
2425
|
+
if ($has_own.call(args, key)) {
|
2426
|
+
value = args[key];
|
2460
2427
|
|
2461
|
-
|
2428
|
+
Opal.hash_put(hash, key, value);
|
2429
|
+
}
|
2430
|
+
}
|
2431
|
+
|
2432
|
+
return hash;
|
2433
|
+
}
|
2462
2434
|
}
|
2463
2435
|
|
2464
2436
|
if (arguments_length % 2 !== 0) {
|
@@ -2502,30 +2474,89 @@
|
|
2502
2474
|
return range;
|
2503
2475
|
};
|
2504
2476
|
|
2477
|
+
var reserved_ivar_names = [
|
2478
|
+
// properties
|
2479
|
+
"constructor", "displayName", "__count__", "__noSuchMethod__",
|
2480
|
+
"__parent__", "__proto__",
|
2481
|
+
// methods
|
2482
|
+
"hasOwnProperty", "valueOf"
|
2483
|
+
];
|
2484
|
+
|
2505
2485
|
// Get the ivar name for a given name.
|
2506
2486
|
// Mostly adds a trailing $ to reserved names.
|
2507
2487
|
//
|
2508
2488
|
Opal.ivar = function(name) {
|
2509
|
-
if (
|
2510
|
-
|
2511
|
-
name === "constructor" ||
|
2512
|
-
name === "displayName" ||
|
2513
|
-
name === "__count__" ||
|
2514
|
-
name === "__noSuchMethod__" ||
|
2515
|
-
name === "__parent__" ||
|
2516
|
-
name === "__proto__" ||
|
2517
|
-
|
2518
|
-
// methods
|
2519
|
-
name === "hasOwnProperty" ||
|
2520
|
-
name === "valueOf"
|
2521
|
-
)
|
2522
|
-
{
|
2523
|
-
return name + "$";
|
2489
|
+
if (reserved_ivar_names.indexOf(name) !== -1) {
|
2490
|
+
name += "$";
|
2524
2491
|
}
|
2525
2492
|
|
2526
2493
|
return name;
|
2527
2494
|
};
|
2528
2495
|
|
2496
|
+
// Support for #freeze
|
2497
|
+
// -------------------
|
2498
|
+
|
2499
|
+
// helper that can be used from methods
|
2500
|
+
function $deny_frozen_access(obj) {
|
2501
|
+
if (obj.$$frozen) {
|
2502
|
+
throw Opal.FrozenError.$new("can't modify frozen " + (obj.$class()) + ": " + (obj), Opal.hash2(["receiver"], {"receiver": obj}));
|
2503
|
+
}
|
2504
|
+
};
|
2505
|
+
Opal.deny_frozen_access = $deny_frozen_access;
|
2506
|
+
|
2507
|
+
// common #freeze runtime support
|
2508
|
+
Opal.freeze = function(obj) {
|
2509
|
+
$prop(obj, "$$frozen", true);
|
2510
|
+
|
2511
|
+
// set $$id
|
2512
|
+
if (!obj.hasOwnProperty('$$id')) { $prop(obj, '$$id', $uid()); }
|
2513
|
+
|
2514
|
+
if (obj.hasOwnProperty('$$meta')) {
|
2515
|
+
// freeze $$meta if it has already been set
|
2516
|
+
obj.$$meta.$freeze();
|
2517
|
+
} else {
|
2518
|
+
// ensure $$meta can be set lazily, $$meta is frozen when set in runtime.js
|
2519
|
+
$prop(obj, '$$meta', null);
|
2520
|
+
}
|
2521
|
+
|
2522
|
+
// $$comparable is used internally and set multiple times
|
2523
|
+
// defining it before sealing ensures it can be modified later on
|
2524
|
+
if (!obj.hasOwnProperty('$$comparable')) { $prop(obj, '$$comparable', null); }
|
2525
|
+
|
2526
|
+
// seal the Object
|
2527
|
+
Object.seal(obj);
|
2528
|
+
|
2529
|
+
return obj;
|
2530
|
+
};
|
2531
|
+
|
2532
|
+
// freze props, make setters of instance variables throw FrozenError
|
2533
|
+
Opal.freeze_props = function(obj) {
|
2534
|
+
var prop, prop_type, desc;
|
2535
|
+
|
2536
|
+
for(prop in obj) {
|
2537
|
+
prop_type = typeof(prop);
|
2538
|
+
|
2539
|
+
// prop_type "object" here is a String(), skip $ props
|
2540
|
+
if ((prop_type === "string" || prop_type === "object") && prop[0] === '$') {
|
2541
|
+
continue;
|
2542
|
+
}
|
2543
|
+
|
2544
|
+
desc = Object.getOwnPropertyDescriptor(obj, prop);
|
2545
|
+
if (desc && desc.enumerable && desc.writable) {
|
2546
|
+
// create closure to retain current value as cv
|
2547
|
+
// for Opal 2.0 let for cv should do the trick, instead of a function
|
2548
|
+
(function() {
|
2549
|
+
// set v to undefined, as if the property is not set
|
2550
|
+
var cv = obj[prop];
|
2551
|
+
Object.defineProperty(obj, prop, {
|
2552
|
+
get: function() { return cv; },
|
2553
|
+
set: function(_val) { $deny_frozen_access(obj); },
|
2554
|
+
enumerable: true
|
2555
|
+
});
|
2556
|
+
})();
|
2557
|
+
}
|
2558
|
+
}
|
2559
|
+
};
|
2529
2560
|
|
2530
2561
|
// Regexps
|
2531
2562
|
// -------
|
@@ -2560,21 +2591,23 @@
|
|
2560
2591
|
// on the object itself ($$gm or $$g attribute).
|
2561
2592
|
//
|
2562
2593
|
Opal.global_multiline_regexp = function(pattern) {
|
2563
|
-
var result;
|
2594
|
+
var result, flags;
|
2595
|
+
|
2596
|
+
// RegExp already has the global and multiline flag
|
2597
|
+
if (pattern.global && pattern.multiline) return pattern;
|
2598
|
+
|
2599
|
+
flags = 'gm' + (pattern.ignoreCase ? 'i' : '');
|
2564
2600
|
if (pattern.multiline) {
|
2565
|
-
if (pattern.global) {
|
2566
|
-
return pattern; // RegExp already has the global and multiline flag
|
2567
|
-
}
|
2568
2601
|
// we are using the $$g attribute because the Regexp is already multiline
|
2569
|
-
if (pattern.$$g
|
2570
|
-
|
2571
|
-
} else {
|
2572
|
-
result = pattern.$$g = new RegExp(pattern.source, 'gm' + (pattern.ignoreCase ? 'i' : ''));
|
2602
|
+
if (pattern.$$g == null) {
|
2603
|
+
pattern.$$g = new RegExp(pattern.source, flags);
|
2573
2604
|
}
|
2574
|
-
|
2575
|
-
result = pattern.$$gm;
|
2605
|
+
result = pattern.$$g;
|
2576
2606
|
} else {
|
2577
|
-
|
2607
|
+
if (pattern.$$gm == null) {
|
2608
|
+
pattern.$$gm = new RegExp(pattern.source, flags);
|
2609
|
+
}
|
2610
|
+
result = pattern.$$gm;
|
2578
2611
|
}
|
2579
2612
|
result.lastIndex = null; // reset lastIndex property
|
2580
2613
|
return result;
|
@@ -2650,9 +2683,7 @@
|
|
2650
2683
|
}
|
2651
2684
|
};
|
2652
2685
|
|
2653
|
-
Opal.
|
2654
|
-
path = Opal.normalize(path);
|
2655
|
-
|
2686
|
+
Opal.load_normalized = function(path) {
|
2656
2687
|
Opal.loaded([path]);
|
2657
2688
|
|
2658
2689
|
var module = Opal.modules[path];
|
@@ -2684,6 +2715,12 @@
|
|
2684
2715
|
return true;
|
2685
2716
|
};
|
2686
2717
|
|
2718
|
+
Opal.load = function(path) {
|
2719
|
+
path = Opal.normalize(path);
|
2720
|
+
|
2721
|
+
return Opal.load_normalized(path);
|
2722
|
+
};
|
2723
|
+
|
2687
2724
|
Opal.require = function(path) {
|
2688
2725
|
path = Opal.normalize(path);
|
2689
2726
|
|
@@ -2691,7 +2728,7 @@
|
|
2691
2728
|
return false;
|
2692
2729
|
}
|
2693
2730
|
|
2694
|
-
return Opal.
|
2731
|
+
return Opal.load_normalized(path);
|
2695
2732
|
};
|
2696
2733
|
|
2697
2734
|
|
@@ -2775,42 +2812,37 @@
|
|
2775
2812
|
|
2776
2813
|
// Operator helpers
|
2777
2814
|
// ----------------
|
2778
|
-
|
2779
|
-
|
2780
|
-
|
2781
|
-
Opal.
|
2782
|
-
Opal.
|
2783
|
-
Opal.
|
2784
|
-
Opal.
|
2785
|
-
Opal.
|
2815
|
+
|
2816
|
+
function are_both_numbers(l,r) { return typeof(l) === 'number' && typeof(r) === 'number' }
|
2817
|
+
|
2818
|
+
Opal.rb_plus = function(l,r) { return are_both_numbers(l,r) ? l + r : l['$+'](r); }
|
2819
|
+
Opal.rb_minus = function(l,r) { return are_both_numbers(l,r) ? l - r : l['$-'](r); }
|
2820
|
+
Opal.rb_times = function(l,r) { return are_both_numbers(l,r) ? l * r : l['$*'](r); }
|
2821
|
+
Opal.rb_divide = function(l,r) { return are_both_numbers(l,r) ? l / r : l['$/'](r); }
|
2822
|
+
Opal.rb_lt = function(l,r) { return are_both_numbers(l,r) ? l < r : l['$<'](r); }
|
2823
|
+
Opal.rb_gt = function(l,r) { return are_both_numbers(l,r) ? l > r : l['$>'](r); }
|
2824
|
+
Opal.rb_le = function(l,r) { return are_both_numbers(l,r) ? l <= r : l['$<='](r); }
|
2825
|
+
Opal.rb_ge = function(l,r) { return are_both_numbers(l,r) ? l >= r : l['$>='](r); }
|
2786
2826
|
|
2787
2827
|
// Optimized helpers for calls like $truthy((a)['$==='](b)) -> $eqeqeq(a, b)
|
2828
|
+
function are_both_numbers_or_strings(lhs, rhs) {
|
2829
|
+
return (typeof lhs === 'number' && typeof rhs === 'number') ||
|
2830
|
+
(typeof lhs === 'string' && typeof rhs === 'string');
|
2831
|
+
}
|
2832
|
+
|
2788
2833
|
function $eqeq(lhs, rhs) {
|
2789
|
-
|
2790
|
-
(typeof lhs === 'string' && typeof rhs === 'string')) {
|
2791
|
-
return lhs === rhs;
|
2792
|
-
}
|
2793
|
-
return $truthy((lhs)['$=='](rhs));
|
2834
|
+
return are_both_numbers_or_strings(lhs,rhs) ? lhs === rhs : $truthy((lhs)['$=='](rhs));
|
2794
2835
|
};
|
2795
2836
|
Opal.eqeq = $eqeq;
|
2796
|
-
|
2797
2837
|
Opal.eqeqeq = function(lhs, rhs) {
|
2798
|
-
|
2799
|
-
(typeof lhs === 'string' && typeof rhs === 'string')) {
|
2800
|
-
return lhs === rhs;
|
2801
|
-
}
|
2802
|
-
return $truthy((lhs)['$==='](rhs));
|
2838
|
+
return are_both_numbers_or_strings(lhs,rhs) ? lhs === rhs : $truthy((lhs)['$==='](rhs));
|
2803
2839
|
};
|
2804
2840
|
Opal.neqeq = function(lhs, rhs) {
|
2805
|
-
|
2806
|
-
(typeof lhs === 'string' && typeof rhs === 'string')) {
|
2807
|
-
return lhs !== rhs;
|
2808
|
-
}
|
2809
|
-
return $truthy((lhs)['$!='](rhs));
|
2841
|
+
return are_both_numbers_or_strings(lhs,rhs) ? lhs !== rhs : $truthy((lhs)['$!='](rhs));
|
2810
2842
|
};
|
2811
2843
|
Opal.not = function(arg) {
|
2812
|
-
if (true === arg) return false;
|
2813
2844
|
if (undefined === arg || null === arg || false === arg || nil === arg) return true;
|
2845
|
+
if (true === arg || arg['$!'].$$pristine) return false;
|
2814
2846
|
return $truthy(arg['$!']());
|
2815
2847
|
}
|
2816
2848
|
|
@@ -2827,29 +2859,49 @@
|
|
2827
2859
|
}
|
2828
2860
|
Opal.return_ivar = function(ivar) {
|
2829
2861
|
return function() {
|
2830
|
-
if (this[ivar] == null)
|
2862
|
+
if (this[ivar] == null) { return nil; }
|
2831
2863
|
return this[ivar];
|
2832
2864
|
}
|
2833
2865
|
}
|
2834
2866
|
Opal.assign_ivar = function(ivar) {
|
2835
2867
|
return function(val) {
|
2868
|
+
$deny_frozen_access(this);
|
2836
2869
|
return this[ivar] = val;
|
2837
2870
|
}
|
2838
2871
|
}
|
2839
2872
|
Opal.assign_ivar_val = function(ivar, static_val) {
|
2840
2873
|
return function() {
|
2874
|
+
$deny_frozen_access(this);
|
2841
2875
|
return this[ivar] = static_val;
|
2842
2876
|
}
|
2843
2877
|
}
|
2844
2878
|
|
2879
|
+
// Primitives for handling parameters
|
2880
|
+
Opal.ensure_kwargs = function(kwargs) {
|
2881
|
+
if (kwargs == null) {
|
2882
|
+
return Opal.hash2([], {});
|
2883
|
+
} else if (kwargs.$$is_hash) {
|
2884
|
+
return kwargs;
|
2885
|
+
} else {
|
2886
|
+
throw Opal.ArgumentError.$new('expected kwargs');
|
2887
|
+
}
|
2888
|
+
}
|
2889
|
+
|
2890
|
+
Opal.get_kwarg = function(kwargs, key) {
|
2891
|
+
if (!$has_own.call(kwargs.$$smap, key)) {
|
2892
|
+
throw Opal.ArgumentError.$new('missing keyword: '+key);
|
2893
|
+
}
|
2894
|
+
return kwargs.$$smap[key];
|
2895
|
+
}
|
2896
|
+
|
2845
2897
|
// Initialization
|
2846
2898
|
// --------------
|
2847
|
-
Opal.BasicObject = BasicObject =
|
2848
|
-
Opal.Object = _Object =
|
2849
|
-
Opal.Module = Module =
|
2850
|
-
Opal.Class = Class =
|
2851
|
-
Opal.Opal = _Opal =
|
2852
|
-
Opal.Kernel = Kernel =
|
2899
|
+
Opal.BasicObject = BasicObject = $allocate_class('BasicObject', null);
|
2900
|
+
Opal.Object = _Object = $allocate_class('Object', Opal.BasicObject);
|
2901
|
+
Opal.Module = Module = $allocate_class('Module', Opal.Object);
|
2902
|
+
Opal.Class = Class = $allocate_class('Class', Opal.Module);
|
2903
|
+
Opal.Opal = _Opal = $allocate_module('Opal');
|
2904
|
+
Opal.Kernel = Kernel = $allocate_module('Kernel');
|
2853
2905
|
|
2854
2906
|
$set_proto(Opal.BasicObject, Opal.Class.$$prototype);
|
2855
2907
|
$set_proto(Opal.Object, Opal.Class.$$prototype);
|
@@ -2857,7 +2909,7 @@
|
|
2857
2909
|
$set_proto(Opal.Class, Opal.Class.$$prototype);
|
2858
2910
|
|
2859
2911
|
// BasicObject can reach itself, avoid const_set to skip the $$base_module logic
|
2860
|
-
BasicObject.$$const
|
2912
|
+
BasicObject.$$const.BasicObject = BasicObject;
|
2861
2913
|
|
2862
2914
|
// Assign basic constants
|
2863
2915
|
$const_set(_Object, "BasicObject", BasicObject);
|
@@ -2899,19 +2951,36 @@
|
|
2899
2951
|
function top_define_method() {
|
2900
2952
|
var args = Opal.slice.call(arguments);
|
2901
2953
|
var block = top_define_method.$$p;
|
2902
|
-
|
2954
|
+
top_define_method.$$p = null;
|
2903
2955
|
return Opal.send(_Object, 'define_method', args, block)
|
2904
2956
|
};
|
2905
2957
|
|
2906
2958
|
// Nil
|
2907
|
-
Opal.NilClass =
|
2959
|
+
Opal.NilClass = $allocate_class('NilClass', Opal.Object);
|
2908
2960
|
$const_set(_Object, 'NilClass', Opal.NilClass);
|
2909
2961
|
nil = Opal.nil = new Opal.NilClass();
|
2910
2962
|
nil.$$id = nil_id;
|
2911
2963
|
nil.call = nil.apply = function() { throw Opal.LocalJumpError.$new('no block given'); };
|
2964
|
+
nil.$$frozen = true;
|
2965
|
+
nil.$$comparable = false;
|
2966
|
+
Object.seal(nil);
|
2967
|
+
|
2968
|
+
Opal.thrower = function(type) {
|
2969
|
+
var thrower = new Error('unexpected '+type);
|
2970
|
+
thrower.$thrower_type = type;
|
2971
|
+
thrower.$throw = function(value) {
|
2972
|
+
if (value == null) value = nil;
|
2973
|
+
thrower.$v = value;
|
2974
|
+
throw thrower;
|
2975
|
+
};
|
2976
|
+
return thrower;
|
2977
|
+
};
|
2978
|
+
|
2979
|
+
Opal.t_eval_return = Opal.thrower("return");
|
2912
2980
|
|
2913
|
-
// Errors
|
2914
|
-
Opal.breaker = new Error('unexpected break (old)');
|
2915
|
-
Opal.returner = new Error('unexpected return');
|
2916
2981
|
TypeError.$$super = Error;
|
2982
|
+
|
2983
|
+
// If enable-file-source-embed compiler option is enabled, each module loaded will add its
|
2984
|
+
// sources to this object
|
2985
|
+
Opal.file_sources = {};
|
2917
2986
|
}).call(this);
|