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.backend_strategy; | 5 library dart2js.kernel.backend_strategy; |
6 | 6 |
7 import 'package:kernel/ast.dart' as ir; | 7 import 'package:kernel/ast.dart' as ir; |
8 | 8 |
9 import '../backend_strategy.dart'; | 9 import '../backend_strategy.dart'; |
10 import '../closure.dart'; | 10 import '../closure.dart'; |
11 import '../common.dart'; | |
11 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; | 12 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; |
12 import '../common/tasks.dart'; | 13 import '../common/tasks.dart'; |
13 import '../compiler.dart'; | 14 import '../compiler.dart'; |
14 import '../elements/entities.dart'; | 15 import '../elements/entities.dart'; |
15 import '../elements/entity_utils.dart' as utils; | 16 import '../elements/entity_utils.dart' as utils; |
16 import '../elements/jumps.dart'; | 17 import '../elements/jumps.dart'; |
17 import '../enqueue.dart'; | 18 import '../enqueue.dart'; |
18 import '../io/source_information.dart'; | 19 import '../io/source_information.dart'; |
19 import '../js/js_source_mapping.dart'; | 20 import '../js/js_source_mapping.dart'; |
20 import '../js_backend/backend.dart'; | 21 import '../js_backend/backend.dart'; |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
272 | 273 |
273 KernelToLocalsMap getLocalsMap(MemberEntity member) { | 274 KernelToLocalsMap getLocalsMap(MemberEntity member) { |
274 return _localsMaps.putIfAbsent( | 275 return _localsMaps.putIfAbsent( |
275 member, () => new KernelToLocalsMapImpl(member)); | 276 member, () => new KernelToLocalsMapImpl(member)); |
276 } | 277 } |
277 } | 278 } |
278 | 279 |
279 class KernelToLocalsMapImpl implements KernelToLocalsMap { | 280 class KernelToLocalsMapImpl implements KernelToLocalsMap { |
280 final List<MemberEntity> _members = <MemberEntity>[]; | 281 final List<MemberEntity> _members = <MemberEntity>[]; |
281 Map<ir.VariableDeclaration, KLocal> _map = <ir.VariableDeclaration, KLocal>{}; | 282 Map<ir.VariableDeclaration, KLocal> _map = <ir.VariableDeclaration, KLocal>{}; |
283 Map<ir.LabeledStatement, KJumpTarget> _jumpTargetMap; | |
282 | 284 |
283 MemberEntity get currentMember => _members.last; | 285 MemberEntity get currentMember => _members.last; |
284 | 286 |
287 // TODO(johnniwinther): Compute this eagerly from the root of the member. | |
288 void _ensureJumpMap(ir.TreeNode node) { | |
289 if (_jumpTargetMap == null) { | |
290 JumpVisitor visitor = new JumpVisitor(currentMember); | |
291 | |
292 // Find the root node for the current member. | |
Siggi Cherem (dart-lang)
2017/06/23 19:34:00
I know this will go away when you do it eagerly, b
Johnni Winther
2017/06/26 09:04:18
Your guess is right.
| |
293 while (node is! ir.Member) { | |
294 node = node.parent; | |
295 } | |
296 | |
297 node.accept(visitor); | |
298 _jumpTargetMap = visitor.jumpTargetMap; | |
299 } | |
300 } | |
301 | |
285 KernelToLocalsMapImpl(MemberEntity member) { | 302 KernelToLocalsMapImpl(MemberEntity member) { |
286 _members.add(member); | 303 _members.add(member); |
287 } | 304 } |
288 | 305 |
289 @override | 306 @override |
290 void enterInlinedMember(MemberEntity member) { | 307 void enterInlinedMember(MemberEntity member) { |
291 _members.add(member); | 308 _members.add(member); |
292 } | 309 } |
293 | 310 |
294 @override | 311 @override |
295 void leaveInlinedMember(MemberEntity member) { | 312 void leaveInlinedMember(MemberEntity member) { |
296 assert(member == currentMember); | 313 assert(member == currentMember); |
297 _members.removeLast(); | 314 _members.removeLast(); |
Siggi Cherem (dart-lang)
2017/06/23 19:34:00
do we need to clear the _jumpTargetMap when we ent
Johnni Winther
2017/06/26 09:04:18
Yes, something like it. I think we need to split i
Siggi Cherem (dart-lang)
2017/06/26 16:44:14
Can you add a note about it here? (maybe TODO(rede
| |
298 } | 315 } |
299 | 316 |
300 @override | 317 @override |
301 JumpTarget getJumpTargetForBreak(ir.BreakStatement node) { | 318 JumpTarget getJumpTargetForBreak(ir.BreakStatement node) { |
302 throw new UnimplementedError('KernelToLocalsMapImpl.getJumpTargetForBreak'); | 319 _ensureJumpMap(node.target); |
320 JumpTarget target = _jumpTargetMap[node.target]; | |
321 assert(target != null, failedAt(currentMember, 'No target for $node.')); | |
322 return target; | |
303 } | 323 } |
304 | 324 |
305 @override | 325 @override |
306 JumpTarget getJumpTargetForContinueSwitch(ir.ContinueSwitchStatement node) { | 326 JumpTarget getJumpTargetForContinueSwitch(ir.ContinueSwitchStatement node) { |
327 _ensureJumpMap(node.target); | |
307 throw new UnimplementedError( | 328 throw new UnimplementedError( |
308 'KernelToLocalsMapImpl.getJumpTargetForContinueSwitch'); | 329 'KernelToLocalsMapImpl.getJumpTargetForContinueSwitch'); |
309 } | 330 } |
310 | 331 |
311 @override | 332 @override |
312 JumpTarget getJumpTargetForSwitchCase(ir.SwitchCase node) { | 333 JumpTarget getJumpTargetForSwitchCase(ir.SwitchCase node) { |
334 _ensureJumpMap(node); | |
313 throw new UnimplementedError( | 335 throw new UnimplementedError( |
314 'KernelToLocalsMapImpl.getJumpTargetForSwitchCase'); | 336 'KernelToLocalsMapImpl.getJumpTargetForSwitchCase'); |
315 } | 337 } |
316 | 338 |
317 @override | 339 @override |
318 JumpTarget getJumpTargetForDo(ir.DoStatement node) { | 340 JumpTarget getJumpTargetForDo(ir.DoStatement node) { |
319 // TODO(johnniwinther): Support do statement as jump target. | 341 _ensureJumpMap(node); |
320 return null; | 342 return _jumpTargetMap[node.parent]; |
321 } | 343 } |
322 | 344 |
323 @override | 345 @override |
324 JumpTarget getJumpTargetForLabel(ir.LabeledStatement node) { | 346 JumpTarget getJumpTargetForLabel(ir.LabeledStatement node) { |
325 throw new UnimplementedError('KernelToLocalsMapImpl.getJumpTargetForLabel'); | 347 _ensureJumpMap(node); |
348 JumpTarget target = _jumpTargetMap[node]; | |
349 assert(target != null, failedAt(currentMember, 'No target for $node.')); | |
350 return target; | |
326 } | 351 } |
327 | 352 |
328 @override | 353 @override |
329 JumpTarget getJumpTargetForSwitch(ir.SwitchStatement node) { | 354 JumpTarget getJumpTargetForSwitch(ir.SwitchStatement node) { |
355 _ensureJumpMap(node); | |
330 throw new UnimplementedError( | 356 throw new UnimplementedError( |
331 'KernelToLocalsMapImpl.getJumpTargetForSwitch'); | 357 'KernelToLocalsMapImpl.getJumpTargetForSwitch'); |
332 } | 358 } |
333 | 359 |
334 @override | 360 @override |
335 JumpTarget getJumpTargetForFor(ir.ForStatement node) { | 361 JumpTarget getJumpTargetForFor(ir.ForStatement node) { |
336 // TODO(johnniwinther): Support for statement as jump target. | 362 _ensureJumpMap(node); |
337 return null; | 363 return _jumpTargetMap[node.parent]; |
338 } | 364 } |
339 | 365 |
340 @override | 366 @override |
341 JumpTarget getJumpTargetForForIn(ir.ForInStatement node) { | 367 JumpTarget getJumpTargetForForIn(ir.ForInStatement node) { |
342 // TODO(johnniwinther): Support for-in statement as jump target. | 368 _ensureJumpMap(node); |
343 return null; | 369 return _jumpTargetMap[node.parent]; |
344 } | 370 } |
345 | 371 |
346 @override | 372 @override |
347 JumpTarget getJumpTargetForWhile(ir.WhileStatement node) { | 373 JumpTarget getJumpTargetForWhile(ir.WhileStatement node) { |
348 // TODO(johnniwinther): Support while statement as jump target. | 374 _ensureJumpMap(node); |
349 return null; | 375 return _jumpTargetMap[node.parent]; |
350 } | 376 } |
351 | 377 |
352 @override | 378 @override |
353 Local getLocal(ir.VariableDeclaration node) { | 379 Local getLocal(ir.VariableDeclaration node) { |
354 return _map.putIfAbsent(node, () { | 380 return _map.putIfAbsent(node, () { |
355 return new KLocal(node.name, currentMember); | 381 return new KLocal(node.name, currentMember); |
356 }); | 382 }); |
357 } | 383 } |
358 | 384 |
359 @override | 385 @override |
360 LoopClosureRepresentationInfo getClosureRepresentationInfoForLoop( | 386 LoopClosureRepresentationInfo getClosureRepresentationInfoForLoop( |
361 ClosureDataLookup closureLookup, ir.TreeNode node) { | 387 ClosureDataLookup closureLookup, ir.TreeNode node) { |
362 return closureLookup.getClosureRepresentationInfoForLoop(node); | 388 return closureLookup.getClosureRepresentationInfoForLoop(node); |
363 } | 389 } |
364 } | 390 } |
365 | 391 |
392 class JumpVisitor extends ir.Visitor { | |
393 final MemberEntity member; | |
394 final Map<ir.LabeledStatement, KJumpTarget> jumpTargetMap = | |
395 <ir.LabeledStatement, KJumpTarget>{}; | |
396 | |
397 JumpVisitor(this.member); | |
398 | |
399 KJumpTarget _getJumpTarget(ir.LabeledStatement node) { | |
400 return jumpTargetMap.putIfAbsent(node, () { | |
401 return new KJumpTarget(member, jumpTargetMap.length); | |
402 }); | |
403 } | |
404 | |
405 @override | |
406 defaultNode(ir.Node node) => node.visitChildren(this); | |
407 | |
408 @override | |
409 visitBreakStatement(ir.BreakStatement node) { | |
410 KJumpTarget target = _getJumpTarget(node.target); | |
411 target.isBreakTarget = true; | |
412 super.visitBreakStatement(node); | |
413 } | |
414 } | |
415 | |
416 class KJumpTarget extends JumpTarget<ir.Node> { | |
417 final MemberEntity memberContext; | |
418 final int nestingLevel; | |
419 | |
420 KJumpTarget(this.memberContext, this.nestingLevel); | |
421 | |
422 bool isBreakTarget = false; | |
423 bool isContinueTarget = false; | |
424 bool isSwitch = false; | |
425 | |
426 @override | |
427 Entity get executableContext => memberContext; | |
428 | |
429 @override | |
430 LabelDefinition<ir.Node> addLabel(ir.Node label, String labelName, | |
431 {bool isBreakTarget: false}) { | |
432 throw new UnimplementedError('KJumpTarget.addLabel'); | |
433 } | |
434 | |
435 @override | |
436 List<LabelDefinition<ir.Node>> get labels { | |
437 return const <LabelDefinition<ir.Node>>[]; | |
438 } | |
439 | |
440 @override | |
441 ir.Node get statement { | |
442 throw new UnimplementedError('KJumpTarget.statement'); | |
443 } | |
444 } | |
445 | |
366 class KLocal implements Local { | 446 class KLocal implements Local { |
367 final String name; | 447 final String name; |
368 final MemberEntity memberContext; | 448 final MemberEntity memberContext; |
369 | 449 |
370 KLocal(this.name, this.memberContext); | 450 KLocal(this.name, this.memberContext); |
371 | 451 |
372 @override | 452 @override |
373 Entity get executableContext => memberContext; | 453 Entity get executableContext => memberContext; |
374 | 454 |
375 String toString() { | 455 String toString() { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
427 Iterable<ClassEntity> sortClasses(Iterable<ClassEntity> classes) { | 507 Iterable<ClassEntity> sortClasses(Iterable<ClassEntity> classes) { |
428 return classes.toList() | 508 return classes.toList() |
429 ..sort((ClassEntity a, ClassEntity b) { | 509 ..sort((ClassEntity a, ClassEntity b) { |
430 int r = _compareLibraries(a.library, b.library); | 510 int r = _compareLibraries(a.library, b.library); |
431 if (r != 0) return r; | 511 if (r != 0) return r; |
432 return _compareNodes( | 512 return _compareNodes( |
433 a, elementMap.getClassNode(a), b, elementMap.getClassNode(b)); | 513 a, elementMap.getClassNode(a), b, elementMap.getClassNode(b)); |
434 }); | 514 }); |
435 } | 515 } |
436 } | 516 } |
OLD | NEW |