dart-hello-world

JavaScript performance comparison

Test case created by WebReflection

Info

a core library has an initialization cost and an execution one. This test compares the difference between basic JS and Dart for the most simple task ever made: the "Hello World".

It would be nice to test in isolation Dart VM performances VS JS VM performances too ... unfortunately not possible right now in this page.

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
JS as it is
function HelloDartTest() {}
HelloDartTest.testMain = function testMain() {
  print("Hello JavaScripter!");
};
HelloDartTest.testMain();


function print(message) {
  // as is for the current isolate$log function
  return;
  console.log(message);
};
pending…
JS out of Dart
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

function native_ArrayFactory__new(typeToken, length) {
  return RTT.setTypeInfo(
      new Array(length),
      Array.$lookupRTT(RTT.getTypeInfo(typeToken).typeArgs));
}

function native_ListFactory__new(typeToken, length) {
  return RTT.setTypeInfo(
      new Array(length),
      Array.$lookupRTT(RTT.getTypeInfo(typeToken).typeArgs));
}

function native_ObjectArray__indexOperator(index) {
  return this[index];
}

function native_ObjectArray__indexAssignOperator(index, value) {
  this[index] = value;
}

function native_ObjectArray_get$length() {
  return this.length;
}

function native_ObjectArray__setLength(length) {
  this.length = length;
}

function native_ObjectArray__add(element) {
  this.push(element);
}

