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

项目:openjdk-jdk10    文件:CodeGenerator.java   
/**
 * Debug code used to print symbols
 *
 * @param block the block we are in
 * @param function the function we are in
 * @param ident identifier for block or function where applicable
 */
private void printSymbols(final Block block, final FunctionNode function, final String ident) {
    if (compiler.getScriptEnvironment()._print_symbols || function.getDebugFlag(FunctionNode.DEBUG_PRINT_SYMBOLS)) {
        final PrintWriter out = compiler.getScriptEnvironment().getErr();
        out.println("[BLOCK in '" + ident + "']");
        if (!block.printSymbols(out)) {
            out.println("<no symbols>");
        }
        out.println();
    }
}
项目:openjdk-jdk10    文件:FindScopeDepths.java   
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;
}
项目:openjdk-jdk10    文件:AssignSymbols.java   
/**
 * This has to run before fix assignment types, store any type specializations for
 * parameters, then turn them into objects for the generic version of this method.
 *
 * @param functionNode functionNode
 */
private FunctionNode finalizeParameters(final FunctionNode functionNode) {
    final List<IdentNode> newParams = new ArrayList<>();
    final boolean isVarArg = functionNode.isVarArg();

    final Block body = functionNode.getBody();
    for (final IdentNode param : functionNode.getParameters()) {
        final Symbol paramSymbol = body.getExistingSymbol(param.getName());
        assert paramSymbol != null;
        assert paramSymbol.isParam() : paramSymbol + " " + paramSymbol.getFlags();
        newParams.add(param.setSymbol(paramSymbol));

        // parameters should not be slots for a function that uses variable arity signature
        if (isVarArg) {
            paramSymbol.setNeedsSlot(false);
        }
    }

    return functionNode.setParameters(lc, newParams);
}
项目:OpenJSharp    文件:Parser.java   
private static void markEval(final LexicalContext lc) {
    final Iterator<FunctionNode> iter = lc.getFunctions();
    boolean flaggedCurrentFn = false;
    while (iter.hasNext()) {
        final FunctionNode fn = iter.next();
        if (!flaggedCurrentFn) {
            lc.setFlag(fn, FunctionNode.HAS_EVAL);
            flaggedCurrentFn = true;
        } else {
            lc.setFlag(fn, FunctionNode.HAS_NESTED_EVAL);
        }
        // NOTE: it is crucial to mark the body of the outer function as needing scope even when we skip
        // parsing a nested function. functionBody() contains code to compensate for the lack of invoking
        // this method when the parser skips a nested function.
        lc.setBlockNeedsScope(lc.getFunctionBody(fn));
    }
}
项目:openjdk-jdk10    文件:FindScopeDepths.java   
@Override
public boolean enterFunctionNode(final FunctionNode functionNode) {
    if (compiler.isOnDemandCompilation()) {
        return true;
    }

    if (isDynamicScopeBoundary(functionNode)) {
        increaseDynamicScopeCount(functionNode);
    }

    final int fnId = functionNode.getId();
    Map<Integer, RecompilableScriptFunctionData> nestedFunctions = fnIdToNestedFunctions.get(fnId);
    if (nestedFunctions == null) {
        nestedFunctions = new HashMap<>();
        fnIdToNestedFunctions.put(fnId, nestedFunctions);
    }

    return true;
}
项目:OpenJSharp    文件:CodeGenerator.java   
private int fixScopeSlot(final FunctionNode functionNode, final int extraSlot) {
    // TODO hack to move the scope to the expected slot (needed because split methods reuse the same slots as the root method)
    final int actualScopeSlot = functionNode.compilerConstant(SCOPE).getSlot(SCOPE_TYPE);
    final int defaultScopeSlot = SCOPE.slot();
    int newExtraSlot = extraSlot;
    if (actualScopeSlot != defaultScopeSlot) {
        if (actualScopeSlot == extraSlot) {
            newExtraSlot = extraSlot + 1;
            method.defineBlockLocalVariable(newExtraSlot, newExtraSlot + 1);
            method.load(Type.OBJECT, extraSlot);
            method.storeHidden(Type.OBJECT, newExtraSlot);
        } else {
            method.defineBlockLocalVariable(actualScopeSlot, actualScopeSlot + 1);
        }
        method.load(SCOPE_TYPE, defaultScopeSlot);
        method.storeCompilerConstant(SCOPE);
    }
    return newExtraSlot;
}
项目:openjdk-jdk10    文件:RecompilableScriptFunctionData.java   
private FunctionNode extractFunctionFromScript(final FunctionNode script) {
    final Set<FunctionNode> fns = new HashSet<>();
    script.getBody().accept(new SimpleNodeVisitor() {
        @Override
        public boolean enterFunctionNode(final FunctionNode fn) {
            fns.add(fn);
            return false;
        }
    });
    assert fns.size() == 1 : "got back more than one method in recompilation";
    final FunctionNode f = fns.iterator().next();
    assert f.getId() == functionNodeId;
    if (!getFunctionFlag(FunctionNode.IS_DECLARED) && f.isDeclared()) {
        return f.clearFlag(null, FunctionNode.IS_DECLARED);
    }
    return f;
}
项目:OpenJSharp    文件:RecompilableScriptFunctionData.java   
Compiler getCompiler(final FunctionNode functionNode, final MethodType actualCallSiteType,
        final ScriptObject runtimeScope, final Map<Integer, Type> invalidatedProgramPoints,
        final int[] continuationEntryPoints) {
    final TypeMap typeMap = typeMap(actualCallSiteType);
    final Type[] paramTypes = typeMap == null ? null : typeMap.getParameterTypes(functionNodeId);
    final Object typeInformationFile = OptimisticTypesPersistence.getLocationDescriptor(source, functionNodeId, paramTypes);
    final Context context = Context.getContextTrusted();
    return new Compiler(
            context,
            context.getEnv(),
            getInstallerForNewCode(),
            functionNode.getSource(),  // source
            context.getErrorManager(),
            isStrict() | functionNode.isStrict(), // is strict
            true,       // is on demand
            this,       // compiledFunction, i.e. this RecompilableScriptFunctionData
            typeMap,    // type map
            getEffectiveInvalidatedProgramPoints(invalidatedProgramPoints, typeInformationFile), // invalidated program points
            typeInformationFile,
            continuationEntryPoints, // continuation entry points
            runtimeScope); // runtime scope
}
项目:openjdk-jdk10    文件:CompiledFunction.java   
private MethodHandle restOfHandle(final OptimismInfo info, final FunctionNode restOfFunction, final boolean canBeDeoptimized) {
    assert info != null;
    assert restOfFunction.getCompileUnit().getUnitClassName().contains("restOf");
    final MethodHandle restOf =
            changeReturnType(
                    info.data.lookupCodeMethod(
                            restOfFunction.getCompileUnit().getCode(),
                            MH.type(restOfFunction.getReturnType().getTypeClass(),
                                    RewriteException.class)),
                    Object.class);

    if (!canBeDeoptimized) {
        return restOf;
    }

    // If rest-of is itself optimistic, we must make sure that we can repeat a deoptimization if it, too hits an exception.
    return MH.catchException(restOf, RewriteException.class, createRewriteExceptionHandler());

}
项目:openjdk-jdk10    文件:ApplySpecialization.java   
private void pushExplodedArgs(final FunctionNode functionNode) {
    int start = 0;

    final MethodType actualCallSiteType = compiler.getCallSiteType(functionNode);
    if (actualCallSiteType == null) {
        throw new TransformFailedException(lc.getCurrentFunction(), "No callsite type");
    }
    assert actualCallSiteType.parameterType(actualCallSiteType.parameterCount() - 1) != Object[].class : "error vararg callsite passed to apply2call " + functionNode.getName() + " " + actualCallSiteType;

    final TypeMap ptm = compiler.getTypeMap();
    if (ptm.needsCallee()) {
        start++;
    }

    start++; // we always use this

    assert functionNode.getNumOfParams() == 0 : "apply2call on function with named paramaters!";
    final List<IdentNode> newParams = new ArrayList<>();
    final long to = actualCallSiteType.parameterCount() - start;
    for (int i = 0; i < to; i++) {
        newParams.add(new IdentNode(functionNode.getToken(), functionNode.getFinish(), EXPLODED_ARGUMENT_PREFIX.symbolName() + (i)));
    }

    callSiteTypes.push(actualCallSiteType);
    explodedArguments.push(newParams);
}
项目:openjdk-jdk10    文件:ApplySpecialization.java   
private boolean hasApplies(final FunctionNode functionNode) {
    try {
        functionNode.accept(new SimpleNodeVisitor() {
            @Override
            public boolean enterFunctionNode(final FunctionNode fn) {
                return fn == functionNode;
            }

            @Override
            public boolean enterCallNode(final CallNode callNode) {
                if (isApply(callNode)) {
                    throw HAS_APPLIES;
                }
                return true;
            }
        });
    } catch (final AppliesFoundException e) {
        return true;
    }

    log.fine("There are no applies in ", DebugLogger.quote(functionNode.getName()), " - nothing to do.");
    return false; // no applies
}
项目:openjdk-jdk10    文件:CompilationPhase.java   
@Override
FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
    final CompileUnit  outermostCompileUnit = compiler.addCompileUnit(0L);

    FunctionNode newFunctionNode;

    //ensure elementTypes, postsets and presets exist for splitter and arraynodes
    newFunctionNode = transformFunction(fn, new SimpleNodeVisitor() {
        @Override
        public LiteralNode<?> leaveLiteralNode(final LiteralNode<?> literalNode) {
            return literalNode.initialize(lc);
        }
    });

    newFunctionNode = new Splitter(compiler, newFunctionNode, outermostCompileUnit).split(newFunctionNode, true);
    newFunctionNode = transformFunction(newFunctionNode, new SplitIntoFunctions(compiler));
    assert newFunctionNode.getCompileUnit() == outermostCompileUnit : "fn=" + fn.getName() + ", fn.compileUnit (" + newFunctionNode.getCompileUnit() + ") != " + outermostCompileUnit;
    assert newFunctionNode.isStrict() == compiler.isStrict() : "functionNode.isStrict() != compiler.isStrict() for " + quote(newFunctionNode.getName());

    return newFunctionNode;
}
项目:openjdk-jdk10    文件:RecompilableScriptFunctionData.java   
private FunctionNode getCachedAst() {
    final Object lCachedAst = cachedAst;
    // Are we softly caching the AST?
    if (lCachedAst instanceof Reference<?>) {
        final FunctionNode fn = (FunctionNode)((Reference<?>)lCachedAst).get();
        if (fn != null) {
            // Yes we are - this is fast
            return cloneSymbols(fn);
        }
    // Are we strongly caching a serialized AST (for split functions only)?
    } else if (lCachedAst instanceof SerializedAst) {
        final SerializedAst serializedAst = (SerializedAst)lCachedAst;
        // Even so, are we also softly caching the AST?
        final FunctionNode cachedFn = serializedAst.cachedAst == null ? null : serializedAst.cachedAst.get();
        if (cachedFn != null) {
            // Yes we are - this is fast
            return cloneSymbols(cachedFn);
        }
        final FunctionNode deserializedFn = deserialize(serializedAst.serializedAst);
        // Softly cache after deserialization, maybe next time we won't need to deserialize
        serializedAst.cachedAst = new SoftReference<>(deserializedFn);
        return deserializedFn;
    }
    // No cached representation; return null for reparsing
    return null;
}
项目:OpenJSharp    文件:AssignSymbols.java   
/**
 * This has to run before fix assignment types, store any type specializations for
 * parameters, then turn them into objects for the generic version of this method.
 *
 * @param functionNode functionNode
 */
