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