| Index: frog/frogsh | 
| diff --git a/frog/frogsh b/frog/frogsh | 
| index eb651dd7166be6fadf795c6e691c42ebf1f7fe42..721dd3b9c9c7929b67a286a863ed607905f22d25 100755 | 
| --- a/frog/frogsh | 
| +++ b/frog/frogsh | 
| @@ -73,42 +73,58 @@ Function.prototype.$genStub = function(argsLength, names) { | 
| // Translate a JavaScript exception to a Dart exception | 
| // TODO(jmesserly): cross browser support. This is Chrome specific. | 
| function $toDartException(e) { | 
| -  var res = e; | 
| +  function attachStack(dartEx) { | 
| +    // TODO(jmesserly): setting the stack property is not a long term solution. | 
| +    var stack = e.stack; | 
| +    // The stack contains the error message, and the stack is all that is | 
| +    // printed (the exception's toString() is never called).  Attempt to replace | 
| +    // the JS message (e.g. TypeError) with the Dart exception's toString(). | 
| +    if (typeof stack == 'string') { | 
| +      try {  // toString is in a try-catch due to Issue 470. | 
| +        var message = dartEx.toString(); | 
| +        if (/^(Type|Range)Error:/.test(stack)) { | 
| +          // Remove JS message. | 
| +          stack = stack.substring(stack.indexOf('\n') + 1); | 
| +        } | 
| +        stack = message + '\n' + stack; | 
| +      } catch(_) { | 
| +        stack = '' + dartEx.constructor.name + ': (corrupt)\n' + stack; | 
| +      } | 
| +    } | 
| +    dartEx.stack = stack; | 
| +    return dartEx; | 
| +  } | 
| + | 
| if (e instanceof TypeError) { | 
| switch(e.type) { | 
| case 'property_not_function': | 
| case 'called_non_callable': | 
| if (e.arguments[0] == null) { | 
| -          res = new NullPointerException(); | 
| +          return attachStack(new NullPointerException()); | 
| } else { | 
| -          res = new ObjectNotClosureException(); | 
| +          return attachStack(new ObjectNotClosureException()); | 
| } | 
| break; | 
| case 'non_object_property_call': | 
| case 'non_object_property_load': | 
| -        res = new NullPointerException(); | 
| +        return attachStack(new NullPointerException()); | 
| break; | 
| case 'undefined_method': | 
| if (e.arguments[0] == 'call' || e.arguments[0] == 'apply') { | 
| -          res = new ObjectNotClosureException(); | 
| +          return attachStack(new ObjectNotClosureException()); | 
| } else { | 
| // TODO(jmesserly): can this ever happen? | 
| -          res = new NoSuchMethodException('', e.arguments[0], []); | 
| +          // sra: Yes. | 
| +          return attachStack(new NoSuchMethodException('', e.arguments[0], [])); | 
| } | 
| break; | 
| } | 
| } else if (e instanceof RangeError) { | 
| if (e.message.indexOf('call stack') >= 0) { | 
| -      res = new StackOverflowException(); | 
| +      return attachStack(new StackOverflowException()); | 
| } | 
| } | 
| -  if (res) { | 
| -    // TODO(jmesserly): setting the stack property is not a long term solution. | 
| -    // Also it causes the exception to print as if it were a JS TypeError or | 
| -    // RangeError, instead of using the proper toString. | 
| -    res.stack = e.stack; | 
| -  } | 
| -  return res; | 
| +  return e; | 
| } | 
| function $notnull_bool(test) { | 
| return (test === true || test === false) ? test : test.is$bool(); // TypeError | 
| @@ -12154,7 +12170,7 @@ CoreJs.prototype.generate = function(w) { | 
| w.writeln("function $stackTraceOf(e) {\n  // TODO(jmesserly): we shouldn't be relying on the e.stack property.\n  // Need to mangle it.\n  return  (e && e.stack) ? e.stack : null;\n}"); | 
| } | 
| if ($notnull_bool(this.useToDartException)) { | 
| -    w.writeln("// Translate a JavaScript exception to a Dart exception\n// TODO(jmesserly): cross browser support. This is Chrome specific.\nfunction $toDartException(e) {\n  var res = e;\n  if (e instanceof TypeError) {\n    switch(e.type) {\n      case 'property_not_function':\n      case 'called_non_callable':\n        if (e.arguments[0] == null) {\n          res = new NullPointerException();\n        } else {\n          res = new ObjectNotClosureException();\n        }\n        break;\n      case 'non_object_property_call':\n      case 'non_object_property_load':\n        res = new NullPointerException();\n        break;\n      case 'undefined_method':\n        if (e.arguments[0] == 'call' || e.arguments[0] == 'apply') {\n          res = new ObjectNotClosureException();\n        } else {\n          // TODO(jmesserly): can this ever happen?\n          res = new NoSuchMethodException('', e.arguments[0], []);\n        }\n        break;\n    }\n  } else if (e instanceof RangeError) {\n    if (e.message.indexOf('call stack') >= 0) {\n      res = new StackOverflowException();\n    }\n  }\n  if (res) {\n    // TODO(jmesserly): setting the stack property is not a long term solution.\n    // Also it causes the exception to print as if it were a JS TypeError or\n    // RangeError, instead of using the proper toString.\n    res.stack = e.stack;\n  }\n  return res;\n}"); | 
| +    w.writeln("// Translate a JavaScript exception to a Dart exception\n// TODO(jmesserly): cross browser support. This is Chrome specific.\nfunction $toDartException(e) {\n  function attachStack(dartEx) {\n    // TODO(jmesserly): setting the stack property is not a long term solution.\n    var stack = e.stack;\n    // The stack contains the error message, and the stack is all that is\n    // printed (the exception's toString() is never called).  Attempt to replace\n    // the JS message (e.g. TypeError) with the Dart exception's toString().\n    if (typeof stack == 'string') {\n      try {  // toString is in a try-catch due to Issue 470.\n        var message = dartEx.toString();\n        if (/^(Type|Range)Error:/.test(stack)) {\n          // Remove JS message.\n          stack = stack.substring(stack.indexOf('\\n') + 1);\n        }\n        stack = message + '\\n' + stack;\n      } catch(_) {\n        stack = '' + dartEx.constructor.name + ': (corrupt)\\n' + stack;\n      }\n    }\n    dartEx.stack = stack;\n    return dartEx;\n  }\n\n  if (e instanceof TypeError) {\n    switch(e.type) {\n      case 'property_not_function':\n      case 'called_non_callable':\n        if (e.arguments[0] == null) {\n          return attachStack(new NullPointerException());\n        } else {\n          return attachStack(new ObjectNotClosureException());\n        }\n        break;\n      case 'non_object_property_call':\n      case 'non_object_property_load':\n        return attachStack(new NullPointerException());\n        break;\n      case 'undefined_method':\n        if (e.arguments[0] == 'call' || e.arguments[0] == 'apply') {\n          return attachStack(new ObjectNotClosureException());\n        } else {\n          // TODO(jmesserly): can this ever happen?\n          // sra: Yes.\n          return attachStack(new NoSuchMethodException('', e.arguments[0], []));\n        }\n        break;\n    }\n  } else if (e instanceof RangeError) {\n    if (e.message.indexOf('call stack') >= 0) {\n      return attachStack(new StackOverflowException());\n    }\n  }\n  return e;\n}"); | 
| } | 
| if ($notnull_bool(this.useNotNullBool)) { | 
| this.useThrow = true; | 
|  |