private FunctionNode finalizeParameters(final FunctionNode functionNode) {
    final List<IdentNode> newParams = new ArrayList<>();
    final boolean isVarArg = functionNode.isVarArg();

    final Block body = functionNode.getBody();
    for (final IdentNode param : functionNode.getParameters()) {
        final Symbol paramSymbol = body.getExistingSymbol(param.getName());
        assert paramSymbol != null;
        assert paramSymbol.isParam() : paramSymbol + " " + paramSymbol.getFlags();
        newParams.add(param.setSymbol(paramSymbol));

        // parameters should not be slots for a function that uses variable arity signature
        if (isVarArg) {
            paramSymbol.setNeedsSlot(false);
        }
    }

    return functionNode.setParameters(lc, newParams);
}
项目:openjdk-jdk10    文件:CompilationPhase.java   
@Override
FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
    final FunctionNode newFunctionNode = transformFunction(fn, new LocalVariableTypesCalculator(compiler));
    final ScriptEnvironment senv = compiler.getScriptEnvironment();
    final PrintWriter       err  = senv.getErr();

    //TODO separate phase for the debug printouts for abstraction and clarity
    if (senv._print_lower_ast || fn.getDebugFlag(FunctionNode.DEBUG_PRINT_LOWER_AST)) {
        err.println("Lower AST for: " + quote(newFunctionNode.getName()));
        err.println(new ASTWriter(newFunctionNode));
    }

    if (senv._print_lower_parse || fn.getDebugFlag(FunctionNode.DEBUG_PRINT_LOWER_PARSE)) {
        err.println("Lower AST for: " + quote(newFunctionNode.getName()));
        err.println(new PrintVisitor(newFunctionNode));
    }

    return newFunctionNode;
}
项目:openjdk-jdk10    文件:Parser.java   
private void checkPropertyRedefinition(final PropertyNode property, final Expression value, final FunctionNode getter, final FunctionNode setter, final Expression prevValue, final FunctionNode prevGetter, final FunctionNode prevSetter) {
    // ECMA 11.1.5 strict mode restrictions
    if (isStrictMode && value != null && prevValue != null) {
        throw error(AbstractParser.message("property.redefinition", property.getKeyName()), property.getToken());
    }

    final boolean isPrevAccessor = prevGetter != null || prevSetter != null;
    final boolean isAccessor     = getter != null     || setter != null;

    // data property redefined as accessor property
    if (prevValue != null && isAccessor) {
        throw error(AbstractParser.message("property.redefinition", property.getKeyName()), property.getToken());
    }

    // accessor property redefined as data
    if (isPrevAccessor && value != null) {
        throw error(AbstractParser.message("property.redefinition", property.getKeyName()), property.getToken());
    }

    if (isAccessor && isPrevAccessor) {
        if (getter != null && prevGetter != null ||
                setter != null && prevSetter != null) {
            throw error(AbstractParser.message("property.redefinition", property.getKeyName()), property.getToken());
        }
    }
}
项目:openjdk-jdk10    文件:IRTranslator.java   
private List<? extends ExpressionTree> translateParameters(final FunctionNode func) {
    final Map<IdentNode, Expression> paramExprs = func.getParameterExpressions();
    if (paramExprs != null) {
        final List<IdentNode> params = func.getParameters();
        final List<ExpressionTreeImpl> exprTrees = new ArrayList<>(params.size());
        for (final IdentNode ident : params) {
            final Expression expr = paramExprs.containsKey(ident)? paramExprs.get(ident) : ident;
            curExpr = null;
            expr.accept(this);
            assert curExpr != null;
            exprTrees.add(curExpr);
        }
        return exprTrees;
    } else {
        return translateExprs(func.getParameters());
    }
}
项目:OpenJSharp    文件:Splitter.java   
private static List<FunctionNode> directChildren(final FunctionNode functionNode) {
    final List<FunctionNode> dc = new ArrayList<>();
    functionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
        @Override
        public boolean enterFunctionNode(final FunctionNode child) {
            if (child == functionNode) {
                return true;
            }
            if (lc.getParentFunction(child) == functionNode) {
                dc.add(child);
            }
            return false;
        }
    });
    return dc;
}
项目:openjdk-jdk10    文件:Lower.java   
@Override
public Node leaveExpressionStatement(final ExpressionStatement expressionStatement) {
    final Expression expr = expressionStatement.getExpression();
    ExpressionStatement node = expressionStatement;

    final FunctionNode currentFunction = lc.getCurrentFunction();

    if (currentFunction.isProgram()) {
        if (!isInternalExpression(expr) && !isEvalResultAssignment(expr)) {
            node = expressionStatement.setExpression(
                new BinaryNode(
                    Token.recast(
                        expressionStatement.getToken(),
                        TokenType.ASSIGN),
                    compilerConstant(RETURN),
                expr));
        }
    }

    if (es6 && expressionStatement.destructuringDeclarationType() != null) {
        throwNotImplementedYet("es6.destructuring", expressionStatement);
    }

    return addStatement(node);
}
项目:OpenJSharp    文件: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;
}
项目:OpenJSharp    文件:FindScopeDepths.java   
@Override
public boolean enterFunctionNode(final FunctionNode functionNode) {
    if (compiler.isOnDemandCompilation()) {
        return true;
    }

    if (isDynamicScopeBoundary(functionNode)) {
        increaseDynamicScopeCount(functionNode);
    }

    final int fnId = functionNode.getId();
    Map<Integer, RecompilableScriptFunctionData> nestedFunctions = fnIdToNestedFunctions.get(fnId);
    if (nestedFunctions == null) {
        nestedFunctions = new HashMap<>();
        fnIdToNestedFunctions.put(fnId, nestedFunctions);
    }

    return true;
}
项目:openjdk-jdk10    文件:Compiler.java   
/**
 * Persist current compilation with the given {@code cacheKey}.
 * @param cacheKey cache key
 * @param functionNode function node
 */
