1476 env.info.finalize.hasFinalizer(); |
1476 env.info.finalize.hasFinalizer(); |
1477 List<Integer> gaps = env.info.gaps.toList(); |
1477 List<Integer> gaps = env.info.gaps.toList(); |
1478 code.statBegin(TreeInfo.endPos(body)); |
1478 code.statBegin(TreeInfo.endPos(body)); |
1479 genFinalizer(env); |
1479 genFinalizer(env); |
1480 code.statBegin(TreeInfo.endPos(env.tree)); |
1480 code.statBegin(TreeInfo.endPos(env.tree)); |
1481 Chain exitChain = code.branch(goto_); |
1481 Chain exitChain; |
|
1482 if (startpc != endpc) { |
|
1483 exitChain = code.branch(goto_); |
|
1484 } else { |
|
1485 exitChain = code.branch(dontgoto); |
|
1486 } |
1482 endFinalizerGap(env); |
1487 endFinalizerGap(env); |
1483 if (startpc != endpc) for (List<JCCatch> l = catchers; l.nonEmpty(); l = l.tail) { |
1488 if (startpc != endpc) { |
1484 // start off with exception on stack |
1489 for (List<JCCatch> l = catchers; l.nonEmpty(); l = l.tail) { |
1485 code.entryPoint(stateTry, l.head.param.sym.type); |
1490 // start off with exception on stack |
1486 genCatch(l.head, env, startpc, endpc, gaps); |
1491 code.entryPoint(stateTry, l.head.param.sym.type); |
1487 genFinalizer(env); |
1492 genCatch(l.head, env, startpc, endpc, gaps); |
1488 if (hasFinalizer || l.tail.nonEmpty()) { |
1493 genFinalizer(env); |
1489 code.statBegin(TreeInfo.endPos(env.tree)); |
1494 if (hasFinalizer || l.tail.nonEmpty()) { |
1490 exitChain = Code.mergeChains(exitChain, |
1495 code.statBegin(TreeInfo.endPos(env.tree)); |
1491 code.branch(goto_)); |
1496 exitChain = Code.mergeChains(exitChain, |
1492 } |
1497 code.branch(goto_)); |
1493 endFinalizerGap(env); |
1498 } |
1494 } |
1499 endFinalizerGap(env); |
1495 if (hasFinalizer) { |
1500 } |
1496 // Create a new register segement to avoid allocating |
1501 |
1497 // the same variables in finalizers and other statements. |
1502 if (hasFinalizer) { |
1498 code.newRegSegment(); |
1503 // Create a new register segement to avoid allocating |
1499 |
1504 // the same variables in finalizers and other statements. |
1500 // Add a catch-all clause. |
1505 code.newRegSegment(); |
1501 |
1506 |
1502 // start off with exception on stack |
1507 // Add a catch-all clause. |
1503 int catchallpc = code.entryPoint(stateTry, syms.throwableType); |
1508 |
1504 |
1509 // start off with exception on stack |
1505 // Register all exception ranges for catch all clause. |
1510 int catchallpc = code.entryPoint(stateTry, syms.throwableType); |
1506 // The range of the catch all clause is from the beginning |
1511 |
1507 // of the try or synchronized block until the present |
1512 // Register all exception ranges for catch all clause. |
1508 // code pointer excluding all gaps in the current |
1513 // The range of the catch all clause is from the beginning |
1509 // environment's GenContext. |
1514 // of the try or synchronized block until the present |
1510 int startseg = startpc; |
1515 // code pointer excluding all gaps in the current |
1511 while (env.info.gaps.nonEmpty()) { |
1516 // environment's GenContext. |
1512 int endseg = env.info.gaps.next().intValue(); |
1517 int startseg = startpc; |
1513 registerCatch(body.pos(), startseg, endseg, |
1518 while (env.info.gaps.nonEmpty()) { |
1514 catchallpc, 0); |
1519 int endseg = env.info.gaps.next().intValue(); |
1515 startseg = env.info.gaps.next().intValue(); |
1520 registerCatch(body.pos(), startseg, endseg, |
1516 } |
1521 catchallpc, 0); |
1517 code.statBegin(TreeInfo.finalizerPos(env.tree)); |
1522 startseg = env.info.gaps.next().intValue(); |
1518 code.markStatBegin(); |
1523 } |
1519 |
|
1520 Item excVar = makeTemp(syms.throwableType); |
|
1521 excVar.store(); |
|
1522 genFinalizer(env); |
|
1523 excVar.load(); |
|
1524 registerCatch(body.pos(), startseg, |
|
1525 env.info.gaps.next().intValue(), |
|
1526 catchallpc, 0); |
|
1527 code.emitop0(athrow); |
|
1528 code.markDead(); |
|
1529 |
|
1530 // If there are jsr's to this finalizer, ... |
|
1531 if (env.info.cont != null) { |
|
1532 // Resolve all jsr's. |
|
1533 code.resolve(env.info.cont); |
|
1534 |
|
1535 // Mark statement line number |
|
1536 code.statBegin(TreeInfo.finalizerPos(env.tree)); |
1524 code.statBegin(TreeInfo.finalizerPos(env.tree)); |
1537 code.markStatBegin(); |
1525 code.markStatBegin(); |
1538 |
1526 |
1539 // Save return address. |
1527 Item excVar = makeTemp(syms.throwableType); |
1540 LocalItem retVar = makeTemp(syms.throwableType); |
1528 excVar.store(); |
1541 retVar.store(); |
1529 genFinalizer(env); |
1542 |
1530 excVar.load(); |
1543 // Generate finalizer code. |
1531 registerCatch(body.pos(), startseg, |
1544 env.info.finalize.genLast(); |
1532 env.info.gaps.next().intValue(), |
1545 |
1533 catchallpc, 0); |
1546 // Return. |
1534 code.emitop0(athrow); |
1547 code.emitop1w(ret, retVar.reg); |
|
1548 code.markDead(); |
1535 code.markDead(); |
|
1536 |
|
1537 // If there are jsr's to this finalizer, ... |
|
1538 if (env.info.cont != null) { |
|
1539 // Resolve all jsr's. |
|
1540 code.resolve(env.info.cont); |
|
1541 |
|
1542 // Mark statement line number |
|
1543 code.statBegin(TreeInfo.finalizerPos(env.tree)); |
|
1544 code.markStatBegin(); |
|
1545 |
|
1546 // Save return address. |
|
1547 LocalItem retVar = makeTemp(syms.throwableType); |
|
1548 retVar.store(); |
|
1549 |
|
1550 // Generate finalizer code. |
|
1551 env.info.finalize.genLast(); |
|
1552 |
|
1553 // Return. |
|
1554 code.emitop1w(ret, retVar.reg); |
|
1555 code.markDead(); |
|
1556 } |
1549 } |
1557 } |
1550 } |
1558 } |
1551 // Resolve all breaks. |
1559 // Resolve all breaks. |
1552 code.resolve(exitChain); |
1560 code.resolve(exitChain); |
1553 |
1561 |