Java Code Examples for jdk.nashorn.internal.ir.Block

The following examples show how to use jdk.nashorn.internal.ir.Block. These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source Project: jdk8u60   Source File: FoldConstants.java    License: GNU General Public License v2.0 6 votes vote down vote up
@Override
public Node leaveIfNode(final IfNode ifNode) {
    final Node test = ifNode.getTest();
    if (test instanceof LiteralNode.PrimitiveLiteralNode) {
        final boolean isTrue = ((LiteralNode.PrimitiveLiteralNode<?>)test).isTrue();
        final Block executed = isTrue ? ifNode.getPass() : ifNode.getFail();
        final Block dropped  = isTrue ? ifNode.getFail() : ifNode.getPass();
        final List<Statement> statements = new ArrayList<>();

        if (executed != null) {
            statements.addAll(executed.getStatements()); // Get statements form executed branch
        }
        if (dropped != null) {
            extractVarNodes(dropped, statements); // Get var-nodes from non-executed branch
        }
        if (statements.isEmpty()) {
            return new EmptyNode(ifNode);
        }
        return BlockStatement.createReplacement(ifNode, ifNode.getFinish(), statements);
    }
    return ifNode;
}
 
Example 2
Source Project: jdk8u_nashorn   Source File: AssignSymbols.java    License: GNU General Public License v2.0 6 votes vote down vote up
@Override
public boolean enterCatchNode(final CatchNode catchNode) {
    final IdentNode exception = catchNode.getException();
    final Block     block     = lc.getCurrentBlock();

    start(catchNode);

    // define block-local exception variable
    final String exname = exception.getName();
    // If the name of the exception starts with ":e", this is a synthetic catch block, likely a catch-all. Its
    // symbol is naturally internal, and should be treated as such.
    final boolean isInternal = exname.startsWith(EXCEPTION_PREFIX.symbolName());
    // IS_LET flag is required to make sure symbol is not visible outside catch block. However, we need to
    // clear the IS_LET flag after creation to allow redefinition of symbol inside the catch block.
    final Symbol symbol = defineSymbol(block, exname, catchNode, IS_VAR | IS_LET | (isInternal ? IS_INTERNAL : 0) | HAS_OBJECT_VALUE);
    symbol.clearFlag(IS_LET);

    return true;
}
 
Example 3
@Override
public Node leaveBlock(final Block block) {
    assert !block.isCatchBlock();

    Block newBlock = block;

    // Block was heavier than SLIT_THRESHOLD in enter, but a sub-block may have
    // been split already, so weigh again before splitting.
    long weight = WeighNodes.weigh(block, weightCache);
    if (weight >= SPLIT_THRESHOLD) {
        final FunctionNode currentFunction = lc.getCurrentFunction();
        newBlock = splitBlock(block, currentFunction);
        weight   = WeighNodes.weigh(newBlock, weightCache);
        lc.setFlag(currentFunction, FunctionNode.IS_SPLIT);
    }
    weightCache.put(newBlock, weight);
    return newBlock;
}
 
Example 4
Source Project: openjdk-8-source   Source File: Attr.java    License: GNU General Public License v2.0 6 votes vote down vote up
/**
 * Initialize parameters for function node. This may require specializing
 * types if a specialization profile is known
 *
 * @param functionNode the function node
 */
private void initParameters(final FunctionNode functionNode, final Block body) {
    int pos = 0;
    for (final IdentNode param : functionNode.getParameters()) {
        addLocalDef(param.getName());

        final Type callSiteParamType = functionNode.getHints().getParameterType(pos);
        int flags = IS_PARAM;
        if (callSiteParamType != null) {
            LOG.info("Param ", param, " has a callsite type ", callSiteParamType, ". Using that.");
            flags |= Symbol.IS_SPECIALIZED_PARAM;
        }

        final Symbol paramSymbol = defineSymbol(body, param.getName(), flags);
        assert paramSymbol != null;

        newType(paramSymbol, callSiteParamType == null ? Type.UNKNOWN : callSiteParamType);

        LOG.info("Initialized param ", pos, "=", paramSymbol);
        pos++;
    }

}
 
