Java 类jdk.nashorn.internal.ir.Symbol 实例源码

项目:openjdk-jdk10    文件:FindScopeDepths.java   
static int findInternalDepth(final LexicalContext lc, final FunctionNode fn, final Block block, final Symbol symbol) {
    final Block bodyBlock = findBodyBlock(lc, fn, block);
    final Iterator<Block> iter = lc.getBlocks(block);
    Block b = iter.next();
    int scopesToStart = 0;
    while (true) {
        if (definedInBlock(b, symbol)) {
            return scopesToStart;
        }
        if (b.needsScope()) {
            scopesToStart++;
        }
        if (b == bodyBlock) {
            break; //don't go past body block, but process it
        }
        b = iter.next();
    }
    return -1;
}
项目:openjdk-jdk10    文件:CodeGenerator.java   
private int getScopeProtoDepth(final Block startingBlock, final Symbol symbol) {
    //walk up the chain from starting block and when we bump into the current function boundary, add the external
    //information.
    final FunctionNode fn   = lc.getCurrentFunction();
    final int externalDepth = compiler.getScriptFunctionData(fn.getId()).getExternalSymbolDepth(symbol.getName());

    //count the number of scopes from this place to the start of the function

    final int internalDepth = FindScopeDepths.findInternalDepth(lc, fn, startingBlock, symbol);
    final int scopesToStart = FindScopeDepths.findScopesToStart(lc, fn, startingBlock);
    int depth = 0;
    if (internalDepth == -1) {
        depth = scopesToStart + externalDepth;
    } else {
        assert internalDepth <= scopesToStart;
        depth = internalDepth;
    }

    return depth;
}
项目:OpenJSharp    文件:AssignSymbols.java   
@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;
}
项目:OpenJSharp    文件:AssignSymbols.java   
/**
 * Marks the current function as one using a scoped symbol. The block defining the symbol will be marked as needing
 * its own scope to hold the variable. If the symbol is defined outside of the current function, it and all
 * functions up to (but not including) the function containing the defining block will be marked as needing parent
 * function scope.
 * @see FunctionNode#needsParentScope()
 */
