OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of dart2js.js_emitter; | 5 part of dart2js.js_emitter; |
6 | 6 |
7 // TODO(ahe): Share these with js_helper.dart. | 7 // TODO(ahe): Share these with js_helper.dart. |
8 const FUNCTION_INDEX = 0; | 8 const FUNCTION_INDEX = 0; |
9 const NAME_INDEX = 1; | 9 const NAME_INDEX = 1; |
10 const CALL_NAME_INDEX = 2; | 10 const CALL_NAME_INDEX = 2; |
11 const REQUIRED_PARAMETER_INDEX = 3; | 11 const REQUIRED_PARAMETER_INDEX = 3; |
12 const OPTIONAL_PARAMETER_INDEX = 4; | 12 const OPTIONAL_PARAMETER_INDEX = 4; |
13 const DEFAULT_ARGUMENTS_INDEX = 5; | 13 const DEFAULT_ARGUMENTS_INDEX = 5; |
14 | 14 |
15 // TODO(ahe): This code should be integrated in CodeEmitterTask.finishClasses. | 15 // TODO(ahe): This code should be integrated in CodeEmitterTask.finishClasses. |
16 String getReflectionDataParser(String classesCollector, | 16 String getReflectionDataParser(String classesCollector, |
17 JavaScriptBackend backend) { | 17 JavaScriptBackend backend) { |
18 Namer namer = backend.namer; | 18 Namer namer = backend.namer; |
19 Compiler compiler = backend.compiler; | 19 Compiler compiler = backend.compiler; |
20 Element closureFromTearOff = compiler.findHelper('closureFromTearOff'); | 20 Element closureFromTearOff = compiler.findHelper('closureFromTearOff'); |
21 String tearOffAccess = | 21 String tearOffAccess; |
22 // Default value for mocked-up test libraries. | 22 String tearOffGlobalObjectName; |
23 'function () { throw "Helper \'closureFromTearOff\' missing." }'; | 23 String tearOffGlobalObject; |
24 if (closureFromTearOff != null) { | 24 if (closureFromTearOff != null) { |
25 tearOffAccess = namer.isolateAccess(closureFromTearOff); | 25 tearOffAccess = namer.isolateAccess(closureFromTearOff); |
| 26 tearOffGlobalObjectName = tearOffGlobalObject = |
| 27 namer.globalObjectFor(closureFromTearOff); |
| 28 } else { |
| 29 // Default values for mocked-up test libraries. |
| 30 tearOffAccess = |
| 31 'function() { throw "Helper \'closureFromTearOff\' missing." }'; |
| 32 tearOffGlobalObjectName = 'MissingHelperFunction'; |
| 33 tearOffGlobalObject = '($tearOffAccess())'; |
26 } | 34 } |
| 35 |
27 String metadataField = '"${namer.metadataField}"'; | 36 String metadataField = '"${namer.metadataField}"'; |
28 String reflectableField = namer.reflectableField; | 37 String reflectableField = namer.reflectableField; |
29 | 38 |
30 // TODO(ahe): Move this string constants to namer. | 39 // TODO(ahe): Move this string constants to namer. |
31 String reflectionInfoField = r'$reflectionInfo'; | 40 String reflectionInfoField = r'$reflectionInfo'; |
32 String reflectionNameField = r'$reflectionName'; | 41 String reflectionNameField = r'$reflectionName'; |
33 String metadataIndexField = r'$metadataIndex'; | 42 String metadataIndexField = r'$metadataIndex'; |
34 | 43 |
35 String defaultValuesField = namer.defaultValuesField; | 44 String defaultValuesField = namer.defaultValuesField; |
36 String methodsWithOptionalArgumentsField = | 45 String methodsWithOptionalArgumentsField = |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 var getterStubName = ${readString("array", "++index")}; | 85 var getterStubName = ${readString("array", "++index")}; |
77 array = array.slice(++index); | 86 array = array.slice(++index); |
78 var requiredParameterInfo = ${readInt("array", "0")}; | 87 var requiredParameterInfo = ${readInt("array", "0")}; |
79 var requiredParameterCount = requiredParameterInfo >> 1; | 88 var requiredParameterCount = requiredParameterInfo >> 1; |
80 var isAccessor = (requiredParameterInfo & 1) === 1; | 89 var isAccessor = (requiredParameterInfo & 1) === 1; |
81 var isSetter = requiredParameterInfo === 3; | 90 var isSetter = requiredParameterInfo === 3; |
82 var isGetter = requiredParameterInfo === 1; | 91 var isGetter = requiredParameterInfo === 1; |
83 var optionalParameterInfo = ${readInt("array", "1")}; | 92 var optionalParameterInfo = ${readInt("array", "1")}; |
84 var optionalParameterCount = optionalParameterInfo >> 1; | 93 var optionalParameterCount = optionalParameterInfo >> 1; |
85 var optionalParametersAreNamed = (optionalParameterInfo & 1) === 1; | 94 var optionalParametersAreNamed = (optionalParameterInfo & 1) === 1; |
| 95 var isIntercepted =''' // Break long line. |
| 96 ''' requiredParameterCount + optionalParameterCount != funcs[0].length; |
86 var functionTypeIndex = ${readFunctionType("array", "2")}; | 97 var functionTypeIndex = ${readFunctionType("array", "2")}; |
87 var isReflectable =''' // Break long line. | 98 var isReflectable =''' // Break long line. |
88 ''' array.length > requiredParameterCount + optionalParameterCount + 3; | 99 ''' array.length > requiredParameterCount + optionalParameterCount + 3; |
89 if (getterStubName) { | 100 if (getterStubName) { |
90 f = tearOff(funcs, array, isStatic, name); | 101 f = tearOff(funcs, array, isStatic, name, isIntercepted); |
91 ''' | 102 ''' |
92 /* Used to create an isolate using spawnFunction.*/ | 103 /* Used to create an isolate using spawnFunction.*/ |
93 ''' | 104 ''' |
94 if (isStatic) init.globalFunctions[name] = f; | 105 if (isStatic) init.globalFunctions[name] = f; |
95 originalDescriptor[getterStubName] = descriptor[getterStubName] = f; | 106 originalDescriptor[getterStubName] = descriptor[getterStubName] = f; |
96 funcs.push(f); | 107 funcs.push(f); |
97 if (getterStubName) functions.push(getterStubName); | 108 if (getterStubName) functions.push(getterStubName); |
98 f.\$stubName = getterStubName; | 109 f.\$stubName = getterStubName; |
99 f.\$callName = null; | 110 f.\$callName = null; |
100 } | 111 } |
(...skipping 21 matching lines...) Expand all Loading... |
122 init.mangledNames[name] = reflectionName; | 133 init.mangledNames[name] = reflectionName; |
123 } | 134 } |
124 funcs[0].$reflectionNameField = reflectionName; | 135 funcs[0].$reflectionNameField = reflectionName; |
125 funcs[0].$metadataIndexField = unmangledNameIndex + 1; | 136 funcs[0].$metadataIndexField = unmangledNameIndex + 1; |
126 if (optionalParameterCount) descriptor[unmangledName + "*"] = funcs[0]; | 137 if (optionalParameterCount) descriptor[unmangledName + "*"] = funcs[0]; |
127 } | 138 } |
128 } | 139 } |
129 '''; | 140 '''; |
130 | 141 |
131 String tearOff = ''' | 142 String tearOff = ''' |
132 function tearOff(funcs, reflectionInfo, isStatic, name) { | 143 function tearOffGetterNoCsp(funcs, reflectionInfo, name, isIntercepted) { |
133 return function() { | 144 return isIntercepted |
134 return $tearOffAccess(''' // Break long line. | 145 ? new Function("funcs", "reflectionInfo", "name",''' // Break long line. |
135 '''this, funcs, reflectionInfo, isStatic, arguments, name); | 146 ''' "$tearOffGlobalObjectName", "c", |
136 } | 147 "return function tearOff_" + name + (functionCounter++)+ "(x) {" + |
| 148 "if (c === null) c = $tearOffAccess(" + |
| 149 "this, funcs, reflectionInfo, false, [x], name);" + |
| 150 "return new c(this, funcs[0], x, name);" + |
| 151 "}")(funcs, reflectionInfo, name, $tearOffGlobalObject, null) |
| 152 : new Function("funcs", "reflectionInfo", "name",''' // Break long line. |
| 153 ''' "$tearOffGlobalObjectName", "c", |
| 154 "return function tearOff_" + name + (functionCounter++)+ "() {" + |
| 155 "if (c === null) c = $tearOffAccess(" + |
| 156 "this, funcs, reflectionInfo, false, [], name);" + |
| 157 "return new c(this, funcs[0], null, name);" + |
| 158 "}")(funcs, reflectionInfo, name, $tearOffGlobalObject, null) |
| 159 } |
| 160 function tearOffGetterCsp(funcs, reflectionInfo, name, isIntercepted) { |
| 161 var cache = null; |
| 162 return isIntercepted |
| 163 ? function(x) { |
| 164 if (cache === null) cache = $tearOffAccess(''' // Break long line. |
| 165 '''this, funcs, reflectionInfo, false, [x], name); |
| 166 return new cache(this, funcs[0], x, name) |
| 167 } |
| 168 : function() { |
| 169 if (cache === null) cache = $tearOffAccess(''' // Break long line. |
| 170 '''this, funcs, reflectionInfo, false, [], name); |
| 171 return new cache(this, funcs[0], null, name) |
| 172 } |
| 173 } |
| 174 function tearOff(funcs, reflectionInfo, isStatic, name, isIntercepted) { |
| 175 var cache; |
| 176 return isStatic |
| 177 ? function() { |
| 178 if (cache === void 0) cache = $tearOffAccess(''' // Break long line. |
| 179 '''this, funcs, reflectionInfo, true, [], name).prototype; |
| 180 return cache; |
| 181 } |
| 182 : tearOffGetter(funcs, reflectionInfo, name, isIntercepted); |
137 } | 183 } |
138 '''; | 184 '''; |
139 | 185 |
| 186 |
| 187 |
| 188 |
140 String init = ''' | 189 String init = ''' |
| 190 var functionCounter = 0; |
| 191 var tearOffGetter = (typeof dart_precompiled == "function") |
| 192 ? tearOffGetterCsp : tearOffGetterNoCsp; |
141 if (!init.libraries) init.libraries = []; | 193 if (!init.libraries) init.libraries = []; |
142 if (!init.mangledNames) init.mangledNames = map(); | 194 if (!init.mangledNames) init.mangledNames = map(); |
143 if (!init.mangledGlobalNames) init.mangledGlobalNames = map(); | 195 if (!init.mangledGlobalNames) init.mangledGlobalNames = map(); |
144 if (!init.statics) init.statics = map(); | 196 if (!init.statics) init.statics = map(); |
145 if (!init.typeInformation) init.typeInformation = map(); | 197 if (!init.typeInformation) init.typeInformation = map(); |
146 if (!init.globalFunctions) init.globalFunctions = map(); | 198 if (!init.globalFunctions) init.globalFunctions = map(); |
147 var libraries = init.libraries; | 199 var libraries = init.libraries; |
148 var mangledNames = init.mangledNames; | 200 var mangledNames = init.mangledNames; |
149 var mangledGlobalNames = init.mangledGlobalNames; | 201 var mangledGlobalNames = init.mangledGlobalNames; |
150 var hasOwnProperty = Object.prototype.hasOwnProperty; | 202 var hasOwnProperty = Object.prototype.hasOwnProperty; |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 (function() { | 340 (function() { |
289 var result = $array[$index]; | 341 var result = $array[$index]; |
290 if ($check) { | 342 if ($check) { |
291 throw new Error( | 343 throw new Error( |
292 name + ": expected value of type \'$type\' at index " + ($index) + | 344 name + ": expected value of type \'$type\' at index " + ($index) + |
293 " but got " + (typeof result)); | 345 " but got " + (typeof result)); |
294 } | 346 } |
295 return result; | 347 return result; |
296 })()'''; | 348 })()'''; |
297 } | 349 } |
OLD | NEW |