Example 5
Source Project: TencentKona-8   Source File: AssignSymbols.java    License: GNU General Public License v2.0 6 votes vote down vote up
@Override
public boolean enterBlock(final Block block) {
    start(block);

    if (lc.isFunctionBody()) {
        assert !block.hasSymbols();
        final FunctionNode fn = lc.getCurrentFunction();
        if (isUnparsedFunction(fn)) {
            // It's a skipped nested function. Just mark the symbols being used by it as being in use.
            for(final String name: compiler.getScriptFunctionData(fn.getId()).getExternalSymbolNames()) {
                nameIsUsed(name, null);
            }
            // Don't bother descending into it, it must be empty anyway.
            assert block.getStatements().isEmpty();
            return false;
        }

        enterFunctionBody();
    }

    return true;
}
 
Example 6
Source Project: openjdk-jdk9   Source File: FoldConstants.java    License: GNU General Public License v2.0 6 votes vote down vote up
@Override
public Node leaveIfNode(final IfNode ifNode) {
    final Node test = ifNode.getTest();
    if (test instanceof LiteralNode.PrimitiveLiteralNode) {
        final boolean isTrue = ((LiteralNode.PrimitiveLiteralNode<?>)test).isTrue();
        final Block executed = isTrue ? ifNode.getPass() : ifNode.getFail();
        final Block dropped  = isTrue ? ifNode.getFail() : ifNode.getPass();
        final List<Statement> statements = new ArrayList<>();

        if (executed != null) {
            statements.addAll(executed.getStatements()); // Get statements form executed branch
        }
        if (dropped != null) {
            extractVarNodesFromDeadCode(dropped, statements); // Get var-nodes from non-executed branch
        }
        if (statements.isEmpty()) {
            return new EmptyNode(ifNode);
        }
        return BlockStatement.createReplacement(ifNode, ifNode.getFinish(), statements);
    }
    return ifNode;
}
 
Example 7
Source Project: TencentKona-8   Source File: AssignSymbols.java    License: GNU General Public License v2.0 6 votes vote down vote up
private void initFunctionWideVariables(final FunctionNode functionNode, final Block body) {
    initCompileConstant(CALLEE, body, IS_PARAM | IS_INTERNAL | HAS_OBJECT_VALUE);
    initCompileConstant(THIS, body, IS_PARAM | IS_THIS | HAS_OBJECT_VALUE);

    if (functionNode.isVarArg()) {
        initCompileConstant(VARARGS, body, IS_PARAM | IS_INTERNAL | HAS_OBJECT_VALUE);
        if (functionNode.needsArguments()) {
            initCompileConstant(ARGUMENTS, body, IS_VAR | IS_INTERNAL | HAS_OBJECT_VALUE);
            defineSymbol(body, ARGUMENTS_VAR.symbolName(), null, IS_VAR | HAS_OBJECT_VALUE);
        }
    }

    initParameters(functionNode, body);
    initCompileConstant(SCOPE, body, IS_VAR | IS_INTERNAL | HAS_OBJECT_VALUE);
    initCompileConstant(RETURN, body, IS_VAR | IS_INTERNAL);
}
 
Example 8
Source Project: openjdk-jdk8u   Source File: AssignSymbols.java    License: GNU General Public License v2.0 6 votes vote down vote up
private void defineFunctionSelfSymbol(final FunctionNode functionNode, final Block body) {
    // Function self-symbol is only declared as a local variable for named function expressions. Declared functions
    // don't need it as they are local variables in their declaring scope.
    if (!functionNode.isNamedFunctionExpression()) {
        return;
    }

    final String name = functionNode.getIdent().getName();
    assert name != null; // As it's a named function expression.

    if (body.getExistingSymbol(name) != null) {
        // Body already has a declaration for the name. It's either a parameter "function x(x)" or a
        // top-level variable "function x() { ... var x; ... }".
        return;
    }

    defineSymbol(body, name, functionNode, IS_VAR | IS_FUNCTION_SELF | HAS_OBJECT_VALUE);
    if(functionNode.allVarsInScope()) { // basically, has deep eval
        // We must conservatively presume that eval'd code can dynamically use the function symbol.
        lc.setFlag(functionNode, FunctionNode.USES_SELF_SYMBOL);
    }
}
 
