OLD | NEW |
1 #!/usr/bin/env node | 1 #!/usr/bin/env node |
2 // ********** Library dart:core ************** | 2 // ********** Library dart:core ************** |
3 // ********** Natives dart:core ************** | 3 // ********** Natives dart:core ************** |
4 /** | 4 /** |
5 * Generates a dynamic call stub for a function. | 5 * Generates a dynamic call stub for a function. |
6 * Our goal is to create a stub method like this on-the-fly: | 6 * Our goal is to create a stub method like this on-the-fly: |
7 * function($0, $1, capture) { this($0, $1, true, capture); } | 7 * function($0, $1, capture) { this($0, $1, true, capture); } |
8 * | 8 * |
9 * This stub then replaces the dynamic one on Function, with one that is | 9 * This stub then replaces the dynamic one on Function, with one that is |
10 * specialized for that particular function, taking into account its default | 10 * specialized for that particular function, taking into account its default |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 } | 66 } |
67 | 67 |
68 // Note: using Function instead of 'eval' to get a clean scope. | 68 // Note: using Function instead of 'eval' to get a clean scope. |
69 // TODO(jmesserly): evaluate the performance of these stubs. | 69 // TODO(jmesserly): evaluate the performance of these stubs. |
70 var f = 'function(' + a.join(',') + '){return $f(' + p.join(',') + ');}'; | 70 var f = 'function(' + a.join(',') + '){return $f(' + p.join(',') + ');}'; |
71 return new Function('$f', 'return ' + f + '').call(null, this); | 71 return new Function('$f', 'return ' + f + '').call(null, this); |
72 } | 72 } |
73 // Translate a JavaScript exception to a Dart exception | 73 // Translate a JavaScript exception to a Dart exception |
74 // TODO(jmesserly): cross browser support. This is Chrome specific. | 74 // TODO(jmesserly): cross browser support. This is Chrome specific. |
75 function $toDartException(e) { | 75 function $toDartException(e) { |
76 var res = e; | 76 function attachStack(dartEx) { |
| 77 // TODO(jmesserly): setting the stack property is not a long term solution. |
| 78 var stack = e.stack; |
| 79 // The stack contains the error message, and the stack is all that is |
| 80 // printed (the exception's toString() is never called). Attempt to replace |
| 81 // the JS message (e.g. TypeError) with the Dart exception's toString(). |
| 82 if (typeof stack == 'string') { |
| 83 try { // toString is in a try-catch due to Issue 470. |
| 84 var message = dartEx.toString(); |
| 85 if (/^(Type|Range)Error:/.test(stack)) { |
| 86 // Remove JS message. |
| 87 stack = stack.substring(stack.indexOf('\n') + 1); |
| 88 } |
| 89 stack = message + '\n' + stack; |
| 90 } catch(_) { |
| 91 stack = '' + dartEx.constructor.name + ': (corrupt)\n' + stack; |
| 92 } |
| 93 } |
| 94 dartEx.stack = stack; |
| 95 return dartEx; |
| 96 } |
| 97 |
77 if (e instanceof TypeError) { | 98 if (e instanceof TypeError) { |
78 switch(e.type) { | 99 switch(e.type) { |
79 case 'property_not_function': | 100 case 'property_not_function': |
80 case 'called_non_callable': | 101 case 'called_non_callable': |
81 if (e.arguments[0] == null) { | 102 if (e.arguments[0] == null) { |
82 res = new NullPointerException(); | 103 return attachStack(new NullPointerException()); |
83 } else { | 104 } else { |
84 res = new ObjectNotClosureException(); | 105 return attachStack(new ObjectNotClosureException()); |
85 } | 106 } |
86 break; | 107 break; |
87 case 'non_object_property_call': | 108 case 'non_object_property_call': |
88 case 'non_object_property_load': | 109 case 'non_object_property_load': |
89 res = new NullPointerException(); | 110 return attachStack(new NullPointerException()); |
90 break; | 111 break; |
91 case 'undefined_method': | 112 case 'undefined_method': |
92 if (e.arguments[0] == 'call' || e.arguments[0] == 'apply') { | 113 if (e.arguments[0] == 'call' || e.arguments[0] == 'apply') { |
93 res = new ObjectNotClosureException(); | 114 return attachStack(new ObjectNotClosureException()); |
94 } else { | 115 } else { |
95 // TODO(jmesserly): can this ever happen? | 116 // TODO(jmesserly): can this ever happen? |
96 res = new NoSuchMethodException('', e.arguments[0], []); | 117 // sra: Yes. |
| 118 return attachStack(new NoSuchMethodException('', e.arguments[0], [])); |
97 } | 119 } |
98 break; | 120 break; |
99 } | 121 } |
100 } else if (e instanceof RangeError) { | 122 } else if (e instanceof RangeError) { |
101 if (e.message.indexOf('call stack') >= 0) { | 123 if (e.message.indexOf('call stack') >= 0) { |
102 res = new StackOverflowException(); | 124 return attachStack(new StackOverflowException()); |
103 } | 125 } |
104 } | 126 } |
105 if (res) { | 127 return e; |
106 // TODO(jmesserly): setting the stack property is not a long term solution. | |
107 // Also it causes the exception to print as if it were a JS TypeError or | |
108 // RangeError, instead of using the proper toString. | |
109 res.stack = e.stack; | |
110 } | |
111 return res; | |
112 } | 128 } |
113 function $notnull_bool(test) { | 129 function $notnull_bool(test) { |
114 return (test === true || test === false) ? test : test.is$bool(); // TypeError | 130 return (test === true || test === false) ? test : test.is$bool(); // TypeError |
115 } | 131 } |
116 function $assert(test, text, url, line, column) { | 132 function $assert(test, text, url, line, column) { |
117 if (typeof test == 'function') test = test(); | 133 if (typeof test == 'function') test = test(); |
118 if (!test) $throw(new AssertError(text, url, line, column)); | 134 if (!test) $throw(new AssertError(text, url, line, column)); |
119 } | 135 } |
120 function $throw(e) { | 136 function $throw(e) { |
121 // If e is not a value, we can use V8's captureStackTrace utility method. | 137 // If e is not a value, we can use V8's captureStackTrace utility method. |
(...skipping 12025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12147 w.writeln("function $varMethod(name, methods) {\n Object.prototype[name] =
function() {\n $patchMethod(this, name, methods);\n return this[name].appl
y(this, Array.prototype.slice.call(arguments));\n };\n}\nfunction $patchMethod(
obj, name, methods) {\n // Get the prototype to patch.\n // Don't overwrite an
existing stub, like the one on Object.prototype\n var proto = Object.getProtot
ypeOf(obj);\n if (!proto || proto.hasOwnProperty(name)) proto = obj;\n var met
hod;\n while (obj && !(method = methods[obj.$typeNameOf()])) {\n obj = Objec
t.getPrototypeOf(obj);\n }\n obj[name] = method || methods['Object'];\n}"); | 12163 w.writeln("function $varMethod(name, methods) {\n Object.prototype[name] =
function() {\n $patchMethod(this, name, methods);\n return this[name].appl
y(this, Array.prototype.slice.call(arguments));\n };\n}\nfunction $patchMethod(
obj, name, methods) {\n // Get the prototype to patch.\n // Don't overwrite an
existing stub, like the one on Object.prototype\n var proto = Object.getProtot
ypeOf(obj);\n if (!proto || proto.hasOwnProperty(name)) proto = obj;\n var met
hod;\n while (obj && !(method = methods[obj.$typeNameOf()])) {\n obj = Objec
t.getPrototypeOf(obj);\n }\n obj[name] = method || methods['Object'];\n}"); |
12148 } | 12164 } |
12149 if ($notnull_bool(this.useGenStub)) { | 12165 if ($notnull_bool(this.useGenStub)) { |
12150 this.useThrow = true; | 12166 this.useThrow = true; |
12151 w.writeln("/**\n * Generates a dynamic call stub for a function.\n * Our goa
l is to create a stub method like this on-the-fly:\n * function($0, $1, captur
e) { this($0, $1, true, capture); }\n *\n * This stub then replaces the dynamic
one on Function, with one that is\n * specialized for that particular function,
taking into account its default\n * arguments.\n */\nFunction.prototype.$genStub
= function(argsLength, names) {\n // TODO(jmesserly): only emit $genStub if ac
tually needed\n\n // Fast path: if no named arguments and arg count matches\n
if (this.length == argsLength && !names) {\n return this;\n }\n\n function
$throwArgMismatch() {\n // TODO(jmesserly): better error message\n $throw(
new ClosureArgumentMismatchException());\n }\n\n var paramsNamed = this.$optio
nal ? (this.$optional.length / 2) : 0;\n var paramsBare = this.length - paramsN
amed;\n var argsNamed = names ? names.length : 0;\n var argsBare = argsLength
- argsNamed;\n\n // Check we got the right number of arguments\n if (argsBare
< paramsBare || argsLength > this.length ||\n argsNamed > paramsNamed) {\n
return $throwArgMismatch;\n }\n\n // First, fill in all of the default valu
es\n var p = new Array(paramsBare);\n if (paramsNamed) {\n p = p.concat(thi
s.$optional.slice(paramsNamed));\n }\n // Fill in positional args\n var a = n
ew Array(argsLength);\n for (var i = 0; i < argsBare; i++) {\n p[i] = a[i] =
'$' + i;\n }\n // Then overwrite with supplied values for optional args\n va
r lastParameterIndex;\n var namesInOrder = true;\n for (var i = 0; i < argsNam
ed; i++) {\n var name = names[i];\n a[i + argsBare] = name;\n var j = t
his.$optional.indexOf(name, 0);\n if (j < 0 || j >= paramsNamed) {\n ret
urn $throwArgMismatch;\n } else if (lastParameterIndex && lastParameterIndex
> j) {\n namesInOrder = false;\n }\n p[j + paramsBare] = name;\n l
astParameterIndex = j;\n }\n\n if (this.length == argsLength && namesInOrder)
{\n // Fast path #2: named arguments, but they're in order.\n return this;
\n }\n\n // Note: using Function instead of 'eval' to get a clean scope.\n //
TODO(jmesserly): evaluate the performance of these stubs.\n var f = 'function(
' + a.join(',') + '){return $f(' + p.join(',') + ');}';\n return new Function('
$f', 'return ' + f + '').call(null, this);\n}"); | 12167 w.writeln("/**\n * Generates a dynamic call stub for a function.\n * Our goa
l is to create a stub method like this on-the-fly:\n * function($0, $1, captur
e) { this($0, $1, true, capture); }\n *\n * This stub then replaces the dynamic
one on Function, with one that is\n * specialized for that particular function,
taking into account its default\n * arguments.\n */\nFunction.prototype.$genStub
= function(argsLength, names) {\n // TODO(jmesserly): only emit $genStub if ac
tually needed\n\n // Fast path: if no named arguments and arg count matches\n
if (this.length == argsLength && !names) {\n return this;\n }\n\n function
$throwArgMismatch() {\n // TODO(jmesserly): better error message\n $throw(
new ClosureArgumentMismatchException());\n }\n\n var paramsNamed = this.$optio
nal ? (this.$optional.length / 2) : 0;\n var paramsBare = this.length - paramsN
amed;\n var argsNamed = names ? names.length : 0;\n var argsBare = argsLength
- argsNamed;\n\n // Check we got the right number of arguments\n if (argsBare
< paramsBare || argsLength > this.length ||\n argsNamed > paramsNamed) {\n
return $throwArgMismatch;\n }\n\n // First, fill in all of the default valu
es\n var p = new Array(paramsBare);\n if (paramsNamed) {\n p = p.concat(thi
s.$optional.slice(paramsNamed));\n }\n // Fill in positional args\n var a = n
ew Array(argsLength);\n for (var i = 0; i < argsBare; i++) {\n p[i] = a[i] =
'$' + i;\n }\n // Then overwrite with supplied values for optional args\n va
r lastParameterIndex;\n var namesInOrder = true;\n for (var i = 0; i < argsNam
ed; i++) {\n var name = names[i];\n a[i + argsBare] = name;\n var j = t
his.$optional.indexOf(name, 0);\n if (j < 0 || j >= paramsNamed) {\n ret
urn $throwArgMismatch;\n } else if (lastParameterIndex && lastParameterIndex
> j) {\n namesInOrder = false;\n }\n p[j + paramsBare] = name;\n l
astParameterIndex = j;\n }\n\n if (this.length == argsLength && namesInOrder)
{\n // Fast path #2: named arguments, but they're in order.\n return this;
\n }\n\n // Note: using Function instead of 'eval' to get a clean scope.\n //
TODO(jmesserly): evaluate the performance of these stubs.\n var f = 'function(
' + a.join(',') + '){return $f(' + p.join(',') + ');}';\n return new Function('
$f', 'return ' + f + '').call(null, this);\n}"); |
12152 } | 12168 } |
12153 if ($notnull_bool(this.useStackTraceOf)) { | 12169 if ($notnull_bool(this.useStackTraceOf)) { |
12154 w.writeln("function $stackTraceOf(e) {\n // TODO(jmesserly): we shouldn't b
e relying on the e.stack property.\n // Need to mangle it.\n return (e && e.s
tack) ? e.stack : null;\n}"); | 12170 w.writeln("function $stackTraceOf(e) {\n // TODO(jmesserly): we shouldn't b
e relying on the e.stack property.\n // Need to mangle it.\n return (e && e.s
tack) ? e.stack : null;\n}"); |
12155 } | 12171 } |
12156 if ($notnull_bool(this.useToDartException)) { | 12172 if ($notnull_bool(this.useToDartException)) { |
12157 w.writeln("// Translate a JavaScript exception to a Dart exception\n// TODO(
jmesserly): cross browser support. This is Chrome specific.\nfunction $toDartExc
eption(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_pr
operty_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 NoS
uchMethodException('', 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}"); | 12173 w.writeln("// Translate a JavaScript exception to a Dart exception\n// TODO(
jmesserly): cross browser support. This is Chrome specific.\nfunction $toDartExc
eption(e) {\n function attachStack(dartEx) {\n // TODO(jmesserly): setting t
he 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 // prin
ted (the exception's toString() is never called). Attempt to replace\n // th
e JS message (e.g. TypeError) with the Dart exception's toString().\n if (typ
eof stack == 'string') {\n try { // toString is in a try-catch due to Issu
e 470.\n var message = dartEx.toString();\n if (/^(Type|Range)Erro
r:/.test(stack)) {\n // Remove JS message.\n stack = stack.sub
string(stack.indexOf('\\n') + 1);\n }\n stack = message + '\\n' +
stack;\n } catch(_) {\n stack = '' + dartEx.constructor.name + ': (c
orrupt)\\n' + stack;\n }\n }\n dartEx.stack = stack;\n return dart
Ex;\n }\n\n if (e instanceof TypeError) {\n switch(e.type) {\n case 'p
roperty_not_function':\n case 'called_non_callable':\n if (e.argumen
ts[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 'no
n_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 Object
NotClosureException());\n } else {\n // TODO(jmesserly): can thi
s ever happen?\n // sra: Yes.\n return attachStack(new NoSuchM
ethodException('', 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 ret
urn e;\n}"); |
12158 } | 12174 } |
12159 if ($notnull_bool(this.useNotNullBool)) { | 12175 if ($notnull_bool(this.useNotNullBool)) { |
12160 this.useThrow = true; | 12176 this.useThrow = true; |
12161 w.writeln("function $notnull_bool(test) {\n return (test === true || test =
== false) ? test : test.is$bool(); // TypeError\n}"); | 12177 w.writeln("function $notnull_bool(test) {\n return (test === true || test =
== false) ? test : test.is$bool(); // TypeError\n}"); |
12162 } | 12178 } |
12163 if ($notnull_bool(this.useAssert)) { | 12179 if ($notnull_bool(this.useAssert)) { |
12164 this.useThrow = true; | 12180 this.useThrow = true; |
12165 w.writeln("function $assert(test, text, url, line, column) {\n if (typeof t
est == 'function') test = test();\n if (!test) $throw(new AssertError(text, url
, line, column));\n}"); | 12181 w.writeln("function $assert(test, text, url, line, column) {\n if (typeof t
est == 'function') test = test();\n if (!test) $throw(new AssertError(text, url
, line, column));\n}"); |
12166 } | 12182 } |
12167 if ($notnull_bool(this.useThrow)) { | 12183 if ($notnull_bool(this.useThrow)) { |
(...skipping 11687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
23855 NATIVE, | 23871 NATIVE, |
23856 NEGATE, | 23872 NEGATE, |
23857 OPERATOR, | 23873 OPERATOR, |
23858 SET, | 23874 SET, |
23859 SOURCE, | 23875 SOURCE, |
23860 STATIC, | 23876 STATIC, |
23861 TYPEDEF ]*/; | 23877 TYPEDEF ]*/; |
23862 var $globals = {}; | 23878 var $globals = {}; |
23863 $static_init(); | 23879 $static_init(); |
23864 main(); | 23880 main(); |
OLD | NEW |