1 /*
   2  * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package jdk.nashorn.internal.ir;
  27 
  28 import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_PROFILE;
  29 import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_STRICT;
  30 import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_TRACE;
  31 import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_TRACE_ENTEREXIT;
  32 import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_TRACE_MISSES;
  33 import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_TRACE_VALUES;
  34 
  35 import java.util.Collections;
  36 import java.util.Iterator;
  37 import java.util.List;
  38 import jdk.nashorn.internal.codegen.CompileUnit;
  39 import jdk.nashorn.internal.codegen.Compiler;
  40 import jdk.nashorn.internal.codegen.CompilerConstants;
  41 import jdk.nashorn.internal.codegen.Namespace;
  42 import jdk.nashorn.internal.codegen.types.Type;
  43 import jdk.nashorn.internal.ir.annotations.Ignore;
  44 import jdk.nashorn.internal.ir.annotations.Immutable;
  45 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
  46 import jdk.nashorn.internal.parser.Token;
  47 import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
  48 import jdk.nashorn.internal.runtime.ScriptFunction;
  49 import jdk.nashorn.internal.runtime.Source;
  50 import jdk.nashorn.internal.runtime.UserAccessorProperty;
  51 import jdk.nashorn.internal.runtime.linker.LinkerCallSite;
  52 
  53 /**
  54  * IR representation for function (or script.)
  55  */
  56 @Immutable
  57 public final class FunctionNode extends LexicalContextExpression implements Flags<FunctionNode>, CompileUnitHolder {
  58     private static final long serialVersionUID = 1L;
  59 
  60     /** Type used for all FunctionNodes */
  61     public static final Type FUNCTION_TYPE = Type.typeFor(ScriptFunction.class);
  62 
  63     /** Function kinds */
  64     public enum Kind {
  65         /** a normal function - nothing special */
  66         NORMAL,
  67         /** a script function */
  68         SCRIPT,
  69         /** a getter, @see {@link UserAccessorProperty} */
  70         GETTER,
  71         /** a setter, @see {@link UserAccessorProperty} */
  72         SETTER,
  73         /** an arrow function */
  74         ARROW,
  75         /** a generator function */
  76         GENERATOR,
  77         /** a module function */
  78         MODULE
  79     }
  80 
  81     /** Source of entity. */
  82     private transient final Source source;
  83 
  84     /**
  85      * Opaque object representing parser state at the end of the function. Used when reparsing outer functions
  86      * to skip parsing inner functions.
  87      */
  88     private final Object endParserState;
  89 
  90     /** External function identifier. */
  91     @Ignore
  92     private final IdentNode ident;
  93 
  94     /** The body of the function node */
  95     private final Block body;
  96 
  97     /** Internal function name. */
  98     private final String name;
  99 
 100     /** Compilation unit. */
 101     private final CompileUnit compileUnit;
 102 
 103     /** Function kind. */
 104     private final Kind kind;
 105 
 106     /** List of parameters. */
 107     private final List<IdentNode> parameters;
 108 
 109     /** First token of function. **/
 110     private final long firstToken;
 111 
 112     /** Last token of function. **/
 113     private final long lastToken;
 114 
 115     /** Method's namespace. */
 116     private transient final Namespace namespace;
 117 
 118     /** Number of properties of "this" object assigned in this function */
 119     @Ignore
 120     private final int thisProperties;
 121 
 122     /** Function flags. */
 123     private final int flags;
 124 
 125     /** Line number of function start */
 126     private final int lineNumber;
 127 
 128     /** Root class for function */
 129     private final Class<?> rootClass;
 130 
 131     /** The ES6 module */
 132     private final Module module;
 133 
 134     /** The debug flags */
 135     private final int debugFlags;
 136 
 137     /** Is anonymous function flag. */
 138     public static final int IS_ANONYMOUS                = 1 << 0;
 139 
 140     /** Is the function created in a function declaration (as opposed to a function expression) */
 141     public static final int IS_DECLARED                 = 1 << 1;
 142 
 143     /** is this a strict mode function? */
 144     public static final int IS_STRICT                   = 1 << 2;
 145 
 146     /** Does the function use the "arguments" identifier ? */
 147     public static final int USES_ARGUMENTS              = 1 << 3;
 148 
 149     /** Has this function been split because it was too large? */
 150     public static final int IS_SPLIT                    = 1 << 4;
 151 
 152     /** Does the function call eval? If it does, then all variables in this function might be get/set by it and it can
 153      * introduce new variables into this function's scope too.*/
 154     public static final int HAS_EVAL                    = 1 << 5;
 155 
 156     /** Does a nested function contain eval? If it does, then all variables in this function might be get/set by it. */
 157     public static final int HAS_NESTED_EVAL             = 1 << 6;
 158 
 159     /** Does this function have any blocks that create a scope? This is used to determine if the function needs to
 160      * have a local variable slot for the scope symbol. */
 161     public static final int HAS_SCOPE_BLOCK             = 1 << 7;
 162 
 163     /**
 164      * Flag this function as one that defines the identifier "arguments" as a function parameter or nested function
 165      * name. This precludes it from needing to have an Arguments object defined as "arguments" local variable. Note that
 166      * defining a local variable named "arguments" still requires construction of the Arguments object (see
 167      * ECMAScript 5.1 Chapter 10.5).
 168      * @see #needsArguments()
 169      */
 170     public static final int DEFINES_ARGUMENTS           = 1 << 8;
 171 
 172     /** Does this function or any of its descendants use variables from an ancestor function's scope (incl. globals)? */
 173     public static final int USES_ANCESTOR_SCOPE         = 1 << 9;
 174 
 175     /** Does this function have nested declarations? */
 176     public static final int HAS_FUNCTION_DECLARATIONS   = 1 << 10;
 177 
 178     /** Does this function have optimistic expressions? (If it does, it can undergo deoptimizing recompilation.) */
 179     public static final int IS_DEOPTIMIZABLE            = 1 << 11;
 180 
 181     /** Are we vararg, but do we just pass the arguments along to apply or call */
 182     public static final int HAS_APPLY_TO_CALL_SPECIALIZATION = 1 << 12;
 183 
 184     /**
 185      * Is this function the top-level program?
 186      */
 187     public static final int IS_PROGRAM                  = 1 << 13;
 188 
 189     /**
 190      * Flag indicating whether this function uses the local variable symbol for itself. Only named function expressions
 191      * can have this flag set if they reference themselves (e.g. "(function f() { return f })". Declared functions will
 192      * use the symbol in their parent scope instead when they reference themselves by name.
 193      */
 194     public static final int USES_SELF_SYMBOL            = 1 << 14;
 195 
 196     /** Does this function use the "this" keyword? */
 197     public static final int USES_THIS                   = 1 << 15;
 198 
 199     /** Is this declared in a dynamic context */
 200     public static final int IN_DYNAMIC_CONTEXT          = 1 << 16;
 201 
 202 
 203     /**
 204      * Whether this function needs the callee {@link ScriptFunction} instance passed to its code as a
 205      * parameter on invocation. Note that we aren't, in fact using this flag in function nodes.
 206      * Rather, it is always calculated (see {@link #needsCallee()}). {@link RecompilableScriptFunctionData}
 207      * will, however, cache the value of this flag.
 208      */
 209     public static final int NEEDS_CALLEE                = 1 << 17;
 210 
 211     /**
 212      * Is the function node cached?
 213      */
 214     public static final int IS_CACHED                   = 1 << 18;
 215 
 216     /**
 217      * Does this function contain a super call? (cf. ES6 14.3.5 Static Semantics: HasDirectSuper)
 218      */
 219     public static final int ES6_HAS_DIRECT_SUPER        = 1 << 19;
 220 
 221     /**
 222      * Does this function use the super binding?
 223      */
 224     public static final int ES6_USES_SUPER              = 1 << 20;
 225 
 226     /**
 227      * Is this function a (class or object) method?
 228      */
 229     public static final int ES6_IS_METHOD               = 1 << 21;
 230 
 231     /**
 232      * Is this the constructor method?
 233      */
 234     public static final int ES6_IS_CLASS_CONSTRUCTOR    = 1 << 22;
 235 
 236     /** Is this the constructor of a subclass (i.e., a class with an extends declaration)? */
 237     public static final int ES6_IS_SUBCLASS_CONSTRUCTOR = 1 << 23;
 238 
 239     /** is this a strong mode function? */
 240     public static final int ES6_IS_STRONG               = 1 << 24;
 241 
 242     /** Does this function use new.target? */
 243     public static final int ES6_USES_NEW_TARGET         = 1 << 25;
 244 
 245     /** Does this function or any nested functions contain an eval? */
 246     private static final int HAS_DEEP_EVAL = HAS_EVAL | HAS_NESTED_EVAL;
 247 
 248     /** Does this function need to store all its variables in scope? */
 249     public static final int HAS_ALL_VARS_IN_SCOPE = HAS_DEEP_EVAL;
 250 
 251     /** Does this function potentially need "arguments"? Note that this is not a full test, as further negative check of REDEFINES_ARGS is needed. */
 252     private static final int MAYBE_NEEDS_ARGUMENTS = USES_ARGUMENTS | HAS_EVAL;
 253 
 254     /** 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. */
 255     public static final int NEEDS_PARENT_SCOPE = USES_ANCESTOR_SCOPE | HAS_DEEP_EVAL | IS_PROGRAM;
 256 
 257 
 258     /**
 259      * The following flags are derived from directive comments within this function.
 260      * Note that even IS_STRICT is one such flag but that requires special handling.
 261      */
 262 
 263     /** parser, print parse tree */
 264     public static final int DEBUG_PRINT_PARSE       = 1 << 0;
 265     /** parser, print lower parse tree */
 266     public static final int DEBUG_PRINT_LOWER_PARSE = 1 << 1;
 267     /** parser, print AST */
 268     public static final int DEBUG_PRINT_AST         = 1 << 2;
 269     /** parser, print lower AST */
 270     public static final int DEBUG_PRINT_LOWER_AST   = 1 << 3;
 271     /** parser, print symbols */
 272     public static final int DEBUG_PRINT_SYMBOLS     = 1 << 4;
 273 
 274     // callsite tracing, profiling within this function
 275     /** profile callsites in this function? */
 276     public static final int DEBUG_PROFILE           = 1 << 5;
 277 
 278     /** trace callsite enterexit in this function? */
 279     public static final int DEBUG_TRACE_ENTEREXIT   = 1 << 6;
 280 
 281     /** trace callsite misses in this function? */
 282     public static final int DEBUG_TRACE_MISSES      = 1 << 7;
 283 
 284     /** trace callsite values in this function? */
 285     public static final int DEBUG_TRACE_VALUES      = 1 << 8;
 286 
 287     /** extension callsite flags mask */
 288     public static final int DEBUG_CALLSITE_FLAGS = DEBUG_PRINT_PARSE |
 289             DEBUG_PRINT_LOWER_PARSE | DEBUG_PRINT_AST | DEBUG_PRINT_LOWER_AST |
 290             DEBUG_PRINT_SYMBOLS | DEBUG_PROFILE | DEBUG_TRACE_ENTEREXIT |
 291             DEBUG_TRACE_MISSES | DEBUG_TRACE_VALUES;
 292 
 293     /** What is the return type of this function? */
 294     public Type returnType = Type.UNKNOWN;
 295 
 296     /**
 297      * Constructor
 298      *
 299      * @param source     the source
 300      * @param lineNumber line number
 301      * @param token      token
 302      * @param finish     finish
 303      * @param firstToken first token of the function node (including the function declaration)
 304      * @param lastToken  lastToken
 305      * @param namespace  the namespace
 306      * @param ident      the identifier
 307      * @param name       the name of the function
 308      * @param parameters parameter list
 309      * @param kind       kind of function as in {@link FunctionNode.Kind}
 310      * @param flags      initial flags
 311      * @param body       body of the function
 312      * @param endParserState The parser state at the end of the parsing.
 313      * @param module     the module
 314      * @param debugFlags the debug flags
 315      */
 316     public FunctionNode(
 317         final Source source,
 318         final int lineNumber,
 319         final long token,
 320         final int finish,
 321         final long firstToken,
 322         final long lastToken,
 323         final Namespace namespace,
 324         final IdentNode ident,
 325         final String name,
 326         final List<IdentNode> parameters,
 327         final FunctionNode.Kind kind,
 328         final int flags,
 329         final Block body,
 330         final Object endParserState,
 331         final Module module,
 332         final int debugFlags) {
 333         super(token, finish);
 334 
 335         this.source           = source;
 336         this.lineNumber       = lineNumber;
 337         this.ident            = ident;
 338         this.name             = name;
 339         this.kind             = kind;
 340         this.parameters       = parameters;
 341         this.firstToken       = firstToken;
 342         this.lastToken        = lastToken;
 343         this.namespace        = namespace;
 344         this.flags            = flags;
 345         this.compileUnit      = null;
 346         this.body             = body;
 347         this.thisProperties   = 0;
 348         this.rootClass        = null;
 349         this.endParserState   = endParserState;
 350         this.module           = module;
 351         this.debugFlags       = debugFlags;
 352     }
 353 
 354     private FunctionNode(
 355         final FunctionNode functionNode,
 356         final long lastToken,
 357         final Object endParserState,
 358         final int flags,
 359         final String name,
 360         final Type returnType,
 361         final CompileUnit compileUnit,
 362         final Block body,
 363         final List<IdentNode> parameters,
 364         final int thisProperties,
 365         final Class<?> rootClass,
 366         final Source source, final Namespace namespace) {
 367         super(functionNode);
 368 
 369         this.endParserState    = endParserState;
 370         this.lineNumber       = functionNode.lineNumber;
 371         this.flags            = flags;
 372         this.name             = name;
 373         this.returnType       = returnType;
 374         this.compileUnit      = compileUnit;
 375         this.lastToken        = lastToken;
 376         this.body             = body;
 377         this.parameters       = parameters;
 378         this.thisProperties   = thisProperties;
 379         this.rootClass        = rootClass;
 380         this.source           = source;
 381         this.namespace        = namespace;
 382 
 383         // the fields below never change - they are final and assigned in constructor
 384         this.ident           = functionNode.ident;
 385         this.kind            = functionNode.kind;
 386         this.firstToken      = functionNode.firstToken;
 387         this.module          = functionNode.module;
 388         this.debugFlags      = functionNode.debugFlags;
 389     }
 390 
 391     @Override
 392     public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
 393         if (visitor.enterFunctionNode(this)) {
 394             return visitor.leaveFunctionNode(setBody(lc, (Block)body.accept(visitor)));
 395         }
 396         return this;
 397     }
 398 
 399     /**
 400      * Visits the parameter nodes of this function. Parameters are normally not visited automatically.
 401      * @param visitor the visitor to apply to the nodes.
 402      * @return a list of parameter nodes, potentially modified from original ones by the visitor.
 403      */
 404     public List<IdentNode> visitParameters(final NodeVisitor<? extends LexicalContext> visitor) {
 405         return Node.accept(visitor, parameters);
 406     }
 407 
 408     /**
 409      * Get additional callsite flags to be used specific to this function.
 410      *
 411      * @return callsite flags
 412      */
 413     public int getCallSiteFlags() {
 414         int callsiteFlags = 0;
 415         if (getFlag(IS_STRICT)) {
 416             callsiteFlags |= CALLSITE_STRICT;
 417         }
 418 
 419         // quick check for extension callsite flags turned on by directives.
 420         if ((debugFlags & DEBUG_CALLSITE_FLAGS) == 0) {
 421             return callsiteFlags;
 422         }
 423 
 424         if (getDebugFlag(DEBUG_PROFILE)) {
 425             callsiteFlags |= CALLSITE_PROFILE;
 426         }
 427 
 428         if (getDebugFlag(DEBUG_TRACE_MISSES)) {
 429             callsiteFlags |= CALLSITE_TRACE | CALLSITE_TRACE_MISSES;
 430         }
 431 
 432         if (getDebugFlag(DEBUG_TRACE_VALUES)) {
 433             callsiteFlags |= CALLSITE_TRACE | CALLSITE_TRACE_ENTEREXIT | CALLSITE_TRACE_VALUES;
 434         }
 435 
 436         if (getDebugFlag(DEBUG_TRACE_ENTEREXIT)) {
 437             callsiteFlags |= CALLSITE_TRACE | CALLSITE_TRACE_ENTEREXIT;
 438         }
 439 
 440         return callsiteFlags;
 441     }
 442 
 443     /**
 444      * Get the source for this function
 445      * @return the source
 446      */
 447     public Source getSource() {
 448         return source;
 449     }
 450 
 451     /**
 452      * Sets the source and namespace for this function. It can only set a non-null source and namespace for a function
 453      * that currently has both a null source and a null namespace. This is used to re-set the source and namespace for
 454      * a deserialized function node.
 455      * @param source the source for the function.
 456      * @param namespace the namespace for the function
 457      * @return a new function node with the set source and namespace
 458      * @throws IllegalArgumentException if the specified source or namespace is null
 459      * @throws IllegalStateException if the function already has either a source or namespace set.
 460      */
 461     public FunctionNode initializeDeserialized(final Source source, final Namespace namespace) {
 462         if (source == null || namespace == null) {
 463             throw new IllegalArgumentException();
 464         } else if (this.source == source && this.namespace == namespace) {
 465             return this;
 466         } else if (this.source != null || this.namespace != null) {
 467             throw new IllegalStateException();
 468         }
 469         return new FunctionNode(
 470             this,
 471             lastToken,
 472             endParserState,
 473             flags,
 474             name,
 475             returnType,
 476             compileUnit,
 477             body,
 478             parameters,
 479             thisProperties,
 480             rootClass, source, namespace);
 481     }
 482 
 483     /**
 484      * Get the unique ID for this function within the script file.
 485      * @return the id
 486      */
 487     public int getId() {
 488         return isProgram() ? -1: Token.descPosition(firstToken);
 489     }
 490 
 491     /**
 492      * get source name - sourceURL or name derived from Source.
 493      *
 494      * @return name for the script source
 495      */
 496     public String getSourceName() {
 497         return getSourceName(source);
 498     }
 499 
 500     /**
 501      * Static source name getter
 502      *
 503      * @param source the source
 504      * @return source name
 505      */
 506     public static String getSourceName(final Source source) {
 507         final String explicitURL = source.getExplicitURL();
 508         return explicitURL != null ? explicitURL : source.getName();
 509     }
 510 
 511     /**
 512      * Function to parse nashorn per-function extension directive comments.
 513      *
 514      * @param directive nashorn extension directive string
 515      * @return integer flag for the given directive.
 516      */
 517     public static int getDirectiveFlag(final String directive) {
 518         switch (directive) {
 519             case "nashorn callsite trace enterexit":
 520                 return DEBUG_TRACE_ENTEREXIT;
 521             case "nashorn callsite trace misses":
 522                 return DEBUG_TRACE_MISSES;
 523             case "nashorn callsite trace objects":
 524                 return DEBUG_TRACE_VALUES;
 525             case "nashorn callsite profile":
 526                 return DEBUG_PROFILE;
 527             case "nashorn print parse":
 528                 return DEBUG_PRINT_PARSE;
 529             case "nashorn print lower parse":
 530                 return DEBUG_PRINT_LOWER_PARSE;
 531             case "nashorn print ast":
 532                 return DEBUG_PRINT_AST;
 533             case "nashorn print lower ast":
 534                 return DEBUG_PRINT_LOWER_AST;
 535             case "nashorn print symbols":
 536                 return DEBUG_PRINT_SYMBOLS;
 537             default:
 538                 // unknown/unsupported directive
 539                 return 0;
 540         }
 541     }
 542 
 543     /**
 544      * Returns the line number.
 545      * @return the line number.
 546      */
 547     public int getLineNumber() {
 548         return lineNumber;
 549     }
 550 
 551     /**
 552      * Create a unique name in the namespace of this FunctionNode
 553      * @param base prefix for name
 554      * @return base if no collision exists, otherwise a name prefix with base
 555      */
 556     public String uniqueName(final String base) {
 557         return namespace.uniqueName(base);
 558     }
 559 
 560     @Override
 561     public void toString(final StringBuilder sb, final boolean printTypes) {
 562         sb.append('[').
 563             append(returnType).
 564             append(']').
 565             append(' ');
 566 
 567         sb.append("function");
 568 
 569         if (ident != null) {
 570             sb.append(' ');
 571             ident.toString(sb, printTypes);
 572         }
 573 
 574         sb.append('(');
 575 
 576         for (final Iterator<IdentNode> iter = parameters.iterator(); iter.hasNext(); ) {
 577             final IdentNode parameter = iter.next();
 578             if (parameter.getSymbol() != null) {
 579                 sb.append('[').append(parameter.getType()).append(']').append(' ');
 580             }
 581             parameter.toString(sb, printTypes);
 582             if (iter.hasNext()) {
 583                 sb.append(", ");
 584             }
 585         }
 586 
 587         sb.append(')');
 588     }
 589 
 590     @Override
 591     public int getFlags() {
 592         return flags;
 593     }
 594 
 595     @Override
 596     public boolean getFlag(final int flag) {
 597         return (flags & flag) != 0;
 598     }
 599 
 600     @Override
 601     public FunctionNode setFlags(final LexicalContext lc, final int flags) {
 602         if (this.flags == flags) {
 603             return this;
 604         }
 605         return Node.replaceInLexicalContext(
 606                 lc,
 607                 this,
 608                 new FunctionNode(
 609                         this,
 610                         lastToken,
 611                         endParserState,
 612                         flags,
 613                         name,
 614                         returnType,
 615                         compileUnit,
 616                         body,
 617                         parameters,
 618                         thisProperties,
 619                         rootClass, source, namespace));
 620     }
 621 
 622     @Override
 623     public FunctionNode clearFlag(final LexicalContext lc, final int flag) {
 624         return setFlags(lc, flags & ~flag);
 625     }
 626 
 627     @Override
 628     public FunctionNode setFlag(final LexicalContext lc, final int flag) {
 629         return setFlags(lc, flags | flag);
 630     }
 631 
 632     /**
 633      * Returns the debug flags for this function.
 634      *
 635      * @return the debug flags
 636      */
 637     public int getDebugFlags() {
 638         return debugFlags;
 639     }
 640 
 641     /**
 642      * Checks whether a debug flag is set for this function.
 643      *
 644      * @param debugFlag the debug flag
 645      * @return true if the flag is set
 646      */
 647     public boolean getDebugFlag(final int debugFlag) {
 648         return (debugFlags & debugFlag) != 0;
 649     }
 650 
 651     /**
 652      * Returns true if the function is the top-level program.
 653      * @return True if this function node represents the top-level program.
 654      */
 655     public boolean isProgram() {
 656         return getFlag(IS_PROGRAM);
 657     }
 658 
 659     /**
 660      * Returns true if the function contains at least one optimistic operation (and thus can be deoptimized).
 661      * @return true if the function contains at least one optimistic operation (and thus can be deoptimized).
 662      */
 663     public boolean canBeDeoptimized() {
 664         return getFlag(IS_DEOPTIMIZABLE);
 665     }
 666 
 667     /**
 668      * Check if this function has a call expression for the identifier "eval" (that is, {@code eval(...)}).
 669      *
 670      * @return true if {@code eval} is called.
 671      */
 672     public boolean hasEval() {
 673         return getFlag(HAS_EVAL);
 674     }
 675 
 676     /**
 677      * Returns true if a function nested (directly or transitively) within this function {@link #hasEval()}.
 678      *
 679      * @return true if a nested function calls {@code eval}.
 680      */
 681     public boolean hasNestedEval() {
 682         return getFlag(HAS_NESTED_EVAL);
 683     }
 684 
 685     /**
 686      * Get the first token for this function
 687      * @return the first token
 688      */
 689     public long getFirstToken() {
 690         return firstToken;
 691     }
 692 
 693     /**
 694      * Check whether this function has nested function declarations
 695      * @return true if nested function declarations exist
 696      */
 697     public boolean hasDeclaredFunctions() {
 698         return getFlag(HAS_FUNCTION_DECLARATIONS);
 699     }
 700 
 701     /**
 702      * Check if this function's generated Java method needs a {@code callee} parameter. Functions that need access to
 703      * their parent scope, functions that reference themselves, and non-strict functions that need an Arguments object
 704      * (since it exposes {@code arguments.callee} property) will need to have a callee parameter. We also return true
 705      * for split functions to make sure symbols slots are the same in the main and split methods.
 706      *
 707      * A function that has had an apply(this,arguments) turned into a call doesn't need arguments anymore, but still
 708      * has to fit the old callsite, thus, we require a dummy callee parameter for those functions as well
 709      *
 710      * @return true if the function's generated Java method needs a {@code callee} parameter.
 711      */
 712     public boolean needsCallee() {
 713         // NOTE: we only need isSplit() here to ensure that :scope can never drop below slot 2 for splitting array units.
 714         return needsParentScope() || usesSelfSymbol() || isSplit() || (needsArguments() && !isStrict()) || hasApplyToCallSpecialization();
 715     }
 716 
 717     /**
 718      * Return {@code true} if this function makes use of the {@code this} object.
 719      *
 720      * @return true if function uses {@code this} object
 721      */
 722     public boolean usesThis() {
 723         return getFlag(USES_THIS);
 724     }
 725 
 726 
 727     /**
 728      * Return true if function contains an apply to call transform
 729      * @return true if this function has transformed apply to call
 730      */
 731     public boolean hasApplyToCallSpecialization() {
 732         return getFlag(HAS_APPLY_TO_CALL_SPECIALIZATION);
 733     }
 734 
 735     /**
 736      * Get the identifier for this function, this is its symbol.
 737      * @return the identifier as an IdentityNode
 738      */
 739     public IdentNode getIdent() {
 740         return ident;
 741     }
 742 
 743     /**
 744      * Get the function body
 745      * @return the function body
 746      */
 747     public Block getBody() {
 748         return body;
 749     }
 750 
 751     /**
 752      * Reset the function body
 753      * @param lc lexical context
 754      * @param body new body
 755      * @return new function node if body changed, same if not
 756      */
 757     public FunctionNode setBody(final LexicalContext lc, final Block body) {
 758         if (this.body == body) {
 759             return this;
 760         }
 761         return Node.replaceInLexicalContext(
 762                 lc,
 763                 this,
 764                 new FunctionNode(
 765                         this,
 766                         lastToken,
 767                         endParserState,
 768                         flags |
 769                             (body.needsScope() ?
 770                                     FunctionNode.HAS_SCOPE_BLOCK :
 771                                     0),
 772                         name,
 773                         returnType,
 774                         compileUnit,
 775                         body,
 776                         parameters,
 777                         thisProperties,
 778                         rootClass, source, namespace));
 779     }
 780 
 781     /**
 782      * Does this function's method needs to be variable arity (gather all script-declared parameters in a final
 783      * {@code Object[]} parameter. Functions that need to have the "arguments" object as well as functions that simply
 784      * declare too many arguments for JVM to handle with fixed arity will need to be variable arity.
 785      * @return true if the Java method in the generated code that implements this function needs to be variable arity.
 786      * @see #needsArguments()
 787      * @see LinkerCallSite#ARGLIMIT
 788      */
 789     public boolean isVarArg() {
 790         return needsArguments() || parameters.size() > LinkerCallSite.ARGLIMIT;
 791     }
 792 
 793     /**
 794      * Was this function declared in a dynamic context, i.e. in a with or eval style
 795      * chain
 796      * @return true if in dynamic context
 797      */
 798     public boolean inDynamicContext() {
 799         return getFlag(IN_DYNAMIC_CONTEXT);
 800     }
 801 
 802     /**
 803      * Check whether a function would need dynamic scope, which is does if it has
 804      * evals and isn't strict.
 805      * @return true if dynamic scope is needed
 806      */
 807     public boolean needsDynamicScope() {
 808         // Function has a direct eval in it (so a top-level "var ..." in the eval code can introduce a new
 809         // variable into the function's scope), and it isn't strict (as evals in strict functions get an
 810         // isolated scope).
 811         return hasEval() && !isStrict();
 812     }
 813 
 814     /**
 815      * Flag this function as declared in a dynamic context
 816      * @param lc lexical context
 817      * @return new function node, or same if unmodified
 818      */
 819     public FunctionNode setInDynamicContext(final LexicalContext lc) {
 820         return setFlag(lc, IN_DYNAMIC_CONTEXT);
 821     }
 822 
 823     /**
 824      * Returns true if this function needs to have an Arguments object defined as a local variable named "arguments".
 825      * Functions that use "arguments" as identifier and don't define it as a name of a parameter or a nested function
 826      * (see ECMAScript 5.1 Chapter 10.5), as well as any function that uses eval or with, or has a nested function that
 827      * does the same, will have an "arguments" object. Also, if this function is a script, it will not have an
 828      * "arguments" object, because it does not have local variables; rather the Global object will have an explicit
 829      * "arguments" property that provides command-line arguments for the script.
 830      * @return true if this function needs an arguments object.
 831      */
 832     public boolean needsArguments() {
 833         // uses "arguments" or calls eval, but it does not redefine "arguments", and finally, it's not a script, since
 834         // for top-level script, "arguments" is picked up from Context by Global.init() instead.
 835         return getFlag(MAYBE_NEEDS_ARGUMENTS) && !getFlag(DEFINES_ARGUMENTS) && !isProgram();
 836     }
 837 
 838     /**
 839      * Returns true if this function needs access to its parent scope. Functions referencing variables outside their
 840      * scope (including global variables), as well as functions that call eval or have a with block, or have nested
 841      * functions that call eval or have a with block, will need a parent scope. Top-level script functions also need a
 842      * parent scope since they might be used from within eval, and eval will need an externally passed scope.
 843      * @return true if the function needs parent scope.
 844      */
 845     public boolean needsParentScope() {
 846         return getFlag(NEEDS_PARENT_SCOPE);
 847     }
 848 
 849     /**
 850      * Set the number of properties assigned to the this object in this function.
 851      * @param lc the current lexical context.
 852      * @param thisProperties number of properties
 853      * @return a potentially modified function node
 854      */
 855     public FunctionNode setThisProperties(final LexicalContext lc, final int thisProperties) {
 856         if (this.thisProperties == thisProperties) {
 857             return this;
 858         }
 859         return Node.replaceInLexicalContext(
 860                 lc,
 861                 this,
 862                 new FunctionNode(
 863                         this,
 864                         lastToken,
 865                         endParserState,
 866                         flags,
 867                         name,
 868                         returnType,
 869                         compileUnit,
 870                         body,
 871                         parameters,
 872                         thisProperties,
 873                         rootClass, source, namespace));
 874     }
 875 
 876     /**
 877      * Get the number of properties assigned to the this object in this function.
 878      * @return number of properties
 879      */
 880     public int getThisProperties() {
 881         return thisProperties;
 882     }
 883 
 884     /**
 885      * Returns true if any of the blocks in this function create their own scope.
 886      * @return true if any of the blocks in this function create their own scope.
 887      */
 888     public boolean hasScopeBlock() {
 889         return getFlag(HAS_SCOPE_BLOCK);
 890     }
 891 
 892     /**
 893      * Return the kind of this function
 894      * @see FunctionNode.Kind
 895      * @return the kind
 896      */
 897     public Kind getKind() {
 898         return kind;
 899     }
 900 
 901     /**
 902      * Return the last token for this function's code
 903      * @return last token
 904      */
 905     public long getLastToken() {
 906         return lastToken;
 907     }
 908 
 909     /**
 910      * Returns the end parser state for this function.
 911      * @return the end parser state for this function.
 912      */
 913     public Object getEndParserState() {
 914         return endParserState;
 915     }
 916 
 917     /**
 918      * Get the name of this function
 919      * @return the name
 920      */
 921     public String getName() {
 922         return name;
 923     }
 924 
 925     /**
 926      * Set the internal name for this function
 927      * @param lc    lexical context
 928      * @param name new name
 929      * @return new function node if changed, otherwise the same
 930      */
 931     public FunctionNode setName(final LexicalContext lc, final String name) {
 932         if (this.name.equals(name)) {
 933             return this;
 934         }
 935         return Node.replaceInLexicalContext(
 936                 lc,
 937                 this,
 938                 new FunctionNode(
 939                         this,
 940                         lastToken,
 941                         endParserState,
 942                         flags,
 943                         name,
 944                         returnType,
 945                         compileUnit,
 946                         body,
 947                         parameters,
 948                         thisProperties,
 949                         rootClass, source, namespace));
 950     }
 951 
 952     /**
 953      * Check if this function should have all its variables in its own scope. Split sub-functions, and
 954      * functions having with and/or eval blocks are such.
 955      *
 956      * @return true if all variables should be in scope
 957      */
 958     public boolean allVarsInScope() {
 959         return getFlag(HAS_ALL_VARS_IN_SCOPE);
 960     }
 961 
 962     /**
 963      * Checks if this function is split into several smaller fragments.
 964      *
 965      * @return true if this function is split into several smaller fragments.
 966      */
 967     public boolean isSplit() {
 968         return getFlag(IS_SPLIT);
 969     }
 970 
 971     /**
 972      * Get the parameters to this function
 973      * @return a list of IdentNodes which represent the function parameters, in order
 974      */
 975     public List<IdentNode> getParameters() {
 976         return Collections.unmodifiableList(parameters);
 977     }
 978 
 979     /**
 980      * Return the number of parameters to this function
 981      * @return the number of parameters
 982      */
 983     public int getNumOfParams() {
 984         return parameters.size();
 985     }
 986 
 987     /**
 988      * Returns the identifier for a named parameter at the specified position in this function's parameter list.
 989      * @param index the parameter's position.
 990      * @return the identifier for the requested named parameter.
 991      * @throws IndexOutOfBoundsException if the index is invalid.
 992      */
 993     public IdentNode getParameter(final int index) {
 994         return parameters.get(index);
 995     }
 996 
 997     /**
 998      * Reset the compile unit used to compile this function
 999      * @see Compiler
1000      * @param  lc lexical context
1001      * @param  parameters the compile unit
1002      * @return function node or a new one if state was changed
1003      */
1004     public FunctionNode setParameters(final LexicalContext lc, final List<IdentNode> parameters) {
1005         if (this.parameters == parameters) {
1006             return this;
1007         }
1008         return Node.replaceInLexicalContext(
1009                 lc,
1010                 this,
1011                 new FunctionNode(
1012                         this,
1013                         lastToken,
1014                         endParserState,
1015                         flags,
1016                         name,
1017                         returnType,
1018                         compileUnit,
1019                         body,
1020                         parameters,
1021                         thisProperties,
1022                         rootClass, source, namespace));
1023     }
1024 
1025     /**
1026      * Check if this function is created as a function declaration (as opposed to function expression)
1027      * @return true if function is declared.
1028      */
1029     public boolean isDeclared() {
1030         return getFlag(IS_DECLARED);
1031     }
1032 
1033     /**
1034      * Check if this function is anonymous
1035      * @return true if function is anonymous
1036      */
1037     public boolean isAnonymous() {
1038         return getFlag(IS_ANONYMOUS);
1039     }
1040 
1041     /**
1042      * Does this function use its self symbol - this is needed only for self-referencing named function expressions.
1043      * Self-referencing declared functions won't have this flag set, as they can access their own symbol through the
1044      * scope (since they're bound to the symbol with their name in their enclosing scope).
1045      * @return true if this function node is a named function expression that uses the symbol for itself.
1046      */
1047     public boolean usesSelfSymbol() {
1048         return getFlag(USES_SELF_SYMBOL);
1049     }
1050 
1051     /**
1052      * Returns true if this is a named function expression (that is, it isn't a declared function, it isn't an
1053      * anonymous function expression, and it isn't a program).
1054      * @return true if this is a named function expression
1055      */
1056     public boolean isNamedFunctionExpression() {
1057         return !getFlag(IS_PROGRAM | IS_ANONYMOUS | IS_DECLARED);
1058     }
1059 
1060     @Override
1061     public Type getType() {
1062         return FUNCTION_TYPE;
1063     }
1064 
1065     @Override
1066     public Type getWidestOperationType() {
1067         return FUNCTION_TYPE;
1068     }
1069 
1070     /**
1071      * Get the return type for this function. Return types can be specialized
1072      * if the compiler knows them, but parameters cannot, as they need to go through
1073      * appropriate object conversion
1074      *
1075      * @return the return type
1076      */
1077     public Type getReturnType() {
1078         return returnType;
1079     }
1080 
1081     /**
1082      * Set the function return type
1083      * @param lc lexical context
1084      * @param returnType new return type
1085      * @return function node or a new one if state was changed
1086      */
1087     public FunctionNode setReturnType(final LexicalContext lc, final Type returnType) {
1088         //we never bother with object types narrower than objects, that will lead to byte code verification errors
1089         //as for instance even if we know we are returning a string from a method, the code generator will always
1090         //treat it as an object, at least for now
1091         final Type type = returnType.isObject() ? Type.OBJECT : returnType;
1092         if (this.returnType == type) {
1093             return this;
1094         }
1095         return Node.replaceInLexicalContext(
1096             lc,
1097             this,
1098             new FunctionNode(
1099                 this,
1100                 lastToken,
1101                 endParserState,
1102                 flags,
1103                 name,
1104                 type,
1105                 compileUnit,
1106                 body,
1107                 parameters,
1108                 thisProperties,
1109                 rootClass, source, namespace
1110                 ));
1111    }
1112 
1113     /**
1114      * Check if the function is generated in strict mode
1115      * @return true if strict mode enabled for function
1116      */
1117     public boolean isStrict() {
1118         return getFlag(IS_STRICT);
1119     }
1120 
1121     /**
1122      * Returns true if this function node has been cached.
1123      * @return true if this function node has been cached.
1124      */
1125     public boolean isCached() {
1126         return getFlag(IS_CACHED);
1127     }
1128 
1129     /**
1130      * Mark this function node as having been cached.
1131      * @param lc the current lexical context
1132      * @return a function node equivalent to this one, with the flag set.
1133      */
1134     public FunctionNode setCached(final LexicalContext lc) {
1135         return setFlag(lc, IS_CACHED);
1136     }
1137 
1138     /**
1139      * Checks if the function is generated in strong mode.
1140      *
1141      * @return true if strong mode enabled for function
1142      */
1143     public boolean isStrong() {
1144         return getFlag(ES6_IS_STRONG);
1145     }
1146 
1147     /**
1148      * Checks if this is an ES6 method.
1149      *
1150      * @return true if the ES6 method flag is set
1151      */
1152     public boolean isMethod() {
1153         return getFlag(ES6_IS_METHOD);
1154     }
1155 
1156     /**
1157      * Checks if this function uses the ES6 super binding.
1158      *
1159      * @return true if the ES6 super flag is set
1160      */
1161     public boolean usesSuper() {
1162         return getFlag(ES6_USES_SUPER);
1163     }
1164 
1165     /**
1166      * Checks if this function directly uses the super binding.
1167      *
1168      * @return true if the ES6 has-direct-super flag is set
1169      */
1170     public boolean hasDirectSuper() {
1171         return getFlag(ES6_HAS_DIRECT_SUPER);
1172     }
1173 
1174     /**
1175      * Checks if this is an ES6 class constructor.
1176      *
1177      * @return true if the ES6 class constructor flag is set
1178      */
1179     public boolean isClassConstructor() {
1180         return getFlag(ES6_IS_CLASS_CONSTRUCTOR);
1181     }
1182 
1183     /**
1184      * Checks if this is an ES6 subclass constructor.
1185      *
1186      * @return true if the ES6 subclass constructor flag is set
1187      */
1188     public boolean isSubclassConstructor() {
1189         return getFlag(ES6_IS_SUBCLASS_CONSTRUCTOR);
1190     }
1191 
1192     /**
1193      * Checks if this function uses the ES6 new-targert.
1194      *
1195      * @return true if the ES6 new-target flag is set
1196      */
1197     public boolean usesNewTarget() {
1198         return getFlag(ES6_USES_NEW_TARGET);
1199     }
1200 
1201     /**
1202      * Checks if this is an ES6 module.
1203      *
1204      * @return true if this is an ES6 module
1205      */
1206     public boolean isModule() {
1207         return kind == Kind.MODULE;
1208     }
1209 
1210     /**
1211      * Returns the functions's ES6 module.
1212      *
1213      * @return the module, or null if this function is not part of one
1214      */
1215     public Module getModule() {
1216         return module;
1217     }
1218 
1219     /**
1220      * Get the compile unit used to compile this function
1221      * @see Compiler
1222      * @return the compile unit
1223      */
1224     @Override
1225     public CompileUnit getCompileUnit() {
1226         return compileUnit;
1227     }
1228 
1229     /**
1230      * Reset the compile unit used to compile this function
1231      * @see Compiler
1232      * @param lc lexical context
1233      * @param compileUnit the compile unit
1234      * @return function node or a new one if state was changed
1235      */
1236     public FunctionNode setCompileUnit(final LexicalContext lc, final CompileUnit compileUnit) {
1237         if (this.compileUnit == compileUnit) {
1238             return this;
1239         }
1240         return Node.replaceInLexicalContext(
1241                 lc,
1242                 this,
1243                 new FunctionNode(
1244                         this,
1245                         lastToken,
1246                         endParserState,
1247                         flags,
1248                         name,
1249                         returnType,
1250                         compileUnit,
1251                         body,
1252                         parameters,
1253                         thisProperties,
1254                         rootClass, source, namespace));
1255     }
1256 
1257     /**
1258      * Create a temporary variable to the current frame.
1259      *
1260      * @param block that needs the temporary
1261      * @param type  Strong type of symbol.
1262      * @param node  Primary node to use symbol.
1263      *
1264      * @return Symbol used.
1265      */
1266 
1267     /**
1268      * Get the symbol for a compiler constant, or null if not available (yet)
1269      * @param cc compiler constant
1270      * @return symbol for compiler constant, or null if not defined yet (for example in Lower)
1271      */
1272     public Symbol compilerConstant(final CompilerConstants cc) {
1273         return body.getExistingSymbol(cc.symbolName());
1274     }
1275 
1276     /**
1277      * Get the root class that this function node compiles to
1278      * @return root class
1279      */
1280     public Class<?> getRootClass() {
1281         return rootClass;
1282     }
1283 
1284     /**
1285      * Reset the root class that this function is compiled to
1286      * @see Compiler
1287      * @param lc lexical context
1288      * @param rootClass root class
1289      * @return function node or a new one if state was changed
1290      */
1291     public FunctionNode setRootClass(final LexicalContext lc, final Class<?> rootClass) {
1292         if (this.rootClass == rootClass) {
1293             return this;
1294         }
1295         return Node.replaceInLexicalContext(
1296                 lc,
1297                 this,
1298                 new FunctionNode(
1299                         this,
1300                         lastToken,
1301                         endParserState,
1302                         flags,
1303                         name,
1304                         returnType,
1305                         compileUnit,
1306                         body,
1307                         parameters,
1308                         thisProperties,
1309                         rootClass, source, namespace));
1310     }
1311 }