Example 9
@Override
public Node leaveBlock(final Block block) {
    if (!artificialBlock) {
        if (lc.isFunctionBody()) {
            // Prepend declaration-only var statements to the top of the statement list.
            lc.prependStatements(getCurrentFunctionState().varStatements);
        } else if (lc.isSplitBody()) {
            appendSplitReturn(FALLTHROUGH_STATE, NO_LINE_NUMBER);
            if (getCurrentFunctionState().fn.isProgram()) {
                // If we're splitting the program, make sure every shard ends with "return :return" and
                // begins with ":return = :return-in;".
                lc.prependStatement(new ExpressionStatement(NO_LINE_NUMBER, NO_TOKEN, NO_FINISH,
                        new BinaryNode(Token.toDesc(TokenType.ASSIGN, 0, 0), createReturnIdent(), createReturnParamIdent())));
            }
        }
    }
    return block;
}
 
Example 10
Source Project: openjdk-jdk8u   Source File: Parser.java    License: GNU General Public License v2.0 6 votes vote down vote up
/**
 * ...IterationStatement :
 *           ...
 *           while ( Expression ) Statement
 *           ...
 *
 * See 12.6
 *
 * Parse while statement.
 */
private void whileStatement() {
    // Capture WHILE token.
    final long whileToken = token;
    // WHILE tested in caller.
    next();

    // Construct WHILE node.
    WhileNode whileNode = new WhileNode(line, whileToken, Token.descPosition(whileToken), false);
    lc.push(whileNode);

    try {
        expect(LPAREN);
        final int whileLine = line;
        final JoinPredecessorExpression test = joinPredecessorExpression();
        expect(RPAREN);
        final Block body = getStatement();
        appendStatement(whileNode =
            new WhileNode(whileLine, whileToken, finish, false).
                setTest(lc, test).
                setBody(lc, body));
    } finally {
        lc.pop(whileNode);
    }
}
 
Example 11
Source Project: hottub   Source File: Parser.java    License: GNU General Public License v2.0 6 votes vote down vote up
/**
 * ...IterationStatement :
 *           ...
 *           while ( Expression ) Statement
 *           ...
 *
 * See 12.6
 *
 * Parse while statement.
 */
private void whileStatement() {
    // Capture WHILE token.
    final long whileToken = token;
    // WHILE tested in caller.
    next();

    // Construct WHILE node.
    WhileNode whileNode = new WhileNode(line, whileToken, Token.descPosition(whileToken), false);
    lc.push(whileNode);

    try {
        expect(LPAREN);
        final int whileLine = line;
        final JoinPredecessorExpression test = joinPredecessorExpression();
        expect(RPAREN);
        final Block body = getStatement();
        appendStatement(whileNode =
            new WhileNode(whileLine, whileToken, finish, false).
                setTest(lc, test).
                setBody(lc, body));
    } finally {
        lc.pop(whileNode);
    }
}
 
Example 12
Source Project: hottub   Source File: FindScopeDepths.java    License: GNU General Public License v2.0 6 votes vote down vote up
static int findScopesToStart(final LexicalContext lc, final FunctionNode fn, final Block block) {
    final Block bodyBlock = findBodyBlock(lc, fn, block);
    final Iterator<Block> iter = lc.getBlocks(block);
    Block b = iter.next();
    int scopesToStart = 0;
    while (true) {
        if (b.needsScope()) {
            scopesToStart++;
        }
        if (b == bodyBlock) {
            break;
        }
        b = iter.next();
    }
    return scopesToStart;
}
 
Example 13
@Override
public boolean enterBlock(final Block block) {
    boolean cloned = false;
    for(final Symbol symbol: block.getSymbols()) {
        if(symbol.isBytecodeLocal()) {
            if (getLocalVariableTypeOrNull(symbol) == null) {
                if (!cloned) {
                    cloneOrNewLocalVariableTypes();
                    cloned = true;
                }
                localVariableTypes.put(symbol, LvarType.UNDEFINED);
            }
            // In case we're repeating analysis of a lexical scope (e.g. it's in a loop),
            // make sure all symbols lexically scoped by the block become valid again.
            invalidatedSymbols.remove(symbol);
        }
    }
    return true;
}
 
Example 14
@Override
public boolean enterBlock(final Block block) {
    boolean cloned = false;
    for(final Symbol symbol: block.getSymbols()) {
        if(symbol.isBytecodeLocal()) {
            if (getLocalVariableTypeOrNull(symbol) == null) {
                if (!cloned) {
                    cloneOrNewLocalVariableTypes();
                    cloned = true;
                }
                localVariableTypes.put(symbol, LvarType.UNDEFINED);
            }
            // In case we're repeating analysis of a lexical scope (e.g. it's in a loop),
            // make sure all symbols lexically scoped by the block become valid again.
            invalidatedSymbols.remove(symbol);
        }
    }
    return true;
}
 
