< prev index next >
src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/FunctionNode.java
Print this page
@@ -67,11 +67,17 @@
/** a script function */
SCRIPT,
/** a getter, @see {@link UserAccessorProperty} */
GETTER,
/** a setter, @see {@link UserAccessorProperty} */
- SETTER
+ SETTER,
+ /** an arrow function */
+ ARROW,
+ /** a generator function */
+ GENERATOR,
+ /** a module function */
+ MODULE
}
/** Source of entity. */
private transient final Source source;
@@ -120,10 +126,16 @@
private final int lineNumber;
/** Root class for function */
private final Class<?> rootClass;
+ /** The ES6 module */
+ private final Module module;
+
+ /** The debug flags */
+ private final int debugFlags;
+
/** Is anonymous function flag. */
public static final int IS_ANONYMOUS = 1 << 0;
/** Is the function created in a function declaration (as opposed to a function expression) */
public static final int IS_DECLARED = 1 << 1;
@@ -185,57 +197,52 @@
public static final int USES_THIS = 1 << 15;
/** Is this declared in a dynamic context */
public static final int IN_DYNAMIC_CONTEXT = 1 << 16;
- /**
- * The following flags are derived from directive comments within this function.
- * Note that even IS_STRICT is one such flag but that requires special handling.
- */
-
- /** parser, print parse tree */
- public static final int IS_PRINT_PARSE = 1 << 17;
- /** parser, print lower parse tree */
- public static final int IS_PRINT_LOWER_PARSE = 1 << 18;
- /** parser, print AST */
- public static final int IS_PRINT_AST = 1 << 19;
- /** parser, print lower AST */
- public static final int IS_PRINT_LOWER_AST = 1 << 20;
- /** parser, print symbols */
- public static final int IS_PRINT_SYMBOLS = 1 << 21;
-
- // callsite tracing, profiling within this function
- /** profile callsites in this function? */
- public static final int IS_PROFILE = 1 << 22;
-
- /** trace callsite enterexit in this function? */
- public static final int IS_TRACE_ENTEREXIT = 1 << 23;
-
- /** trace callsite misses in this function? */
- public static final int IS_TRACE_MISSES = 1 << 24;
-
- /** trace callsite values in this function? */
- public static final int IS_TRACE_VALUES = 1 << 25;
/**
* Whether this function needs the callee {@link ScriptFunction} instance passed to its code as a
* parameter on invocation. Note that we aren't, in fact using this flag in function nodes.
* Rather, it is always calculated (see {@link #needsCallee()}). {@link RecompilableScriptFunctionData}
* will, however, cache the value of this flag.
*/
- public static final int NEEDS_CALLEE = 1 << 26;
+ public static final int NEEDS_CALLEE = 1 << 17;
/**
* Is the function node cached?
*/
- public static final int IS_CACHED = 1 << 27;
+ public static final int IS_CACHED = 1 << 18;
- /** extension callsite flags mask */
- public static final int EXTENSION_CALLSITE_FLAGS = IS_PRINT_PARSE |
- IS_PRINT_LOWER_PARSE | IS_PRINT_AST | IS_PRINT_LOWER_AST |
- IS_PRINT_SYMBOLS | IS_PROFILE | IS_TRACE_ENTEREXIT |
- IS_TRACE_MISSES | IS_TRACE_VALUES;
+ /**
+ * Does this function contain a super call? (cf. ES6 14.3.5 Static Semantics: HasDirectSuper)
+ */
+ public static final int ES6_HAS_DIRECT_SUPER = 1 << 19;
+
+ /**
+ * Does this function use the super binding?
+ */
+ public static final int ES6_USES_SUPER = 1 << 20;
+
+ /**
+ * Is this function a (class or object) method?
+ */
+ public static final int ES6_IS_METHOD = 1 << 21;
+
+ /**
+ * Is this the constructor method?
+ */
+ public static final int ES6_IS_CLASS_CONSTRUCTOR = 1 << 22;
+
+ /** Is this the constructor of a subclass (i.e., a class with an extends declaration)? */
+ public static final int ES6_IS_SUBCLASS_CONSTRUCTOR = 1 << 23;
+
+ /** is this a strong mode function? */
+ public static final int ES6_IS_STRONG = 1 << 24;
+
+ /** Does this function use new.target? */
+ public static final int ES6_USES_NEW_TARGET = 1 << 25;
/** Does this function or any nested functions contain an eval? */
private static final int HAS_DEEP_EVAL = HAS_EVAL | HAS_NESTED_EVAL;
/** Does this function need to store all its variables in scope? */
@@ -245,12 +252,48 @@
private static final int MAYBE_NEEDS_ARGUMENTS = USES_ARGUMENTS | HAS_EVAL;
/** Does this function need the parent scope? It needs it if either it or its descendants use variables from it, or have a deep eval, or it's the program. */
public static final int NEEDS_PARENT_SCOPE = USES_ANCESTOR_SCOPE | HAS_DEEP_EVAL | IS_PROGRAM;
+
+ /**
+ * The following flags are derived from directive comments within this function.
+ * Note that even IS_STRICT is one such flag but that requires special handling.
+ */
+
+ /** parser, print parse tree */
+ public static final int DEBUG_PRINT_PARSE = 1 << 0;
+ /** parser, print lower parse tree */
+ public static final int DEBUG_PRINT_LOWER_PARSE = 1 << 1;
+ /** parser, print AST */
+ public static final int DEBUG_PRINT_AST = 1 << 2;
+ /** parser, print lower AST */
+ public static final int DEBUG_PRINT_LOWER_AST = 1 << 3;
+ /** parser, print symbols */
+ public static final int DEBUG_PRINT_SYMBOLS = 1 << 4;
+
+ // callsite tracing, profiling within this function
+ /** profile callsites in this function? */
+ public static final int DEBUG_PROFILE = 1 << 5;
+
+ /** trace callsite enterexit in this function? */
+ public static final int DEBUG_TRACE_ENTEREXIT = 1 << 6;
+
+ /** trace callsite misses in this function? */
+ public static final int DEBUG_TRACE_MISSES = 1 << 7;
+
+ /** trace callsite values in this function? */
+ public static final int DEBUG_TRACE_VALUES = 1 << 8;
+
+ /** extension callsite flags mask */
+ public static final int DEBUG_CALLSITE_FLAGS = DEBUG_PRINT_PARSE |
+ DEBUG_PRINT_LOWER_PARSE | DEBUG_PRINT_AST | DEBUG_PRINT_LOWER_AST |
+ DEBUG_PRINT_SYMBOLS | DEBUG_PROFILE | DEBUG_TRACE_ENTEREXIT |
+ DEBUG_TRACE_MISSES | DEBUG_TRACE_VALUES;
+
/** What is the return type of this function? */
- private Type returnType = Type.UNKNOWN;
+ public Type returnType = Type.UNKNOWN;
/**
* Constructor
*
* @param source the source
@@ -265,10 +308,12 @@
* @param parameters parameter list
* @param kind kind of function as in {@link FunctionNode.Kind}
* @param flags initial flags
* @param body body of the function
* @param endParserState The parser state at the end of the parsing.
+ * @param module the module
+ * @param debugFlags the debug flags
*/
public FunctionNode(
final Source source,
final int lineNumber,
final long token,
@@ -280,11 +325,13 @@
final String name,
final List<IdentNode> parameters,
final FunctionNode.Kind kind,
final int flags,
final Block body,
- final Object endParserState) {
+ final Object endParserState,
+ final Module module,
+ final int debugFlags) {
super(token, finish);
this.source = source;
this.lineNumber = lineNumber;
this.ident = ident;
@@ -298,10 +345,12 @@
this.compileUnit = null;
this.body = body;
this.thisProperties = 0;
this.rootClass = null;
this.endParserState = endParserState;
+ this.module = module;
+ this.debugFlags = debugFlags;
}
private FunctionNode(
final FunctionNode functionNode,
final long lastToken,
@@ -333,10 +382,12 @@
// the fields below never change - they are final and assigned in constructor
this.ident = functionNode.ident;
this.kind = functionNode.kind;
this.firstToken = functionNode.firstToken;
+ this.module = functionNode.module;
+ this.debugFlags = functionNode.debugFlags;
}
@Override
public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
if (visitor.enterFunctionNode(this)) {
@@ -364,27 +415,27 @@
if (getFlag(IS_STRICT)) {
callsiteFlags |= CALLSITE_STRICT;
}
// quick check for extension callsite flags turned on by directives.
- if ((flags & EXTENSION_CALLSITE_FLAGS) == 0) {
+ if ((debugFlags & DEBUG_CALLSITE_FLAGS) == 0) {
return callsiteFlags;
}
- if (getFlag(IS_PROFILE)) {
+ if (getDebugFlag(DEBUG_PROFILE)) {
callsiteFlags |= CALLSITE_PROFILE;
}
- if (getFlag(IS_TRACE_MISSES)) {
+ if (getDebugFlag(DEBUG_TRACE_MISSES)) {
callsiteFlags |= CALLSITE_TRACE | CALLSITE_TRACE_MISSES;
}
- if (getFlag(IS_TRACE_VALUES)) {
+ if (getDebugFlag(DEBUG_TRACE_VALUES)) {
callsiteFlags |= CALLSITE_TRACE | CALLSITE_TRACE_ENTEREXIT | CALLSITE_TRACE_VALUES;
}
- if (getFlag(IS_TRACE_ENTEREXIT)) {
+ if (getDebugFlag(DEBUG_TRACE_ENTEREXIT)) {
callsiteFlags |= CALLSITE_TRACE | CALLSITE_TRACE_ENTEREXIT;
}
return callsiteFlags;
}
@@ -464,27 +515,27 @@
* @return integer flag for the given directive.
*/
public static int getDirectiveFlag(final String directive) {
switch (directive) {
case "nashorn callsite trace enterexit":
- return IS_TRACE_ENTEREXIT;
+ return DEBUG_TRACE_ENTEREXIT;
case "nashorn callsite trace misses":
- return IS_TRACE_MISSES;
+ return DEBUG_TRACE_MISSES;
case "nashorn callsite trace objects":
- return IS_TRACE_VALUES;
+ return DEBUG_TRACE_VALUES;
case "nashorn callsite profile":
- return IS_PROFILE;
+ return DEBUG_PROFILE;
case "nashorn print parse":
- return IS_PRINT_PARSE;
+ return DEBUG_PRINT_PARSE;
case "nashorn print lower parse":
- return IS_PRINT_LOWER_PARSE;
+ return DEBUG_PRINT_LOWER_PARSE;
case "nashorn print ast":
- return IS_PRINT_AST;
+ return DEBUG_PRINT_AST;
case "nashorn print lower ast":
- return IS_PRINT_LOWER_AST;
+ return DEBUG_PRINT_LOWER_AST;
case "nashorn print symbols":
- return IS_PRINT_SYMBOLS;
+ return DEBUG_PRINT_SYMBOLS;
default:
// unknown/unsupported directive
return 0;
}
}
@@ -577,10 +628,29 @@
public FunctionNode setFlag(final LexicalContext lc, final int flag) {
return setFlags(lc, flags | flag);
}
/**
+ * Returns the debug flags for this function.
+ *
+ * @return the debug flags
+ */
+ public int getDebugFlags() {
+ return debugFlags;
+ }
+
+ /**
+ * Checks whether a debug flag is set for this function.
+ *
+ * @param debugFlag the debug flag
+ * @return true if the flag is set
+ */
+ public boolean getDebugFlag(final int debugFlag) {
+ return (debugFlags & debugFlag) != 0;
+ }
+
+ /**
* Returns true if the function is the top-level program.
* @return True if this function node represents the top-level program.
*/
public boolean isProgram() {
return getFlag(IS_PROGRAM);
@@ -1063,10 +1133,90 @@
*/
public FunctionNode setCached(final LexicalContext lc) {
return setFlag(lc, IS_CACHED);
}
+ /**
+ * Checks if the function is generated in strong mode.
+ *
+ * @return true if strong mode enabled for function
+ */
+ public boolean isStrong() {
+ return getFlag(ES6_IS_STRONG);
+ }
+
+ /**
+ * Checks if this is an ES6 method.
+ *
+ * @return true if the ES6 method flag is set
+ */
+ public boolean isMethod() {
+ return getFlag(ES6_IS_METHOD);
+ }
+
+ /**
+ * Checks if this function uses the ES6 super binding.
+ *
+ * @return true if the ES6 super flag is set
+ */
+ public boolean usesSuper() {
+ return getFlag(ES6_USES_SUPER);
+ }
+
+ /**
+ * Checks if this function directly uses the super binding.
+ *
+ * @return true if the ES6 has-direct-super flag is set
+ */
+ public boolean hasDirectSuper() {
+ return getFlag(ES6_HAS_DIRECT_SUPER);
+ }
+
+ /**
+ * Checks if this is an ES6 class constructor.
+ *
+ * @return true if the ES6 class constructor flag is set
+ */
+ public boolean isClassConstructor() {
+ return getFlag(ES6_IS_CLASS_CONSTRUCTOR);
+ }
+
+ /**
+ * Checks if this is an ES6 subclass constructor.
+ *
+ * @return true if the ES6 subclass constructor flag is set
+ */
+ public boolean isSubclassConstructor() {
+ return getFlag(ES6_IS_SUBCLASS_CONSTRUCTOR);
+ }
+
+ /**
+ * Checks if this function uses the ES6 new-targert.
+ *
+ * @return true if the ES6 new-target flag is set
+ */
+ public boolean usesNewTarget() {
+ return getFlag(ES6_USES_NEW_TARGET);
+ }
+
+ /**
+ * Checks if this is an ES6 module.
+ *
+ * @return true if this is an ES6 module
+ */
+ public boolean isModule() {
+ return kind == Kind.MODULE;
+ }
+
+ /**
+ * Returns the functions's ES6 module.
+ *
+ * @return the module, or null if this function is not part of one
+ */
+ public Module getModule() {
+ return module;
+ }
/**
* Get the compile unit used to compile this function
* @see Compiler
* @return the compile unit
< prev index next >