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.
Files changed (131) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build.yml +4 -1
  3. data/HACKING.md +23 -0
  4. data/UNRELEASED.md +42 -0
  5. data/benchmark/run.rb +1 -0
  6. data/docs/compiled_ruby.md +8 -0
  7. data/docs/compiler.md +1 -1
  8. data/docs/compiler_directives.md +1 -1
  9. data/docs/getting_started.md +17 -0
  10. data/docs/headless_chrome.md +1 -1
  11. data/docs/index.md +123 -0
  12. data/docs/templates.md +37 -37
  13. data/docs/unsupported_features.md +0 -4
  14. data/lib/opal/builder.rb +59 -39
  15. data/lib/opal/builder_scheduler/prefork.rb +259 -0
  16. data/lib/opal/builder_scheduler/sequential.rb +13 -0
  17. data/lib/opal/builder_scheduler.rb +29 -0
  18. data/lib/opal/cache/file_cache.rb +5 -0
  19. data/lib/opal/cli.rb +22 -18
  20. data/lib/opal/cli_options.rb +4 -0
  21. data/lib/opal/cli_runners/chrome.rb +13 -9
  22. data/lib/opal/cli_runners/chrome_cdp_interface.rb +19 -2
  23. data/lib/opal/cli_runners/compiler.rb +1 -1
  24. data/lib/opal/cli_runners/gjs.rb +3 -1
  25. data/lib/opal/cli_runners/mini_racer.rb +5 -3
  26. data/lib/opal/cli_runners/nodejs.rb +3 -3
  27. data/lib/opal/cli_runners/server.rb +13 -28
  28. data/lib/opal/cli_runners/system_runner.rb +5 -3
  29. data/lib/opal/cli_runners.rb +7 -6
  30. data/lib/opal/compiler.rb +25 -2
  31. data/lib/opal/config.rb +10 -0
  32. data/lib/opal/nodes/args/ensure_kwargs_are_kwargs.rb +2 -6
  33. data/lib/opal/nodes/args/extract_kwarg.rb +3 -4
  34. data/lib/opal/nodes/args/extract_kwargs.rb +3 -1
  35. data/lib/opal/nodes/args/extract_kwoptarg.rb +1 -1
  36. data/lib/opal/nodes/args/extract_kwrestarg.rb +4 -1
  37. data/lib/opal/nodes/args/extract_optarg.rb +1 -1
  38. data/lib/opal/nodes/args/extract_post_arg.rb +1 -1
  39. data/lib/opal/nodes/args/extract_post_optarg.rb +1 -1
  40. data/lib/opal/nodes/args/extract_restarg.rb +2 -2
  41. data/lib/opal/nodes/args/initialize_iterarg.rb +1 -1
  42. data/lib/opal/nodes/args/initialize_shadowarg.rb +1 -1
  43. data/lib/opal/nodes/args/prepare_post_args.rb +4 -2
  44. data/lib/opal/nodes/base.rb +14 -3
  45. data/lib/opal/nodes/call.rb +10 -14
  46. data/lib/opal/nodes/class.rb +3 -1
  47. data/lib/opal/nodes/closure.rb +250 -0
  48. data/lib/opal/nodes/def.rb +7 -11
  49. data/lib/opal/nodes/definitions.rb +4 -2
  50. data/lib/opal/nodes/if.rb +12 -2
  51. data/lib/opal/nodes/iter.rb +11 -17
  52. data/lib/opal/nodes/logic.rb +15 -63
  53. data/lib/opal/nodes/module.rb +3 -1
  54. data/lib/opal/nodes/rescue.rb +23 -15
  55. data/lib/opal/nodes/scope.rb +7 -1
  56. data/lib/opal/nodes/top.rb +27 -4
  57. data/lib/opal/nodes/while.rb +42 -26
  58. data/lib/opal/nodes.rb +1 -0
  59. data/lib/opal/os.rb +59 -0
  60. data/lib/opal/rewriter.rb +2 -0
  61. data/lib/opal/rewriters/returnable_logic.rb +14 -0
  62. data/lib/opal/rewriters/thrower_finder.rb +90 -0
  63. data/lib/opal/simple_server.rb +12 -6
  64. data/lib/opal/source_map/file.rb +1 -1
  65. data/lib/opal/source_map/map.rb +9 -1
  66. data/lib/opal/util.rb +1 -1
  67. data/lib/opal/version.rb +1 -1
  68. data/opal/corelib/array.rb +68 -3
  69. data/opal/corelib/basic_object.rb +1 -0
  70. data/opal/corelib/comparable.rb +1 -1
  71. data/opal/corelib/complex.rb +1 -0
  72. data/opal/corelib/constants.rb +2 -2
  73. data/opal/corelib/enumerable.rb +4 -2
  74. data/opal/corelib/enumerator/chain.rb +4 -0
  75. data/opal/corelib/enumerator/generator.rb +5 -3
  76. data/opal/corelib/enumerator/lazy.rb +3 -1
  77. data/opal/corelib/enumerator/yielder.rb +2 -4
  78. data/opal/corelib/enumerator.rb +3 -1
  79. data/opal/corelib/error/errno.rb +2 -1
  80. data/opal/corelib/error.rb +13 -2
  81. data/opal/corelib/hash.rb +39 -1
  82. data/opal/corelib/kernel.rb +56 -5
  83. data/opal/corelib/module.rb +60 -4
  84. data/opal/corelib/proc.rb +8 -5
  85. data/opal/corelib/rational.rb +1 -0
  86. data/opal/corelib/regexp.rb +15 -1
  87. data/opal/corelib/runtime.js +307 -238
  88. data/opal/corelib/string/encoding.rb +0 -6
  89. data/opal/corelib/string.rb +28 -7
  90. data/opal/corelib/time.rb +5 -2
  91. data/opal/corelib/unsupported.rb +2 -14
  92. data/spec/filters/bugs/delegate.rb +11 -0
  93. data/spec/filters/bugs/kernel.rb +1 -3
  94. data/spec/filters/bugs/language.rb +3 -23
  95. data/spec/filters/bugs/method.rb +0 -1
  96. data/spec/filters/bugs/module.rb +0 -3
  97. data/spec/filters/bugs/proc.rb +0 -3
  98. data/spec/filters/bugs/set.rb +4 -16
  99. data/spec/filters/bugs/unboundmethod.rb +0 -2
  100. data/spec/filters/unsupported/array.rb +0 -58
  101. data/spec/filters/unsupported/freeze.rb +8 -192
  102. data/spec/filters/unsupported/hash.rb +0 -25
  103. data/spec/filters/unsupported/kernel.rb +0 -1
  104. data/spec/filters/unsupported/privacy.rb +17 -0
  105. data/spec/lib/builder_spec.rb +14 -0
  106. data/spec/lib/cli_runners/server_spec.rb +2 -3
  107. data/spec/lib/cli_spec.rb +1 -1
  108. data/spec/lib/compiler_spec.rb +1 -1
  109. data/spec/opal/core/language/if_spec.rb +13 -0
  110. data/spec/opal/core/module_spec.rb +8 -0
  111. data/spec/ruby_specs +2 -1
  112. data/stdlib/await.rb +44 -7
  113. data/stdlib/delegate.rb +427 -6
  114. data/stdlib/headless_chrome.rb +6 -2
  115. data/stdlib/nodejs/file.rb +2 -1
  116. data/stdlib/opal-parser.rb +1 -1
  117. data/stdlib/opal-platform.rb +1 -1
  118. data/stdlib/opal-replutils.rb +5 -3
  119. data/stdlib/promise.rb +3 -0
  120. data/stdlib/rbconfig.rb +4 -1
  121. data/stdlib/ruby2_keywords.rb +60 -0
  122. data/stdlib/set.rb +21 -0
  123. data/tasks/performance.rake +41 -35
  124. data/tasks/releasing.rake +1 -0
  125. data/tasks/testing/mspec_special_calls.rb +1 -0
  126. data/tasks/testing.rake +5 -5
  127. data/test/nodejs/test_await.rb +39 -1
  128. metadata +27 -14
  129. data/docs/faq.md +0 -17
  130. data/lib/opal/rewriters/break_finder.rb +0 -36
  131. data/spec/opal/core/kernel/freeze_spec.rb +0 -15
