| OLD | NEW |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 library dart2js.kernel.element_map; | 5 library dart2js.kernel.element_map; |
| 6 | 6 |
| 7 import 'package:kernel/ast.dart' as ir; | 7 import 'package:kernel/ast.dart' as ir; |
| 8 | 8 |
| 9 import '../closure.dart' show BoxLocal, ThisLocal; | 9 import '../closure.dart' show BoxLocal, ThisLocal; |
| 10 import '../common.dart'; | 10 import '../common.dart'; |
| (...skipping 2151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2162 FunctionData data = _memberData[function.memberIndex]; | 2162 FunctionData data = _memberData[function.memberIndex]; |
| 2163 data.forEachParameter(this, f); | 2163 data.forEachParameter(this, f); |
| 2164 } | 2164 } |
| 2165 | 2165 |
| 2166 void _forEachConstructorBody( | 2166 void _forEachConstructorBody( |
| 2167 IndexedClass cls, void f(ConstructorBodyEntity member)) { | 2167 IndexedClass cls, void f(ConstructorBodyEntity member)) { |
| 2168 ClassEnv env = _classEnvs[cls.classIndex]; | 2168 ClassEnv env = _classEnvs[cls.classIndex]; |
| 2169 env.forEachConstructorBody(f); | 2169 env.forEachConstructorBody(f); |
| 2170 } | 2170 } |
| 2171 | 2171 |
| 2172 JRecordField _constructBoxedField( |
| 2173 ir.VariableDeclaration variable, |
| 2174 BoxLocal boxLocal, |
| 2175 JClass container, |
| 2176 Map<String, MemberEntity> memberMap, |
| 2177 KernelToLocalsMap localsMap) { |
| 2178 Local local = localsMap.getLocalVariable(variable); |
| 2179 var boxedField = new JRecordField( |
| 2180 local.name, _memberData.length, boxLocal, container, variable.isConst); |
| 2181 _memberList.add(boxedField); |
| 2182 _memberData.add(new ClosureFieldData(new ClosureMemberDefinition( |
| 2183 boxedField, |
| 2184 computeSourceSpanFromTreeNode(variable), |
| 2185 MemberKind.closureField, |
| 2186 variable))); |
| 2187 memberMap[boxedField.name] = boxedField; |
| 2188 |
| 2189 return boxedField; |
| 2190 } |
| 2191 |
| 2192 /// Make a container controlling access to records, that is, variables that |
| 2193 /// are accessed in different scopes. This function creates the container |
| 2194 /// and returns a map of locals to the corresponding records created. |
| 2195 Map<Local, JRecordField> makeRecordContainer( |
| 2196 KernelScopeInfo info, MemberEntity member, KernelToLocalsMap localsMap) { |
| 2197 Map<Local, JRecordField> boxedFields = {}; |
| 2198 if (info.boxedVariables.isNotEmpty) { |
| 2199 NodeBox box = info.capturedVariablesAccessor; |
| 2200 |
| 2201 var container = new JRecord(member.library, _classEnvs.length, box.name); |
| 2202 _classList.add(container); |
| 2203 Map<String, MemberEntity> memberMap = <String, MemberEntity>{}; |
| 2204 _classEnvs.add(new RecordEnv(memberMap)); |
| 2205 |
| 2206 var containerData = new ClassData( |
| 2207 null, |
| 2208 new ClosureClassDefinition(container, |
| 2209 computeSourceSpanFromTreeNode(getMemberDefinition(member).node))); |
| 2210 containerData |
| 2211 ..isMixinApplication = false |
| 2212 ..thisType = new InterfaceType(container, const <DartType>[]) |
| 2213 ..supertype = commonElements.objectType |
| 2214 ..interfaces = const <InterfaceType>[]; |
| 2215 var setBuilder = new _KernelOrderedTypeSetBuilder(this, container); |
| 2216 _classData.add(containerData); |
| 2217 containerData.orderedTypeSet = setBuilder.createOrderedTypeSet( |
| 2218 containerData.supertype, const Link<InterfaceType>()); |
| 2219 |
| 2220 BoxLocal boxLocal = new BoxLocal(box.name, member); |
| 2221 for (ir.VariableDeclaration variable in info.boxedVariables) { |
| 2222 boxedFields[localsMap.getLocalVariable(variable)] = |
| 2223 _constructBoxedField( |
| 2224 variable, boxLocal, container, memberMap, localsMap); |
| 2225 } |
| 2226 } |
| 2227 return boxedFields; |
| 2228 } |
| 2229 |
| 2172 KernelClosureClass constructClosureClass( | 2230 KernelClosureClass constructClosureClass( |
| 2173 MemberEntity member, | 2231 MemberEntity member, |
| 2174 ir.FunctionNode node, | 2232 ir.FunctionNode node, |
| 2175 JLibrary enclosingLibrary, | 2233 JLibrary enclosingLibrary, |
| 2234 Map<Local, JRecordField> boxedCapturedVariables, |
| 2176 KernelScopeInfo info, | 2235 KernelScopeInfo info, |
| 2177 ir.Location location, | 2236 ir.Location location, |
| 2178 KernelToLocalsMap localsMap, | 2237 KernelToLocalsMap localsMap, |
| 2179 InterfaceType supertype) { | 2238 InterfaceType supertype) { |
| 2180 String name = _computeClosureName(node); | 2239 String name = _computeClosureName(node); |
| 2181 JClass classEntity = | 2240 JClass classEntity = |
| 2182 new JClosureClass(enclosingLibrary, _classEnvs.length, name); | 2241 new JClosureClass(enclosingLibrary, _classEnvs.length, name); |
| 2183 _classList.add(classEntity); | 2242 _classList.add(classEntity); |
| 2184 Map<String, MemberEntity> memberMap = <String, MemberEntity>{}; | 2243 Map<String, MemberEntity> memberMap = <String, MemberEntity>{}; |
| 2185 _classEnvs.add(new ClosureClassEnv(memberMap)); | 2244 _classEnvs.add(new ClosureClassEnv(memberMap)); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2205 if (node.parent is ir.FunctionDeclaration) { | 2264 if (node.parent is ir.FunctionDeclaration) { |
| 2206 ir.FunctionDeclaration parent = node.parent; | 2265 ir.FunctionDeclaration parent = node.parent; |
| 2207 closureEntity = localsMap.getLocalVariable(parent.variable); | 2266 closureEntity = localsMap.getLocalVariable(parent.variable); |
| 2208 } else if (node.parent is ir.FunctionExpression) { | 2267 } else if (node.parent is ir.FunctionExpression) { |
| 2209 closureEntity = new JLocal('', localsMap.currentMember); | 2268 closureEntity = new JLocal('', localsMap.currentMember); |
| 2210 } | 2269 } |
| 2211 Local thisLocal = | 2270 Local thisLocal = |
| 2212 info.hasThisLocal ? new ThisLocal(localsMap.currentMember) : null; | 2271 info.hasThisLocal ? new ThisLocal(localsMap.currentMember) : null; |
| 2213 | 2272 |
| 2214 KernelClosureClass cls = new KernelClosureClass.fromScopeInfo( | 2273 KernelClosureClass cls = new KernelClosureClass.fromScopeInfo( |
| 2215 classEntity, node, info, localsMap, closureEntity, thisLocal); | 2274 classEntity, |
| 2216 int i = 0; | 2275 node, |
| 2276 <Local, JRecordField>{}, |
| 2277 info, |
| 2278 localsMap, |
| 2279 closureEntity, |
| 2280 thisLocal); |
| 2281 int fieldNumber = 0; |
| 2217 for (ir.VariableDeclaration variable in info.freeVariables) { | 2282 for (ir.VariableDeclaration variable in info.freeVariables) { |
| 2218 // Make a corresponding field entity in this closure class for every | 2283 // Make a corresponding field entity in this closure class for every |
| 2219 // single freeVariable in the KernelScopeInfo.freeVariable. | 2284 // single freeVariable in the KernelScopeInfo.freeVariable. |
| 2220 _constructClosureFields(member, cls, memberMap, variable, i, | 2285 _constructClosureField( |
| 2221 info.capturedVariablesAccessor, localsMap); | 2286 member, |
| 2222 i++; | 2287 cls, |
| 2288 memberMap, |
| 2289 variable, |
| 2290 boxedCapturedVariables, |
| 2291 fieldNumber, |
| 2292 info.capturedVariablesAccessor, |
| 2293 localsMap); |
| 2294 fieldNumber++; |
| 2223 } | 2295 } |
| 2224 | 2296 |
| 2225 FunctionEntity callMethod = cls.callMethod = new JClosureCallMethod( | 2297 FunctionEntity callMethod = cls.callMethod = new JClosureCallMethod( |
| 2226 _memberData.length, | 2298 _memberData.length, |
| 2227 cls, | 2299 cls, |
| 2228 _getParameterStructure(node), | 2300 _getParameterStructure(node), |
| 2229 _getAsyncMarker(node)); | 2301 _getAsyncMarker(node)); |
| 2230 _memberList.add(cls.callMethod); | 2302 _memberList.add(cls.callMethod); |
| 2231 | 2303 |
| 2232 _memberData.add(new ClosureFunctionData( | 2304 _memberData.add(new ClosureFunctionData( |
| 2233 new ClosureMemberDefinition(callMethod, closureData.definition.location, | 2305 new ClosureMemberDefinition(callMethod, closureData.definition.location, |
| 2234 MemberKind.closureCall, node.parent), | 2306 MemberKind.closureCall, node.parent), |
| 2235 getFunctionType(node), | 2307 getFunctionType(node), |
| 2236 node)); | 2308 node)); |
| 2237 memberMap[cls.callMethod.name] = cls.callMethod; | 2309 memberMap[cls.callMethod.name] = cls.callMethod; |
| 2238 return cls; | 2310 return cls; |
| 2239 } | 2311 } |
| 2240 | 2312 |
| 2241 _constructClosureFields( | 2313 _constructClosureField( |
| 2242 MemberEntity member, | 2314 MemberEntity member, |
| 2243 KernelClosureClass cls, | 2315 KernelClosureClass cls, |
| 2244 Map<String, MemberEntity> memberMap, | 2316 Map<String, MemberEntity> memberMap, |
| 2245 ir.VariableDeclaration variable, | 2317 ir.VariableDeclaration variable, |
| 2318 Map<Local, JRecordField> boxedCapturedVariables, |
| 2246 int fieldNumber, | 2319 int fieldNumber, |
| 2247 NodeBox box, | 2320 NodeBox box, |
| 2248 KernelToLocalsMap localsMap) { | 2321 KernelToLocalsMap localsMap) { |
| 2249 // NOTE: This construction order may be slightly different than the | 2322 // NOTE: This construction order may be slightly different than the |
| 2250 // old Element version. The old version did all the boxed items and then | 2323 // old Element version. The old version did all the boxed items and then |
| 2251 // all the others. | 2324 // all the others. |
| 2252 Local capturedLocal = localsMap.getLocalVariable(variable); | 2325 Local capturedLocal = localsMap.getLocalVariable(variable); |
| 2253 if (cls.isBoxed(capturedLocal)) { | 2326 JRecordField field = boxedCapturedVariables[capturedLocal]; |
| 2254 FieldEntity boxedField = new JRecordField( | 2327 FieldEntity closureField = new JClosureField( |
| 2255 _getClosureVariableName(capturedLocal.name, fieldNumber), | 2328 _getClosureVariableName(capturedLocal.name, fieldNumber), |
| 2256 _memberData.length, | 2329 _memberData.length, |
| 2257 new BoxLocal(box.name, | 2330 cls, |
| 2258 localsMap.getLocalVariable(box.executableContext), member), | 2331 variable.isConst, |
| 2259 cls.closureClassEntity, | 2332 variable.isFinal || variable.isConst); |
| 2260 variable.isConst); | 2333 _memberList.add(closureField); |
| 2261 cls.localToFieldMap[capturedLocal] = boxedField; | 2334 _memberData.add(new ClosureFieldData(new ClosureMemberDefinition( |
| 2262 _memberList.add(boxedField); | 2335 cls.localToFieldMap[capturedLocal], |
| 2263 _memberData.add(new ClosureFieldData(new ClosureMemberDefinition( | 2336 computeSourceSpanFromTreeNode(variable), |
| 2264 boxedField, | 2337 MemberKind.closureField, |
| 2265 computeSourceSpanFromTreeNode(variable), | 2338 variable))); |
| 2266 MemberKind.closureField, | 2339 memberMap[closureField.name] = closureField; |
| 2267 variable))); | 2340 if (boxedCapturedVariables.containsKey(capturedLocal)) { |
| 2268 memberMap[boxedField.name] = boxedField; | 2341 cls.localToFieldMap[field.box] = closureField; |
| 2342 cls.boxedVariables[capturedLocal] = field; |
| 2269 } else { | 2343 } else { |
| 2270 FieldEntity closureField = new JClosureField( | |
| 2271 _getClosureVariableName(capturedLocal.name, fieldNumber), | |
| 2272 _memberData.length, | |
| 2273 cls, | |
| 2274 variable.isConst, | |
| 2275 variable.isFinal || variable.isConst); | |
| 2276 cls.localToFieldMap[capturedLocal] = closureField; | 2344 cls.localToFieldMap[capturedLocal] = closureField; |
| 2277 _memberList.add(closureField); | |
| 2278 _memberData.add(new ClosureFieldData(new ClosureMemberDefinition( | |
| 2279 cls.localToFieldMap[capturedLocal], | |
| 2280 computeSourceSpanFromTreeNode(variable), | |
| 2281 MemberKind.closureField, | |
| 2282 variable))); | |
| 2283 memberMap[closureField.name] = closureField; | |
| 2284 } | 2345 } |
| 2285 } | 2346 } |
| 2286 | 2347 |
| 2287 // Returns a non-unique name for the given closure element. | 2348 // Returns a non-unique name for the given closure element. |
| 2288 String _computeClosureName(ir.TreeNode treeNode) { | 2349 String _computeClosureName(ir.TreeNode treeNode) { |
| 2289 var parts = <String>[]; | 2350 var parts = <String>[]; |
| 2290 if (treeNode is ir.Field && treeNode.name.name != "") { | 2351 if (treeNode is ir.Field && treeNode.name.name != "") { |
| 2291 parts.add(treeNode.name.name); | 2352 parts.add(treeNode.name.name); |
| 2292 } else { | 2353 } else { |
| 2293 parts.add('closure'); | 2354 parts.add('closure'); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2332 /// | 2393 /// |
| 2333 /// These names are not used in generated code, just as element name. | 2394 /// These names are not used in generated code, just as element name. |
| 2334 String _getClosureVariableName(String name, int id) { | 2395 String _getClosureVariableName(String name, int id) { |
| 2335 return "_captured_${name}_$id"; | 2396 return "_captured_${name}_$id"; |
| 2336 } | 2397 } |
| 2337 | 2398 |
| 2338 String getDeferredUri(ir.LibraryDependency node) { | 2399 String getDeferredUri(ir.LibraryDependency node) { |
| 2339 throw new UnimplementedError('JsKernelToElementMap.getDeferredUri'); | 2400 throw new UnimplementedError('JsKernelToElementMap.getDeferredUri'); |
| 2340 } | 2401 } |
| 2341 } | 2402 } |
| OLD | NEW |