private void functionUsesScopeSymbol(final Symbol symbol) {
    final String name = symbol.getName();
    for (final Iterator<LexicalContextNode> contextNodeIter = lc.getAllNodes(); contextNodeIter.hasNext(); ) {
        final LexicalContextNode node = contextNodeIter.next();
        if (node instanceof Block) {
            final Block block = (Block)node;
            if (block.getExistingSymbol(name) != null) {
                assert lc.contains(block);
                lc.setBlockNeedsScope(block);
                break;
            }
        } else if (node instanceof FunctionNode) {
            lc.setFlag(node, FunctionNode.USES_ANCESTOR_SCOPE);
        }
    }
}
项目:OpenJSharp    文件:AssignSymbols.java   
@Override
public Node leaveIdentNode(final IdentNode identNode) {
    if (identNode.isPropertyName()) {
        return identNode;
    }

    final Symbol symbol = nameIsUsed(identNode.getName(), identNode);

    if (!identNode.isInitializedHere()) {
        symbol.increaseUseCount();
    }

    IdentNode newIdentNode = identNode.setSymbol(symbol);

    // If a block-scoped var is used before its declaration mark it as dead.
    // We can only statically detect this for local vars, cross-function symbols require runtime checks.
    if (symbol.isBlockScoped() && !symbol.hasBeenDeclared() && !identNode.isDeclaredHere() && isLocal(lc.getCurrentFunction(), symbol)) {
        newIdentNode = newIdentNode.markDead();
    }

    return end(newIdentNode);
}
项目:OpenJSharp    文件:AssignSymbols.java   
private Symbol nameIsUsed(final String name, final IdentNode origin) {
    final Block block = lc.getCurrentBlock();

    Symbol symbol = findSymbol(block, name);

    //If an existing symbol with the name is found, use that otherwise, declare a new one
    if (symbol != null) {
        log.info("Existing symbol = ", symbol);
        if (symbol.isFunctionSelf()) {
            final FunctionNode functionNode = lc.getDefiningFunction(symbol);
            assert functionNode != null;
            assert lc.getFunctionBody(functionNode).getExistingSymbol(CALLEE.symbolName()) != null;
            lc.setFlag(functionNode, FunctionNode.USES_SELF_SYMBOL);
        }

        // if symbol is non-local or we're in a with block, we need to put symbol in scope (if it isn't already)
        maybeForceScope(symbol);
    } else {
        log.info("No symbol exists. Declare as global: ", name);
        symbol = defineSymbol(block, name, origin, IS_GLOBAL | IS_SCOPE);
    }

    functionUsesSymbol(symbol);
    return symbol;
}
项目:openjdk-jdk10    文件:AssignSymbols.java   
@Override
public Node leaveIdentNode(final IdentNode identNode) {
    if (identNode.isPropertyName()) {
        return identNode;
    }

    final Symbol symbol = nameIsUsed(identNode.getName(), identNode);

    if (!identNode.isInitializedHere()) {
        symbol.increaseUseCount();
    }

    IdentNode newIdentNode = identNode.setSymbol(symbol);

    // If a block-scoped var is used before its declaration mark it as dead.
    // We can only statically detect this for local vars, cross-function symbols require runtime checks.
    if (symbol.isBlockScoped() && !symbol.hasBeenDeclared() && !identNode.isDeclaredHere() && isLocal(lc.getCurrentFunction(), symbol)) {
        newIdentNode = newIdentNode.markDead();
    }

    return end(newIdentNode);
}
项目:openjdk-jdk10    文件:LocalVariableTypesCalculator.java   
@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;
}
项目:OpenJSharp    文件:LocalVariableTypesCalculator.java   
private LocalVariableConversion createConversion(final Symbol symbol, final LvarType branchLvarType,
        final Map<Symbol, LvarType> joinLvarTypes, final LocalVariableConversion next) {
    final LvarType targetType = joinLvarTypes.get(symbol);
    assert targetType != null;
    if(targetType == branchLvarType) {
        return next;
    }
    // NOTE: we could naively just use symbolIsUsed(symbol, branchLvarType) here, but that'd be wrong. While
    // technically a conversion will read the value of the symbol with that type, but it will also write it to a new
    // type, and that type might be dead (we can't know yet). For this reason, we don't treat conversion reads as
    // real uses until we know their target type is live. If we didn't do this, and just did a symbolIsUsed here,
    // we'd introduce false live variables which could nevertheless turn into dead ones in a subsequent
    // deoptimization, causing a shift in the list of live locals that'd cause erroneous restoration of
    // continuations (since RewriteException's byteCodeSlots carries an array and not a name-value map).

    symbolIsConverted(symbol, branchLvarType, targetType);
    //symbolIsUsed(symbol, branchLvarType);
    return new LocalVariableConversion(symbol, branchLvarType.type, targetType.type, next);
}
项目:OpenJSharp    文件:LocalVariableTypesCalculator.java   
void calculateTypeLiveness(final Symbol symbol) {
    if(symbol.hasSlotFor(Type.OBJECT)) {
        if(hasConversion(D2O)) {
            symbol.setHasSlotFor(Type.NUMBER);
        }
        if(hasConversion(L2O)) {
            symbol.setHasSlotFor(Type.LONG);
        }
        if(hasConversion(I2O)) {
            symbol.setHasSlotFor(Type.INT);
        }
    }
    if(symbol.hasSlotFor(Type.NUMBER)) {
        if(hasConversion(L2D)) {
            symbol.setHasSlotFor(Type.LONG);
        }
        if(hasConversion(I2D)) {
            symbol.setHasSlotFor(Type.INT);
        }
    }
    if(symbol.hasSlotFor(Type.LONG)) {
        if(hasConversion(I2L)) {
            symbol.setHasSlotFor(Type.INT);
        }
    }
}
项目:OpenJSharp    文件:LocalVariableTypesCalculator.java   
@Override
public boolean enterTernaryNode(final TernaryNode ternaryNode) {
    final Expression test = ternaryNode.getTest();
    final Expression trueExpr = ternaryNode.getTrueExpression();
    final Expression falseExpr = ternaryNode.getFalseExpression();

    test.accept(this);

    final Map<Symbol, LvarType> testExitLvarTypes = localVariableTypes;
    if(!isAlwaysFalse(test)) {
        trueExpr.accept(this);
    }
    final Map<Symbol, LvarType> trueExitLvarTypes = localVariableTypes;
    localVariableTypes = testExitLvarTypes;
    if(!isAlwaysTrue(test)) {
        falseExpr.accept(this);
    }
    final Map<Symbol, LvarType> falseExitLvarTypes = localVariableTypes;
    localVariableTypes = getUnionTypes(trueExitLvarTypes, falseExitLvarTypes);
    setConversion((JoinPredecessor)trueExpr, trueExitLvarTypes, localVariableTypes);
    setConversion((JoinPredecessor)falseExpr, falseExitLvarTypes, localVariableTypes);
    return false;
}
项目:openjdk-jdk10    文件:CodeGenerator.java   
private void loadFastScopeProto(final Symbol symbol, final boolean swap) {
    final int depth = getScopeProtoDepth(lc.getCurrentBlock(), symbol);
    assert depth != -1 : "Couldn't find scope depth for symbol " + symbol.getName() + " in " + lc.getCurrentFunction();
    if (depth > 0) {
        if (swap) {
            method.swap();
        }
        if (depth > 1) {
            method.load(depth);
            method.invoke(ScriptObject.GET_PROTO_DEPTH);
        } else {
            method.invoke(ScriptObject.GET_PROTO);
        }
        if (swap) {
            method.swap();
        }
    }
}
项目:openjdk-jdk10    文件:LocalVariableTypesCalculator.java   
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;
}
项目:OpenJSharp    文件:CodeGenerator.java   
private int getScopeProtoDepth(final Block startingBlock, final Symbol symbol) {
    //walk up the chain from starting block and when we bump into the current function boundary, add the external
    //information.
    final FunctionNode fn   = lc.getCurrentFunction();
    final int externalDepth = compiler.getScriptFunctionData(fn.getId()).getExternalSymbolDepth(symbol.getName());

    //count the number of scopes from this place to the start of the function

    final int internalDepth = FindScopeDepths.findInternalDepth(lc, fn, startingBlock, symbol);
    final int scopesToStart = FindScopeDepths.findScopesToStart(lc, fn, startingBlock);
    int depth = 0;
    if (internalDepth == -1) {
        depth = scopesToStart + externalDepth;
    } else {
        assert internalDepth <= scopesToStart;
        depth = internalDepth;
    }

    return depth;
}
项目:openjdk-jdk10    文件:LocalVariableTypesCalculator.java   
private LocalVariableConversion createConversion(final Symbol symbol, final LvarType branchLvarType,
        final Map<Symbol, LvarType> joinLvarTypes, final LocalVariableConversion next) {
    if (invalidatedSymbols.contains(symbol)) {
        return next;
    }
    final LvarType targetType = joinLvarTypes.get(symbol);
    assert targetType != null;
    if(targetType == branchLvarType) {
        return next;
    }
    // NOTE: we could naively just use symbolIsUsed(symbol, branchLvarType) here, but that'd be wrong. While
    // technically a conversion will read the value of the symbol with that type, but it will also write it to a new
    // type, and that type might be dead (we can't know yet). For this reason, we don't treat conversion reads as
    // real uses until we know their target type is live. If we didn't do this, and just did a symbolIsUsed here,
    // we'd introduce false live variables which could nevertheless turn into dead ones in a subsequent
    // deoptimization, causing a shift in the list of live locals that'd cause erroneous restoration of
    // continuations (since RewriteException's byteCodeSlots carries an array and not a name-value map).

    symbolIsConverted(symbol, branchLvarType, targetType);
    return new LocalVariableConversion(symbol, branchLvarType.type, targetType.type, next);
}
项目:openjdk-jdk10    文件:AssignSymbols.java   
/**
 * Checks if various symbols that were provisionally marked as needing a slot ended up unused, and marks them as not
 * needing a slot after all.
 * @param functionNode the function node
 * @return the passed in node, for easy chaining
 */