@@ -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
- Opal.uid = function() {
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 != null) {
102
- return obj.$$id;
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 (Opal.gvars.DEBUG) console.log('Exited with status '+status); };
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
- Opal.gvars["!"] = exception;
124
- Opal.gvars["@"] = exception.$backtrace();
124
+ $gvars["!"] = exception;
125
+ $gvars["@"] = exception.$backtrace();
125
126
  }
126
127
  else {
127
- Opal.gvars["!"] = Opal.gvars["@"] = nil;
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 = Opal.ancestors(cref);
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, skip_missing) {
332
- if (!skip_missing) {
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); if (result != null) return result;
350
- result = const_missing(cref, name, skip_missing); if (result != null) return 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, skip_missing);
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, skip_missing);
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(Opal.ancestors(cref));
458
- if (inherit && cref.$$is_module) modules = modules.concat([Opal.Object]).concat(Opal.ancestors(Opal.Object));
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
- Opal.allocate_class = function(name, superclass, singleton) {
538
- var klass, constructor;
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
- constructor = function() {
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
- constructor = function(){};
551
+ klass = function(){};
553
552
  }
554
553
 
555
554
  if (name && name !== nil) {
556
- $prop(constructor, 'displayName', '::'+name);
555
+ $prop(klass, 'displayName', '::'+name);
557
556
  }
558
557
 
559
- klass = constructor;
560
-
561
558
  $prop(klass, '$$name', name);
562
- $prop(klass, '$$constructor', constructor);
563
- $prop(klass, '$$prototype', constructor.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
- // Class doesn't exist, create a new one with given superclass...
682
-
683
- // Not specifying a superclass means we can assume it to be Object
684
- if (superclass == null) {
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
- // Create the class object (instance of Class)
689
- klass = Opal.allocate_class(name, superclass);
690
- $const_set(scope, name, klass);
682
+ // Create the class object (instance of Class)
683
+ klass = $allocate_class(name, superclass);
684
+ $const_set(scope, name, klass);
691
685
 
692
- // Call .inherited() hook with new class on the superclass
693
- if (superclass.$inherited) {
694
- superclass.$inherited(klass);
695
- }
686
+ // Call .inherited() hook with new class on the superclass
687
+ if (superclass.$inherited) {
688
+ superclass.$inherited(klass);
689
+ }
696
690
 
697
- if (bridged) {
698
- Opal.bridge(bridged, klass);
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
- Opal.allocate_module = function(name) {
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
- if (Opal.trace_class) { invoke_tracers_for_class(module); }
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 = Opal.allocate_class(null, superclass, true);
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
- $prop(klass, '$$meta', meta);
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 = Opal.allocate_class(null, Opal.Module, true);
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
- $prop(mod, '$$meta', meta);
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 = Opal.allocate_class(nil, superclass, true);
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
- $prop(object, '$$meta', klass);
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 = Opal.ancestors(mod);
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
- if (obj.$$meta) {
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 = Opal.ancestors(module),
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 = Opal.ancestors(module),
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 = Opal.ancestors(module),
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 = Opal.ancestors(module);
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 = Opal.ancestors(includer),
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 = Opal.ancestors(module);
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 = Opal.ancestors(prepender);
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
- Opal.ancestors = function(module) {
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 = Opal.ancestors(module.$$super), length = mods.length; i < length; i++) {
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
- delete method_missing_stub.$$p;
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
- if (obj.hasOwnProperty('$$meta')) {
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 = Opal.ancestors(object.$$is_class ? Opal.get_singleton_class(object) : (object.$$meta || object.$$class));
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.$to_hash();
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
- if (recv.hasOwnProperty('$$meta')) {
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] !== 'undefined') {
1937
- refine_module = refine_modules[ancestor];
1938
- // Does this module define a method we want to call?
1939
- if (typeof refine_module.$$prototype['$'+method] !== 'undefined') {
1940
- body = refine_module.$$prototype['$'+method];
1941
- return Opal.send2(recv, body, method, args, block, blockopts);
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
- delete alias.$$p;
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(Opal.gvars, new_name, {
2150
+ Object.defineProperty($gvars, new_name, {
2181
2151
  configurable: true,
2182
2152
  enumerable: true,
2183
2153
  get: function() {
2184
- return Opal.gvars[old_name];
2154
+ return $gvars[old_name];
2185
2155
  },
2186
2156
  set: function(new_value) {
2187
- Opal.gvars[old_name] = new_value;
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 && arguments[0].$$is_array) {
2403
+ if (arguments_length === 1) {
2434
2404
  args = arguments[0];
2435
- length = args.length;
2436
2405
 
2437
- for (i = 0; i < length; i++) {
2438
- if (args[i].length !== 2) {
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
- return hash;
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
- if (arguments_length === 1) {
2452
- args = arguments[0];
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
- return hash;
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
- // properties
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 != null) {
2570
- result = pattern.$$g;
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
- } else if (pattern.$$gm != null) {
2575
- result = pattern.$$gm;
2605
+ result = pattern.$$g;
2576
2606
  } else {
2577
- result = pattern.$$gm = new RegExp(pattern.source, 'gm' + (pattern.ignoreCase ? 'i' : ''));
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.load = function(path) {
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.load(path);
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
- Opal.rb_plus = function(l,r) { return (typeof(l) === 'number' && typeof(r) === 'number') ? l + r : l['$+'](r); }
2779
- Opal.rb_minus = function(l,r) { return (typeof(l) === 'number' && typeof(r) === 'number') ? l - r : l['$-'](r); }
2780
- Opal.rb_times = function(l,r) { return (typeof(l) === 'number' && typeof(r) === 'number') ? l * r : l['$*'](r); }
2781
- Opal.rb_divide = function(l,r) { return (typeof(l) === 'number' && typeof(r) === 'number') ? l / r : l['$/'](r); }
2782
- Opal.rb_lt = function(l,r) { return (typeof(l) === 'number' && typeof(r) === 'number') ? l < r : l['$<'](r); }
2783
- Opal.rb_gt = function(l,r) { return (typeof(l) === 'number' && typeof(r) === 'number') ? l > r : l['$>'](r); }
2784
- Opal.rb_le = function(l,r) { return (typeof(l) === 'number' && typeof(r) === 'number') ? l <= r : l['$<='](r); }
2785
- Opal.rb_ge = function(l,r) { return (typeof(l) === 'number' && typeof(r) === 'number') ? l >= r : l['$>='](r); }
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
- if ((typeof lhs === 'number' && typeof rhs === 'number') ||
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
- if ((typeof lhs === 'number' && typeof rhs === 'number') ||
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
- if ((typeof lhs === 'number' && typeof rhs === 'number') ||
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) this[ivar] = nil;
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 = Opal.allocate_class('BasicObject', null);
2848
- Opal.Object = _Object = Opal.allocate_class('Object', Opal.BasicObject);
2849
- Opal.Module = Module = Opal.allocate_class('Module', Opal.Object);
2850
- Opal.Class = Class = Opal.allocate_class('Class', Opal.Module);
2851
- Opal.Opal = _Opal = Opal.allocate_module('Opal');
2852
- Opal.Kernel = Kernel = Opal.allocate_module('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["BasicObject"] = BasicObject;
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
- delete top_define_method.$$p;
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 = Opal.allocate_class('NilClass', Opal.Object);
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);