Chromium Code Reviews| 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 |