private static FunctionNode removeUnusedSlots(final FunctionNode functionNode) {
    if (!functionNode.needsCallee()) {
        functionNode.compilerConstant(CALLEE).setNeedsSlot(false);
    }
    if (!(functionNode.hasScopeBlock() || functionNode.needsParentScope())) {
        functionNode.compilerConstant(SCOPE).setNeedsSlot(false);
    }
    // Named function expressions that end up not referencing themselves won't need a local slot for the self symbol.
    if(functionNode.isNamedFunctionExpression() && !functionNode.usesSelfSymbol()) {
        final Symbol selfSymbol = functionNode.getBody().getExistingSymbol(functionNode.getIdent().getName());
        if(selfSymbol != null && selfSymbol.isFunctionSelf()) {
            selfSymbol.setNeedsSlot(false);
            selfSymbol.clearFlag(Symbol.IS_VAR);
        }
    }
    return functionNode;
}
项目:OpenJSharp    文件:MethodEmitter.java   
/**
 * Pushes the value of the symbol to the stack with the specified type. No type conversion is being performed, and
 * the type is only being used if the symbol addresses a local variable slot. The value of the symbol is loaded if
 * it addresses a local variable slot, or it is a parameter (in which case it can also be loaded from a vararg array
 * or the arguments object). If it is neither, the operation is a no-op.
 *
 * @param symbol the symbol addressing the value being loaded
 * @param type the presumed type of the value when it is loaded from a local variable slot
 * @return the method emitter
 */