public void persistClassInfo(final String cacheKey, final FunctionNode functionNode) {
    if (cacheKey != null && env._persistent_cache) {
        // If this is an on-demand compilation create a function initializer for the function being compiled.
        // Otherwise use function initializer map generated by codegen.
        final Map<Integer, FunctionInitializer> initializers = new HashMap<>();
        if (isOnDemandCompilation()) {
            initializers.put(functionNode.getId(), new FunctionInitializer(functionNode, getInvalidatedProgramPoints()));
        } else {
            for (final CompileUnit compileUnit : getCompileUnits()) {
                for (final FunctionNode fn : compileUnit.getFunctionNodes()) {
                    initializers.put(fn.getId(), new FunctionInitializer(fn));
                }
            }
        }
        final String mainClassName = getFirstCompileUnit().getUnitClassName();
        installer.storeScript(cacheKey, source, mainClassName, bytecode, initializers, constantData.toArray(), compilationId);
    }
}
项目:openjdk-jdk10    文件:IRTranslator.java   
@Override
public boolean enterFunctionNode(final FunctionNode functionNode) {
    assert !functionNode.isDeclared() || functionNode.isAnonymous() : "should not reach here for function declaration";

    final List<? extends ExpressionTree> paramTrees = translateParameters(functionNode);
    final BlockTree blockTree = (BlockTree) translateBlock(functionNode.getBody(), true);
    curExpr = new FunctionExpressionTreeImpl(functionNode, paramTrees, blockTree);

    return false;
}
项目:openjdk-jdk10    文件:RecompilableScriptFunctionData.java   
private FunctionNode deserialize(final byte[] serializedAst) {
    final ScriptEnvironment env = installer.getContext().getEnv();
    final Timing timing = env._timing;
    final long t1 = System.nanoTime();
    try {
        return AstDeserializer.deserialize(serializedAst).initializeDeserialized(source, new Namespace(env.getNamespace()));
    } finally {
        timing.accumulateTime("'Deserialize'", System.nanoTime() - t1);
    }
}
项目:openjdk-jdk10    文件:MethodEmitter.java   
/**
 * Constructor - internal use from ClassEmitter only
 * @see ClassEmitter#method
 *
 * @param classEmitter the class emitter weaving the class this method is in
 * @param method       a method visitor
 * @param functionNode a function node representing this method
 */