function $inlineArrayIndexCheck(array, index) {
  if (index >= 0 && index < array.length) {
    return index;
  }
  native__ArrayJsUtil__throwIndexOutOfRangeException(index);
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Extend the Boolean prototype with members expected in dart.
 *
 * TODO(jimhug): Add verification to ! and truth tests
 */

Boolean.$instanceOf = function(obj) {
  return typeof obj == 'boolean' || obj instanceof Boolean;
};

function native_BoolImplementation_EQ(other) {
  if (typeof other == 'boolean') {
    return this == other;
  } else if (other instanceof Boolean) {
    // Must convert other to a primitive for value equality to work
    return this == Boolean(other);
  } else {
    return false;
  }
}

function native_BoolImplementation_toString() {
  return (this == true) ? "true" : "false";
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Helpers for lazy static initialization.
 */

var static$uninitialized = {};
var static$initializing = {};

// Optimized versions of closure bindings.
// Name convention: $bind<number-of-scopes>_<number-of-arguments>(fn, this, scopes, args)
function $bind0_0(fn, thisObj) {
  return function() {
    return fn.call(thisObj);
  }
}
function $bind0_1(fn, thisObj) {
  return function(arg) {
    return fn.call(thisObj, arg);
  }
}
function $bind0_2(fn, thisObj) {
  return function(arg1, arg2) {
    return fn.call(thisObj, arg1, arg2);
  }
}
function $bind0_3(fn, thisObj) {
  return function(arg1, arg2, arg3) {
    return fn.call(thisObj, arg1, arg2, arg3);
  }
}
function $bind0_4(fn, thisObj) {
  return function(arg1, arg2, arg3, arg4) {
    return fn.call(thisObj, arg1, arg2, arg3, arg4);
  }
}
function $bind0_5(fn, thisObj) {
  return function(arg1, arg2, arg3, arg4, arg5) {
    return fn.call(thisObj, arg1, arg2, arg3, arg4, arg5);
  }
}

function $bind1_0(fn, thisObj, scope) {
  return function() {
    return fn.call(thisObj, scope);
  }
}
function $bind1_1(fn, thisObj, scope) {
  return function(arg) {
    return fn.call(thisObj, scope, arg);
  }
}
function $bind1_2(fn, thisObj, scope) {
  return function(arg1, arg2) {
    return fn.call(thisObj, scope, arg1, arg2);
  }
}
function $bind1_3(fn, thisObj, scope) {
  return function(arg1, arg2, arg3) {
    return fn.call(thisObj, scope, arg1, arg2, arg3);
  }
}
function $bind1_4(fn, thisObj, scope) {
  return function(arg1, arg2, arg3, arg4) {
    return fn.call(thisObj, scope, arg1, arg2, arg3, arg4);
  }
}
function $bind1_5(fn, thisObj, scope) {
  return function(arg1, arg2, arg3, arg4, arg5) {
    return fn.call(thisObj, scope, arg1, arg2, arg3, arg4, arg5);
  }
}

function $bind2_0(fn, thisObj, scope1, scope2) {
  return function() {
    return fn.call(thisObj, scope1, scope2);
  }
}
function $bind2_1(fn, thisObj, scope1, scope2) {
  return function(arg) {
    return fn.call(thisObj, scope1, scope2, arg);
  }
}
function $bind2_2(fn, thisObj, scope1, scope2) {
  return function(arg1, arg2) {
    return fn.call(thisObj, scope1, scope2, arg1, arg2);
  }
}
function $bind2_3(fn, thisObj, scope1, scope2) {
  return function(arg1, arg2, arg3) {
    return fn.call(thisObj, scope1, scope2, arg1, arg2, arg3);
  }
}
function $bind2_4(fn, thisObj, scope1, scope2) {
  return function(arg1, arg2, arg3, arg4) {
    return fn.call(thisObj, scope1, scope2, arg1, arg2, arg3, arg4);
  }
}
function $bind2_5(fn, thisObj, scope1, scope2) {
  return function(arg1, arg2, arg3, arg4, arg5) {
    return fn.call(thisObj, scope1, scope2, arg1, arg2, arg3, arg4, arg5);
  }
}

function $bind3_0(fn, thisObj, scope1, scope2, scope3) {
  return function() {
    return fn.call(thisObj, scope1, scope2, scope3);
  }
}
function $bind3_1(fn, thisObj, scope1, scope2, scope3) {
  return function(arg) {
    return fn.call(thisObj, scope1, scope2, scope3, arg);
  }
}
function $bind3_2(fn, thisObj, scope1, scope2, scope3) {
  return function(arg1, arg2) {
    return fn.call(thisObj, scope1, scope2, arg1, arg2);
  }
}
function $bind3_3(fn, thisObj, scope1, scope2, scope3) {
  return function(arg1, arg2, arg3) {
    return fn.call(thisObj, scope1, scope2, scope3, arg1, arg2, arg3);
  }
}
function $bind3_4(fn, thisObj, scope1, scope2, scope3) {
  return function(arg1, arg2, arg3, arg4) {
    return fn.call(thisObj, scope1, scope2, scope3, arg1, arg2, arg3, arg4);
  }
}
function $bind3_5(fn, thisObj, scope1, scope2, scope3) {
  return function(arg1, arg2, arg3, arg4, arg5) {
    return fn.call(thisObj, scope1, scope2, scope3, arg1, arg2, arg3, arg4, arg5);
  }
}

/**
 * Implements extends for dart classes on javascript prototypes.
 * @param {Function} child
 * @param {Function} parent
 */

function $inherits(child, parent) {
  if (child.prototype.__proto__) {
    child.prototype.__proto__ = parent.prototype;
  } else {
    function tmp() {};
    tmp.prototype = parent.prototype;
    child.prototype = new tmp();
    child.prototype.constructor = child;
  }
}

/**
 * @param {Function} fn
 * @param {Object|undefined} thisObj
 * @param {...*} var_args
 */

function $bind(fn, thisObj, var_args) {
  if (arguments.length > 2) {
    var boundArgs = Array.prototype.slice.call(arguments, 2);
    return function() {
      // Prepend the bound arguments to the current arguments.
      var newArgs = Array.prototype.slice.call(arguments);
      Array.prototype.unshift.apply(newArgs, boundArgs);
      return fn.apply(thisObj, newArgs);
    };
  } else {
    return function() {
      return fn.apply(thisObj, arguments);
    };
  }
}

/**
 * Dart null object that should be used by JS implementation to test for
 * Dart null.
 *
 * TODO(ngeoffray): update dartc to generate this variable instead of
 *                  undefined.
 * @const
 */

var $Dart$Null = void 0;

function assert(expr, msg) {
  var val = typeof(expr) == 'function' ? expr() : expr;
  if (!val) {
    // TODO: throw a Dart AssertionError instead
    var err = new Error('Assertion failed. ' + (msg || ''));
    Error.captureStackTrace && Error.captureStackTrace(err);
    throw err;
  }
}

// TODO(jimhug): Remove these functions after updating compiler backend.
function BIT_OR$operator(val1, val2) {
  return (typeof(val1) == 'number' && typeof(val2) == 'number')
      ? val1 | val2
      : val1.BIT_OR$operator(val2);
}

function BIT_XOR$operator(val1, val2) {
  return (typeof(val1) == 'number' && typeof(val2) == 'number')
      ? val1 ^ val2
      : val1.BIT_XOR$operator(val2);
}

function BIT_AND$operator(val1, val2) {
  return (typeof(val1) == 'number' && typeof(val2) == 'number')
      ? val1 & val2
      : val1.BIT_AND$operator(val2);
}

function BIT_NOT$operator(val) {
  return (typeof(val) == 'number') ? ~val : val.BIT_NOT$operator();
}

function SHL$operator(val1, val2) {
  return (typeof(val1) == 'number' && typeof(val2) == 'number')
      ? val1 << val2
      : val1.SHL$operator(val2);
}

function SAR$operator(val1, val2) {
  return (typeof(val1) == 'number' && typeof(val2) == 'number')
      ? val1 >> val2
      : val1.SAR$operator(val2);
}

function SHR$operator(val1, val2) {
  return val1.SHR$operator(val2);
}

function ADD$operator(val1, val2) {
  return (typeof(val1) == 'number' && typeof(val2) == 'number')
      ? val1 + val2
      : val1.ADD$operator(val2);
}

function SUB$operator(val1, val2) {
  return (typeof(val1) == 'number' && typeof(val2) == 'number')
      ? val1 - val2
      : val1.SUB$operator(val2);
}

function MUL$operator(val1, val2) {
  return (typeof(val1) == 'number' && typeof(val2) == 'number')
      ? val1 * val2
      : val1.MUL$operator(val2);
}

function DIV$operator(val1, val2) {
  return (typeof(val1) == 'number' && typeof(val2) == 'number')
      ? val1 / val2
      : val1.DIV$operator(val2);
}

function MOD$operator(val1, val2) {
  return (typeof(val1) == 'number' && typeof(val2) == 'number')
      ? number$euclideanModulo(val1, val2)
      : val1.MOD$operator(val2);
}

function TRUNC$operator(val1, val2) {
  if (typeof(val1) == 'number' && typeof(val2) == 'number') {
    var tmp = val1 / val2;
    return (tmp < 0) ? Math.ceil(tmp) : Math.floor(tmp);
  } else {
    return val1.TRUNC$operator(val2);
  }
}

function negate$operator(val) {
  return (typeof(val) == 'number') ? -val : val.negate$operator();
}

function LT$operator(val1, val2) {
  return (typeof(val1) == 'number' && typeof(val2) == 'number')
      ? val1 < val2
      : val1.LT$operator(val2);
}

function GT$operator(val1, val2) {
  return (typeof(val1) == 'number' && typeof(val2) == 'number')
      ? val1 > val2
      : val1.GT$operator(val2);
}

function LTE$operator(val1, val2) {
  return (typeof(val1) == 'number' && typeof(val2) == 'number')
      ? val1 <= val2
      : val1.LTE$operator(val2);
}

function GTE$operator(val1, val2) {
  return (typeof(val1) == 'number' && typeof(val2) == 'number')
      ? val1 >= val2
      : val1.GTE$operator(val2);
}


/**
 * These operators need to work correctly with undefined
 * so must be functions.
 */

function EQ$operator(val1, val2) {
  if (val1 === $Dart$Null) {
    return val2 === $Dart$Null;
  } else {
    return (typeof(val1) == 'number' && typeof(val2) == 'number')
        ? val1 == val2
        : val1.EQ$operator(val2);
  }
}

function NE$operator(val1, val2) {
  return !EQ$operator(val1, val2);
}

// The following operator-functions are not called from Dart-generated code, but
// only from handwritten JS code.
function INDEX$operator(obj, index) {
  return obj.INDEX$operator(index);
}

function ASSIGN_INDEX$operator(obj, index, newVal) {
  obj.ASSIGN_INDEX$operator(index, newVal);
}

function $Dart$ThrowException(e) {
  // If e is not a value, we can use V8's captureStackTrace utility method.
  if (e && (typeof e == "object") && Error.captureStackTrace) {
    Error.captureStackTrace(e);
  }
  throw e;
}

function $toString(x) {
  return native__StringJsUtil_toDartString(x);
}

// Translate a JavaScript exception to a Dart exception
// TODO(zundel): cross browser support.  This is Chrome specific.
function $transformBrowserException(e) {
  if (e instanceof TypeError) {
    switch(e.type) {
    case "property_not_function":
    case "called_non_callable":
      if (e.arguments[0] == "undefined") {
        return native_ExceptionHelper_createNullPointerException();
      }
      return native_ExceptionHelper_createObjectNotClosureException();
    case "non_object_property_call":
    case "non_object_property_load":
      return native_ExceptionHelper_createNullPointerException();
    case "undefined_method":
      if (e.arguments[0] == "call" || e.arguments[0] == "apply") {
        return native_ExceptionHelper_createObjectNotClosureException();
      }
      return native_ExceptionHelper_createNoSuchMethodException(
          "", e.arguments[0], []);
    }
  }
  return e;
}

// Throws a NoSuchMethodException (used by named-parameter trampolines).
function $nsme() {
  var e = native_ExceptionHelper_createNoSuchMethodException("", "", []);
  $Dart$ThrowException(e);
}

// Throws a NoSuchMethodException (used when instantiating via a non-existent class or ctor).
function $nsme2(name, args) {
  var e = native_ExceptionHelper_createNoSuchMethodException(name, name, args);
  $Dart$ThrowException(e);
}

// Shared named-argument object used by call-sites with no named arguments.
/** @const */
var $noargs = {count:0};

// Used for invoking dart functions from js.
function $dartcall(fn, args) {
  args.unshift(args.length, $noargs);
  fn.apply(null, args);
}

//
// The following methods are used to create canonical constants.
//

function native_ConstHelper_getConstId(o) {
  return $dart_const_id(o);
}

// compile time const canonicalization helpers
function $dart_const_id(o) {
   if (o === $Dart$Null) return "";
   if (typeof o === "number") return "n" + o;
   if (typeof o === "boolean") return "b" + ((o) ? 1 : 0);
   if (typeof o === "string") return $dart_const_string_id(o);
   if (typeof o === "function") throw "a function is not a constant expression";
   var result = o.$dartConstId;
   if (result === undefined) {
     throw "internal error: reference to non-canonical constant";
   }
   return result;
}

// Array ids have the form: "aID,ID,ID"
function $dart_const_array_id(o) {
  var ids = [];
  for (var i=o.length-1; i>=0; i--) {
    ids.push($dart_const_id(o[i]));
  }
  return "a" + ids.join(",");
}

var $CONST_MAP_PREFIX = ":"

// String ids have the form "sID"
var $string_id = 0;
var $string_id_cache = {};
function $dart_const_string_id(s) {
  var key = $CONST_MAP_PREFIX + s;
  var id = $string_id_cache[key];
  if (!id) {
    id = "s" + (++$string_id);
    $string_id_cache[key] = id;
  }
  return id;
}

// A place to store the canonical consts
var $consts = {};

function $isDartMap(o) {
  return !!(o && o.$implements$Map$Dart);
}

// Intern const object "o"
function $intern(o, type_args) {
  var id;
  // Maps and arrays need special handling
  // TODO(johnlenz): This array check may not be sufficient across iframes.
  if (o instanceof Array) {
    // Dart array literals are implemented as JavaScript native arrays.
    id = $dart_const_array_id(o);
  } else if ($isDartMap(o)) {
    // Dart map literals are currently implemented by a non-const Dart class.
    id = native_ConstHelper_getConstMapId(o);
  } else {
    id = "o" + o.$const_id();
  }
  if (type_args != null) {
    id += '<';
    for (var i=type_args.length-1; i >= 0; i--) {
      id += type_args[i];
      id += ","
    }
    id += '>';
  }
  var key = $CONST_MAP_PREFIX + id;
  var match = $consts[key];
  if (match != null) {
    return match;
  }
  o.$dartConstId = id;
  $consts[key] = o;
  return o;
}

function $Dart$MapLiteralFactory() {
  return native__CoreJsUtil__newMapLiteral();
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Dart core library.

function date$validateValue(value) {
  if (isNaN(value)) {
    // TODO(floitsch): Use real exception object.
    throw Error("Invalid Date");
  }
  return value;
}

function native_DateImplementation__valueFromDecomposed(
    years, month, day, hours, minutes, seconds, milliseconds, isUtc) {
  // JavaScript has 0-based months.
  var jsMonth = month - 1;
  var value = isUtc ?
              Date.UTC(years, jsMonth, day,
                       hours, minutes, seconds, milliseconds) :
              new Date(years, jsMonth, day,
                       hours, minutes, seconds, milliseconds).valueOf();
  return date$validateValue(value);
}

function native_DateImplementation__valueFromString(str) {
  return date$validateValue(Date.parse(str));
}

function native_DateImplementation__now() {
  return new Date().valueOf();
}

function date$dateFrom(dartDate, value) {
  // Lazily keep a JS Date stored in the dart object.
  var date = dartDate.date;
  if (!date) {
    date = new Date(value);
    dartDate.date = date;
  }
  return date;
}

function native_DateImplementation__getYear(value, isUtc) {
  var date = date$dateFrom(this, value);
  return isUtc ? date.getUTCFullYear() : date.getFullYear();
}

function native_DateImplementation__getMonth(value, isUtc) {
  var date = date$dateFrom(this, value);
  var jsMonth = isUtc ? date.getUTCMonth() : date.getMonth();
  // JavaScript has 0-based months.
  return jsMonth + 1;
}

function native_DateImplementation__getDay(value, isUtc) {
  var date = date$dateFrom(this, value);
  return isUtc ? date.getUTCDate() : date.getDate();
}

function native_DateImplementation__getHours(value, isUtc) {
  var date = date$dateFrom(this, value);
  return isUtc ? date.getUTCHours() : date.getHours();
}

function native_DateImplementation__getMinutes(value, isUtc) {
  var date = date$dateFrom(this, value);
  return isUtc ? date.getUTCMinutes() : date.getMinutes();
}

function native_DateImplementation__getSeconds(value, isUtc) {
  var date = date$dateFrom(this, value);
  return isUtc ? date.getUTCSeconds() : date.getSeconds();
}

function native_DateImplementation__getMilliseconds(value, isUtc) {
  var date = date$dateFrom(this, value);
  return isUtc ? date.getUTCMilliseconds() : date.getMilliseconds();
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

var isolate$current = null;
var isolate$rootIsolate = null;  // Will only be set in the main worker.
var isolate$inits = [];
var isolate$globalThis = this;

// These declarations are needed to avoid errors from the Closure Compiler
// optimizer. They are defined in client/dom/generated/dart_dom_wrapping.js.
var __dom_wrap;
var __dom_unwrap;

var isolate$inWorker =
    (typeof isolate$globalThis['importScripts']) != "undefined";
var isolate$supportsWorkers =
    isolate$inWorker || ((typeof isolate$globalThis['Worker']) != 'undefined');

var isolate$MAIN_WORKER_ID = 0;
// Non-main workers will update the id variable.
var isolate$thisWorkerId = isolate$MAIN_WORKER_ID;

// Whether to use web workers when implementing isolates.
var isolate$useWorkers = isolate$supportsWorkers;
// Uncomment this to not use web workers even if they're available.
//   isolate$useWorkers = false;

// Whether to use the web-worker JSON-based message serialization protocol,
// even if not using web workers.
var isolate$useWorkerSerializationProtocol = false;
// Uncomment this to always use the web-worker JSON-based message
// serialization protocol, e.g. for testing purposes.
//   isolate$useWorkerSerializationProtocol = true;


// ------- SendPort -------
function isolate$sendMessage(workerId, isolateId, receivePortId,
                             message, replyTo) {
  // Both, the message and the replyTo are already serialized.
  if (workerId == isolate$thisWorkerId) {
    var isolate = isolate$isolateRegistry.get(isolateId);
    if (!isolate) return;  // Isolate has been closed.
    var receivePort = isolate.getReceivePortForId(receivePortId);
    if (!receivePort) return;  // ReceivePort has been closed.
    isolate$receiveMessage(receivePort, isolate, message, replyTo);
  } else {
    var worker;
    if (isolate$inWorker) {
      worker = isolate$mainWorker;
    } else {
      worker = isolate$workerRegistry.get(workerId);
    }
    worker.postMessage({ command: 'message',
                         workerId: workerId,
                         isolateId: isolateId,
                         portId: receivePortId,
                         msg: message,
                         replyTo: replyTo });
  }
}

function isolate$receiveMessage(port, isolate,
                                serializedMessage, serializedReplyTo) {
  isolate$IsolateEvent.enqueue(isolate, function() {
    var message = isolate$deserializeMessage(serializedMessage);
    var replyTo = isolate$deserializeMessage(serializedReplyTo);
    native_ReceivePortImpl__invokeCallback(port, message, replyTo);
    native__IsolateJsUtil__promiseQueueProcess();
  });
}

// ------- ReceivePort -------

function native_ReceivePortImpl__register(id) {
  isolate$current.registerReceivePort(id, this);
}

function native_ReceivePortImpl__unregister(id) {
  isolate$current.unregisterReceivePort(id);
}

function native_ReceivePortImpl__currentWorkerId() {
  return isolate$thisWorkerId;
}

function native_ReceivePortImpl__currentIsolateId() {
  return isolate$current.id;
}

// -------- Registry ---------
function isolate$Registry() {
  this.map = {};
  this.count = 0;
}

isolate$Registry.prototype.register = function(id, val) {
  if (this.map[id]) {
    throw Error("Registry: Elements must be registered only once.");
  }
  this.map[id] = val;
  this.count++;
};

isolate$Registry.prototype.unregister = function(id) {
  if (id in this.map) {
    delete this.map[id];
    this.count--;
  }
};

isolate$Registry.prototype.get = function(id) {
  return this.map[id];
};

isolate$Registry.prototype.isEmpty = function() {
  return this.count === 0;
};


// ------- Worker registry -------
// Only used in the main worker.
var isolate$workerRegistry = new isolate$Registry();

// ------- Isolate registry -------
// Isolates must be registered if, and only if, receive ports are alive.
// Normally no open receive-ports means that the isolate is dead, but
// DOM callbacks could resurrect it.
var isolate$isolateRegistry = new isolate$Registry();

// ------- Debugging log function -------
function isolate$log(msg) {
  return;
  if (isolate$inWorker) {
    isolate$mainWorker.postMessage({ command: 'log', msg: msg });
  } else {
    try {
      isolate$globalThis.console.log(msg);
    } catch(e) {
      throw String(e.stack);
    }
  }
}

function isolate$initializeWorker(workerId) {
  isolate$thisWorkerId = workerId;
}

var isolate$workerPrint = false;
if (isolate$inWorker) {
  isolate$workerPrint = function(msg){
    isolate$mainWorker.postMessage({ command: 'print', msg: msg });
  }
}

// ------- Message handler -------
function isolate$processWorkerMessage(sender, e) {
  var msg = e.data;
  switch (msg.command) {
    case 'start':
      isolate$log("starting worker: " + msg.id + " " + msg.factoryName);
      isolate$initializeWorker(msg.id);
      var runnerObject = (isolate$globalThis[msg.factoryName])();
      var serializedReplyTo = msg.replyTo;
      isolate$IsolateEvent.enqueue(new isolate$Isolate(), function() {
        var replyTo = isolate$deserializeMessage(serializedReplyTo);
        native__IsolateJsUtil__startIsolate(runnerObject, replyTo);
      });
      isolate$runEventLoop();
      break;
    case 'spawn-worker':
      isolate$spawnWorker(msg.factoryName, msg.replyPort);
      break;
    case 'message':
      isolate$sendMessage(msg.workerId, msg.isolateId, msg.portId,
                          msg.msg, msg.replyTo);
      isolate$runEventLoop();
      break;
    case 'close':
      isolate$log("Closing Worker");
      isolate$workerRegistry.unregister(sender.id);
      sender.terminate();
      isolate$runEventLoop();
      break;
    case 'log':
      isolate$log(msg.msg);
      break;
    case 'print':
      native__IsolateJsUtil__print(msg.msg);
      break;
    case 'error':
      throw msg.msg;
      break;
  }
}

if (isolate$supportsWorkers) {
  isolate$globalThis.onmessage = function(e) {
    isolate$processWorkerMessage(isolate$mainWorker, e);
  };
}

// ------- Default Worker -------
function isolate$MainWorker() {
  this.id = isolate$MAIN_WORKER_ID;
}

var isolate$mainWorker = new isolate$MainWorker();
isolate$mainWorker.postMessage = function(msg) {
  isolate$globalThis.postMessage(msg);
};

var isolate$nextFreeIsolateId = 1;

// Native methods for isolate functionality.
/**
 * @constructor
 */

function isolate$Isolate() {
  // The isolate ids is only unique within the current worker and frame.
  this.id = isolate$nextFreeIsolateId++;
  // When storing information on DOM nodes the isolate's id is not enough.
  // We instead use a token with a hashcode. The token can be stored in the
  // DOM node (since it is small and will not keep much data alive).
  this.token = new Object();
  this.token.hashCode = (Math.random() * 0xFFFFFFF) >>> 0;
  this.receivePorts = new isolate$Registry();
  this.run(function() {
    // The Dart-to-JavaScript compiler builds a list of functions that
    // need to run for each isolate to setup the state of static
    // variables. Run through the list and execute each function.
    for (var i = 0, len = isolate$inits.length; i < len; i++) {
      isolate$inits[i]();
    }
  });
}

// It is allowed to stack 'run' calls. The stacked isolates can be different.
// That is Isolate1.run could call the DOM which then calls Isolate2.run.
isolate$Isolate.prototype.run = function(code) {
  var old = isolate$current;
  isolate$current = this;
  var result = null;
  try {
    result = code();
  } finally {
    isolate$current = old;
  }
  return result;
};

isolate$Isolate.prototype.registerReceivePort = function(id, port) {
  if (this.receivePorts.isEmpty()) {
    isolate$isolateRegistry.register(this.id, this);
  }
  this.receivePorts.register(id, port);
};

isolate$Isolate.prototype.unregisterReceivePort = function(id) {
  this.receivePorts.unregister(id);
  if (this.receivePorts.isEmpty()) {
    isolate$isolateRegistry.unregister(this.id);
  }
};

isolate$Isolate.prototype.getReceivePortForId = function(id) {
  return this.receivePorts.get(id);
};

var isolate$events = [];

/**
 * @constructor
 */

function isolate$IsolateEvent(isolate, fn) {
  this.isolate = isolate;
  this.fn = fn;
}

isolate$IsolateEvent.prototype.process = function() {
  this.isolate.run(this.fn);
};

isolate$IsolateEvent.enqueue = function(isolate, fn) {
  isolate$events.push(new isolate$IsolateEvent(isolate, fn));
};

isolate$IsolateEvent.dequeue = function() {
  if (isolate$events.length == 0) return $Dart$Null;
  var result = isolate$events[0];
  isolate$events.splice(0, 1);
  return result;
};

function native_IsolateNatives__spawn(runnable, light, replyPort) {
  // TODO(floitsch): throw exception if runnable's class doesn't have a
  // default constructor.
  if (isolate$useWorkers && !light) {
    isolate$startWorker(runnable, replyPort);
  } else {
    isolate$startNonWorker(runnable, replyPort);
  }
}

function native_IsolateNatives_bind(fn) {
  var isolate = isolate$current;
  return function() {
    var self = this;
    var args = arguments;
    isolate.run(function() {
      fn.apply(self, args);
    });
    isolate$runEventLoop();
  };
}

function isolate$startNonWorker(runnable, replyTo) {
  // Spawn a new isolate and create the receive port in it.
  var spawned = new isolate$Isolate();

  // Instead of just running the provided runnable, we create a
  // new cloned instance of it with a fresh state in the spawned
  // isolate. This way, we do not get cross-isolate references
  // through the runnable.
  var factory = runnable.getIsolateFactory();
  isolate$IsolateEvent.enqueue(spawned, function() {
    native__IsolateJsUtil__startIsolate(factory(), replyTo);
  });
}

// This field is only used by the main worker.
var isolate$nextFreeWorkerId = isolate$thisWorkerId + 1;

var isolate$thisScript = function() {
  if (!isolate$supportsWorkers || isolate$inWorker) return null;

  // TODO(5334778): Find a cross-platform non-brittle way of getting the
  // currently running script.
  var scripts = document.getElementsByTagName('script');
  // The scripts variable only contains the scripts that have already been
  // executed. The last one is the currently running script.
  var script = scripts[scripts.length - 1];
  var src = script.src;
  if (!src) {
    // TODO()
    src = "FIXME:5407062" + "_" + Math.random().toString();
    script.src = src;
  }
  return src;
}();

function isolate$startWorker(runnable, replyPort) {
  var factory = runnable.getIsolateFactory();
  var factoryName = factory.name;
  var serializedReplyPort = isolate$serializeMessage(replyPort);
  if (isolate$inWorker) {
    isolate$mainWorker.postMessage({ command: 'spawn-worker',
                                     factoryName: factoryName,
                                     replyPort: serializedReplyPort } );
  } else {
    isolate$spawnWorker(factoryName, serializedReplyPort);
  }
}

function isolate$spawnWorker(factoryName, serializedReplyPort) {
  var worker = new Worker(isolate$thisScript);
  worker.onmessage = function(e) {
    isolate$processWorkerMessage(worker, e);
  };
  var workerId = isolate$nextFreeWorkerId++;
  // We also store the id on the worker itself so that we can unregister it.
  worker.id = workerId;
  isolate$workerRegistry.register(workerId, worker);
  worker.postMessage({ command: 'start',
                       id: workerId,
                       replyTo: serializedReplyPort,
                       factoryName: factoryName });
}

function native_SendPortImpl__sendNow(message, replyTo) {
  if (replyTo !== $Dart$Null && !(replyTo instanceof SendPortImpl$Dart)) {
    throw "SendPort::send: Illegal replyTo type.";
  }
  message = isolate$serializeMessage(message);
  replyTo = isolate$serializeMessage(replyTo);
  var workerId = native_SendPortImpl__getWorkerId(this);
  var isolateId = native_SendPortImpl__getIsolateId(this);
  var receivePortId = native_SendPortImpl__getReceivePortId(this);
  isolate$sendMessage(workerId, isolateId, receivePortId, message, replyTo);
}

function isolate$closeWorkerIfNecessary() {
  if (!isolate$isolateRegistry.isEmpty()) return;
  isolate$mainWorker.postMessage( { command: 'close' } );
}

function isolate$doOneEventLoopIteration() {
  var CONTINUE_LOOP = true;
  var STOP_LOOP = false;
  var event = isolate$IsolateEvent.dequeue();
  if (!event) {
    if (isolate$inWorker) {
      isolate$closeWorkerIfNecessary();
    } else if (!isolate$isolateRegistry.isEmpty() &&
               isolate$workerRegistry.isEmpty() &&
               !isolate$supportsWorkers && (typeof(window) == 'undefined')) {
      // This should only trigger when running on the command-line.
      // We don't want this check to execute in the browser where the isolate
      // might still be alive due to DOM callbacks.
      // throw Error("Program exited with open ReceivePorts.");
    }
    return STOP_LOOP;
  } else {
    event.process();
    return CONTINUE_LOOP;
  }
}

function isolate$doRunEventLoop() {
  if (typeof window != 'undefined' && window.setTimeout) {
    (function next() {
      var continueLoop = isolate$doOneEventLoopIteration();
      if (!continueLoop) return;
      // TODO(kasperl): It might turn out to be too expensive to call
      // setTimeout for every single event. This needs more investigation.
      window.setTimeout(next, 0);
    })();
  } else {
    while (true) {
      var continueLoop = isolate$doOneEventLoopIteration();
      if (!continueLoop) break;
    }
  }
}

function isolate$runEventLoop() {
  if (!isolate$inWorker) {
    isolate$doRunEventLoop();
  } else {
    try {
      isolate$doRunEventLoop();
    } catch(e) {
      // TODO(floitsch): try to send stack-trace to the other side.
      isolate$mainWorker.postMessage({ command: 'error', msg: "" + e });
    }
  }
}

function RunEntry(entry, args) {
  // Don't start the main loop again, if we are in a worker.
  if (isolate$inWorker) return;
  var isolate = new isolate$Isolate();
  isolate$rootIsolate = isolate;
  isolate$IsolateEvent.enqueue(isolate, function() {
    entry(args);
  });
  isolate$runEventLoop();

  // BUG(5151491): This should not be necessary, but because closures
  // passed to the DOM as event handlers do not bind their isolate
  // automatically we try to give them a reasonable context to live in
  // by having a "default" isolate (the first one created).
  isolate$current = isolate;
}

// ------- Message Serializing and Deserializing -------

function native_MessageTraverser__clearAttachedInfo(o) {
  o['__MessageTraverser__attached_info__'] = (void 0);
}

function native_MessageTraverser__setAttachedInfo(o, info) {
  o['__MessageTraverser__attached_info__'] = info;
}

function native_MessageTraverser__getAttachedInfo(o) {
  return o['__MessageTraverser__attached_info__'];
}

function native_Serializer__newJsArray(len) {
  return new Array(len);
}

function native_Serializer__jsArrayIndexSet(jsArray, index, val) {
  jsArray[index] = val;
}

function native_Serializer__dartListToJsArrayNoCopy(list) {
  if (list instanceof Array) {
    RTT.removeTypeInfo(list);
    return list;
  } else {
    var len = native__ArrayJsUtil__arrayLength(list);
    var array = new Array(len);
    for (var i = 0; i < len; i++) {
      array[i] = INDEX$operator(list, i);
    }
    return array;
  }
}

function native_Deserializer__isJsArray(x) {
  return x instanceof Array;
}

function native_Deserializer__jsArrayIndex(x, index) {
  return x[index];
}

function native_Deserializer__jsArrayLength(x) {
  return x.length;
}

function isolate$serializeMessage(message) {
  if (isolate$useWorkers || isolate$useWorkerSerializationProtocol) {
    return native__IsolateJsUtil__serializeObject(message);
  } else {
    return native__IsolateJsUtil__copyObject(message);
  }
}

function isolate$deserializeMessage(message) {
  if (isolate$useWorkers || isolate$useWorkerSerializationProtocol) {
    return native__IsolateJsUtil__deserializeMessage(message);
  } else {
    // Nothing more to do.
    return message;
  }
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Native methods for Math.
var native_Math_ceil = Math.ceil;
var native_Math_floor = Math.floor;
var native_Math_max = Math.max;
var native_Math_min = Math.min;
var native_Math_round = Math.round;

// A valid integer-string is composed of:
//   optional whitespace: \s*
//   an optional sign: [+-]?
//   either digits (at least one): \d+
//       or a hex-literal: 0[xX][0-9abcdefABCDEF]+
//   optional whitespace: \s*
var math$INT_REGEXP =
    /^\s*[+-]?(:?\d+|0[xX][0-9abcdefABCDEF]+)\s*$/;

// A valid double-string is composed of:
//   optional whitespace: \s*
//   an optional sign: [+-]?
//   either:
//      digits* . digits+ exponent?
//      digits+ exponent
//      Infinity
//      NaN
//   optional whitespace: \s*
var math$DOUBLE_REGEXP =
    /^\s*[+-]?((\d*\.\d+([eE][+-]?\d+)?)|(\d+([eE][+-]?\d+))|Infinity|NaN)\s*$/;

function native_MathNatives_parseDouble(str) {
  if (math$INT_REGEXP.test(str) || math$DOUBLE_REGEXP.test(str)) return +str;
  throw native_MathNatives__newBadNumberFormat(str);
}



function native_MathNatives_parseInt(str) {
  if (math$INT_REGEXP.test(str)) return +str;
  throw native_MathNatives__newBadNumberFormat(str);
}

function native_MathNatives_random() { return Math.random(); }
function native_MathNatives_sin(x) { return Math.sin(x); }
function native_MathNatives_cos(x) { return Math.cos(x); }
function native_MathNatives_tan(x) { return Math.tan(x); }
function native_MathNatives_asin(x) { return Math.asin(x); }
function native_MathNatives_acos(x) { return Math.acos(x); }
function native_MathNatives_atan(x) { return Math.atan(x); }
function native_MathNatives_atan2(x, y) { return Math.atan2(x, y); }
function native_MathNatives_sqrt(x) { return Math.sqrt(x); }
function native_MathNatives_exp(x) { return Math.exp(x); }
function native_MathNatives_log(x) { return Math.log(x); }
function native_MathNatives_pow(x, y) { return Math.pow(x, y); }
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Extend the Number prototype with members expected in dart.
 *
 * TODO(jimhug): Figure out how to map dart's number hierarchy to Number.
 */


Number.$instanceOf = function(obj) {
  return typeof obj == 'number' || obj instanceof Number;
};

function native_NumberImplementation_BIT_OR(other) {
  return this | other;
}

function native_NumberImplementation_BIT_XOR(other) {
  return this ^ other;
}

function native_NumberImplementation_BIT_AND(other) {
  return this & other;
}

function native_NumberImplementation_SHL(other) {
  return this << other;
}

function native_NumberImplementation_SAR(other) {
  return this >> other;
}

function native_NumberImplementation_ADD(other) {
  return this + other;
}

function native_NumberImplementation_SUB(other) {
  return this - other;
}

function native_NumberImplementation_MUL(other) {
  return this * other;
}

function native_NumberImplementation_DIV(other) {
  return this / other;
}

function native_NumberImplementation_TRUNC(other) {
  var tmp = this / other;
  if (tmp < 0) {
    return Math.ceil(tmp);
  } else {
    return Math.floor(tmp);
  }
}

function number$euclideanModulo(a, b) {
  var result = a % b;
  if (result == 0) {
    return 0;  // Make sure we don't return -0.0.
  } else if (result < 0) {
    if (b < 0) {
      return result - b;
    } else {
      return result + b;
    }
  }
  return result;
}

function native_NumberImplementation_MOD(other) {
  return number$euclideanModulo(this, other);
}

function native_NumberImplementation_LT(other) {
  return this < other;
}

function native_NumberImplementation_GT(other) {
  return this > other;
}

function native_NumberImplementation_LTE(other) {
  return this <= other;
}

function native_NumberImplementation_GTE(other) {
  return this >= other;
}

function native_NumberImplementation_EQ(other) {
  if (typeof other == 'number') {
    return this == other;
  } else if (other instanceof Number) {
    // Must convert other to a primitive for value equality to work
    return this == Number(other);
  } else {
    return false;
  }
}

function native_NumberImplementation_BIT_NOT() {
  return ~this;
}

function native_NumberImplementation_negate() { return -this; }

function native_NumberImplementation_remainder(other) {
  return this % other;
}

function native_NumberImplementation_abs() { return Math.abs(this); }

function native_NumberImplementation_round() { return Math.round(this); }
function native_NumberImplementation_floor() { return Math.floor(this); }
function native_NumberImplementation_ceil() { return Math.ceil(this); }
function native_NumberImplementation_truncate() {
  return (this < 0) ? Math.ceil(this) : Math.floor(this);
}
function native_NumberImplementation_isNegative() {
  // TODO(floitsch): is there a faster way to detect -0?
  if (this == 0) return (1 / this) < 0;
  return this < 0;
}
function native_NumberImplementation_isEven() { return ((this & 1) == 0); }
function native_NumberImplementation_isOdd() { return ((this & 1) == 1); }
function native_NumberImplementation_isNaN() { return isNaN(this); }
function native_NumberImplementation_isInfinite() {
  return (this == Infinity) || (this == -Infinity);
}

function native_NumberImplementation_toString() {
  return this.toString();
}
function native_NumberImplementation_toStringAsFixed(fractionDigits) {
  return this.toFixed(fractionDigits);
}
function native_NumberImplementation_toStringAsPrecision(precision) {
  return this.toPrecision(precision);
}
function native_NumberImplementation_toStringAsExponential(fractionDigits) {
  return this.toExponential(fractionDigits);
}
function native_NumberImplementation_toRadixString(radix) {
  return this.toString(radix);
}

function native_NumberImplementation_hashCode() {
  return this & 0xFFFFFFF;
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

Object.$instanceOf = function(obj) {
  return true;
};
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

function native__Logger__printString(str) {
  if (isolate$workerPrint) {
    isolate$workerPrint(str);
  } else if (this.console) {
    this.console.log(str);
  } else if (this.write) {
    this.write(str);
    this.write('\n');
  }
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

function native_JSSyntaxRegExp_firstMatch(str) {
  var re = $DartRegExpToJSRegExp(this);
  var m = re.exec(str);
  if (m != null) {
    var match = native_JSSyntaxMatch__new(this, str);
    match.match_ = m;
    match.lastIndex_ = re.lastIndex;
    return match;
  }
  return $Dart$Null;
}

function native_JSSyntaxRegExp_hasMatch(str) {
  return $DartRegExpToJSRegExp(this).test(str);
}

function native_JSSyntaxRegExp_stringMatch(str) {
  var m = $DartRegExpToJSRegExp(this).exec(str);
  return (m != null ? m[0] : $Dart$Null);
}

function native_JSSyntaxMatch_group(nb) {
  return this.match_[nb];
}

function native_JSSyntaxMatch_groupCount() {
  return this.match_.length;
}

function native_JSSyntaxMatch_start() {
  return this.match_.index;
}

function native_JSSyntaxMatch_end() {
  return this.lastIndex_;
}

function native__LazyAllMatchesIterator__jsInit(regExp) {
  this.re = $DartRegExpToJSRegExp(regExp);
}

// The given RegExp is only used to initialize a new Match. We use the
// cached JS regexp to compute the next match.
function native__LazyAllMatchesIterator__computeNextMatch(regExp, str) {
  var re = this.re;
  if (re === null) return $Dart$Null;
  var m = re.exec(str);
  if (m == null) {
    this.re = null;
    return $Dart$Null;
  }
  var match = native_JSSyntaxMatch__new(regExp, str);
  match.match_ = m;
  match.lastIndex_ = re.lastIndex;
  return match;
}

function $DartRegExpToJSRegExp(exp) {
  var flags = "g";
  if (native_JSSyntaxRegExp__multiLine(exp)) flags += "m";
  if (native_JSSyntaxRegExp__ignoreCase(exp)) flags += "i";
  return new RegExp(native_JSSyntaxRegExp__pattern(exp), flags);
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// The following methods are used to handle type information
//

/**
 * @constructor
 * @param {string} classkey
 * @param {string=} typekey
 * @param {Array.<RTT>=} typeargs
 */

function RTT(classkey, typekey, typeargs) {
  this.classKey = classkey;
  this.typeKey = typekey ? typekey : classkey;
  this.typeArgs = typeargs;
  this.implementedTypes = {};
  // Add self
  this.implementedTypes[classkey] = this;
  // Add Object
  if (classkey != $cls('Object')) {
    this.implementedTypes[$cls('Object')] = RTT.objectType;
  }
}

/** @type {Object.<string, Object>} */
RTT.types = {};

/** @type {Array.<RTT>} */
RTT.prototype.derivedTypes = [];

/** @return {string} */
RTT.prototype.toString = function() { return this.typeKey; }

/**
 * @param {*} value
 * @return {boolean} Whether this type is implemented by the value
 */

RTT.prototype.implementedBy = function(value){
  return (value == null) ? RTT.nullInstanceOf(this) :
      this.implementedByType(RTT.getTypeInfo(value));
};

/**
 * A helper function for safely looking up a value
 * in a Object used as a map.
 * @param {Object.<*>} map
 * @param {srting} key
 * @return {*} the value or null;
 */

function $mapLookup(map, key) {
  return map.hasOwnProperty(key) ? map[key] : null;
}

/**
 * @param {!RTT} other
 * @return {boolean} Whether this type is implement by other
 */

RTT.prototype.implementedByType = function(otherType) {
  if (otherType === this || otherType === RTT.dynamicType) {
    return true;
  }
  var targetTypeInfo = $mapLookup(otherType.implementedTypes, this.classKey);
  if (targetTypeInfo == null) {
    return false;
  }
  if (targetTypeInfo.typeArgs && this.typeArgs) {
    for(var i = this.typeArgs.length - 1; i >= 0; i--) {
      if (!this.typeArgs[i].implementedByType(targetTypeInfo.typeArgs[i])) {
        return false;
      }
    }
  }
  return true;
};

/**
 * @return {string} the class name associated with this type
 */

RTT.prototype.getClassName = function() {
  var name = this.classKey;
  if (name.substr(0, 4) == "cls:") {
    name = name.substr(4);
  }
  if (name.substr(-5) == "$Dart") {
    name = name.substr(0, name.length - 5);
  }
  return name;
}

/**
 * @param {RTT}
 * @return {boolean}
 */

RTT.nullInstanceOf = function(type) {
  return type === RTT.objectType || type === RTT.dynamicType;
};

/**
 * @param {*} value The value to retrieve type information for
 * @return {RTT}
 */

RTT.getNativeTypeInfo = function(value) {
  if (value instanceof Array) return Array.$lookupRTT();
  switch (typeof value) {
    case 'string': return String.$lookupRTT();
    case 'number': return Number.$lookupRTT();
    case 'boolean': return Boolean.$lookupRTT();
  }
  return RTT.placeholderType;
};

/**
 * @param {string} name
 * @param {function(RTT,Array.<RTT>)=} implementsSupplier
 * @param {Array.<RTT>=} typeArgs
 * @return {RTT} The RTT information object
 */

RTT.create = function(name, implementsSupplier, typeArgs) {
  if (name == $cls("Object")) return RTT.objectType;
  var typekey = RTT.getTypeKey(name, typeArgs);
  var rtt = $mapLookup(RTT.types, typekey);
  if (rtt) {
    return rtt;
  }
  var classkey = RTT.getTypeKey(name);
  rtt = new RTT(classkey, typekey, typeArgs);
  RTT.types[typekey] = rtt;
  if (implementsSupplier) {
    implementsSupplier(rtt, typeArgs);
  }
  return rtt;
};

/**
 * @param {string} classkey
 * @param {Array.<(RTT|string)>=} typeargs
 * @return {string}
 */

RTT.getTypeKey = function(classkey, typeargs) {
  var key = classkey;
  if (typeargs) {
    key += "<" + typeargs.join(",") + ">";
  }
  return key;
};

/**
 * @return {*} value
 * @return {RTT} return the RTT information object for the value
 */

RTT.getTypeInfo = function(value) {
  return (value.$typeInfo) ? value.$typeInfo : RTT.getNativeTypeInfo(value);
};

/**
 * @param {Object} o
 * @param {RTT} rtt
 * Sets the RTT on the object and returns the object itself.
 */

RTT.setTypeInfo = function(o, rtt) {
  o.$typeInfo = rtt;
  return o;
};

/**
 * @param {Object} o
 * Removes any RTT from the object and returns the object itself.
 */

RTT.removeTypeInfo = function(o) {
  o.$typeInfo = null;
  return o;
};

/**
 * The typeArg array is optional
 * @param {Array.<RTT>=} typeArgs
 * @param {number} i
 * @return {RTT}
 */

RTT.getTypeArg = function(typeArgs, i) {
  if (typeArgs) {
    if (typeArgs.length > i) {
      return typeArgs[i];
    } else {
      throw new Error("Missing type arg");
    }
  }
  return RTT.dynamicType;
};

/**
 * The typeArg array is optional
 * @param {*} o
 * @param {string} classkey
 * @return {Array.<RTT>}
 */

RTT.getTypeArgsFor = function(o, classkey) {
  var rtt = $mapLookup(RTT.getTypeInfo(o).implementedTypes, classkey);
  if (!rtt) {
    throw new Error("internal error: can not find " +
        classkey + " in " + JSON.stringify(o));
  }
  return rtt.typeArgs;
};

// Base types for runtime type information

/** @type {!RTT} */
RTT.objectType = new RTT($cls('Object'));
RTT.objectType.implementedBy = function(o) {return true};
RTT.objectType.implementedByType = function(o) {return true};

/** @type {!RTT} */
RTT.dynamicType = new RTT($cls('Dynamic'));
RTT.dynamicType.implementedBy = function(o) {return true};
RTT.dynamicType.implementedByType = function(o) {return true};

/** @type {!RTT} */
RTT.placeholderType = new RTT($cls('::'));
RTT.placeholderType.implementedBy = function(o) {return true};
RTT.placeholderType.implementedByType = function(o) {return true};

/**
 * Checks that a value is assignable to an expected type, and either returns that
 * value if it is, or else throws a TypeMismatchException.
 *
 * @param {!RTT} the expected type
 * @param {*} the value to check
 * @return {*} the value
 */

function $chk(rtt, value) {
  // null can be assigned to any type
  if (value == $Dart$Null || rtt.implementedBy(value)) {
    return value;
  }
  $te(rtt, value);
}

/**
 * Throw a TypeError.  See core.dart for the ExceptionHelper class.
 *
 * @param {!RTT} the expected type
 * @param {*) the value that failed
 */

function $te(rtt, value) {
  var srcType = RTT.getTypeInfo(value).getClassName();
  var dstType = rtt.getClassName();
  var e = native_ExceptionHelper_createTypeError(srcType, dstType);
  $Dart$ThrowException(e);
}

// Setup the Function object
Function.prototype.$implements$Function$Dart = 1;
RTT.setTypeInfo(Function.prototype, RTT.create($cls('Function$Dart')));

/**
 * @param {string} cls
 * @return {string}
 * @consistentIdGenerator
 */

function $cls(cls) {
  return "cls:" + cls;
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Extend the String prototype with members expected in dart.
 */


String.$instanceOf = function(obj) {
  return typeof obj == 'string' || obj instanceof String;
};

function native_StringImplementation__indexOperator(index) {
  return this[index];
}

function native_StringImplementation__charCodeAt(index) {
  return this.charCodeAt(index);
}

function native_StringImplementation_get$length() {
  return this.length;
}

function native_StringImplementation_EQ(other) {
  if (typeof other == 'string') {
    return this == other;
  } else if (other instanceof String) {
    // Must convert other to a primitive for value equality to work.
    return this == String(other);
  } else {
    return false;
  }
}

function native_StringImplementation_indexOf(other, startIndex) {
  return this.indexOf(other, startIndex);
}

function native_StringImplementation_lastIndexOf(other, fromIndex) {
  if (other == "") {
    return Math.min(this.length, fromIndex);
  }
  return this.lastIndexOf(other, fromIndex);
}

function native_StringImplementation_concat(other) {
  return this.concat(other);
}

function native_StringImplementation__substringUnchecked(startIndex, endIndex) {
  return this.substring(startIndex, endIndex);
}

function native_StringImplementation_trim() {
  if (this.trim) return this.trim();
  return this.replace(new RegExp("^[\s]+|[\s]+$", "g"), "");
}

function native_StringImplementation__replace(from, to) {
  if (String.$instanceOf(from)) {
    return this.replace(from, to);
  } else {
    return this.replace($DartRegExpToJSRegExp(from), to);
  }
}

function native_StringImplementation__replaceAll(from, to) {
  if (String.$instanceOf(from)) {
    var regexp = new RegExp(
        from.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'g');
    return this.replace(regexp, to);
  } else {
    var regexp = $DartRegExpToJSRegExp(from);
    return this.replace(regexp, to);
  }
}

function native_StringImplementation__split(pattern) {
  if (String.$instanceOf(pattern)) {
    return this.split(pattern);
  } else {
    return this.split($DartRegExpToJSRegExp(pattern));
  }
}

function native_StringImplementation_toLowerCase() {
  return this.toLowerCase();
}

function native_StringImplementation_toUpperCase() {
  return this.toUpperCase();
}

// Inherited from Hashable.
function native_StringImplementation_hashCode() {
  if (this.hash_ === undefined) {
    for (var i = 0; i < this.length; i++) {
      var ch = this.charCodeAt(i);
      this.hash_ += ch;
      this.hash_ += this.hash_ << 10;
      this.hash_ ^= this.hash_ >> 6;
    }

    this.hash_ += this.hash_ << 3;
    this.hash_ ^= this.hash_ >> 11;
    this.hash_ += this.hash_ << 15;
    this.hash_ = this.hash_ & ((1 << 29) - 1);
  }
  return this.hash_;
}

function native_StringImplementation_toString() {
  // Return the primitive string of this String object.
  return String(this);
}

// TODO(floitsch): If we allow comparison operators on the String class we
// should move this function into dart world.
function native_StringImplementation_compareTo(other) {
  if (this == other) return 0;
  if (this < other) return -1;
  return 1;
}

function native_StringImplementation__newFromValues(array) {
  if (!(array instanceof Array)) {
    var length = native__ArrayJsUtil__arrayLength(array);
    var tmp = new Array(length);
    for (var i = 0; i < length; i++) {
      tmp[i] = INDEX$operator(array, i);
    }
    array = tmp;
  }
  return String.fromCharCode.apply(this, array);
}

// Deprecated old name of new String.fromValues(..).
function native_StringBase_createFromCharCodes(array) {
  return native_StringImplementation__newFromValues(array);
}
function ArrayFactory$Dart(){
}

ArrayFactory$Dart.$lookupRTT = function(){
  return RTT.create($cls('ArrayFactory$Dart'));
}
;
ArrayFactory$Dart.$addTo = function(target){
  var rtt = ArrayFactory$Dart.$lookupRTT();
  target.implementedTypes[rtt.classKey] = rtt;
}
;
ArrayFactory$Dart.prototype.$implements$ArrayFactory$Dart = 1;
ArrayFactory$Dart.prototype.$implements$Object$Dart = 1;
ArrayFactory$Dart.Array$from$5$Factory = function($typeArgs, other){
  var array = ArrayFactory$Dart.Array$$Factory([RTT.getTypeArg($typeArgs, 0)], $Dart$Null);
  {
    var $0 = other.iterator$named(0, $noargs);
    while ($0.hasNext$named(0, $noargs)) {
      var e = $0.next$named(0, $noargs);
      {
        array.add$named(1, $noargs, e);
      }
    }
  }
  return array;
}
;
ArrayFactory$Dart.Array$fromArray$5$Factory = function($typeArgs, other, startIndex, endIndex){
  var tmp$0;
  var array = ArrayFactory$Dart.Array$$Factory([RTT.getTypeArg($typeArgs, 0)], $Dart$Null);
  if (GT$operator(endIndex, other.length$getter())) {
    endIndex = other.length$getter();
  }
  if (LT$operator(startIndex, 0)) {
    startIndex = 0;
  }
  var count = SUB$operator(endIndex, startIndex);
  if (GT$operator(count, 0)) {
    array.length$setter(tmp$0 = count) , tmp$0;
    Arrays$Dart.copy$member(other, startIndex, array, 0, count);
  }
  return array;
}
;
ArrayFactory$Dart.Array$$Factory = function($typeArgs, length_0){
  var tmp$0;
  var isFixed = true;
  if (length_0 == null) {
    length_0 = 0;
    isFixed = false;
  }
   else {
    if (LT$operator(length_0, 0)) {
      $Dart$ThrowException(IllegalArgumentException$Dart.IllegalArgumentException$$Factory(length_0));
    }
  }
  var array = ArrayFactory$Dart._new$$member_(TypeToken$Dart.TypeToken$$Factory(TypeToken$Dart.$lookupRTT([RTT.getTypeArg($typeArgs, 0)])), length_0);
  array._isFixed$$setter_(tmp$0 = isFixed) , tmp$0;
  return array;
}
;
ArrayFactory$Dart._new$$member_ = function(typeToken, length_0){
  return native_ArrayFactory__new(typeToken, length_0);
}
;
ArrayFactory$Dart._new$$named_ = function($n, $o, typeToken, length_0){
  var seen = 0;
  var def = 0;
  if (seen != $o.count || seen + def + $n != 2)
    $nsme();
  return ArrayFactory$Dart._new$$member_(typeToken, length_0);
}
;
ArrayFactory$Dart._new$$getter_ = function _new$$getter_(){
  return ArrayFactory$Dart._new$$named_;
}
;
function ListFactory$Dart(){
}

ListFactory$Dart.$lookupRTT = function(){
  return RTT.create($cls('ListFactory$Dart'));
}
;
ListFactory$Dart.$addTo = function(target){
  var rtt = ListFactory$Dart.$lookupRTT();
  target.implementedTypes[rtt.classKey] = rtt;
}
;
ListFactory$Dart.prototype.$implements$ListFactory$Dart = 1;
ListFactory$Dart.prototype.$implements$Object$Dart = 1;
ListFactory$Dart.List$from$4$Factory = function($typeArgs, other){
  var list = ListFactory$Dart.List$$Factory([RTT.getTypeArg($typeArgs, 0)], $Dart$Null);
  {
    var $0 = other.iterator$named(0, $noargs);
    while ($0.hasNext$named(0, $noargs)) {
      var e = $0.next$named(0, $noargs);
      {
        list.add$named(1, $noargs, e);
      }
    }
  }
  return list;
}
;
ListFactory$Dart.List$fromList$4$Factory = function($typeArgs, other, startIndex, endIndex){
  var tmp$0;
  var list = ListFactory$Dart.List$$Factory([RTT.getTypeArg($typeArgs, 0)], $Dart$Null);
  if (GT$operator(endIndex, other.length$getter())) {
    endIndex = other.length$getter();
  }
  if (LT$operator(startIndex, 0)) {
    startIndex = 0;
  }
  var count = SUB$operator(endIndex, startIndex);
  if (GT$operator(count, 0)) {
    list.length$setter(tmp$0 = count) , tmp$0;
    Arrays$Dart.copy$member(other, startIndex, list, 0, count);
  }
  return list;
}
;
ListFactory$Dart.List$$Factory = function($typeArgs, length_0){
  var tmp$0;
  var isFixed = true;
  if (length_0 == null) {
    length_0 = 0;
    isFixed = false;
  }
   else {
    if (LT$operator(length_0, 0)) {
      $Dart$ThrowException(IllegalArgumentException$Dart.IllegalArgumentException$$Factory(length_0));
    }
  }
  var list = ListFactory$Dart._new$$member_(TypeToken$Dart.TypeToken$$Factory(TypeToken$Dart.$lookupRTT([RTT.getTypeArg($typeArgs, 0)])), length_0);
  list._isFixed$$setter_(tmp$0 = isFixed) , tmp$0;
  return list;
}
;
ListFactory$Dart._new$$member_ = function(typeToken, length_0){
  return native_ListFactory__new(typeToken, length_0);
}
;
ListFactory$Dart._new$$named_ = function($n, $o, typeToken, length_0){
  var seen = 0;
  var def = 0;
  if (seen != $o.count || seen + def + $n != 2)
    $nsme();
  return ListFactory$Dart._new$$member_(typeToken, length_0);
}
;
ListFactory$Dart._new$$getter_ = function _new$$getter_(){
  return ListFactory$Dart._new$$named_;
}
;
Array.$lookupRTT = function(typeArgs){
  return RTT.create($cls('Array'), Array.$RTTimplements, typeArgs);
}
;
Array.$RTTimplements = function(rtt, typeArgs){
  Array.$addTo(rtt, typeArgs);
  rtt.derivedTypes = [];
}
;
Array.$addTo = function(target, typeArgs){
  var rtt = Array.$lookupRTT(typeArgs);
  target.implementedTypes[rtt.classKey] = rtt;
  Array$Dart.$addTo(target, [RTT.getTypeArg(target.typeArgs, 0)]);
}
;
Array.prototype.$implements$ObjectArray$Dart = 1;
Array.prototype.$implements$Array$Dart = 1;
Array.prototype.$implements$List$Dart = 1;
Array.prototype.$implements$Collection$Dart = 1;
Array.prototype.$implements$Iterable$Dart = 1;
Array.prototype.$implements$Object$Dart = 1;
Array.prototype._isFixed$$named_ = function(){
  return this._isFixed$$getter_().apply(this, arguments);
}
;
Array.prototype._isFixed$$getter_ = function(){
  return this._isFixed$$field_;
}
;
Array.prototype._isFixed$$setter_ = function(tmp$0){
  this._isFixed$$field_ = tmp$0;
}
;
Array.prototype.INDEX$operator = function(index){
  if (LTE$operator(0, index) && LT$operator(index, this.length$getter())) {
    return this._indexOperator$$member_(index);
  }
  $Dart$ThrowException(IndexOutOfRangeException$Dart.IndexOutOfRangeException$$Factory(index));
}
;
Array.prototype.ASSIGN_INDEX$operator = function(index, value){
  if (LT$operator(index, 0) || LTE$operator(this.length$getter(), index)) {
    $Dart$ThrowException(IndexOutOfRangeException$Dart.IndexOutOfRangeException$$Factory(index));
  }
  this._indexAssignOperator$$member_(index, value);
}
;
Array.prototype.iterator$member = function(){
  if (this._isFixed$$getter_()) {
    return FixedSizeArrayIterator$Dart.FixedSizeArrayIterator$$Factory(FixedSizeArrayIterator$Dart.$lookupRTT([RTT.getTypeArg(RTT.getTypeArgsFor(this, $cls('Array')), 0)]), this);
  }
   else {
    return VariableSizeArrayIterator$Dart.VariableSizeArrayIterator$$Factory(VariableSizeArrayIterator$Dart.$lookupRTT([RTT.getTypeArg(RTT.getTypeArgsFor(this, $cls('Array')), 0)]), this);
  }
}
;
Array.prototype.iterator$named = function($n, $o){
  var seen = 0;
  var def = 0;
  if (seen != $o.count || seen + def + $n != 0)
    $nsme();
  return Array.prototype.iterator$member.call(this);
}
;
Array.prototype.iterator$getter = function iterator$getter(){
  return $bind(Array.prototype.iterator$named, this);
}
;
Array.prototype._indexOperator$$member_ = function(index){
  return native_ObjectArray__indexOperator.call(this, index);
}
;
Array.prototype._indexOperator$$named_ = function($n, $o, index){
  var seen = 0;
  var def = 0;
  if (seen != $o.count || seen + def + $n != 1)
    $nsme();
  return Array.prototype._indexOperator$$member_.call(this, index);
}
;
Array.prototype._indexOperator$$getter_ = function _indexOperator$$getter_(){
  return $bind(Array.prototype._indexOperator$$named_, this);
}
;
Array.prototype._indexAssignOperator$$member_ = function(index, value){
  return native_ObjectArray__indexAssignOperator.call(this, index, value);
}
;
Array.prototype._indexAssignOperator$$named_ = function($n, $o, index, value){
  var seen = 0;
  var def = 0;
  if (seen != $o.count || seen + def + $n != 2)
    $nsme();
  return Array.prototype._indexAssignOperator$$member_.call(this, index, value);
}
;
Array.prototype._indexAssignOperator$$getter_ = function _indexAssignOperator$$getter_(){
  return $bind(Array.prototype._indexAssignOperator$$named_, this);
}
;
Array.prototype.length$named = function(){
  return this.length$getter().apply(this, arguments);
}
;
Array.prototype.length$getter = function(){
  return native_ObjectArray_get$length.call(this);
}
;
Array.prototype.length$setter = function(length_0){
  if (this._isFixed$$getter_()) {
    $Dart$ThrowException($intern(UnsupportedOperationException$Dart.UnsupportedOperationException$$Factory('Cannot change the length of a non-extendable array')));
  }
   else {
    this._setLength$$member_(length_0);
  }
}
;
Array.prototype._setLength$$member_ = function(length_0){
  return native_ObjectArray__setLength.call(this, length_0);
}
;
Array.prototype._setLength$$named_ = function($n, $o, length_0){
  var seen = 0;
  var def = 0;
  if (seen != $o.count || seen + def + $n != 1)
    $nsme();
  return Array.prototype._setLength$$member_.call(this, length_0);
}
;
Array.prototype._setLength$$getter_ = function _setLength$$getter_(){
  return $bind(Array.prototype._setLength$$named_, this);
}
;
Array.prototype._add$$member_ = function(value){
  return native_ObjectArray__add.call(this, value);
}
;
Array.prototype._add$$named_ = function($n, $o, value){
  var seen = 0;
  var def = 0;
  if (seen != $o.count || seen + def + $n != 1)
    $nsme();
  return Array.prototype._add$$member_.call(this, value);
}
;
Array.prototype._add$$getter_ = function _add$$getter_(){
  return $bind(Array.prototype._add$$named_, this);
}
;
Array.prototype.forEach$member = function(f){
  Collections$Dart.forEach$member(this, f);
}
;
Array.prototype.forEach$named = function($n, $o, f){
  var seen = 0;
  var def = 0;
  if (seen != $o.count || seen + def + $n != 1)
    $nsme();
  return Array.prototype.forEach$member.call(this, f);
}
;
Array.prototype.forEach$getter = function forEach$getter(){
  return $bind(Array.prototype.forEach$named, this);
}
;
Array.prototype.filter$member = function(f){
  return Collections$Dart.filter$member(this, ArrayFactory$Dart.Array$$Factory([RTT.getTypeArg(RTT.getTypeArgsFor(this, $cls('Array')), 0)], $Dart$Null), f);
}
;
Array.prototype.filter$named = function($n, $o, f){
  var seen = 0;
  var def = 0;
  if (seen != $o.count || seen + def + $n != 1)
    $nsme();
  return Array.prototype.filter$member.call(this, f);
}
;
Array.prototype.filter$getter
pending…

Compare results of other browsers

Revisions

You can edit these tests or add even more tests to this page by appending /edit to the URL. Here’s a list of current revisions for this page:

5 comments

WebReflection commented :

For everybody, this test is not wrong, it's testing the cost of the library core initialization against no initialization at all.

As I have said it is obviously unfair test but this cost is what we will have for real in every browser that do not implement native Dart VM.

Also this test does not include script parsing and transforming time, and this, once again, is how much Drat could go slower in real world cases ( and mobile devices )

Adrian Schmidt commented :

I'm running this test in Firefox 7.0.1 on Mac OS X (Snow Leopard). I'm getting dialogs for printing the page when running the "JS as it is". Is this expected behaviour?

Ayanami Rei commented :

99% slower

As expected from makers of slow-ass Android.

Avoid Google, live fast, die young.

Alex Russell commented :

Hopefully this test page will be updated when the Dart compiler implements tree shaking for an apples/apples view.

Whatever you think of Dart, the 0.01 compiler output won't be what Dart code generates in the 1.0.

Regards

David Higgins commented :

Working on a library for Dart as we speak, so stop whining. This is the coolest thing to hit the net since under construction GIFs.

Add a comment