MethodEmitter load(final Symbol symbol, final Type type) {
    assert symbol != null;
    if (symbol.hasSlot()) {
        final int slot = symbol.getSlot(type);
        debug("load symbol", symbol.getName(), " slot=", slot, "type=", type);
        load(type, slot);
       // _try(new Label("dummy"), new Label("dummy2"), recovery);
       // method.visitTryCatchBlock(new Label(), arg1, arg2, arg3);
    } else if (symbol.isParam()) {
        assert functionNode.isVarArg() : "Non-vararg functions have slotted parameters";
        final int index = symbol.getFieldIndex();
        if (functionNode.needsArguments()) {
            // ScriptObject.getArgument(int) on arguments
            debug("load symbol", symbol.getName(), " arguments index=", index);
            loadCompilerConstant(ARGUMENTS);
            load(index);
            ScriptObject.GET_ARGUMENT.invoke(this);
        } else {
            // array load from __varargs__
            debug("load symbol", symbol.getName(), " array index=", index);
            loadCompilerConstant(VARARGS);
            load(symbol.getFieldIndex());
            arrayload();
        }
    }
    return this;
}
项目:OpenJSharp    文件:MethodEmitter.java   
void storeCompilerConstant(final CompilerConstants cc, final Type type) {
    final Symbol symbol = getCompilerConstantSymbol(cc);
    if(!symbol.hasSlot()) {
        return;
    }
    debug("store compiler constant ", symbol);
    store(symbol, type != null ? type : getCompilerConstantType(cc));
}
项目:OpenJSharp    文件:MethodEmitter.java   
void closeLocalVariable(final Symbol symbol, final Label label) {
    final LocalVariableDef def = localVariableDefs.get(symbol);
    if(def != null) {
        endLocalValueDef(symbol, def, label.getLabel());
    }
    if(isReachable()) {
        markDeadLocalVariable(symbol);
    }
}
项目:OpenJSharp    文件:MethodEmitter.java   
private void endLocalValueDef(final Symbol symbol, final LocalVariableDef def, final jdk.internal.org.objectweb.asm.Label label) {
    String name = symbol.getName();
    if (name.equals(THIS.symbolName())) {
        name = THIS_DEBUGGER.symbolName();
    }
    method.visitLocalVariable(name, def.type.getDescriptor(), null, def.label, label, symbol.getSlot(def.type));
}
项目:OpenJSharp    文件:SharedScopeCall.java   
/**
 * Constructor.
 *
 * @param symbol the symbol
 * @param valueType the type of the value
 * @param returnType the return type
 * @param paramTypes the function parameter types
 * @param flags the callsite flags
 */