MethodEmitter(final ClassEmitter classEmitter, final MethodVisitor method, final FunctionNode functionNode) {
    this.context      = classEmitter.getContext();
    this.classEmitter = classEmitter;
    this.method       = method;
    this.functionNode = functionNode;
    this.stack        = null;
    this.log          = context.getLogger(CodeGenerator.class);
    this.debug        = log.isEnabled();
}
项目:OpenJSharp    文件:Parser.java   
private FunctionNode restoreFunctionNode(final FunctionNode functionNode, final long lastToken) {
    final Block newBody = restoreBlock(lc.getFunctionBody(functionNode));

    return lc.pop(functionNode).
        setBody(lc, newBody).
        setLastToken(lc, lastToken).
        setState(lc, errors.hasErrors() ? CompilationState.PARSE_ERROR : CompilationState.PARSED);
}
项目:OpenJSharp    文件:Parser.java   
/**
 * Program :
 *      SourceElements?
 *
 * See 14
 *
 * Parse the top level script.
 */
private FunctionNode program(final String scriptName, final boolean allowPropertyFunction) {
    // Make a pseudo-token for the script holding its start and length.
    final long functionToken = Token.toDesc(FUNCTION, Token.descPosition(Token.withDelimiter(token)), source.getLength());
    final int  functionLine  = line;
    // Set up the script to append elements.

    FunctionNode script = newFunctionNode(
        functionToken,
        new IdentNode(functionToken, Token.descPosition(functionToken), scriptName),
        new ArrayList<IdentNode>(),
        FunctionNode.Kind.SCRIPT,
        functionLine);

    functionDeclarations = new ArrayList<>();
    sourceElements(allowPropertyFunction);
    addFunctionDeclarations(script);
    functionDeclarations = null;

    expect(EOF);

    script.setFinish(source.getLength() - 1);

    script = restoreFunctionNode(script, token); //commit code
    script = script.setBody(lc, script.getBody().setNeedsScope(lc));

    return script;
}
项目:openjdk-jdk10    文件:ModuleTreeImpl.java   
private ModuleTreeImpl(final FunctionNode func,
        final List<? extends ImportEntryTree> imports,
        final List<? extends ExportEntryTree> localExports,
        final List<? extends ExportEntryTree> indirectExports,
        final List<? extends ExportEntryTree> starExports) {
    super(func);
    assert func.getKind() == FunctionNode.Kind.MODULE : "module function node expected";
    this.mod = func.getModule();
    this.imports = imports;
    this.localExports = localExports;
    this.indirectExports = indirectExports;
    this.starExports = starExports;
}
项目:openjdk-jdk10    文件:CompilationPhase.java   
@Override
FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
    if (compiler.useOptimisticTypes()) {
        return transformFunction(fn, new OptimisticTypesCalculator(compiler));
    }
    return fn;
}
项目:OpenJSharp    文件:RecompilableScriptFunctionData.java   
/**
 * Constructor - public as scripts use it
 *
 * @param functionNode        functionNode that represents this function code
 * @param installer           installer for code regeneration versions of this function
 * @param allocationDescriptor descriptor for the allocation behavior when this function is used as a constructor
 * @param nestedFunctions     nested function map
 * @param externalScopeDepths external scope depths
 * @param internalSymbols     internal symbols to method, defined in its scope
 * @param serializedAst       a serialized AST representation. Normally only used for split functions.
 */
