opal 1.7.4 → 1.8.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.eslintrc.js +1 -0
- data/.github/workflows/build.yml +9 -9
- data/.rubocop/todo.yml +2 -2
- data/.rubocop.yml +17 -10
- data/.rubocop_todo.yml +311 -0
- data/CHANGELOG.md +1 -15
- data/README.md +7 -7
- data/UNRELEASED.md +92 -1
- data/benchmark-ips/bm_block_vs_yield.rb +3 -0
- data/benchmark-ips/bm_slice_or_not.rb +53 -0
- data/docs/bridging.md +112 -0
- data/docs/compiled_ruby.md +10 -10
- data/docs/getting_started.md +18 -22
- data/docs/releasing.md +8 -16
- data/lib/opal/cli_runners/chrome_cdp_interface.rb +1 -0
- data/lib/opal/cli_runners/firefox_cdp_interface.rb +1 -0
- data/lib/opal/compiler.rb +33 -1
- data/lib/opal/nodes/args/extract_kwoptarg.rb +2 -1
- data/lib/opal/nodes/call.rb +1 -1
- data/lib/opal/nodes/call_special.rb +71 -47
- data/lib/opal/nodes/closure.rb +15 -7
- data/lib/opal/nodes/defined.rb +1 -1
- data/lib/opal/nodes/hash.rb +14 -30
- data/lib/opal/nodes/if.rb +37 -29
- data/lib/opal/nodes/literal.rb +15 -7
- data/lib/opal/nodes/rescue.rb +1 -1
- data/lib/opal/nodes/x_string.rb +13 -0
- data/lib/opal/parser/patch.rb +1 -0
- data/lib/opal/rewriters/for_rewriter.rb +36 -24
- data/lib/opal/source_map/file.rb +1 -1
- data/lib/opal/version.rb +1 -1
- data/opal/corelib/array/pack.rb +1 -0
- data/opal/corelib/array.rb +110 -64
- data/opal/corelib/basic_object.rb +1 -0
- data/opal/corelib/binding.rb +2 -0
- data/opal/corelib/boolean.rb +1 -0
- data/opal/corelib/class.rb +28 -8
- data/opal/corelib/comparable.rb +1 -0
- data/opal/corelib/complex.rb +3 -1
- data/opal/corelib/constants.rb +2 -2
- data/opal/corelib/dir.rb +2 -0
- data/opal/corelib/enumerable.rb +3 -2
- data/opal/corelib/enumerator/arithmetic_sequence.rb +3 -1
- data/opal/corelib/enumerator/chain.rb +1 -0
- data/opal/corelib/enumerator/generator.rb +1 -0
- data/opal/corelib/enumerator/lazy.rb +1 -0
- data/opal/corelib/enumerator/yielder.rb +2 -0
- data/opal/corelib/enumerator.rb +1 -0
- data/opal/corelib/error/errno.rb +2 -0
- data/opal/corelib/error.rb +22 -0
- data/opal/corelib/file.rb +1 -0
- data/opal/corelib/hash.rb +224 -519
- data/opal/corelib/helpers.rb +1 -0
- data/opal/corelib/io.rb +2 -0
- data/opal/corelib/irb.rb +2 -0
- data/opal/corelib/kernel/format.rb +1 -0
- data/opal/corelib/kernel.rb +70 -15
- data/opal/corelib/main.rb +2 -0
- data/opal/corelib/marshal/read_buffer.rb +2 -0
- data/opal/corelib/marshal/write_buffer.rb +2 -0
- data/opal/corelib/math/polyfills.rb +2 -0
- data/opal/corelib/math.rb +1 -0
- data/opal/corelib/method.rb +2 -0
- data/opal/corelib/module.rb +45 -5
- data/opal/corelib/nil.rb +3 -1
- data/opal/corelib/number.rb +30 -1
- data/opal/corelib/numeric.rb +2 -0
- data/opal/corelib/object_space.rb +1 -0
- data/opal/corelib/pack_unpack/format_string_parser.rb +2 -0
- data/opal/corelib/proc.rb +30 -28
- data/opal/corelib/process.rb +2 -0
- data/opal/corelib/random/formatter.rb +2 -0
- data/opal/corelib/random/math_random.js.rb +2 -0
- data/opal/corelib/random/mersenne_twister.rb +2 -0
- data/opal/corelib/random/seedrandom.js.rb +2 -0
- data/opal/corelib/random.rb +1 -0
- data/opal/corelib/range.rb +35 -13
- data/opal/corelib/rational.rb +3 -1
- data/opal/corelib/regexp.rb +1 -0
- data/opal/corelib/runtime.js +297 -259
- data/opal/corelib/set.rb +2 -0
- data/opal/corelib/string/encoding.rb +3 -0
- data/opal/corelib/string/unpack.rb +2 -0
- data/opal/corelib/string.rb +56 -20
- data/opal/corelib/struct.rb +4 -2
- data/opal/corelib/time.rb +2 -1
- data/opal/corelib/trace_point.rb +2 -0
- data/opal/corelib/unsupported.rb +2 -0
- data/opal/corelib/variables.rb +2 -0
- data/opal.gemspec +2 -2
- data/spec/filters/bugs/array.rb +58 -2
- data/spec/filters/bugs/basicobject.rb +7 -0
- data/spec/filters/bugs/bigdecimal.rb +1 -2
- data/spec/filters/bugs/binding.rb +1 -0
- data/spec/filters/bugs/class.rb +2 -3
- data/spec/filters/bugs/complex.rb +3 -0
- data/spec/filters/bugs/date.rb +5 -2
- data/spec/filters/bugs/datetime.rb +1 -0
- data/spec/filters/bugs/delegate.rb +1 -2
- data/spec/filters/bugs/encoding.rb +1 -1
- data/spec/filters/bugs/enumerable.rb +11 -3
- data/spec/filters/bugs/enumerator.rb +15 -2
- data/spec/filters/bugs/exception.rb +9 -4
- data/spec/filters/bugs/file.rb +2 -0
- data/spec/filters/bugs/float.rb +1 -0
- data/spec/filters/bugs/freeze.rb +5 -49
- data/spec/filters/bugs/hash.rb +1 -13
- data/spec/filters/bugs/integer.rb +5 -6
- data/spec/filters/bugs/kernel.rb +12 -43
- data/spec/filters/bugs/language.rb +33 -15
- data/spec/filters/bugs/marshal.rb +63 -4
- data/spec/filters/bugs/method.rb +2 -10
- data/spec/filters/bugs/module.rb +18 -7
- data/spec/filters/bugs/objectspace.rb +2 -0
- data/spec/filters/bugs/pathname.rb +1 -0
- data/spec/filters/bugs/proc.rb +4 -2
- data/spec/filters/bugs/random.rb +0 -3
- data/spec/filters/bugs/range.rb +1 -2
- data/spec/filters/bugs/rational.rb +2 -0
- data/spec/filters/bugs/refinement.rb +19 -0
- data/spec/filters/bugs/regexp.rb +27 -5
- data/spec/filters/bugs/ruby-32.rb +0 -6
- data/spec/filters/bugs/set.rb +10 -2
- data/spec/filters/bugs/singleton.rb +0 -2
- data/spec/filters/bugs/string.rb +140 -2
- data/spec/filters/bugs/struct.rb +16 -10
- data/spec/filters/bugs/time.rb +56 -2
- data/spec/filters/bugs/trace_point.rb +1 -0
- data/spec/filters/bugs/unboundmethod.rb +4 -9
- data/spec/filters/bugs/warnings.rb +0 -1
- data/spec/filters/platform/firefox/exception.rb +3 -3
- data/spec/filters/platform/firefox/kernel.rb +1 -0
- data/spec/filters/platform/safari/exception.rb +2 -2
- data/spec/filters/platform/safari/float.rb +1 -0
- data/spec/filters/platform/safari/kernel.rb +1 -0
- data/spec/filters/platform/safari/literal_regexp.rb +2 -2
- data/spec/filters/unsupported/hash.rb +1 -0
- data/spec/lib/compiler_spec.rb +28 -17
- data/spec/mspec-opal/formatters.rb +2 -0
- data/spec/mspec-opal/runner.rb +2 -0
- data/spec/opal/core/array/dup_spec.rb +2 -0
- data/spec/opal/core/class/clone_spec.rb +36 -0
- data/spec/opal/core/exception_spec.rb +2 -0
- data/spec/opal/core/hash/internals_spec.rb +154 -206
- data/spec/opal/core/hash_spec.rb +2 -0
- data/spec/opal/core/iterable_props_spec.rb +2 -0
- data/spec/opal/core/kernel/at_exit_spec.rb +2 -0
- data/spec/opal/core/kernel/respond_to_spec.rb +2 -0
- data/spec/opal/core/language/arguments/mlhs_arg_spec.rb +2 -0
- data/spec/opal/core/language/safe_navigator_spec.rb +2 -0
- data/spec/opal/core/language/xstring_send_spec.rb +15 -0
- data/spec/opal/core/language/xstring_spec.rb +2 -0
- data/spec/opal/core/language_spec.rb +2 -0
- data/spec/opal/core/module_spec.rb +44 -0
- data/spec/opal/core/number/to_i_spec.rb +2 -0
- data/spec/opal/core/object_id_spec.rb +2 -6
- data/spec/opal/core/regexp/match_spec.rb +2 -0
- data/spec/opal/core/runtime/bridged_classes_spec.rb +38 -0
- data/spec/opal/core/runtime/constants_spec.rb +2 -0
- data/spec/opal/core/runtime/eval_spec.rb +2 -0
- data/spec/opal/core/runtime/exit_spec.rb +2 -0
- data/spec/opal/core/runtime/is_a_spec.rb +2 -0
- data/spec/opal/core/runtime/loaded_spec.rb +2 -0
- data/spec/opal/core/runtime/method_missing_spec.rb +2 -0
- data/spec/opal/core/runtime/rescue_spec.rb +2 -0
- data/spec/opal/core/runtime/string_spec.rb +2 -0
- data/spec/opal/core/runtime/truthy_spec.rb +2 -0
- data/spec/opal/core/runtime_spec.rb +2 -6
- data/spec/opal/core/string/to_sym_spec.rb +2 -0
- data/spec/opal/language/predefined_spec.rb +20 -0
- data/spec/opal/language/yield_spec.rb +43 -0
- data/spec/opal/stdlib/js_spec.rb +2 -0
- data/spec/opal/stdlib/native/alias_native_spec.rb +2 -0
- data/spec/opal/stdlib/native/array_spec.rb +2 -0
- data/spec/opal/stdlib/native/date_spec.rb +2 -0
- data/spec/opal/stdlib/native/each_spec.rb +2 -0
- data/spec/opal/stdlib/native/element_reference_spec.rb +2 -0
- data/spec/opal/stdlib/native/exposure_spec.rb +2 -0
- data/spec/opal/stdlib/native/ext_spec.rb +2 -0
- data/spec/opal/stdlib/native/hash_spec.rb +30 -2
- data/spec/opal/stdlib/native/initialize_spec.rb +2 -0
- data/spec/opal/stdlib/native/method_missing_spec.rb +2 -0
- data/spec/opal/stdlib/native/native_alias_spec.rb +2 -0
- data/spec/opal/stdlib/native/native_class_spec.rb +2 -0
- data/spec/opal/stdlib/native/native_module_spec.rb +2 -0
- data/spec/opal/stdlib/native/native_reader_spec.rb +2 -0
- data/spec/opal/stdlib/native/native_writer_spec.rb +2 -0
- data/spec/opal/stdlib/native/new_spec.rb +2 -0
- data/spec/opal/stdlib/native/struct_spec.rb +2 -0
- data/spec/ruby_specs +0 -2
- data/spec/spec_helper.rb +2 -0
- data/stdlib/await.rb +1 -0
- data/stdlib/base64.rb +2 -0
- data/stdlib/bigdecimal/bignumber.js.rb +2 -0
- data/stdlib/bigdecimal/util.rb +1 -0
- data/stdlib/bigdecimal.rb +4 -0
- data/stdlib/buffer/array.rb +2 -0
- data/stdlib/buffer/view.rb +2 -0
- data/stdlib/buffer.rb +2 -0
- data/stdlib/cgi.rb +14 -0
- data/stdlib/console.rb +2 -0
- data/stdlib/date/date_time.rb +2 -0
- data/stdlib/date.rb +2 -0
- data/stdlib/delegate.rb +5 -4
- data/stdlib/deno/base.rb +2 -0
- data/stdlib/deno/file.rb +2 -0
- data/stdlib/erb.rb +2 -0
- data/stdlib/gjs/io.rb +2 -0
- data/stdlib/gjs/kernel.rb +2 -0
- data/stdlib/headless_browser/base.rb +2 -0
- data/stdlib/headless_browser/file.rb +1 -0
- data/stdlib/headless_browser.rb +1 -0
- data/stdlib/js.rb +2 -0
- data/stdlib/json.rb +9 -15
- data/stdlib/logger.rb +2 -0
- data/stdlib/nashorn/file.rb +2 -0
- data/stdlib/nashorn/io.rb +2 -0
- data/stdlib/native.rb +48 -48
- data/stdlib/nodejs/base.rb +2 -0
- data/stdlib/nodejs/dir.rb +2 -0
- data/stdlib/nodejs/env.rb +2 -0
- data/stdlib/nodejs/file.rb +2 -0
- data/stdlib/nodejs/fileutils.rb +2 -0
- data/stdlib/nodejs/io.rb +2 -0
- data/stdlib/nodejs/js-yaml-3-6-1.js +1 -1
- data/stdlib/nodejs/kernel.rb +2 -0
- data/stdlib/nodejs/open-uri.rb +2 -0
- data/stdlib/nodejs/pathname.rb +2 -0
- data/stdlib/nodejs/require.rb +2 -0
- data/stdlib/nodejs/yaml.rb +9 -3
- data/stdlib/opal/miniracer.rb +2 -0
- data/stdlib/opal-parser.rb +8 -1
- data/stdlib/opal-platform.rb +2 -0
- data/stdlib/opal-replutils.rb +2 -0
- data/stdlib/open-uri.rb +4 -1
- data/stdlib/ostruct.rb +4 -2
- data/stdlib/pathname.rb +3 -1
- data/stdlib/pp.rb +1 -0
- data/stdlib/promise/v2.rb +24 -7
- data/stdlib/quickjs/io.rb +2 -0
- data/stdlib/quickjs/kernel.rb +2 -0
- data/stdlib/quickjs.rb +2 -0
- data/stdlib/securerandom.rb +2 -0
- data/stdlib/stringio.rb +2 -0
- data/stdlib/strscan.rb +2 -0
- data/stdlib/time.rb +2 -0
- data/stdlib/uri.rb +1 -0
- data/tasks/performance/optimization_status.rb +2 -0
- data/tasks/testing.rake +16 -11
- data/test/nodejs/test_await.rb +1 -0
- data/test/nodejs/test_dir.rb +2 -0
- data/test/nodejs/test_error.rb +2 -0
- data/test/nodejs/test_file.rb +2 -0
- data/test/nodejs/test_string.rb +2 -0
- data/test/nodejs/test_yaml.rb +20 -0
- data/test/opal/promisev2/test_always.rb +14 -0
- data/test/opal/unsupported_and_bugs.rb +0 -8
- metadata +26 -13
- data/spec/filters/bugs/openstruct.rb +0 -8
data/opal/corelib/runtime.js
CHANGED
@@ -119,14 +119,16 @@
|
|
119
119
|
|
120
120
|
// @private
|
121
121
|
// Pops an exception from the stack and updates `$!`.
|
122
|
-
Opal.pop_exception = function() {
|
122
|
+
Opal.pop_exception = function(rescued_exception) {
|
123
123
|
var exception = Opal.exceptions.pop();
|
124
|
-
if (exception) {
|
124
|
+
if (exception === rescued_exception) {
|
125
|
+
// Current $! is raised in the rescue block, so we don't update it
|
126
|
+
}
|
127
|
+
else if (exception) {
|
125
128
|
$gvars["!"] = exception;
|
126
|
-
$gvars["@"] = exception.$backtrace();
|
127
129
|
}
|
128
130
|
else {
|
129
|
-
$gvars["!"] =
|
131
|
+
$gvars["!"] = nil;
|
130
132
|
}
|
131
133
|
};
|
132
134
|
|
@@ -152,6 +154,14 @@
|
|
152
154
|
}
|
153
155
|
}
|
154
156
|
|
157
|
+
// Reuse the same object for performance/memory sake
|
158
|
+
var prop_options = {
|
159
|
+
value: undefined,
|
160
|
+
enumerable: false,
|
161
|
+
configurable: true,
|
162
|
+
writable: true
|
163
|
+
};
|
164
|
+
|
155
165
|
function $prop(object, name, initialValue) {
|
156
166
|
if (typeof(object) === "string") {
|
157
167
|
// Special case for:
|
@@ -163,12 +173,8 @@
|
|
163
173
|
// numbers, true, false and null do not support it.
|
164
174
|
object[name] = initialValue;
|
165
175
|
} else {
|
166
|
-
|
167
|
-
|
168
|
-
enumerable: false,
|
169
|
-
configurable: true,
|
170
|
-
writable: true
|
171
|
-
});
|
176
|
+
prop_options.value = initialValue;
|
177
|
+
Object.defineProperty(object, name, prop_options);
|
172
178
|
}
|
173
179
|
}
|
174
180
|
|
@@ -538,6 +544,13 @@
|
|
538
544
|
Opal.$$$ = Opal.const_get_qualified;
|
539
545
|
Opal.$r = Opal.const_get_relative_factory;
|
540
546
|
|
547
|
+
function descends_from_bridged_class(klass) {
|
548
|
+
if (klass == null) return false;
|
549
|
+
if (klass.$$bridge) return klass;
|
550
|
+
if (klass.$$super) return descends_from_bridged_class(klass.$$super);
|
551
|
+
return false;
|
552
|
+
}
|
553
|
+
|
541
554
|
// Modules & Classes
|
542
555
|
// -----------------
|
543
556
|
|
@@ -567,14 +580,13 @@
|
|
567
580
|
// @return new [Class] or existing ruby class
|
568
581
|
//
|
569
582
|
function $allocate_class(name, superclass, singleton) {
|
570
|
-
var klass;
|
583
|
+
var klass, bridged_descendant;
|
571
584
|
|
572
|
-
if (
|
585
|
+
if (bridged_descendant = descends_from_bridged_class(superclass)) {
|
573
586
|
// Inheritance from bridged classes requires
|
574
587
|
// calling original JS constructors
|
575
588
|
klass = function() {
|
576
|
-
var
|
577
|
-
self = new ($bind.apply(superclass.$$constructor, [null].concat(args)))();
|
589
|
+
var self = new ($bind.apply(bridged_descendant.$$constructor, $prepend(null, arguments)))();
|
578
590
|
|
579
591
|
// and replacing a __proto__ manually
|
580
592
|
$set_proto(self, klass.$$prototype);
|
@@ -601,6 +613,7 @@
|
|
601
613
|
$prop(klass, '$$ancestors', []);
|
602
614
|
$prop(klass, '$$ancestors_cache_version', null);
|
603
615
|
$prop(klass, '$$subclasses', []);
|
616
|
+
$prop(klass, '$$cloned_from', []);
|
604
617
|
|
605
618
|
$prop(klass.$$prototype, '$$class', klass);
|
606
619
|
|
@@ -768,6 +781,7 @@
|
|
768
781
|
$prop(module, '$$own_prepended_modules', []);
|
769
782
|
$prop(module, '$$ancestors', [module]);
|
770
783
|
$prop(module, '$$ancestors_cache_version', null);
|
784
|
+
$prop(module, '$$cloned_from', []);
|
771
785
|
|
772
786
|
$set_proto(module, Opal.Module.prototype);
|
773
787
|
|
@@ -1538,7 +1552,6 @@
|
|
1538
1552
|
// @param method_name [String] The js-name of the method to stub (e.g. "$foo")
|
1539
1553
|
// @return [undefined]
|
1540
1554
|
Opal.stub_for = function(method_name) {
|
1541
|
-
|
1542
1555
|
function method_missing_stub() {
|
1543
1556
|
// Copy any given block onto the method_missing dispatcher
|
1544
1557
|
this.$method_missing.$$p = method_missing_stub.$$p;
|
@@ -1547,11 +1560,8 @@
|
|
1547
1560
|
method_missing_stub.$$p = null;
|
1548
1561
|
|
1549
1562
|
// call method missing with correct args (remove '$' prefix on method name)
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
return this.$method_missing.apply(this, [method_name.slice(1)].concat(args_ary));
|
1554
|
-
}
|
1563
|
+
return this.$method_missing.apply(this, $prepend(method_name.slice(1), arguments));
|
1564
|
+
};
|
1555
1565
|
|
1556
1566
|
method_missing_stub.$$stub = true;
|
1557
1567
|
|
@@ -1604,15 +1614,22 @@
|
|
1604
1614
|
|
1605
1615
|
// Super dispatcher
|
1606
1616
|
Opal.find_super = function(obj, mid, current_func, defcheck, allow_stubs) {
|
1607
|
-
var jsid = $jsid(mid), ancestors, super_method;
|
1617
|
+
var jsid = $jsid(mid), ancestors, ancestor, super_method, method_owner, current_index = -1, i;
|
1608
1618
|
|
1609
1619
|
ancestors = get_ancestors(obj);
|
1620
|
+
method_owner = current_func.$$owner;
|
1610
1621
|
|
1611
|
-
|
1622
|
+
for (i = 0; i < ancestors.length; i++) {
|
1623
|
+
ancestor = ancestors[i];
|
1624
|
+
if (ancestor === method_owner || ancestor.$$cloned_from.indexOf(method_owner) !== -1) {
|
1625
|
+
current_index = i;
|
1626
|
+
break;
|
1627
|
+
}
|
1628
|
+
}
|
1612
1629
|
|
1613
|
-
for (
|
1614
|
-
|
1615
|
-
|
1630
|
+
for (i = current_index + 1; i < ancestors.length; i++) {
|
1631
|
+
ancestor = ancestors[i];
|
1632
|
+
var proto = ancestor.$$prototype;
|
1616
1633
|
|
1617
1634
|
if (proto.hasOwnProperty('$$dummy')) {
|
1618
1635
|
proto = proto.$$define_methods_on;
|
@@ -1660,6 +1677,17 @@
|
|
1660
1677
|
// @deprecated
|
1661
1678
|
Opal.find_iter_super_dispatcher = Opal.find_block_super;
|
1662
1679
|
|
1680
|
+
function call_lambda(block, arg, ret) {
|
1681
|
+
try {
|
1682
|
+
block(arg);
|
1683
|
+
} catch (e) {
|
1684
|
+
if (e === ret) {
|
1685
|
+
return ret.$v;
|
1686
|
+
}
|
1687
|
+
throw e;
|
1688
|
+
}
|
1689
|
+
}
|
1690
|
+
|
1663
1691
|
// handles yield calls for 1 yielded arg
|
1664
1692
|
Opal.yield1 = function(block, arg) {
|
1665
1693
|
if (typeof(block) !== "function") {
|
@@ -1667,16 +1695,23 @@
|
|
1667
1695
|
}
|
1668
1696
|
|
1669
1697
|
var has_mlhs = block.$$has_top_level_mlhs_arg,
|
1670
|
-
has_trailing_comma = block.$$has_trailing_comma_in_args
|
1698
|
+
has_trailing_comma = block.$$has_trailing_comma_in_args,
|
1699
|
+
is_returning_lambda = block.$$is_lambda && block.$$ret;
|
1671
1700
|
|
1672
1701
|
if (block.length > 1 || ((has_mlhs || has_trailing_comma) && block.length === 1)) {
|
1673
1702
|
arg = Opal.to_ary(arg);
|
1674
1703
|
}
|
1675
1704
|
|
1676
1705
|
if ((block.length > 1 || (has_trailing_comma && block.length === 1)) && arg.$$is_array) {
|
1706
|
+
if (is_returning_lambda) {
|
1707
|
+
return call_lambda(block.apply.bind(block, null), arg, block.$$ret);
|
1708
|
+
}
|
1677
1709
|
return block.apply(null, arg);
|
1678
1710
|
}
|
1679
1711
|
else {
|
1712
|
+
if (is_returning_lambda) {
|
1713
|
+
return call_lambda(block, arg, block.$$ret);
|
1714
|
+
}
|
1680
1715
|
return block(arg);
|
1681
1716
|
}
|
1682
1717
|
};
|
@@ -1689,17 +1724,13 @@
|
|
1689
1724
|
|
1690
1725
|
if (block.length > 1 && args.length === 1) {
|
1691
1726
|
if (args[0].$$is_array) {
|
1692
|
-
|
1727
|
+
args = args[0];
|
1693
1728
|
}
|
1694
1729
|
}
|
1695
1730
|
|
1696
|
-
if (
|
1697
|
-
|
1698
|
-
for(var i = 0, l = args_ary.length; i < l; i++) { args_ary[i] = args[i]; }
|
1699
|
-
|
1700
|
-
return block.apply(null, args_ary);
|
1731
|
+
if (block.$$is_lambda && block.$$ret) {
|
1732
|
+
return call_lambda(block.apply.bind(block, null), args, block.$$ret);
|
1701
1733
|
}
|
1702
|
-
|
1703
1734
|
return block.apply(null, args);
|
1704
1735
|
};
|
1705
1736
|
|
@@ -1812,11 +1843,10 @@
|
|
1812
1843
|
};
|
1813
1844
|
|
1814
1845
|
// Used for extracting keyword arguments from arguments passed to
|
1815
|
-
// JS function.
|
1816
|
-
// as a last item, returns a blank Hash.
|
1846
|
+
// JS function.
|
1817
1847
|
//
|
1818
1848
|
// @param parameters [Array]
|
1819
|
-
// @return [Hash]
|
1849
|
+
// @return [Hash] or undefined
|
1820
1850
|
//
|
1821
1851
|
Opal.extract_kwargs = function(parameters) {
|
1822
1852
|
var kwargs = parameters[parameters.length - 1];
|
@@ -1828,7 +1858,7 @@
|
|
1828
1858
|
|
1829
1859
|
// Used to get a list of rest keyword arguments. Method takes the given
|
1830
1860
|
// keyword args, i.e. the hash literal passed to the method containing all
|
1831
|
-
// keyword
|
1861
|
+
// keyword arguments passed to method, as well as the used args which are
|
1832
1862
|
// the names of required and optional arguments defined. This method then
|
1833
1863
|
// just returns all key/value pairs which have not been used, in a new
|
1834
1864
|
// hash literal.
|
@@ -1838,19 +1868,16 @@
|
|
1838
1868
|
// @return [Hash]
|
1839
1869
|
//
|
1840
1870
|
Opal.kwrestargs = function(given_args, used_args) {
|
1841
|
-
var
|
1842
|
-
map = {},
|
1843
|
-
key ,
|
1844
|
-
given_map = given_args.$$smap;
|
1871
|
+
var map = new Map();
|
1845
1872
|
|
1846
|
-
|
1873
|
+
Opal.hash_each(given_args, false, function(key, value) {
|
1847
1874
|
if (!used_args[key]) {
|
1848
|
-
|
1849
|
-
map[key] = given_map[key];
|
1875
|
+
Opal.hash_put(map, key, value);
|
1850
1876
|
}
|
1851
|
-
|
1877
|
+
return [false, false];
|
1878
|
+
});
|
1852
1879
|
|
1853
|
-
return
|
1880
|
+
return map;
|
1854
1881
|
};
|
1855
1882
|
|
1856
1883
|
function apply_blockopts(block, blockopts) {
|
@@ -1874,6 +1901,11 @@
|
|
1874
1901
|
}
|
1875
1902
|
Opal.jsid = $jsid;
|
1876
1903
|
|
1904
|
+
function $prepend(first, second) {
|
1905
|
+
if (!second.$$is_array) second = $slice(second);
|
1906
|
+
return [first].concat(second);
|
1907
|
+
}
|
1908
|
+
|
1877
1909
|
// Calls passed method on a ruby object with arguments and block:
|
1878
1910
|
//
|
1879
1911
|
// Can take a method or a method name.
|
@@ -1917,7 +1949,7 @@
|
|
1917
1949
|
Opal.send2 = function(recv, body, method, args, block, blockopts) {
|
1918
1950
|
if (body == null && method != null && recv.$method_missing) {
|
1919
1951
|
body = recv.$method_missing;
|
1920
|
-
args =
|
1952
|
+
args = $prepend(method, args);
|
1921
1953
|
}
|
1922
1954
|
|
1923
1955
|
apply_blockopts(block, blockopts);
|
@@ -2073,6 +2105,18 @@
|
|
2073
2105
|
return Opal.defn(Opal.get_singleton_class(obj), jsid, body);
|
2074
2106
|
};
|
2075
2107
|
|
2108
|
+
// Since JavaScript has no concept of modules, we create proxy classes
|
2109
|
+
// called `iclasses` that store copies of methods loaded. We need to
|
2110
|
+
// update them if we remove a method.
|
2111
|
+
function remove_method_from_iclasses(obj, jsid) {
|
2112
|
+
if (obj.$$is_module) {
|
2113
|
+
for (var i = 0, iclasses = obj.$$iclasses, length = iclasses.length; i < length; i++) {
|
2114
|
+
var iclass = iclasses[i];
|
2115
|
+
delete iclass[jsid];
|
2116
|
+
}
|
2117
|
+
}
|
2118
|
+
}
|
2119
|
+
|
2076
2120
|
// Called from #remove_method.
|
2077
2121
|
Opal.rdef = function(obj, jsid) {
|
2078
2122
|
if (!$has_own(obj.$$prototype, jsid)) {
|
@@ -2081,6 +2125,8 @@
|
|
2081
2125
|
|
2082
2126
|
delete obj.$$prototype[jsid];
|
2083
2127
|
|
2128
|
+
remove_method_from_iclasses(obj, jsid);
|
2129
|
+
|
2084
2130
|
if (obj.$$is_singleton) {
|
2085
2131
|
if (obj.$$prototype.$singleton_method_removed && !obj.$$prototype.$singleton_method_removed.$$stub) {
|
2086
2132
|
obj.$$prototype.$singleton_method_removed(jsid.substr(1));
|
@@ -2101,6 +2147,8 @@
|
|
2101
2147
|
|
2102
2148
|
Opal.add_stub_for(obj.$$prototype, jsid);
|
2103
2149
|
|
2150
|
+
remove_method_from_iclasses(obj, jsid);
|
2151
|
+
|
2104
2152
|
if (obj.$$is_singleton) {
|
2105
2153
|
if (obj.$$prototype.$singleton_method_undefined && !obj.$$prototype.$singleton_method_undefined.$$stub) {
|
2106
2154
|
obj.$$prototype.$singleton_method_undefined(jsid.substr(1));
|
@@ -2159,17 +2207,25 @@
|
|
2159
2207
|
|
2160
2208
|
// We need a wrapper because otherwise properties
|
2161
2209
|
// would be overwritten on the original body.
|
2162
|
-
alias =
|
2163
|
-
var block = alias.$$p, args, i, ii;
|
2210
|
+
alias = Opal.wrapMethodBody(body);
|
2164
2211
|
|
2165
|
-
|
2166
|
-
|
2167
|
-
|
2168
|
-
|
2212
|
+
// Try to make the browser pick the right name
|
2213
|
+
alias.displayName = name;
|
2214
|
+
alias.$$alias_of = body;
|
2215
|
+
alias.$$alias_name = name;
|
2169
2216
|
|
2170
|
-
|
2217
|
+
Opal.defn(obj, id, alias);
|
2171
2218
|
|
2172
|
-
|
2219
|
+
return obj;
|
2220
|
+
};
|
2221
|
+
|
2222
|
+
Opal.wrapMethodBody = function(body) {
|
2223
|
+
var wrapped = function() {
|
2224
|
+
var block = wrapped.$$p;
|
2225
|
+
|
2226
|
+
wrapped.$$p = null;
|
2227
|
+
|
2228
|
+
return Opal.send(this, body, arguments, block);
|
2173
2229
|
};
|
2174
2230
|
|
2175
2231
|
// Assign the 'length' value with defineProperty because
|
@@ -2177,21 +2233,14 @@
|
|
2177
2233
|
// It doesn't work in older browsers (like Chrome 38), where
|
2178
2234
|
// an exception is thrown breaking Opal altogether.
|
2179
2235
|
try {
|
2180
|
-
Object.defineProperty(
|
2236
|
+
Object.defineProperty(wrapped, 'length', { value: body.length });
|
2181
2237
|
} catch (e) {}
|
2182
2238
|
|
2183
|
-
|
2184
|
-
|
2185
|
-
|
2186
|
-
alias.$$arity = body.$$arity == null ? body.length : body.$$arity;
|
2187
|
-
alias.$$parameters = body.$$parameters;
|
2188
|
-
alias.$$source_location = body.$$source_location;
|
2189
|
-
alias.$$alias_of = body;
|
2190
|
-
alias.$$alias_name = name;
|
2191
|
-
|
2192
|
-
Opal.defn(obj, id, alias);
|
2239
|
+
wrapped.$$arity = body.$$arity == null ? body.length : body.$$arity;
|
2240
|
+
wrapped.$$parameters = body.$$parameters;
|
2241
|
+
wrapped.$$source_location = body.$$source_location;
|
2193
2242
|
|
2194
|
-
return
|
2243
|
+
return wrapped;
|
2195
2244
|
};
|
2196
2245
|
|
2197
2246
|
Opal.alias_gvar = function(new_name, old_name) {
|
@@ -2225,228 +2274,169 @@
|
|
2225
2274
|
// Hashes
|
2226
2275
|
// ------
|
2227
2276
|
|
2228
|
-
Opal.hash_init = function(
|
2229
|
-
|
2230
|
-
|
2231
|
-
hash.$$keys = [];
|
2232
|
-
};
|
2277
|
+
Opal.hash_init = function (_hash) {
|
2278
|
+
console.warn("DEPRECATION: Opal.hash_init is deprecated and is now a no-op.");
|
2279
|
+
}
|
2233
2280
|
|
2234
2281
|
Opal.hash_clone = function(from_hash, to_hash) {
|
2235
2282
|
to_hash.$$none = from_hash.$$none;
|
2236
2283
|
to_hash.$$proc = from_hash.$$proc;
|
2237
2284
|
|
2238
|
-
|
2239
|
-
key = keys[i];
|
2240
|
-
|
2241
|
-
if (key.$$is_string) {
|
2242
|
-
value = smap[key];
|
2243
|
-
} else {
|
2244
|
-
value = key.value;
|
2245
|
-
key = key.key;
|
2246
|
-
}
|
2247
|
-
|
2285
|
+
return Opal.hash_each(from_hash, to_hash, function(key, value) {
|
2248
2286
|
Opal.hash_put(to_hash, key, value);
|
2249
|
-
|
2287
|
+
return [false, to_hash];
|
2288
|
+
});
|
2250
2289
|
};
|
2251
2290
|
|
2252
2291
|
Opal.hash_put = function(hash, key, value) {
|
2253
|
-
|
2254
|
-
|
2255
|
-
|
2256
|
-
|
2257
|
-
hash
|
2258
|
-
|
2259
|
-
|
2292
|
+
var type = typeof key;
|
2293
|
+
if (type === "string" || type === "symbol" || type === "number" || type === "boolean" || type === "bigint") {
|
2294
|
+
hash.set(key, value)
|
2295
|
+
} else if (key.$$is_string) {
|
2296
|
+
hash.set(key.valueOf(), value);
|
2297
|
+
} else {
|
2298
|
+
if (!hash.$$keys)
|
2299
|
+
hash.$$keys = new Map();
|
2260
2300
|
|
2261
|
-
|
2262
|
-
|
2301
|
+
var key_hash = key.$$is_string ? key.valueOf() : (hash.$$by_identity ? Opal.id(key) : key.$hash()),
|
2302
|
+
keys = hash.$$keys;
|
2263
2303
|
|
2264
|
-
|
2265
|
-
|
2266
|
-
|
2267
|
-
|
2268
|
-
|
2269
|
-
}
|
2304
|
+
if (!keys.has(key_hash)) {
|
2305
|
+
keys.set(key_hash, [key]);
|
2306
|
+
hash.set(key, value);
|
2307
|
+
return;
|
2308
|
+
}
|
2270
2309
|
|
2271
|
-
|
2310
|
+
var objects = keys.get(key_hash),
|
2311
|
+
object;
|
2272
2312
|
|
2273
|
-
|
2274
|
-
|
2275
|
-
|
2276
|
-
|
2277
|
-
|
2313
|
+
for (var i=0; i<objects.length; i++) {
|
2314
|
+
object = objects[i];
|
2315
|
+
if (key === object || key['$eql?'](object)) {
|
2316
|
+
hash.set(object, value);
|
2317
|
+
return;
|
2318
|
+
}
|
2278
2319
|
}
|
2279
|
-
last_bucket = bucket;
|
2280
|
-
bucket = bucket.next;
|
2281
|
-
}
|
2282
2320
|
|
2283
|
-
|
2284
|
-
|
2285
|
-
hash.$$keys.push(bucket);
|
2286
|
-
last_bucket.next = bucket;
|
2321
|
+
objects.push(key);
|
2322
|
+
hash.set(key, value);
|
2287
2323
|
}
|
2288
2324
|
};
|
2289
2325
|
|
2290
2326
|
Opal.hash_get = function(hash, key) {
|
2291
|
-
|
2292
|
-
|
2293
|
-
|
2294
|
-
|
2295
|
-
|
2296
|
-
|
2297
|
-
|
2298
|
-
|
2299
|
-
|
2300
|
-
|
2301
|
-
|
2302
|
-
|
2303
|
-
|
2304
|
-
while (bucket) {
|
2305
|
-
if (key === bucket.key || key['$eql?'](bucket.key)) {
|
2306
|
-
return bucket.value;
|
2327
|
+
var type = typeof key;
|
2328
|
+
if (type === "string" || type === "symbol" || type === "number" || type === "boolean" || type === "bigint") {
|
2329
|
+
return hash.get(key)
|
2330
|
+
} else if (hash.$$keys) {
|
2331
|
+
var key_hash = key.$$is_string ? key.valueOf() : (hash.$$by_identity ? Opal.id(key) : key.$hash()),
|
2332
|
+
objects = hash.$$keys.get(key_hash),
|
2333
|
+
object;
|
2334
|
+
|
2335
|
+
if (objects !== undefined) {
|
2336
|
+
for (var i=0; i<objects.length; i++) {
|
2337
|
+
object = objects[i];
|
2338
|
+
if (key === object || key['$eql?'](object))
|
2339
|
+
return hash.get(object);
|
2307
2340
|
}
|
2308
|
-
|
2341
|
+
} else if (key.$$is_string) {
|
2342
|
+
return hash.get(key_hash);
|
2309
2343
|
}
|
2344
|
+
} else if (key.$$is_string) {
|
2345
|
+
return hash.get(key.valueOf());
|
2310
2346
|
}
|
2311
2347
|
};
|
2312
2348
|
|
2313
|
-
|
2314
|
-
var
|
2315
|
-
|
2316
|
-
|
2317
|
-
if (typeof key !== "string") key = key.valueOf();
|
2318
|
-
|
2319
|
-
if (!$has_own(hash.$$smap, key)) {
|
2320
|
-
return;
|
2321
|
-
}
|
2322
|
-
|
2323
|
-
for (i = 0; i < length; i++) {
|
2324
|
-
key_tmp = keys[i];
|
2325
|
-
|
2326
|
-
if (key_tmp.$$is_string && typeof key_tmp !== "string") {
|
2327
|
-
key_tmp = key_tmp.valueOf();
|
2328
|
-
}
|
2329
|
-
|
2330
|
-
if (key_tmp === key) {
|
2331
|
-
keys.splice(i, 1);
|
2332
|
-
break;
|
2333
|
-
}
|
2334
|
-
}
|
2335
|
-
|
2336
|
-
value = hash.$$smap[key];
|
2337
|
-
delete hash.$$smap[key];
|
2349
|
+
function $hash_delete_stage2(hash, key) {
|
2350
|
+
var value = hash.get(key);
|
2351
|
+
if (value !== undefined) {
|
2352
|
+
hash.delete(key);
|
2338
2353
|
return value;
|
2339
2354
|
}
|
2355
|
+
}
|
2340
2356
|
|
2341
|
-
|
2342
|
-
|
2343
|
-
if (
|
2344
|
-
return;
|
2345
|
-
}
|
2346
|
-
|
2347
|
-
|
2348
|
-
|
2349
|
-
|
2350
|
-
if (
|
2351
|
-
|
2352
|
-
|
2353
|
-
|
2354
|
-
|
2355
|
-
|
2356
|
-
|
2357
|
+
Opal.hash_delete = function(hash, key) {
|
2358
|
+
var type = typeof key
|
2359
|
+
if (type === "string" || type === "symbol" || type === "number" || type === "boolean" || type === "bigint") {
|
2360
|
+
return $hash_delete_stage2(hash, key);
|
2361
|
+
} else if (hash.$$keys) {
|
2362
|
+
var key_hash = key.$$is_string ? key.valueOf() : (hash.$$by_identity ? Opal.id(key) : key.$hash()),
|
2363
|
+
objects = hash.$$keys.get(key_hash),
|
2364
|
+
object;
|
2365
|
+
|
2366
|
+
if (objects !== undefined) {
|
2367
|
+
for (var i=0; i<objects.length; i++) {
|
2368
|
+
object = objects[i];
|
2369
|
+
if (key === object || key['$eql?'](object)) {
|
2370
|
+
objects.splice(i, 1);
|
2371
|
+
if (objects.length === 0)
|
2372
|
+
hash.$$keys.delete(key_hash);
|
2373
|
+
return $hash_delete_stage2(hash, object);
|
2357
2374
|
}
|
2358
2375
|
}
|
2359
|
-
|
2360
|
-
|
2361
|
-
last_bucket.next = bucket.next;
|
2362
|
-
}
|
2363
|
-
else if (last_bucket) {
|
2364
|
-
delete last_bucket.next;
|
2365
|
-
}
|
2366
|
-
else if (bucket.next) {
|
2367
|
-
hash.$$map[key_hash] = bucket.next;
|
2368
|
-
}
|
2369
|
-
else {
|
2370
|
-
delete hash.$$map[key_hash];
|
2371
|
-
}
|
2372
|
-
|
2373
|
-
return value;
|
2376
|
+
} else if (key.$$is_string) {
|
2377
|
+
return $hash_delete_stage2(hash, key_hash);
|
2374
2378
|
}
|
2375
|
-
|
2376
|
-
|
2379
|
+
} else if (key.$$is_string) {
|
2380
|
+
return $hash_delete_stage2(hash, key.valueOf());
|
2377
2381
|
}
|
2378
2382
|
};
|
2379
2383
|
|
2380
2384
|
Opal.hash_rehash = function(hash) {
|
2381
|
-
|
2385
|
+
var keys = hash.$$keys;
|
2382
2386
|
|
2383
|
-
|
2384
|
-
|
2385
|
-
}
|
2387
|
+
if (keys)
|
2388
|
+
keys.clear();
|
2386
2389
|
|
2387
|
-
|
2390
|
+
Opal.hash_each(hash, false, function(key, value) {
|
2391
|
+
var type = typeof key;
|
2392
|
+
if (type === "string" || type === "symbol" || type === "number" || type === "boolean" || type === "bigint")
|
2393
|
+
return [false, false]; // nothing to rehash
|
2388
2394
|
|
2389
|
-
|
2390
|
-
continue;
|
2391
|
-
}
|
2395
|
+
var key_hash = key.$$is_string ? key.valueOf() : (hash.$$by_identity ? Opal.id(key) : key.$hash());
|
2392
2396
|
|
2393
|
-
|
2394
|
-
|
2397
|
+
if (!keys)
|
2398
|
+
hash.$$keys = keys = new Map();
|
2395
2399
|
|
2396
|
-
|
2397
|
-
|
2398
|
-
|
2399
|
-
last_bucket.next = bucket.next;
|
2400
|
-
}
|
2401
|
-
else if (last_bucket) {
|
2402
|
-
delete last_bucket.next;
|
2403
|
-
}
|
2404
|
-
else if (bucket.next) {
|
2405
|
-
hash.$$map[hash.$$keys[i].key_hash] = bucket.next;
|
2406
|
-
}
|
2407
|
-
else {
|
2408
|
-
delete hash.$$map[hash.$$keys[i].key_hash];
|
2409
|
-
}
|
2410
|
-
break;
|
2411
|
-
}
|
2412
|
-
last_bucket = bucket;
|
2413
|
-
bucket = bucket.next;
|
2400
|
+
if (!keys.has(key_hash)) {
|
2401
|
+
keys.set(key_hash, [key]);
|
2402
|
+
return [false, false];
|
2414
2403
|
}
|
2415
2404
|
|
2416
|
-
|
2405
|
+
var objects = keys.get(key_hash),
|
2406
|
+
objects_copy = $slice(objects),
|
2407
|
+
object;
|
2417
2408
|
|
2418
|
-
|
2419
|
-
|
2420
|
-
|
2409
|
+
for (var i=0; i<objects_copy.length; i++) {
|
2410
|
+
object = objects_copy[i];
|
2411
|
+
if (key === object || key['$eql?'](object)) {
|
2412
|
+
// got a duplicate, remove it
|
2413
|
+
objects.splice(objects.indexOf(object), 1);
|
2414
|
+
hash.delete(object);
|
2415
|
+
}
|
2421
2416
|
}
|
2422
2417
|
|
2423
|
-
|
2424
|
-
last_bucket = undefined;
|
2418
|
+
objects.push(key);
|
2425
2419
|
|
2426
|
-
|
2427
|
-
|
2428
|
-
last_bucket = undefined;
|
2429
|
-
break;
|
2430
|
-
}
|
2431
|
-
last_bucket = bucket;
|
2432
|
-
bucket = bucket.next;
|
2433
|
-
}
|
2420
|
+
return [false, false]
|
2421
|
+
});
|
2434
2422
|
|
2435
|
-
|
2436
|
-
last_bucket.next = hash.$$keys[i];
|
2437
|
-
}
|
2438
|
-
}
|
2423
|
+
return hash;
|
2439
2424
|
};
|
2440
2425
|
|
2441
|
-
Opal.hash = function() {
|
2442
|
-
var arguments_length = arguments.length,
|
2426
|
+
Opal.hash = function () {
|
2427
|
+
var arguments_length = arguments.length,
|
2428
|
+
args,
|
2429
|
+
hash,
|
2430
|
+
i,
|
2431
|
+
length,
|
2432
|
+
key,
|
2433
|
+
value;
|
2443
2434
|
|
2444
2435
|
if (arguments_length === 1 && arguments[0].$$is_hash) {
|
2445
2436
|
return arguments[0];
|
2446
2437
|
}
|
2447
2438
|
|
2448
|
-
hash = new
|
2449
|
-
Opal.hash_init(hash);
|
2439
|
+
hash = new Map();
|
2450
2440
|
|
2451
2441
|
if (arguments_length === 1) {
|
2452
2442
|
args = arguments[0];
|
@@ -2456,7 +2446,7 @@
|
|
2456
2446
|
|
2457
2447
|
for (i = 0; i < length; i++) {
|
2458
2448
|
if (args[i].length !== 2) {
|
2459
|
-
$raise(Opal.ArgumentError,
|
2449
|
+
$raise(Opal.ArgumentError, 'value not of length 2: ' + args[i].$inspect());
|
2460
2450
|
}
|
2461
2451
|
|
2462
2452
|
key = args[i][0];
|
@@ -2466,8 +2456,7 @@
|
|
2466
2456
|
}
|
2467
2457
|
|
2468
2458
|
return hash;
|
2469
|
-
}
|
2470
|
-
else {
|
2459
|
+
} else {
|
2471
2460
|
args = arguments[0];
|
2472
2461
|
for (key in args) {
|
2473
2462
|
if ($has_own(args, key)) {
|
@@ -2482,7 +2471,7 @@
|
|
2482
2471
|
}
|
2483
2472
|
|
2484
2473
|
if (arguments_length % 2 !== 0) {
|
2485
|
-
$raise(Opal.ArgumentError,
|
2474
|
+
$raise(Opal.ArgumentError, 'odd number of arguments for Hash');
|
2486
2475
|
}
|
2487
2476
|
|
2488
2477
|
for (i = 0; i < arguments_length; i += 2) {
|
@@ -2501,15 +2490,29 @@
|
|
2501
2490
|
// function.
|
2502
2491
|
//
|
2503
2492
|
Opal.hash2 = function(keys, smap) {
|
2504
|
-
|
2505
|
-
|
2506
|
-
hash.$$smap = smap;
|
2507
|
-
hash.$$map = Object.create(null);
|
2508
|
-
hash.$$keys = keys;
|
2493
|
+
console.warn("DEPRECATION: `Opal.hash2` is deprecated and will be removed in Opal 2.0. Use `new Map()` with an array of key/value pairs instead.");
|
2509
2494
|
|
2495
|
+
var hash = new Map();
|
2496
|
+
for (var i = 0, max = keys.length; i < max; i++) {
|
2497
|
+
hash.set(keys[i], smap[keys[i]]);
|
2498
|
+
}
|
2510
2499
|
return hash;
|
2511
2500
|
};
|
2512
2501
|
|
2502
|
+
Opal.hash_each = function (hash, dres, fun) {
|
2503
|
+
// dres = default result, returned if hash is empty
|
2504
|
+
// fun is called as fun(key, value) and must return a array with [break, result]
|
2505
|
+
// if break is true, iteration stops and result is returned
|
2506
|
+
// if break is false, iteration continues and eventually the last result is returned
|
2507
|
+
var res;
|
2508
|
+
for (var i = 0, entry, entries = Array.from(hash.entries()), l = entries.length; i < l; i++) {
|
2509
|
+
entry = entries[i];
|
2510
|
+
res = fun(entry[0], entry[1]);
|
2511
|
+
if (res[0]) return res[1];
|
2512
|
+
}
|
2513
|
+
return res ? res[1] : dres;
|
2514
|
+
};
|
2515
|
+
|
2513
2516
|
// Create a new range instance with first and last values, and whether the
|
2514
2517
|
// range excludes the last value.
|
2515
2518
|
//
|
@@ -2547,7 +2550,7 @@
|
|
2547
2550
|
// helper that can be used from methods
|
2548
2551
|
function $deny_frozen_access(obj) {
|
2549
2552
|
if (obj.$$frozen) {
|
2550
|
-
$raise(Opal.FrozenError, "can't modify frozen " + (obj.$class()) + ": " + (obj),
|
2553
|
+
$raise(Opal.FrozenError, "can't modify frozen " + (obj.$class()) + ": " + (obj), new Map([["receiver", obj]]));
|
2551
2554
|
}
|
2552
2555
|
};
|
2553
2556
|
Opal.deny_frozen_access = $deny_frozen_access;
|
@@ -2672,7 +2675,7 @@
|
|
2672
2675
|
if (part.ignoreCase !== ignoreCase)
|
2673
2676
|
Opal.Kernel.$warn(
|
2674
2677
|
"ignore case doesn't match for " + part.source.$inspect(),
|
2675
|
-
|
2678
|
+
new Map([['uplevel', 1]])
|
2676
2679
|
)
|
2677
2680
|
|
2678
2681
|
part = part.source;
|
@@ -2923,7 +2926,7 @@
|
|
2923
2926
|
// Primitives for handling parameters
|
2924
2927
|
Opal.ensure_kwargs = function(kwargs) {
|
2925
2928
|
if (kwargs == null) {
|
2926
|
-
return
|
2929
|
+
return new Map();
|
2927
2930
|
} else if (kwargs.$$is_hash) {
|
2928
2931
|
return kwargs;
|
2929
2932
|
} else {
|
@@ -2932,10 +2935,11 @@
|
|
2932
2935
|
}
|
2933
2936
|
|
2934
2937
|
Opal.get_kwarg = function(kwargs, key) {
|
2935
|
-
|
2938
|
+
var kwarg = Opal.hash_get(kwargs, key);
|
2939
|
+
if (kwarg === undefined) {
|
2936
2940
|
$raise(Opal.ArgumentError, 'missing keyword: '+key);
|
2937
2941
|
}
|
2938
|
-
return
|
2942
|
+
return kwarg;
|
2939
2943
|
}
|
2940
2944
|
|
2941
2945
|
// Arrays of size > 32 elements that contain only strings,
|
@@ -2965,6 +2969,20 @@
|
|
2965
2969
|
return array;
|
2966
2970
|
}
|
2967
2971
|
|
2972
|
+
// Opal32-checksum algorithm for #hash
|
2973
|
+
// -----------------------------------
|
2974
|
+
Opal.opal32_init = $return_val(0x4f70616c);
|
2975
|
+
|
2976
|
+
function $opal32_ror(n, d) {
|
2977
|
+
return (n << d)|(n >>> (32 - d));
|
2978
|
+
};
|
2979
|
+
|
2980
|
+
Opal.opal32_add = function(hash, next) {
|
2981
|
+
hash ^= next;
|
2982
|
+
hash = $opal32_ror(hash, 1);
|
2983
|
+
return hash;
|
2984
|
+
};
|
2985
|
+
|
2968
2986
|
// Initialization
|
2969
2987
|
// --------------
|
2970
2988
|
Opal.BasicObject = BasicObject = $allocate_class('BasicObject', null);
|
@@ -3020,10 +3038,9 @@
|
|
3020
3038
|
|
3021
3039
|
// Foward calls to define_method on the top object to Object
|
3022
3040
|
function top_define_method() {
|
3023
|
-
var args = $slice(arguments);
|
3024
3041
|
var block = top_define_method.$$p;
|
3025
3042
|
top_define_method.$$p = null;
|
3026
|
-
return Opal.send(_Object, 'define_method',
|
3043
|
+
return Opal.send(_Object, 'define_method', arguments, block)
|
3027
3044
|
};
|
3028
3045
|
|
3029
3046
|
// Nil
|
@@ -3037,16 +3054,37 @@
|
|
3037
3054
|
Object.seal(nil);
|
3038
3055
|
|
3039
3056
|
Opal.thrower = function(type) {
|
3040
|
-
var thrower =
|
3041
|
-
|
3042
|
-
|
3043
|
-
|
3044
|
-
|
3045
|
-
|
3046
|
-
|
3057
|
+
var thrower = {
|
3058
|
+
$thrower_type: type,
|
3059
|
+
$throw: function(value, called_from_lambda) {
|
3060
|
+
if (value == null) value = nil;
|
3061
|
+
if (this.is_orphan && !called_from_lambda) {
|
3062
|
+
$raise(Opal.LocalJumpError, 'unexpected ' + type, value, type.$to_sym());
|
3063
|
+
}
|
3064
|
+
this.$v = value;
|
3065
|
+
throw this;
|
3066
|
+
},
|
3067
|
+
is_orphan: false
|
3068
|
+
}
|
3047
3069
|
return thrower;
|
3048
3070
|
};
|
3049
3071
|
|
3072
|
+
// Define a "$@" global variable, which would compute and return a backtrace on demand.
|
3073
|
+
Object.defineProperty($gvars, "@", {
|
3074
|
+
enumerable: true,
|
3075
|
+
configurable: true,
|
3076
|
+
get: function() {
|
3077
|
+
if ($truthy($gvars["!"])) return $gvars["!"].$backtrace();
|
3078
|
+
return nil;
|
3079
|
+
},
|
3080
|
+
set: function(bt) {
|
3081
|
+
if ($truthy($gvars["!"]))
|
3082
|
+
$gvars["!"].$set_backtrace(bt);
|
3083
|
+
else
|
3084
|
+
$raise(Opal.ArgumentError, "$! not set");
|
3085
|
+
}
|
3086
|
+
});
|
3087
|
+
|
3050
3088
|
Opal.t_eval_return = Opal.thrower("return");
|
3051
3089
|
|
3052
3090
|
TypeError.$$super = Error;
|