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) {