public RecompilableScriptFunctionData(
    final FunctionNode functionNode,
    final CodeInstaller<ScriptEnvironment> installer,
    final AllocatorDescriptor allocationDescriptor,
    final Map<Integer, RecompilableScriptFunctionData> nestedFunctions,
    final Map<String, Integer> externalScopeDepths,
    final Set<String> internalSymbols,
    final byte[] serializedAst) {

    super(functionName(functionNode),
          Math.min(functionNode.getParameters().size(), MAX_ARITY),
          getDataFlags(functionNode));

    this.functionName        = functionNode.getName();
    this.lineNumber          = functionNode.getLineNumber();
    this.functionFlags       = functionNode.getFlags() | (functionNode.needsCallee() ? FunctionNode.NEEDS_CALLEE : 0);
    this.functionNodeId      = functionNode.getId();
    this.source              = functionNode.getSource();
    this.endParserState      = functionNode.getEndParserState();
    this.token               = tokenFor(functionNode);
    this.installer           = installer;
    this.allocationStrategy  = AllocationStrategy.get(allocationDescriptor);
    this.nestedFunctions     = smallMap(nestedFunctions);
    this.externalScopeDepths = smallMap(externalScopeDepths);
    this.internalSymbols     = smallSet(new HashSet<>(internalSymbols));

    for (final RecompilableScriptFunctionData nfn : nestedFunctions.values()) {
        assert nfn.getParent() == null;
        nfn.setParent(this);
    }

    this.serializedAst = serializedAst;
    createLogger();
}
项目:openjdk-jdk10    文件:Parser.java   
/**
 * ReturnStatement :
 *      return Expression? ; // [no LineTerminator here]
 *
 * See 12.9
 *
 * Parse RETURN statement.
 */