SharedScopeCall(final Symbol symbol, final Type valueType, final Type returnType, final Type[] paramTypes, final int flags) {
    this.symbol = symbol;
    this.valueType = valueType;
    this.returnType = returnType;
    this.paramTypes = paramTypes;
    assert (flags & CALLSITE_OPTIMISTIC) == 0;
    this.flags = flags;
    // If paramTypes is not null this is a call, otherwise it's just a get.
    this.isCall = paramTypes != null;
}
项目:OpenJSharp    文件:AssignSymbols.java   
/**
 * Define symbols for all variable declarations at the top of the function scope. This way we can get around
 * problems like
 *
 * while (true) {
 *   break;
 *   if (true) {
 *     var s;
 *   }
 * }
 *
 * to an arbitrary nesting depth.
 *
 * see NASHORN-73
 *
 * @param functionNode the FunctionNode we are entering
 * @param body the body of the FunctionNode we are entering
 */
private void acceptDeclarations(final FunctionNode functionNode, final Block body) {
    // This visitor will assign symbol to all declared variables.
    body.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
        @Override
        protected boolean enterDefault(final Node node) {
            // Don't bother visiting expressions; var is a statement, it can't be inside an expression.
            // This will also prevent visiting nested functions (as FunctionNode is an expression).
            return !(node instanceof Expression);
        }

        @Override
        public Node leaveVarNode(final VarNode varNode) {
            final IdentNode ident  = varNode.getName();
            final boolean blockScoped = varNode.isBlockScoped();
            if (blockScoped && lc.inUnprotectedSwitchContext()) {
                throwUnprotectedSwitchError(varNode);
            }
            final Block block = blockScoped ? lc.getCurrentBlock() : body;
            final Symbol symbol = defineSymbol(block, ident.getName(), ident, varNode.getSymbolFlags());
            if (varNode.isFunctionDeclaration()) {
                symbol.setIsFunctionDeclaration();
            }
            return varNode.setName(ident.setSymbol(symbol));
        }
    });
}
项目:OpenJSharp    文件:AssignSymbols.java   
private <T extends Node> T end(final T node, final boolean printNode) {
    if (debug) {
        final StringBuilder sb = new StringBuilder();

        sb.append("[LEAVE ").
            append(name(node)).
            append("] ").
            append(printNode ? node.toString() : "").
            append(" in '").
            append(lc.getCurrentFunction().getName()).
            append('\'');

        if (node instanceof IdentNode) {
            final Symbol symbol = ((IdentNode)node).getSymbol();
            if (symbol == null) {
                sb.append(" <NO SYMBOL>");
            } else {
                sb.append(" <symbol=").append(symbol).append('>');
            }
        }

        log.unindent();
        log.info(sb);
    }

    return node;
}
项目:openjdk-jdk10    文件:LocalVariableTypesCalculator.java   
private void symbolIsConverted(final Symbol symbol, final LvarType from, final LvarType to) {
    SymbolConversions conversions = symbolConversions.get(symbol);
    if(conversions == null) {
        conversions = new SymbolConversions();
        symbolConversions.put(symbol, conversions);
    }
    conversions.recordConversion(from, to);
}
项目:OpenJSharp    文件:AssignSymbols.java   
/**
 * 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;
}
项目:OpenJSharp    文件:AssignSymbols.java   
/**
 * Declares that the current function is using the symbol.
 * @param symbol the symbol used by the current function.
 */
