private void OptimizeFunction(OptFunctionNode theFunction) { if (theFunction.fnode.RequiresActivation()) { return; } inDirectCallFunction = theFunction.IsTargetOfDirectCall(); this.theFunction = theFunction; ObjArray statementsArray = new ObjArray(); BuildStatementList_r(theFunction.fnode, statementsArray); Node[] theStatementNodes = new Node[statementsArray.Size()]; statementsArray.ToArray(theStatementNodes); Block.RunFlowAnalyzes(theFunction, theStatementNodes); if (!theFunction.fnode.RequiresActivation()) { parameterUsedInNumberContext = false; foreach (Node theStatementNode in theStatementNodes) { RewriteForNumberVariables(theStatementNode, NumberType); } theFunction.SetParameterNumberContext(parameterUsedInNumberContext); } }
/// <summary>Returns an array of all functions in the given script.</summary> /// <remarks>Returns an array of all functions in the given script.</remarks> private static DebuggableScript[] GetAllFunctions(DebuggableScript function) { ObjArray functions = new ObjArray(); CollectFunctions_r(function, functions); DebuggableScript[] result = new DebuggableScript[functions.Size()]; functions.ToArray(result); return result; }
private void InitScriptNodesData(ScriptNode scriptOrFn) { ObjArray x = new ObjArray(); CollectScriptNodes_r(scriptOrFn, x); int count = x.Size(); scriptOrFnNodes = new ScriptNode[count]; x.ToArray(scriptOrFnNodes); scriptOrFnIndexes = new ObjToIntMap(count); for (int i = 0; i != count; ++i) { scriptOrFnIndexes.Put(scriptOrFnNodes[i], i); } }
private static Block[] BuildBlocks(Node[] statementNodes) { // a mapping from each target node to the block it begins IDictionary<Node, Block.FatBlock> theTargetBlocks = new Dictionary<Node, Block.FatBlock>(); ObjArray theBlocks = new ObjArray(); // there's a block that starts at index 0 int beginNodeIndex = 0; for (int i = 0; i < statementNodes.Length; i++) { switch (statementNodes[i].GetType()) { case Token.TARGET: { if (i != beginNodeIndex) { Block.FatBlock fb = NewFatBlock(beginNodeIndex, i - 1); if (statementNodes[beginNodeIndex].GetType() == Token.TARGET) { theTargetBlocks.Put(statementNodes[beginNodeIndex], fb); } theBlocks.Add(fb); // start the next block at this node beginNodeIndex = i; } break; } case Token.IFNE: case Token.IFEQ: case Token.GOTO: { Block.FatBlock fb = NewFatBlock(beginNodeIndex, i); if (statementNodes[beginNodeIndex].GetType() == Token.TARGET) { theTargetBlocks.Put(statementNodes[beginNodeIndex], fb); } theBlocks.Add(fb); // start the next block at the next node beginNodeIndex = i + 1; break; } } } if (beginNodeIndex != statementNodes.Length) { Block.FatBlock fb = NewFatBlock(beginNodeIndex, statementNodes.Length - 1); if (statementNodes[beginNodeIndex].GetType() == Token.TARGET) { theTargetBlocks.Put(statementNodes[beginNodeIndex], fb); } theBlocks.Add(fb); } // build successor and predecessor links for (int i_1 = 0; i_1 < theBlocks.Size(); i_1++) { Block.FatBlock fb = (Block.FatBlock)(theBlocks.Get(i_1)); Node blockEndNode = statementNodes[fb.realBlock.itsEndNodeIndex]; int blockEndNodeType = blockEndNode.GetType(); if ((blockEndNodeType != Token.GOTO) && (i_1 < (theBlocks.Size() - 1))) { Block.FatBlock fallThruTarget = (Block.FatBlock)(theBlocks.Get(i_1 + 1)); fb.AddSuccessor(fallThruTarget); fallThruTarget.AddPredecessor(fb); } if ((blockEndNodeType == Token.IFNE) || (blockEndNodeType == Token.IFEQ) || (blockEndNodeType == Token.GOTO)) { Node target = ((Jump)blockEndNode).target; Block.FatBlock branchTargetBlock = theTargetBlocks.Get(target); target.PutProp(Node.TARGETBLOCK_PROP, branchTargetBlock.realBlock); fb.AddSuccessor(branchTargetBlock); branchTargetBlock.AddPredecessor(fb); } } Block[] result = new Block[theBlocks.Size()]; for (int i_2 = 0; i_2 < theBlocks.Size(); i_2++) { Block.FatBlock fb = (Block.FatBlock)(theBlocks.Get(i_2)); Block b = fb.realBlock; b.itsSuccessors = fb.GetSuccessors(); b.itsPredecessors = fb.GetPredecessors(); b.itsBlockID = i_2; result[i_2] = b; } return result; }