Example 15
private Map<Symbol, LvarType> getBreakTargetTypes(final LexicalContextNode 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;
}
 
Example 16
Source Project: nashorn   Source File: Attr.java    License: GNU General Public License v2.0 6 votes vote down vote up
/**
 * Initialize parameters for function node. This may require specializing
 * types if a specialization profile is known
 *
 * @param functionNode the function node
 */
private void initParameters(final FunctionNode functionNode, final Block body) {
    int pos = 0;
    for (final IdentNode param : functionNode.getParameters()) {
        addLocalDef(param.getName());

        final Type callSiteParamType = functionNode.getHints().getParameterType(pos);
        int flags = IS_PARAM;
        if (callSiteParamType != null) {
            LOG.info("Param ", param, " has a callsite type ", callSiteParamType, ". Using that.");
            flags |= Symbol.IS_SPECIALIZED_PARAM;
        }

        final Symbol paramSymbol = defineSymbol(body, param.getName(), flags);
        assert paramSymbol != null;

        newType(paramSymbol, callSiteParamType == null ? Type.UNKNOWN : callSiteParamType);

        LOG.info("Initialized param ", pos, "=", paramSymbol);
        pos++;
    }

}
 
Example 17
@Override
public boolean enterBlock(final Block block) {
    start(block);

    if (lc.isFunctionBody()) {
        assert !block.hasSymbols();
        final FunctionNode fn = lc.getCurrentFunction();
        if (isUnparsedFunction(fn)) {
            // It's a skipped nested function. Just mark the symbols being used by it as being in use.
            for(final String name: compiler.getScriptFunctionData(fn.getId()).getExternalSymbolNames()) {
                nameIsUsed(name, null);
            }
            // Don't bother descending into it, it must be empty anyway.
            assert block.getStatements().isEmpty();
            return false;
        }

        enterFunctionBody();
    }

    return true;
}
 
Example 18
private Map<Symbol, LvarType> getBreakTargetTypes(final LexicalContextNode 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;
}
 
Example 19
Source Project: openjdk-jdk8u   Source File: Lower.java    License: GNU General Public License v2.0 5 votes vote down vote up
private static Block createFinallyBlock(final Block finallyBody) {
    final List<Statement> newStatements = new ArrayList<>();
    for (final Statement statement : finallyBody.getStatements()) {
        newStatements.add(statement);
        if (statement.hasTerminalFlags()) {
            break;
        }
    }
    return finallyBody.setStatements(null, newStatements);
}
 
Example 20
Source Project: openjdk-8   Source File: CodeGenerator.java    License: GNU General Public License v2.0 5 votes vote down vote up
@Override
public boolean enterIfNode(final IfNode ifNode) {
    lineNumber(ifNode);

    final Expression test = ifNode.getTest();
    final Block pass = ifNode.getPass();
    final Block fail = ifNode.getFail();

    final Label failLabel  = new Label("if_fail");
    final Label afterLabel = fail == null ? failLabel : new Label("if_done");

    new BranchOptimizer(this, method).execute(test, failLabel, false);

    boolean passTerminal = false;
    boolean failTerminal = false;

    pass.accept(this);
    if (!pass.hasTerminalFlags()) {
        method._goto(afterLabel); //don't fallthru to fail block
    } else {
        passTerminal = pass.isTerminal();
    }

    if (fail != null) {
        method.label(failLabel);
        fail.accept(this);
        failTerminal = fail.isTerminal();
    }

    //if if terminates, put the after label there
    if (!passTerminal || !failTerminal) {
        method.label(afterLabel);
    }

    return false;
}
 
Example 21
Source Project: openjdk-jdk9   Source File: Lower.java    License: GNU General Public License v2.0 5 votes vote down vote up
private static Block prependFinally(final Block finallyBlock, final Statement statement) {
    final Block inlinedFinally = ensureUniqueNamesIn(finallyBlock);
    if (isTerminalFinally(finallyBlock)) {
        return inlinedFinally;
    }
    final List<Statement> stmts = inlinedFinally.getStatements();
    final List<Statement> newStmts = new ArrayList<>(stmts.size() + 1);
    newStmts.addAll(stmts);
    newStmts.add(statement);
    return new Block(inlinedFinally.getToken(), statement.getFinish(), newStmts);
}
 
