private Map<Symbol, LvarType> getBreakTargetTypes(final BreakableNode target) { // Remove symbols defined in the the blocks that are being broken out of. Map<Symbol, LvarType> types = localVariableTypes; for(final Iterator<LexicalContextNode> it = lc.getAllNodes(); it.hasNext();) { final LexicalContextNode node = it.next(); if(node instanceof Block) { for(final Symbol symbol: ((Block)node).getSymbols()) { if(localVariableTypes.containsKey(symbol)) { if(types == localVariableTypes) { types = cloneMap(localVariableTypes); } types.remove(symbol); } } } if(node == target) { break; } } return types; }
private boolean enterJumpStatement(final JumpStatement jump) { if(!reachable) { return false; } final BreakableNode target = jump.getTarget(lc); jumpToLabel(jump, jump.getTargetLabel(target), getBreakTargetTypes(target)); doesNotContinueSequentially(); return false; }
private boolean enterJumpStatement(final JumpStatement jump) { if(!method.isReachable()) { return false; } enterStatement(jump); method.beforeJoinPoint(jump); final BreakableNode target = jump.getTarget(lc); popScopesUntil(target); final Label targetLabel = jump.getTargetLabel(target); targetLabel.markAsBreakTarget(); method._goto(targetLabel); return false; }
@Override public boolean enterBreakNode(final BreakNode breakNode) { lineNumber(breakNode); final BreakableNode breakFrom = lc.getBreakable(breakNode.getLabel()); for (int i = 0; i < lc.getScopeNestingLevelTo(breakFrom); i++) { closeWith(); } method.splitAwareGoto(lc, breakFrom.getBreakLabel()); return false; }
/** * BreakStatement : * break Identifier? ; // [no LineTerminator here] * * See 12.8 * */ private void breakStatement() { // Capture BREAK token. final int breakLine = line; final long breakToken = token; // BREAK tested in caller. nextOrEOL(); LabelNode labelNode = null; // SEMICOLON or label. switch (type) { case RBRACE: case SEMICOLON: case EOL: case EOF: break; default: final IdentNode ident = getIdent(); labelNode = lc.findLabel(ident.getName()); if (labelNode == null) { throw error(AbstractParser.message("undefined.label", ident.getName()), ident.getToken()); } break; } //either an explicit label - then get its node or just a "break" - get first breakable //targetNode is what we are breaking out from. final String labelName = labelNode == null ? null : labelNode.getLabelName(); final BreakableNode targetNode = lc.getBreakable(labelName); if (targetNode == null) { throw error(AbstractParser.message("illegal.break.stmt"), breakToken); } endOfLine(); // Construct and add BREAK node. appendStatement(new BreakNode(breakLine, breakToken, finish, labelName)); }
/** * BreakStatement : * break Identifier? ; // [no LineTerminator here] * * See 12.8 * */ private void breakStatement() { // Capture BREAK token. final int breakLine = line; final long breakToken = token; // BREAK tested in caller. nextOrEOL(); LabelNode labelNode = null; // SEMICOLON or label. switch (type) { case RBRACE: case SEMICOLON: case EOL: case EOF: break; default: final IdentNode ident = getIdent(); labelNode = lc.findLabel(ident.getName()); if (labelNode == null) { throw error(AbstractParser.message("undefined.label", ident.getName()), ident.getToken()); } break; } //either an explicit label - then get its node or just a "break" - get first breakable //targetNode is what we are breaking out from. final IdentNode label = labelNode == null ? null : labelNode.getLabel(); final BreakableNode targetNode = lc.getBreakable(label); if (targetNode == null) { throw error(AbstractParser.message("illegal.break.stmt"), breakToken); } endOfLine(); // Construct and add BREAK node. appendStatement(new BreakNode(breakLine, breakToken, finish, label == null ? null : new IdentNode(label))); }
/** * Leave a breakable node. If there's a join point associated with its break label (meaning there was at least one * break statement to the end of the node), insert the join point into the flow. * @param breakable the breakable node being left. */ private void leaveBreakable(final BreakableNode breakable) { joinOnLabel(breakable.getBreakLabel()); }
/** * Leave a breakable node. If there's a join point associated with its break label (meaning there was at least one * break statement to the end of the node), insert the join point into the flow. * @param breakable the breakable node being left. */ private void leaveBreakable(final BreakableNode breakable) { joinOnLabel(breakable.getBreakLabel()); assertTypeStackIsEmpty(); }