private void functionUsesSymbol(final Symbol symbol) {
    assert symbol != null;
    if (symbol.isScope()) {
        if (symbol.isGlobal()) {
            functionUsesGlobalSymbol();
        } else {
            functionUsesScopeSymbol(symbol);
        }
    } else {
        assert !symbol.isGlobal(); // Every global is also scope
    }
}
项目:OpenJSharp    文件:AssignSymbols.java   
private void checkConstAssignment(final IdentNode ident) {
    // Check for reassignment of constant
    final Symbol symbol = ident.getSymbol();
    if (symbol.isConst()) {
        throwParserException(ECMAErrors.getMessage("syntax.error.assign.constant", symbol.getName()), ident);
    }
}
项目:OpenJSharp    文件:AssignSymbols.java   
private Node leaveASSIGN(final BinaryNode binaryNode) {
    // If we're assigning a property of the this object ("this.foo = ..."), record it.
    final Expression lhs = binaryNode.lhs();
    if (lhs instanceof AccessNode) {
        final AccessNode accessNode = (AccessNode) lhs;
        final Expression base = accessNode.getBase();
        if (base instanceof IdentNode) {
            final Symbol symbol = ((IdentNode)base).getSymbol();
            if(symbol.isThis()) {
                thisProperties.peek().add(accessNode.getProperty());
            }
        }
    }
    return binaryNode;
}
项目:OpenJSharp    文件:AssignSymbols.java   
/**
 * 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 || isSplitArray(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();
}
项目:OpenJSharp    文件:FindScopeDepths.java   
private static boolean definedInBlock(final Block block, final Symbol symbol) {
    if (symbol.isGlobal()) {
        if (block.isGlobalScope()) {
            return true;
        }
        //globals cannot be defined anywhere else
        return false;
    }
    return block.getExistingSymbol(symbol.getName()) == symbol;
}
项目:OpenJSharp    文件:FindScopeDepths.java   
private void addExternalSymbol(final FunctionNode functionNode, final Symbol symbol, final int depthAtStart) {
    final int fnId = functionNode.getId();
    Map<String, Integer> depths = externalSymbolDepths.get(fnId);
    if (depths == null) {
        depths = new HashMap<>();
        externalSymbolDepths.put(fnId, depths);
    }
    depths.put(symbol.getName(), depthAtStart);
}
项目:openjdk-jdk10    文件:LocalVariableTypesCalculator.java   
/**
 * Marks a local variable as having a specific type from this point onward. Invoked by stores to local variables.
 * @param symbol the symbol representing the variable
 * @param type the type
 */