Example 22
private int assignSlots(final Block block, final int firstSlot) {
    int fromSlot = firstSlot;
    final MethodEmitter method = methodEmitters.peek();
    for (final Symbol symbol : block.getSymbols()) {
        if (symbol.hasSlot()) {
            symbol.setFirstSlot(fromSlot);
            final int toSlot = fromSlot + symbol.slotCount();
            method.defineBlockLocalVariable(fromSlot, toSlot);
            fromSlot = toSlot;
        }
    }
    return fromSlot;
}
 
Example 23
Source Project: openjdk-jdk8u-backup   Source File: Parser.java    License: GNU General Public License v2.0 5 votes vote down vote up
/**
 * ...IterationStatement :
 *           ...
 *           do Statement while( Expression ) ;
 *           ...
 *
 * See 12.6
 *
 * Parse DO WHILE statement.
 */
private void doStatement() {
    // Capture DO token.
    final long doToken = token;
    // DO tested in the caller.
    next();

    WhileNode doWhileNode = new WhileNode(-1, doToken, Token.descPosition(doToken), true);
    lc.push(doWhileNode);

    try {
       // Get DO body.
        final Block body = getStatement();

        expect(WHILE);
        expect(LPAREN);
        final int doLine = line;
        final JoinPredecessorExpression test = joinPredecessorExpression();
        expect(RPAREN);

        if (type == SEMICOLON) {
            endOfLine();
        }
        doWhileNode.setFinish(finish);

        //line number is last
        appendStatement(doWhileNode =
            new WhileNode(doLine, doToken, finish, true).
                setBody(lc, body).
                setTest(lc, test));
    } finally {
        lc.pop(doWhileNode);
    }
}
 
Example 24
Source Project: openjdk-8   Source File: FoldConstants.java    License: GNU General Public License v2.0 5 votes vote down vote up
private static void extractVarNodes(final Block block, final List<Statement> statements) {
    final LexicalContext lc = new LexicalContext();
    block.accept(lc, new NodeVisitor<LexicalContext>(lc) {
        @Override
        public boolean enterVarNode(VarNode varNode) {
            statements.add(varNode.setInit(null));
            return false;
        }
    });
}
 
Example 25
Source Project: TencentKona-8   Source File: AssignSymbols.java    License: GNU General Public License v2.0 5 votes vote down vote up
private FunctionNode createSyntheticInitializers(final FunctionNode functionNode) {
    final List<VarNode> syntheticInitializers = new ArrayList<>(2);

    // Must visit the new var nodes in the context of the body. We could also just set the new statements into the
    // block and then revisit the entire block, but that seems to be too much double work.
    final Block body = functionNode.getBody();
    lc.push(body);
    try {
        if (functionNode.usesSelfSymbol()) {
            // "var fn = :callee"
            syntheticInitializers.add(createSyntheticInitializer(functionNode.getIdent(), CALLEE, functionNode));
        }

        if (functionNode.needsArguments()) {
            // "var arguments = :arguments"
            syntheticInitializers.add(createSyntheticInitializer(createImplicitIdentifier(ARGUMENTS_VAR.symbolName()),
                    ARGUMENTS, functionNode));
        }

        if (syntheticInitializers.isEmpty()) {
            return functionNode;
        }

        for(final ListIterator<VarNode> it = syntheticInitializers.listIterator(); it.hasNext();) {
            it.set((VarNode)it.next().accept(this));
        }
    } finally {
        lc.pop(body);
    }

    final List<Statement> stmts = body.getStatements();
    final List<Statement> newStatements = new ArrayList<>(stmts.size() + syntheticInitializers.size());
    newStatements.addAll(syntheticInitializers);
    newStatements.addAll(stmts);
    return functionNode.setBody(lc, body.setStatements(lc, newStatements));
}
 
Example 26
Source Project: jdk8u60   Source File: AssignSymbols.java    License: GNU General Public License v2.0 5 votes vote down vote up
/**
 * Search for symbol in the lexical context starting from the given block.
 * @param name Symbol name.
 * @return Found symbol or null if not found.
 */
private Symbol findSymbol(final Block block, final String name) {
    for (final Iterator<Block> blocks = lc.getBlocks(block); blocks.hasNext();) {
        final Symbol symbol = blocks.next().getExistingSymbol(name);
        if (symbol != null) {
            return symbol;
        }
    }
    return null;
}
 
