opal/corelib/runtime.js in opal-1.6.1 vs opal/corelib/runtime.js in opal-1.7.0.rc1
- old
+ new
@@ -75,15 +75,16 @@
experimental_features_severity: 'warning',// warning, ignore
enable_stack_trace: true // true, false
};
// Minify common function calls
- var $has_own = Object.hasOwnProperty;
+ var $call = Function.prototype.call;
var $bind = Function.prototype.bind;
+ var $has_own = Object.hasOwn || $call.bind(Object.prototype.hasOwnProperty);
var $set_proto = Object.setPrototypeOf;
- var $slice = Array.prototype.slice;
- var $splice = Array.prototype.splice;
+ var $slice = $call.bind(Array.prototype.slice);
+ var $splice = $call.bind(Array.prototype.splice);
// Nil object id is always 4
var nil_id = 4;
// Generates even sequential numbers greater than 4
@@ -127,10 +128,32 @@
else {
$gvars["!"] = $gvars["@"] = nil;
}
};
+ // A helper function for raising things, that gracefully degrades if necessary
+ // functionality is not yet loaded.
+ function $raise(klass, message) {
+ // Raise Exception, so we can know that something wrong is going on.
+ if (!klass) klass = Opal.Exception || Error;
+
+ if (Kernel && Kernel.$raise) {
+ if (arguments.length > 2) {
+ Kernel.$raise(klass.$new.apply(klass, $slice(arguments, 1)));
+ }
+ else {
+ Kernel.$raise(klass, message);
+ }
+ }
+ else if (!klass.$new) {
+ throw new klass(message);
+ }
+ else {
+ throw klass.$new(message);
+ }
+ }
+
function $prop(object, name, initialValue) {
if (typeof(object) === "string") {
// Special case for:
// s = "string"
// def s.m; end
@@ -154,11 +177,10 @@
// @deprecated
Opal.defineProperty = Opal.prop;
Opal.slice = $slice;
-
// Helpers
// -----
var $truthy = Opal.truthy = function(val) {
return false !== val && nil !== val && undefined !== val && null !== val && (!(val instanceof Boolean) || true === val.valueOf());
@@ -171,16 +193,16 @@
Opal.type_error = function(object, type, method, coerced) {
object = object.$$class;
if (coerced && method) {
coerced = coerced.$$class;
- return Opal.TypeError.$new(
+ $raise(Opal.TypeError,
"can't convert " + object + " into " + type +
" (" + object + "#" + method + " gives " + coerced + ")"
)
} else {
- return Opal.TypeError.$new(
+ $raise(Opal.TypeError,
"no implicit conversion of " + object + " into " + type
)
}
};
@@ -195,17 +217,17 @@
if (Opal.is_a(object, type)) return object;
// Fast path for the most common situation
if (object['$respond_to?'].$$pristine && object.$method_missing.$$pristine) {
- body = object['$' + method];
- if (body == null || body.$$stub) throw Opal.type_error(object, type);
+ body = object[$jsid(method)];
+ if (body == null || body.$$stub) Opal.type_error(object, type);
return body.apply(object, args);
}
if (!object['$respond_to?'](method)) {
- throw Opal.type_error(object, type);
+ Opal.type_error(object, type);
}
if (args == null) args = [];
return Opal.send(object, method, args);
}
@@ -310,11 +332,11 @@
if (cref == null) return;
ancestors = $ancestors(cref);
for (i = 0, ii = ancestors.length; i < ii; i++) {
- if (ancestors[i].$$const && $has_own.call(ancestors[i].$$const, name)) {
+ if (ancestors[i].$$const && $has_own(ancestors[i].$$const, name)) {
return ancestors[i].$$const[name];
} else if (ancestors[i].$$autoload && ancestors[i].$$autoload[name]) {
return handle_autoload(ancestors[i], name);
}
}
@@ -340,11 +362,11 @@
if (cref == null) return;
if (cref === '::') cref = _Object;
if (!cref.$$is_module && !cref.$$is_class) {
- throw new Opal.TypeError(cref.toString() + " is not a class/module");
+ $raise(Opal.TypeError, cref.toString() + " is not a class/module");
}
result = const_get_name(cref, name);
return result != null || skip_missing ? result : const_missing(cref, name);
};
@@ -365,11 +387,11 @@
if (cref == null) return;
if (cref === '::') cref = _Object;
if (!cref.$$is_module && !cref.$$is_class) {
- throw new Opal.TypeError(cref.toString() + " is not a class/module");
+ $raise(Opal.TypeError, cref.toString() + " is not a class/module");
}
if ((cache = cref.$$const_cache) == null) {
$prop(cref, '$$const_cache', Object.create(null));
cache = cref.$$const_cache;
@@ -416,18 +438,25 @@
};
// Register the constant on a cref and opportunistically set the name of
// unnamed classes/modules.
function $const_set(cref, name, value) {
+ var new_const = true;
+
if (cref == null || cref === '::') cref = _Object;
if (value.$$is_a_module) {
if (value.$$name == null || value.$$name === nil) value.$$name = name;
if (value.$$base_module == null) value.$$base_module = cref;
}
cref.$$const = (cref.$$const || Object.create(null));
+
+ if (name in cref.$$const || ("$$autoload" in cref && name in cref.$$autoload)) {
+ new_const = false;
+ }
+
cref.$$const[name] = value;
// Add a short helper to navigate constants manually.
// @example
// Opal.$$.Regexp.$$.IGNORECASE
@@ -439,10 +468,14 @@
if (cref === _Object) Opal[name] = value;
// Name new class directly onto current scope (Opal.Foo.Baz = klass)
$prop(cref, name, value);
+ if (new_const && cref.$const_added && !cref.$const_added.$$pristine) {
+ cref.$const_added(name);
+ }
+
return value;
};
Opal.const_set = $const_set;
@@ -488,11 +521,11 @@
if (cref.$$autoload && cref.$$autoload[name]) {
delete cref.$$autoload[name];
return nil;
}
- throw Opal.NameError.$new("constant "+cref+"::"+cref.$name()+" not defined");
+ $raise(Opal.NameError, "constant "+cref+"::"+cref.$name()+" not defined");
};
// Generates a function that is a curried const_get_relative.
Opal.const_get_relative_factory = function(nesting) {
return function(name, skip_missing) {
@@ -538,11 +571,11 @@
if (superclass != null && superclass.$$bridge) {
// Inheritance from bridged classes requires
// calling original JS constructors
klass = function() {
- var args = $slice.call(arguments),
+ var args = $slice(arguments),
self = new ($bind.apply(superclass.$$constructor, [null].concat(args)))();
// and replacing a __proto__ manually
$set_proto(self, klass.$$prototype);
return self;
@@ -620,20 +653,20 @@
// If the class exists in the scope, then we must use that
if (klass) {
// Make sure the existing constant is a class, or raise error
if (!klass.$$is_class) {
- throw Opal.TypeError.$new(name + " is not a class");
+ $raise(Opal.TypeError, name + " is not a class");
}
return klass;
}
}
function ensureSuperclassMatch(klass, superclass) {
if (klass.$$super !== superclass) {
- throw Opal.TypeError.$new("superclass mismatch for class " + klass.$$name);
+ $raise(Opal.TypeError, "superclass mismatch for class " + klass.$$name);
}
}
Opal.klass = function(scope, superclass, name) {
var bridged;
@@ -654,11 +687,11 @@
) {
if (superclass.constructor && superclass.constructor.name == "Function") {
bridged = superclass;
superclass = _Object;
} else {
- throw Opal.TypeError.$new("superclass must be a Class (" + (
+ $raise(Opal.TypeError, "superclass must be a Class (" + (
(superclass.constructor && (superclass.constructor.name || superclass.constructor.$$name)) ||
typeof(superclass)
) + " given)");
}
}
@@ -746,11 +779,11 @@
var module = const_get_name(scope, name);
if (module == null && scope === _Object) module = const_lookup_ancestors(_Object, name);
if (module) {
if (!module.$$is_module && module !== _Object) {
- throw Opal.TypeError.$new(name + " is not a module");
+ $raise(Opal.TypeError, name + " is not a module");
}
}
return module;
}
@@ -997,11 +1030,11 @@
i, length = ancestors.length;
for (i = length - 2; i >= 0; i--) {
var ancestor = ancestors[i];
- if ($has_own.call(ancestor.$$cvars, name)) {
+ if ($has_own(ancestor.$$cvars, name)) {
ancestor.$$cvars[name] = value;
return value;
}
}
@@ -1013,26 +1046,26 @@
// Gets class variable with specified +name+ from provided +module+
//
// @param module [Module]
// @param name [String]
Opal.class_variable_get = function(module, name, tolerant) {
- if ($has_own.call(module.$$cvars, name))
+ if ($has_own(module.$$cvars, name))
return module.$$cvars[name];
var ancestors = $ancestors(module),
i, length = ancestors.length;
for (i = 0; i < length; i++) {
var ancestor = ancestors[i];
- if ($has_own.call(ancestor.$$cvars, name)) {
+ if ($has_own(ancestor.$$cvars, name)) {
return ancestor.$$cvars[name];
}
}
if (!tolerant)
- throw Opal.NameError.$new('uninitialized class variable '+name+' in '+module.$name());
+ $raise(Opal.NameError, 'uninitialized class variable '+name+' in '+module.$name());
return nil;
}
function isRoot(proto) {
@@ -1100,11 +1133,11 @@
Opal.append_features = function(module, includer) {
var module_ancestors = $ancestors(module);
var iclasses = [];
if (module_ancestors.indexOf(includer) !== -1) {
- throw Opal.ArgumentError.$new('cyclic include detected');
+ $raise(Opal.ArgumentError, 'cyclic include detected');
}
for (var i = 0, length = module_ancestors.length; i < length; i++) {
var ancestor = module_ancestors[i], iclass = create_iclass(ancestor);
$prop(iclass, '$$included', true);
@@ -1205,11 +1238,11 @@
// parent
var module_ancestors = $ancestors(module);
var iclasses = [];
if (module_ancestors.indexOf(prepender) !== -1) {
- throw Opal.ArgumentError.$new('cyclic prepend detected');
+ $raise(Opal.ArgumentError, 'cyclic prepend detected');
}
for (var i = 0, length = module_ancestors.length; i < length; i++) {
var ancestor = module_ancestors[i], iclass = create_iclass(ancestor);
$prop(iclass, '$$prepended', true);
@@ -1261,11 +1294,11 @@
}
end_chain_on = Object.getPrototypeOf(end_chain_on);
}
} else {
- throw Opal.RuntimeError.$new("Prepending a module multiple times is not supported");
+ $raise(Opal.RuntimeError, "Prepending a module multiple times is not supported");
}
$set_proto(start_chain_after, chain.first);
$set_proto(chain.last, end_chain_on);
@@ -1358,11 +1391,11 @@
// @param constructor [JS.Function] native JavaScript constructor to use
// @return [Class] returns the passed Ruby class
//
Opal.bridge = function(native_klass, klass) {
if (native_klass.hasOwnProperty('$$bridge')) {
- throw Opal.ArgumentError.$new("already bridged");
+ $raise(Opal.ArgumentError, "already bridged");
}
// constructor is a JS function with a prototype chain like:
// - constructor
// - super
@@ -1476,11 +1509,11 @@
var proto = Opal.BasicObject.$$prototype;
var stub, existing_method;
stubs = stubs.split(',');
for (var i = 0, length = stubs.length; i < length; i++) {
- stub = '$'+stubs[i], existing_method = proto[stub];
+ stub = $jsid(stubs[i]), existing_method = proto[stub];
if (existing_method == null || existing_method.$$stub) {
Opal.add_stub_for(proto, stub);
}
}
@@ -1541,11 +1574,11 @@
else {
inspect += object.$$class.$$name + '#';
}
inspect += meth;
- throw Opal.ArgumentError.$new('[' + inspect + '] wrong number of arguments (given ' + actual + ', expected ' + expected + ')');
+ $raise(Opal.ArgumentError, '[' + inspect + '] wrong number of arguments (given ' + actual + ', expected ' + expected + ')');
};
// Arity count error dispatcher for blocks
//
// @param actual [Fixnum] number of arguments given to block
@@ -1553,11 +1586,11 @@
// @param context [Object] context of the block definition
// @raise [ArgumentError]
Opal.block_ac = function(actual, expected, context) {
var inspect = "`block in " + context + "'";
- throw Opal.ArgumentError.$new(inspect + ': wrong number of arguments (given ' + actual + ', expected ' + expected + ')');
+ $raise(Opal.ArgumentError, inspect + ': wrong number of arguments (given ' + actual + ', expected ' + expected + ')');
};
function get_ancestors(obj) {
if (obj.hasOwnProperty('$$meta') && obj.$$meta !== null) {
return $ancestors(obj.$$meta);
@@ -1566,11 +1599,11 @@
}
};
// Super dispatcher
Opal.find_super = function(obj, mid, current_func, defcheck, allow_stubs) {
- var jsid = '$' + mid, ancestors, super_method;
+ var jsid = $jsid(mid), ancestors, super_method;
ancestors = get_ancestors(obj);
var current_index = ancestors.indexOf(current_func.$$owner);
@@ -1588,26 +1621,26 @@
}
}
if (!defcheck && super_method && super_method.$$stub && obj.$method_missing.$$pristine) {
// method_missing hasn't been explicitly defined
- throw Opal.NoMethodError.$new('super: no superclass method `'+mid+"' for "+obj, mid);
+ $raise(Opal.NoMethodError, 'super: no superclass method `'+mid+"' for "+obj, mid);
}
return (super_method.$$stub && !allow_stubs) ? null : super_method;
};
// Iter dispatcher for super in a block
Opal.find_block_super = function(obj, jsid, current_func, defcheck, implicit) {
var call_jsid = jsid;
if (!current_func) {
- throw Opal.RuntimeError.$new("super called outside of method");
+ $raise(Opal.RuntimeError, "super called outside of method");
}
if (implicit && current_func.$$define_meth) {
- throw Opal.RuntimeError.$new(
+ $raise(Opal.RuntimeError,
"implicit argument passing of super from method defined by define_method() is not supported. " +
"Specify all arguments explicitly"
);
}
@@ -1625,11 +1658,11 @@
Opal.find_iter_super_dispatcher = Opal.find_block_super;
// handles yield calls for 1 yielded arg
Opal.yield1 = function(block, arg) {
if (typeof(block) !== "function") {
- throw Opal.LocalJumpError.$new("no block given");
+ $raise(Opal.LocalJumpError, "no block given");
}
var has_mlhs = block.$$has_top_level_mlhs_arg,
has_trailing_comma = block.$$has_trailing_comma_in_args;
@@ -1646,11 +1679,11 @@
};
// handles yield for > 1 yielded arg
Opal.yieldX = function(block, args) {
if (typeof(block) !== "function") {
- throw Opal.LocalJumpError.$new("no block given");
+ $raise(Opal.LocalJumpError, "no block given");
}
if (block.length > 1 && args.length === 1) {
if (args[0].$$is_array) {
return block.apply(null, args[0]);
@@ -1712,16 +1745,16 @@
var hash = value.$to_hash();
if (hash.$$is_hash) {
return hash;
}
else {
- throw Opal.TypeError.$new("Can't convert " + value.$$class +
+ $raise(Opal.TypeError, "Can't convert " + value.$$class +
" to Hash (" + value.$$class + "#to_hash gives " + hash.$$class + ")");
}
}
else {
- throw Opal.TypeError.$new("no implicit conversion of " + value.$$class + " into Hash");
+ $raise(Opal.TypeError, "no implicit conversion of " + value.$$class + " into Hash");
}
};
// Helpers for implementing multiple assignment
// Our code for extracting the values and assigning them only works if the
@@ -1740,11 +1773,11 @@
}
else if (ary.$$is_array) {
return ary;
}
else {
- throw Opal.TypeError.$new("Can't convert " + value.$$class +
+ $raise(Opal.TypeError, "Can't convert " + value.$$class +
" to Array (" + value.$$class + "#to_ary gives " + ary.$$class + ")");
}
}
else {
return [value];
@@ -1764,11 +1797,11 @@
}
else if (ary.$$is_array) {
return ary;
}
else {
- throw Opal.TypeError.$new("Can't convert " + value.$$class +
+ $raise(Opal.TypeError, "Can't convert " + value.$$class +
" to Array (" + value.$$class + "#to_a gives " + ary.$$class + ")");
}
}
else {
return [value];
@@ -1783,11 +1816,11 @@
// @return [Hash]
//
Opal.extract_kwargs = function(parameters) {
var kwargs = parameters[parameters.length - 1];
if (kwargs != null && Opal.respond_to(kwargs, '$to_hash', true)) {
- $splice.call(parameters, parameters.length - 1);
+ $splice(parameters, parameters.length - 1);
return kwargs;
}
};
// Used to get a list of rest keyword arguments. Method takes the given
@@ -1824,10 +1857,17 @@
else if (typeof(blockopts) === 'object') {
Object.assign(block, blockopts);
}
}
+ // Optimization for a costly operation of prepending '$' to method names
+ var jsid_cache = {}
+ function $jsid(name) {
+ return jsid_cache[name] || (jsid_cache[name] = '$' + name);
+ }
+ Opal.jsid = $jsid;
+
// Calls passed method on a ruby object with arguments and block:
//
// Can take a method or a method name.
//
// 1. When method name gets passed it invokes it by its name
@@ -1856,13 +1896,13 @@
if (typeof(method) === 'function') {
body = method;
method = null;
} else if (typeof(method) === 'string') {
- body = recv['$'+method];
+ body = recv[$jsid(method)];
} else {
- throw Opal.NameError.$new("Passed method should be a string or a function");
+ $raise(Opal.NameError, "Passed method should be a string or a function");
}
return Opal.send2(recv, body, method, args, block, blockopts);
};
@@ -1903,12 +1943,12 @@
// Does this module refine a given call for a given ancestor module?
if (typeof refine_modules[ancestor] === 'undefined') continue;
refine_module = refine_modules[ancestor];
// Does this module define a method we want to call?
- if (typeof refine_module.$$prototype['$'+method] !== 'undefined') {
- body = refine_module.$$prototype['$'+method];
+ if (typeof refine_module.$$prototype[$jsid(method)] !== 'undefined') {
+ body = refine_module.$$prototype[$jsid(method)];
return Opal.send2(recv, body, method, args, block, blockopts);
}
}
}
}
@@ -2018,19 +2058,19 @@
// Define a singleton method on the given object (see Opal.def).
Opal.defs = function(obj, jsid, body, blockopts) {
apply_blockopts(body, blockopts);
if (obj.$$is_string || obj.$$is_number) {
- throw Opal.TypeError.$new("can't define singleton");
+ $raise(Opal.TypeError, "can't define singleton");
}
return Opal.defn(Opal.get_singleton_class(obj), jsid, body);
};
// Called from #remove_method.
Opal.rdef = function(obj, jsid) {
- if (!$has_own.call(obj.$$prototype, jsid)) {
- throw Opal.NameError.$new("method '" + jsid.substr(1) + "' not defined in " + obj.$name());
+ if (!$has_own(obj.$$prototype, jsid)) {
+ $raise(Opal.NameError, "method '" + jsid.substr(1) + "' not defined in " + obj.$name());
}
delete obj.$$prototype[jsid];
if (obj.$$is_singleton) {
@@ -2046,11 +2086,11 @@
};
// Called from #undef_method.
Opal.udef = function(obj, jsid) {
if (!obj.$$prototype[jsid] || obj.$$prototype[jsid].$$stub) {
- throw Opal.NameError.$new("method '" + jsid.substr(1) + "' not defined in " + obj.$name());
+ $raise(Opal.NameError, "method '" + jsid.substr(1) + "' not defined in " + obj.$name());
}
Opal.add_stub_for(obj.$$prototype, jsid);
if (obj.$$is_singleton) {
@@ -2068,21 +2108,21 @@
function is_method_body(body) {
return (typeof(body) === "function" && !body.$$stub);
}
Opal.alias = function(obj, name, old) {
- var id = '$' + name,
- old_id = '$' + old,
+ var id = $jsid(name),
+ old_id = $jsid(old),
body,
alias;
// Aliasing on main means aliasing on Object...
if (typeof obj.$$prototype === 'undefined') {
obj = Opal.Object;
}
- body = obj.$$prototype['$' + old];
+ body = obj.$$prototype[old_id];
// When running inside #instance_eval the alias refers to class methods.
if (obj.$$eval) {
return Opal.alias(Opal.get_singleton_class(obj), name, old);
}
@@ -2099,11 +2139,11 @@
// try to look into Object
body = Opal.Object.$$prototype[old_id]
}
if (!is_method_body(body)) {
- throw Opal.NameError.$new("undefined method `" + old + "' for class `" + obj.$name() + "'")
+ $raise(Opal.NameError, "undefined method `" + old + "' for class `" + obj.$name() + "'")
}
}
// If the body is itself an alias use the original body
// to keep the max depth at 1.
@@ -2133,11 +2173,11 @@
} catch (e) {}
// Try to make the browser pick the right name
alias.displayName = name;
- alias.$$arity = body.$$arity;
+ alias.$$arity = body.$$arity == null ? body.length : body.$$arity;
alias.$$parameters = body.$$parameters;
alias.$$source_location = body.$$source_location;
alias.$$alias_of = body;
alias.$$alias_name = name;
@@ -2159,15 +2199,15 @@
});
return nil;
}
Opal.alias_native = function(obj, name, native_name) {
- var id = '$' + name,
+ var id = $jsid(name),
body = obj.$$prototype[native_name];
if (typeof(body) !== "function" || body.$$stub) {
- throw Opal.NameError.$new("undefined native method `" + native_name + "' for class `" + obj.$name() + "'")
+ $raise(Opal.NameError, "undefined native method `" + native_name + "' for class `" + obj.$name() + "'")
}
Opal.defn(obj, id, body);
return obj;
@@ -2201,21 +2241,21 @@
}
};
Opal.hash_put = function(hash, key, value) {
if (key.$$is_string) {
- if (!$has_own.call(hash.$$smap, key)) {
+ if (!$has_own(hash.$$smap, key)) {
hash.$$keys.push(key);
}
hash.$$smap[key] = value;
return;
}
var key_hash, bucket, last_bucket;
key_hash = hash.$$by_identity ? Opal.id(key) : key.$hash();
- if (!$has_own.call(hash.$$map, key_hash)) {
+ if (!$has_own(hash.$$map, key_hash)) {
bucket = {key: key, key_hash: key_hash, value: value};
hash.$$keys.push(bucket);
hash.$$map[key_hash] = bucket;
return;
}
@@ -2239,20 +2279,20 @@
}
};
Opal.hash_get = function(hash, key) {
if (key.$$is_string) {
- if ($has_own.call(hash.$$smap, key)) {
+ if ($has_own(hash.$$smap, key)) {
return hash.$$smap[key];
}
return;
}
var key_hash, bucket;
key_hash = hash.$$by_identity ? Opal.id(key) : key.$hash();
- if ($has_own.call(hash.$$map, key_hash)) {
+ if ($has_own(hash.$$map, key_hash)) {
bucket = hash.$$map[key_hash];
while (bucket) {
if (key === bucket.key || key['$eql?'](bucket.key)) {
return bucket.value;
@@ -2266,11 +2306,11 @@
var i, keys = hash.$$keys, length = keys.length, value, key_tmp;
if (key.$$is_string) {
if (typeof key !== "string") key = key.valueOf();
- if (!$has_own.call(hash.$$smap, key)) {
+ if (!$has_own(hash.$$smap, key)) {
return;
}
for (i = 0; i < length; i++) {
key_tmp = keys[i];
@@ -2290,11 +2330,11 @@
return value;
}
var key_hash = key.$hash();
- if (!$has_own.call(hash.$$map, key_hash)) {
+ if (!$has_own(hash.$$map, key_hash)) {
return;
}
var bucket = hash.$$map[key_hash], last_bucket;
@@ -2365,11 +2405,11 @@
bucket = bucket.next;
}
hash.$$keys[i].key_hash = key_hash;
- if (!$has_own.call(hash.$$map, key_hash)) {
+ if (!$has_own(hash.$$map, key_hash)) {
hash.$$map[key_hash] = hash.$$keys[i];
continue;
}
bucket = hash.$$map[key_hash];
@@ -2406,11 +2446,11 @@
if (arguments[0].$$is_array) {
length = args.length;
for (i = 0; i < length; i++) {
if (args[i].length !== 2) {
- throw Opal.ArgumentError.$new("value not of length 2: " + args[i].$inspect());
+ $raise(Opal.ArgumentError, "value not of length 2: " + args[i].$inspect());
}
key = args[i][0];
value = args[i][1];
@@ -2420,11 +2460,11 @@
return hash;
}
else {
args = arguments[0];
for (key in args) {
- if ($has_own.call(args, key)) {
+ if ($has_own(args, key)) {
value = args[key];
Opal.hash_put(hash, key, value);
}
}
@@ -2432,11 +2472,11 @@
return hash;
}
}
if (arguments_length % 2 !== 0) {
- throw Opal.ArgumentError.$new("odd number of arguments for Hash");
+ $raise(Opal.ArgumentError, "odd number of arguments for Hash");
}
for (i = 0; i < arguments_length; i += 2) {
key = arguments[i];
value = arguments[i + 1];
@@ -2497,11 +2537,11 @@
// -------------------
// helper that can be used from methods
function $deny_frozen_access(obj) {
if (obj.$$frozen) {
- throw Opal.FrozenError.$new("can't modify frozen " + (obj.$class()) + ": " + (obj), Opal.hash2(["receiver"], {"receiver": obj}));
+ $raise(Opal.FrozenError, "can't modify frozen " + (obj.$class()) + ": " + (obj), Opal.hash2(["receiver"], {"receiver": obj}));
}
};
Opal.deny_frozen_access = $deny_frozen_access;
// common #freeze runtime support
@@ -2699,15 +2739,11 @@
else {
var severity = Opal.config.missing_require_severity;
var message = 'cannot load such file -- ' + path;
if (severity === "error") {
- if (Opal.LoadError) {
- throw Opal.LoadError.$new(message)
- } else {
- throw message
- }
+ $raise(Opal.LoadError, message);
}
else if (severity === "warning") {
console.warn('WARNING: LoadError: ' + message);
}
}
@@ -2744,11 +2780,11 @@
// @param name [String] the canonical name of the encoding
// @param type [String] possible values are either `"encoding"`, `"internal_encoding"`, or `undefined
Opal.set_encoding = function(str, name, type) {
if (typeof type === "undefined") type = "encoding";
if (typeof str === 'string' || str.$$frozen === true)
- throw Opal.FrozenError.$new("can't modify frozen String");
+ $raise(Opal.FrozenError, "can't modify frozen String");
var encoding = Opal.find_encoding(name);
if (encoding === str[type]) { return str; }
@@ -2759,11 +2795,11 @@
// Fetches the encoding for the given name or raises ArgumentError.
Opal.find_encoding = function(name) {
var register = Opal.encodings;
var encoding = register[name] || register[name.toUpperCase()];
- if (!encoding) throw Opal.ArgumentError.$new("unknown encoding name - " + name);
+ if (!encoding) $raise(Opal.ArgumentError, "unknown encoding name - " + name);
return encoding;
}
// @returns a String object with the encoding set from a string literal
Opal.enc = function(str, name) {
@@ -2881,21 +2917,48 @@
if (kwargs == null) {
return Opal.hash2([], {});
} else if (kwargs.$$is_hash) {
return kwargs;
} else {
- throw Opal.ArgumentError.$new('expected kwargs');
+ $raise(Opal.ArgumentError, 'expected kwargs');
}
}
Opal.get_kwarg = function(kwargs, key) {
- if (!$has_own.call(kwargs.$$smap, key)) {
- throw Opal.ArgumentError.$new('missing keyword: '+key);
+ if (!$has_own(kwargs.$$smap, key)) {
+ $raise(Opal.ArgumentError, 'missing keyword: '+key);
}
return kwargs.$$smap[key];
}
+ // Arrays of size > 32 elements that contain only strings,
+ // symbols, integers and nils are compiled as a self-extracting
+ // string.
+ Opal.large_array_unpack = function(str) {
+ var array = str.split(","), length = array.length, i;
+ for (i = 0; i < length; i++) {
+ switch(array[i][0]) {
+ case undefined:
+ array[i] = nil
+ break;
+ case '-':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ array[i] = +array[i];
+ }
+ }
+ return array;
+ }
+
// Initialization
// --------------
Opal.BasicObject = BasicObject = $allocate_class('BasicObject', null);
Opal.Object = _Object = $allocate_class('Object', Opal.BasicObject);
Opal.Module = Module = $allocate_class('Module', Opal.Object);
@@ -2947,21 +3010,21 @@
Opal.top.$to_s = Opal.top.$inspect = $return_val('main');
Opal.top.$define_method = top_define_method;
// Foward calls to define_method on the top object to Object
function top_define_method() {
- var args = Opal.slice.call(arguments);
+ var args = $slice(arguments);
var block = top_define_method.$$p;
top_define_method.$$p = null;
return Opal.send(_Object, 'define_method', args, block)
};
// Nil
Opal.NilClass = $allocate_class('NilClass', Opal.Object);
$const_set(_Object, 'NilClass', Opal.NilClass);
nil = Opal.nil = new Opal.NilClass();
nil.$$id = nil_id;
- nil.call = nil.apply = function() { throw Opal.LocalJumpError.$new('no block given'); };
+ nil.call = nil.apply = function() { $raise(Opal.LocalJumpError, 'no block given'); };
nil.$$frozen = true;
nil.$$comparable = false;
Object.seal(nil);
Opal.thrower = function(type) {