private void returnStatement() {
    // check for return outside function
    if (lc.getCurrentFunction().getKind() == FunctionNode.Kind.SCRIPT || lc.getCurrentFunction().getKind() == FunctionNode.Kind.MODULE) {
        throw error(AbstractParser.message("invalid.return"));
    }

    // Capture RETURN token.
    final int  returnLine  = line;
    final long returnToken = token;
    // RETURN tested in caller.
    nextOrEOL();

    Expression expression = null;

    // SEMICOLON or expression.
    switch (type) {
    case RBRACE:
    case SEMICOLON:
    case EOL:
    case EOF:
        break;

    default:
        expression = expression();
        break;
    }

    endOfLine();

    // Construct and add RETURN node.
    appendStatement(new ReturnNode(returnLine, returnToken, finish, expression));
}
项目:openjdk-jdk10    文件:CompilationPhase.java   
/**
 * Start a compilation phase
 * @param compiler the compiler to use
 * @param functionNode function to compile
 * @return function node
 */
protected FunctionNode begin(final Compiler compiler, final FunctionNode functionNode) {
    compiler.getLogger().indent();
    startTime = System.nanoTime();

     return functionNode;
 }
项目:OpenJSharp    文件:RecompilableScriptFunctionData.java   
FunctionNode reparse() {
    if (isSerialized()) {
        return deserialize();
    }

    final int descPosition = Token.descPosition(token);
    final Context context = Context.getContextTrusted();
    final Parser parser = new Parser(
        context.getEnv(),
        source,
        new Context.ThrowErrorManager(),
        isStrict(),
        // source starts at line 0, so even though lineNumber is the correct declaration line, back off
        // one to make it exclusive
        lineNumber - 1,
        context.getLogger(Parser.class));

    if (getFunctionFlag(FunctionNode.IS_ANONYMOUS)) {
        parser.setFunctionName(functionName);
    }
    parser.setReparsedFunction(this);

    final FunctionNode program = parser.parse(CompilerConstants.PROGRAM.symbolName(), descPosition,
            Token.descLength(token), true);
    // Parser generates a program AST even if we're recompiling a single function, so when we are only
    // recompiling a single function, extract it from the program.
    return (isProgram() ? program : extractFunctionFromScript(program)).setName(null, functionName);
}
项目:OpenJSharp    文件:ApplySpecialization.java   
private void pushExplodedArgs(final FunctionNode functionNode) {
    int start = 0;

    final MethodType actualCallSiteType = compiler.getCallSiteType(functionNode);
    if (actualCallSiteType == null) {
        throw new TransformFailedException(lc.getCurrentFunction(), "No callsite type");
    }
    assert actualCallSiteType.parameterType(actualCallSiteType.parameterCount() - 1) != Object[].class : "error vararg callsite passed to apply2call " + functionNode.getName() + " " + actualCallSiteType;

    final TypeMap ptm = compiler.getTypeMap();
    if (ptm.needsCallee()) {
        start++;
    }

    start++; //we always uses this

    final List<IdentNode> params    = functionNode.getParameters();
    final List<IdentNode> newParams = new ArrayList<>();
    final long to = Math.max(params.size(), actualCallSiteType.parameterCount() - start);
    for (int i = 0; i < to; i++) {
        if (i >= params.size()) {
            newParams.add(new IdentNode(functionNode.getToken(), functionNode.getFinish(), EXPLODED_ARGUMENT_PREFIX.symbolName() + (i)));
        } else {
            newParams.add(params.get(i));
        }
    }

    callSiteTypes.push(actualCallSiteType);
    explodedArguments.push(newParams);
}
项目:openjdk-jdk10    文件:Parser.java   
private FunctionNode createFunctionNode(final ParserContextFunctionNode function, final long startToken, final IdentNode ident, final List<IdentNode> parameters, final FunctionNode.Kind kind, final int functionLine, final Block body) {
    // assert body.isFunctionBody() || body.getFlag(Block.IS_PARAMETER_BLOCK) && ((BlockStatement) body.getLastStatement()).getBlock().isFunctionBody();
    // Start new block.
    final FunctionNode functionNode =
        new FunctionNode(
            source,
            functionLine,
            body.getToken(),
            Token.descPosition(body.getToken()),
            startToken,
            function.getLastToken(),
            namespace,
            ident,
            function.getName(),
            parameters,
            function.getParameterExpressions(),
            kind,
            function.getFlags(),
            body,
            function.getEndParserState(),
            function.getModule(),
            function.getDebugFlags());

    printAST(functionNode);

    return functionNode;
}
项目:openjdk-jdk10    文件:RecompilableScriptFunctionData.java   
private static String functionName(final FunctionNode fn) {
    if (fn.isAnonymous()) {
        return "";
    }
    final FunctionNode.Kind kind = fn.getKind();
    if (kind == FunctionNode.Kind.GETTER || kind == FunctionNode.Kind.SETTER) {
        final String name = NameCodec.decode(fn.getIdent().getName());
        return name.substring(GET_SET_PREFIX_LENGTH);
    }
    return fn.getIdent().getName();
}
项目:openjdk-jdk10    文件:RecompilableScriptFunctionData.java   
/**
 * Check whether a certain name is a global symbol, i.e. only exists as defined
 * in outermost scope and not shadowed by being parameter or assignment in inner
 * scopes
 *
 * @param functionNode function node to check
 * @param symbolName symbol name
 * @return true if global symbol
 */