Example 27
Source Project: nashorn   Source File: CodeGenerator.java    License: GNU General Public License v2.0 5 votes vote down vote up
@Override
public boolean enterIfNode(final IfNode ifNode) {
    lineNumber(ifNode);

    final Expression test = ifNode.getTest();
    final Block pass = ifNode.getPass();
    final Block fail = ifNode.getFail();

    final Label failLabel  = new Label("if_fail");
    final Label afterLabel = fail == null ? failLabel : new Label("if_done");

    new BranchOptimizer(this, method).execute(test, failLabel, false);

    boolean passTerminal = false;
    boolean failTerminal = false;

    pass.accept(this);
    if (!pass.hasTerminalFlags()) {
        method._goto(afterLabel); //don't fallthru to fail block
    } else {
        passTerminal = pass.isTerminal();
    }

    if (fail != null) {
        method.label(failLabel);
        fail.accept(this);
        failTerminal = fail.isTerminal();
    }

    //if if terminates, put the after label there
    if (!passTerminal || !failTerminal) {
        method.label(afterLabel);
    }

    return false;
}
 
Example 28
/**
 * Split a block into sub methods.
 *
 * @param block Block or function to split.
 *
 * @return new weight for the resulting block.
 */
private Block splitBlock(final Block block, final FunctionNode function) {

    final List<Statement> splits = new ArrayList<>();
    List<Statement> statements = new ArrayList<>();
    long statementsWeight = 0;

    for (final Statement statement : block.getStatements()) {
        final long weight = WeighNodes.weigh(statement, weightCache);

        if (statementsWeight + weight >= SPLIT_THRESHOLD || statement.isTerminal()) {
            if (!statements.isEmpty()) {
                splits.add(createBlockSplitNode(block, function, statements, statementsWeight));
                statements = new ArrayList<>();
                statementsWeight = 0;
            }
        }

        if (statement.isTerminal()) {
            splits.add(statement);
        } else {
            statements.add(statement);
            statementsWeight += weight;
        }
    }

    if (!statements.isEmpty()) {
        splits.add(createBlockSplitNode(block, function, statements, statementsWeight));
    }

    return block.setStatements(lc, splits);
}
 
Example 29
Source Project: TencentKona-8   Source File: AssignSymbols.java    License: GNU General Public License v2.0 5 votes vote down vote up
/**
 * Determines if the symbol has to be a scope symbol. In general terms, it has to be a scope symbol if it can only
 * be reached from the current block by traversing a function node, a split node, or a with node.
 * @param symbol the symbol checked for needing to be a scope symbol
 * @return true if the symbol has to be a scope symbol.
 */
private boolean symbolNeedsToBeScope(final Symbol symbol) {
    if (symbol.isThis() || symbol.isInternal()) {
        return false;
    }

    final FunctionNode func = lc.getCurrentFunction();
    if ( func.allVarsInScope() || (!symbol.isBlockScoped() && func.isProgram())) {
        return true;
    }

    boolean previousWasBlock = false;
    for (final Iterator<LexicalContextNode> it = lc.getAllNodes(); it.hasNext();) {
        final LexicalContextNode node = it.next();
        if (node instanceof FunctionNode || isSplitLiteral(node)) {
            // We reached the function boundary or a splitting boundary without seeing a definition for the symbol.
            // It needs to be in scope.
            return true;
        } else if (node instanceof WithNode) {
            if (previousWasBlock) {
                // We reached a WithNode; the symbol must be scoped. Note that if the WithNode was not immediately
                // preceded by a block, this means we're currently processing its expression, not its body,
                // therefore it doesn't count.
                return true;
            }
            previousWasBlock = false;
        } else if (node instanceof Block) {
            if (((Block)node).getExistingSymbol(symbol.getName()) == symbol) {
                // We reached the block that defines the symbol without reaching either the function boundary, or a
                // WithNode. The symbol need not be scoped.
                return false;
            }
            previousWasBlock = true;
        } else {
            previousWasBlock = false;
        }
    }
    throw new AssertionError();
}
 
Example 30
Source Project: jdk8u_nashorn   Source File: Splitter.java    License: GNU General Public License v2.0 5 votes vote down vote up
@Override
public boolean enterBlock(final Block block) {
    if (block.isCatchBlock()) {
        return false;
    }

    final long weight = WeighNodes.weigh(block, weightCache);

    if (weight < SPLIT_THRESHOLD) {
        weightCache.put(block, weight);
        return false;
    }

    return true;
}