private void setType(final Symbol symbol, final LvarType type) {
    if(getLocalVariableTypeOrNull(symbol) == type) {
        return;
    }
    assert symbol.hasSlot();
    assert !symbol.isGlobal();
    cloneOrNewLocalVariableTypes();
    localVariableTypes.put(symbol, type);
}
项目:openjdk-jdk10    文件:CompilationPhase.java   
@Override
FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
    // It's not necessary to guard the marking of symbols as locals with this "if" condition for
    // correctness, it's just an optimization -- runtime type calculation is not used when the compilation
    // is not an on-demand optimistic compilation, so we can skip locals marking then.
    if (compiler.useOptimisticTypes() && compiler.isOnDemandCompilation()) {
        fn.getBody().accept(new SimpleNodeVisitor() {
            @Override
            public boolean enterFunctionNode(final FunctionNode functionNode) {
                // OTOH, we must not declare symbols from nested functions to be locals. As we're doing on-demand
                // compilation, and we're skipping parsing the function bodies for nested functions, this
                // basically only means their parameters. It'd be enough to mistakenly declare to be a local a
                // symbol in the outer function named the same as one of the parameters, though.
                return false;
            };
            @Override
            public boolean enterBlock(final Block block) {
                for (final Symbol symbol: block.getSymbols()) {
                    if (!symbol.isScope()) {
                        compiler.declareLocalSymbol(symbol.getName());
                    }
                }
                return true;
            };
        });
    }
    return fn;
}
项目:OpenJSharp    文件:CodeGeneratorLexicalContext.java   
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;
}
项目:openjdk-jdk10    文件:LocalVariableTypesCalculator.java   
@Override
public boolean enterIdentNode(final IdentNode identNode) {
    final Symbol symbol = identNode.getSymbol();
    if(symbol.isBytecodeLocal()) {
        symbolIsUsed(symbol);
        final LvarType type = getLocalVariableType(symbol);
        setIdentifierLvarType(identNode, type);
        typeStack.push(type);
    } else {
        pushExpressionType(identNode);
    }
    return false;
}
项目:OpenJSharp    文件:LocalVariableTypesCalculator.java   
private void symbolIsConverted(final Symbol symbol, final LvarType from, final LvarType to) {
    SymbolConversions conversions = symbolConversions.get(symbol);
    if(conversions == null) {
        conversions = new SymbolConversions();
        symbolConversions.put(symbol, conversions);
    }
    conversions.recordConversion(from, to);
}
项目:OpenJSharp    文件:LocalVariableTypesCalculator.java   
@Override
public boolean enterBlock(final Block block) {
    for(final Symbol symbol: block.getSymbols()) {
        if(symbol.isBytecodeLocal() && getLocalVariableTypeOrNull(symbol) == null) {
            setType(symbol, LvarType.UNDEFINED);
        }
    }
    return true;
}
项目:OpenJSharp    文件:LocalVariableTypesCalculator.java   
private void enterDoWhileLoop(final WhileNode loopNode) {
    final JoinPredecessorExpression test = loopNode.getTest();
    final Block body = loopNode.getBody();
    final Label continueLabel = loopNode.getContinueLabel();
    final Label breakLabel = loopNode.getBreakLabel();
    final Map<Symbol, LvarType> beforeLoopTypes = localVariableTypes;
    final Label repeatLabel = new Label("");
    for(;;) {
        jumpToLabel(loopNode, repeatLabel, beforeLoopTypes);
        final Map<Symbol, LvarType> beforeRepeatTypes = localVariableTypes;
        body.accept(this);
        if(reachable) {
            jumpToLabel(body, continueLabel);
        }
        joinOnLabel(continueLabel);
        if(!reachable) {
            break;
        }
        test.accept(this);
        jumpToLabel(test, breakLabel);
        if(isAlwaysFalse(test)) {
            break;
        }
        jumpToLabel(test, repeatLabel);
        joinOnLabel(repeatLabel);
        if(localVariableTypes.equals(beforeRepeatTypes)) {
            break;
        }
        resetJoinPoint(continueLabel);
        resetJoinPoint(breakLabel);
        resetJoinPoint(repeatLabel);
    }

    if(isAlwaysTrue(test)) {
        doesNotContinueSequentially();
    }

    leaveBreakable(loopNode);
}
项目:OpenJSharp    文件:LocalVariableTypesCalculator.java   
@Override
public boolean enterIdentNode(final IdentNode identNode) {
    final Symbol symbol = identNode.getSymbol();
    if(symbol.isBytecodeLocal()) {
        symbolIsUsed(symbol);
        setIdentifierLvarType(identNode, getLocalVariableType(symbol));
    }
    return false;
}
项目:openjdk-jdk10    文件:LocalVariableTypesCalculator.java   
@Override
public boolean enterTernaryNode(final TernaryNode ternaryNode) {
    final Expression test = ternaryNode.getTest();
    final Expression trueExpr = ternaryNode.getTrueExpression();
    final Expression falseExpr = ternaryNode.getFalseExpression();

    visitExpression(test);

    final Map<Symbol, LvarType> testExitLvarTypes = localVariableTypes;
    final LvarType trueType;
    if(!isAlwaysFalse(test)) {
        trueType = visitExpression(trueExpr);
    } else {
        trueType = null;
    }
    final Map<Symbol, LvarType> trueExitLvarTypes = localVariableTypes;
    localVariableTypes = testExitLvarTypes;
    final LvarType falseType;
    if(!isAlwaysTrue(test)) {
        falseType = visitExpression(falseExpr);
    } else {
        falseType = null;
    }
    final Map<Symbol, LvarType> falseExitLvarTypes = localVariableTypes;
    localVariableTypes = getUnionTypes(trueExitLvarTypes, falseExitLvarTypes);
    setConversion((JoinPredecessor)trueExpr, trueExitLvarTypes, localVariableTypes);
    setConversion((JoinPredecessor)falseExpr, falseExitLvarTypes, localVariableTypes);

    typeStack.push(trueType != null ? falseType != null ? widestLvarType(trueType, falseType) : trueType : assertNotNull(falseType));
    return false;
}