src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Block.java

Print this page




  39 
  40 /**
  41  * IR representation for a list of statements.
  42  */
  43 @Immutable
  44 public class Block extends Node implements BreakableNode, Terminal, Flags<Block> {
  45     private static final long serialVersionUID = 1L;
  46 
  47     /** List of statements */
  48     protected final List<Statement> statements;
  49 
  50     /** Symbol table - keys must be returned in the order they were put in. */
  51     protected final Map<String, Symbol> symbols;
  52 
  53     /** Entry label. */
  54     private final Label entryLabel;
  55 
  56     /** Break label. */
  57     private final Label breakLabel;
  58 
  59     /** Does the block/function need a new scope? */
  60     protected final int flags;
  61 
  62     /**
  63      * @see JoinPredecessor
  64      */
  65     private final LocalVariableConversion conversion;
  66 
  67     /** Flag indicating that this block needs scope */
  68     public static final int NEEDS_SCOPE = 1 << 0;
  69 
  70     /**
  71      * Is this block tagged as terminal based on its contents
  72      * (usually the last statement)
  73      */
  74     public static final int IS_TERMINAL = 1 << 2;
  75 
  76     /**
  77      * Is this block the eager global scope - i.e. the original program. This isn't true for the
  78      * outermost level of recompiles
  79      */
  80     public static final int IS_GLOBAL_SCOPE = 1 << 3;
  81 
  82     /**





  83      * Constructor
  84      *
  85      * @param token      The first token of the block
  86      * @param finish     The index of the last character
  87      * @param flags      The flags of the block
  88      * @param statements All statements in the block
  89      */
  90     public Block(final long token, final int finish, final int flags, final Statement... statements) {
  91         super(token, finish);
  92 
  93         this.statements = Arrays.asList(statements);
  94         this.symbols    = new LinkedHashMap<>();
  95         this.entryLabel = new Label("block_entry");
  96         this.breakLabel = new Label("block_break");
  97         final int len = statements.length;
  98         final int terminalFlags = len > 0 && statements[len - 1].hasTerminalFlags() ? IS_TERMINAL : 0;
  99         this.flags = terminalFlags | flags;
 100         this.conversion = null;
 101     }
 102 
 103     /**
 104      * Constructs a new block
 105      *
 106      * @param token The first token of the block
 107      * @param finish The index of the last character
 108      * @param statements All statements in the block
 109      */
 110     public Block(final long token, final int finish, final Statement...statements){
 111         this(token, finish, 0, statements);
 112     }
 113 
 114     /**
 115      * Constructs a new block
 116      *
 117      * @param token The first token of the block
 118      * @param finish The index of the last character
 119      * @param statements All statements in the block
 120      */
 121     public Block(final long token, final int finish, final List<Statement> statements){
 122         this(token, finish, 0, statements);
 123     }
 124 
 125     /**
 126      * Constructor
 127      *
 128      * @param token      The first token of the block
 129      * @param finish     The index of the last character
 130      * @param flags      The flags of the block
 131      * @param statements All statements in the block
 132      */
 133     public Block(final long token, final int finish, final int flags, final List<Statement> statements) {
 134         this(token, finish, flags, statements.toArray(new Statement[statements.size()]));
 135     }
 136 
 137     private Block(final Block block, final int finish, final List<Statement> statements, final int flags, final Map<String, Symbol> symbols, final LocalVariableConversion conversion) {
 138         super(block, finish);
 139         this.statements = statements;
 140         this.flags      = flags;
 141         this.symbols    = new LinkedHashMap<>(symbols); //todo - symbols have no dependencies on any IR node and can as far as we understand it be shallow copied now
 142         this.entryLabel = new Label(block.entryLabel);


 347         return Node.replaceInLexicalContext(lc, this, new Block(this, Math.max(finish, lastFinish), statements, flags, symbols, conversion));
 348     }
 349 
 350     /**
 351      * Add or overwrite an existing symbol in the block
 352      *
 353      * @param lc     get lexical context
 354      * @param symbol symbol
 355      */
 356     public void putSymbol(final LexicalContext lc, final Symbol symbol) {
 357         symbols.put(symbol.getName(), symbol);
 358     }
 359 
 360     /**
 361      * Check whether scope is necessary for this Block
 362      *
 363      * @return true if this function needs a scope
 364      */
 365     public boolean needsScope() {
 366         return (flags & NEEDS_SCOPE) == NEEDS_SCOPE;









 367     }
 368 
 369     @Override
 370     public Block setFlags(final LexicalContext lc, final int flags) {
 371         if (this.flags == flags) {
 372             return this;
 373         }
 374         return Node.replaceInLexicalContext(lc, this, new Block(this, finish, statements, flags, symbols, conversion));
 375     }
 376 
 377     @Override
 378     public Block clearFlag(final LexicalContext lc, final int flag) {
 379         return setFlags(lc, flags & ~flag);
 380     }
 381 
 382     @Override
 383     public Block setFlag(final LexicalContext lc, final int flag) {
 384         return setFlags(lc, flags | flag);
 385     }
 386 




  39 
  40 /**
  41  * IR representation for a list of statements.
  42  */
  43 @Immutable
  44 public class Block extends Node implements BreakableNode, Terminal, Flags<Block> {
  45     private static final long serialVersionUID = 1L;
  46 
  47     /** List of statements */
  48     protected final List<Statement> statements;
  49 
  50     /** Symbol table - keys must be returned in the order they were put in. */
  51     protected final Map<String, Symbol> symbols;
  52 
  53     /** Entry label. */
  54     private final Label entryLabel;
  55 
  56     /** Break label. */
  57     private final Label breakLabel;
  58 
  59     /** Does the block/function need a new scope? Is this synthetic? */
  60     protected final int flags;
  61 
  62     /**
  63      * @see JoinPredecessor
  64      */
  65     private final LocalVariableConversion conversion;
  66 
  67     /** Flag indicating that this block needs scope */
  68     public static final int NEEDS_SCOPE = 1 << 0;
  69 
  70     /**
  71      * Is this block tagged as terminal based on its contents
  72      * (usually the last statement)
  73      */
  74     public static final int IS_TERMINAL = 1 << 2;
  75 
  76     /**
  77      * Is this block the eager global scope - i.e. the original program. This isn't true for the
  78      * outermost level of recompiles
  79      */
  80     public static final int IS_GLOBAL_SCOPE = 1 << 3;
  81 
  82     /**
  83      * Is this block a synthetic one introduced by Parser?
  84      */
  85     public static final int IS_SYNTHETIC = 1 << 4;
  86 
  87     /**
  88      * Constructor
  89      *
  90      * @param token      The first token of the block
  91      * @param finish     The index of the last character
  92      * @param flags      The flags of the block
  93      * @param statements All statements in the block
  94      */
  95     public Block(final long token, final int finish, final int flags, final Statement... statements) {
  96         super(token, finish);
  97 
  98         this.statements = Arrays.asList(statements);
  99         this.symbols    = new LinkedHashMap<>();
 100         this.entryLabel = new Label("block_entry");
 101         this.breakLabel = new Label("block_break");
 102         final int len = statements.length;
 103         final int terminalFlags = len > 0 && statements[len - 1].hasTerminalFlags() ? IS_TERMINAL : 0;
 104         this.flags = terminalFlags | flags;
 105         this.conversion = null;
 106     }
 107 
 108     /**
 109      * Constructs a new block
 110      *
 111      * @param token The first token of the block
 112      * @param finish The index of the last character
 113      * @param statements All statements in the block
 114      */
 115     public Block(final long token, final int finish, final Statement...statements){
 116         this(token, finish, IS_SYNTHETIC, statements);
 117     }
 118 
 119     /**
 120      * Constructs a new block
 121      *
 122      * @param token The first token of the block
 123      * @param finish The index of the last character
 124      * @param statements All statements in the block
 125      */
 126     public Block(final long token, final int finish, final List<Statement> statements){
 127         this(token, finish, IS_SYNTHETIC, statements);
 128     }
 129 
 130     /**
 131      * Constructor
 132      *
 133      * @param token      The first token of the block
 134      * @param finish     The index of the last character
 135      * @param flags      The flags of the block
 136      * @param statements All statements in the block
 137      */
 138     public Block(final long token, final int finish, final int flags, final List<Statement> statements) {
 139         this(token, finish, flags, statements.toArray(new Statement[statements.size()]));
 140     }
 141 
 142     private Block(final Block block, final int finish, final List<Statement> statements, final int flags, final Map<String, Symbol> symbols, final LocalVariableConversion conversion) {
 143         super(block, finish);
 144         this.statements = statements;
 145         this.flags      = flags;
 146         this.symbols    = new LinkedHashMap<>(symbols); //todo - symbols have no dependencies on any IR node and can as far as we understand it be shallow copied now
 147         this.entryLabel = new Label(block.entryLabel);


 352         return Node.replaceInLexicalContext(lc, this, new Block(this, Math.max(finish, lastFinish), statements, flags, symbols, conversion));
 353     }
 354 
 355     /**
 356      * Add or overwrite an existing symbol in the block
 357      *
 358      * @param lc     get lexical context
 359      * @param symbol symbol
 360      */
 361     public void putSymbol(final LexicalContext lc, final Symbol symbol) {
 362         symbols.put(symbol.getName(), symbol);
 363     }
 364 
 365     /**
 366      * Check whether scope is necessary for this Block
 367      *
 368      * @return true if this function needs a scope
 369      */
 370     public boolean needsScope() {
 371         return (flags & NEEDS_SCOPE) == NEEDS_SCOPE;
 372     }
 373 
 374     /**
 375      * Check whether this block is synthetic or not.
 376      *
 377      * @return true if this is a synthetic block
 378      */
 379     public boolean isSynthetic() {
 380         return (flags & IS_SYNTHETIC) == IS_SYNTHETIC;
 381     }
 382 
 383     @Override
 384     public Block setFlags(final LexicalContext lc, final int flags) {
 385         if (this.flags == flags) {
 386             return this;
 387         }
 388         return Node.replaceInLexicalContext(lc, this, new Block(this, finish, statements, flags, symbols, conversion));
 389     }
 390 
 391     @Override
 392     public Block clearFlag(final LexicalContext lc, final int flag) {
 393         return setFlags(lc, flags & ~flag);
 394     }
 395 
 396     @Override
 397     public Block setFlag(final LexicalContext lc, final int flag) {
 398         return setFlags(lc, flags | flag);
 399     }
 400