public boolean isGlobalSymbol(final FunctionNode functionNode, final String symbolName) {
    RecompilableScriptFunctionData data = getScriptFunctionData(functionNode.getId());
    assert data != null;

    do {
        if (data.hasInternalSymbol(symbolName)) {
            return false;
        }
        data = data.getParent();
    } while(data != null);

    return true;
}
项目:openjdk-jdk10    文件:RecompilableScriptFunctionData.java   
/**
 * Initializes this function data with the eagerly generated version of the code. This method can only be invoked
 * by the compiler internals in Nashorn and is public for implementation reasons only. Attempting to invoke it
 * externally will result in an exception.
 *
 * @param functionNode FunctionNode for this data
 */
public void initializeCode(final FunctionNode functionNode) {
    // Since the method is public, we double-check that we aren't invoked with an inappropriate compile unit.
    if (!code.isEmpty() || functionNode.getId() != functionNodeId || !functionNode.getCompileUnit().isInitializing(this, functionNode)) {
        throw new IllegalStateException(name);
    }
    addCode(lookup(functionNode), null, null, functionNode.getFlags());
}
项目:OpenJSharp    文件:JSONWriter.java   
/**
 * Returns AST as JSON compatible string.
 *
 * @param context context
 * @param code code to be parsed
 * @param name name of the code source (used for location)
 * @param includeLoc tells whether to include location information for nodes or not
 * @return JSON string representation of AST of the supplied code
 */
public static String parse(final Context context, final String code, final String name, final boolean includeLoc) {
    final Parser       parser     = new Parser(context.getEnv(), sourceFor(name, code), new Context.ThrowErrorManager(), context.getEnv()._strict, context.getLogger(Parser.class));
    final JSONWriter   jsonWriter = new JSONWriter(includeLoc);
    try {
        final FunctionNode functionNode = parser.parse(); //symbol name is ":program", default
        functionNode.accept(jsonWriter);
        return jsonWriter.getString();
    } catch (final ParserException e) {
        e.throwAsEcmaException();
        return null;
    }
}
项目: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;
}