Base type for AstRoot and FunctionNode nodes, which need to collect much of the same information.
Inheritance: Scope
Esempio n. 1
0
		public void Transform(ScriptNode tree)
		{
			TransformCompilationUnit(tree);
			for (int i = 0; i != tree.GetFunctionCount(); ++i)
			{
				FunctionNode fn = tree.GetFunctionNode(i);
				Transform(fn);
			}
		}
Esempio n. 2
0
		// It is assumed that (NumberType | AnyType) == AnyType
		internal virtual void Optimize(ScriptNode scriptOrFn)
		{
			//  run on one function at a time for now
			int functionCount = scriptOrFn.GetFunctionCount();
			for (int i = 0; i != functionCount; ++i)
			{
				OptFunctionNode f = OptFunctionNode.Get(scriptOrFn, i);
				OptimizeFunction(f);
			}
		}
Esempio n. 3
0
		private void TransformCompilationUnit(ScriptNode tree)
		{
			loops = new ObjArray();
			loopEnds = new ObjArray();
			// to save against upchecks if no finally blocks are used.
			hasFinally = false;
			// Flatten all only if we are not using scope objects for block scope
			bool createScopeObjects = tree.GetType() != Token.FUNCTION || ((FunctionNode)tree).RequiresActivation();
			tree.FlattenSymbolTable(!createScopeObjects);
			//uncomment to print tree before transformation
			bool inStrictMode = tree is AstRoot && ((AstRoot)tree).IsInStrictMode();
			TransformCompilationUnit_r(tree, tree, tree, createScopeObjects, inStrictMode);
		}
Esempio n. 4
0
		public virtual object Compile(CompilerEnvirons compilerEnv, ScriptNode tree, string encodedSource, bool returnFunction)
		{
			int serial;
			lock (globalLock)
			{
				serial = ++globalSerialClassCounter;
			}
			string baseName = "c";
			if (tree.GetSourceName().Length > 0)
			{
				baseName = tree.GetSourceName().ReplaceAll("\\W", "_");
				if (!char.IsJavaIdentifierStart(baseName[0]))
				{
					baseName = "_" + baseName;
				}
			}
			string mainClassName = "org.mozilla.javascript.gen." + baseName + "_" + serial;
			byte[] mainClassBytes = CompileToClassFile(compilerEnv, mainClassName, tree, encodedSource, returnFunction);
			return new object[] { mainClassName, mainClassBytes };
		}
Esempio n. 5
0
		// fixupTable[i] = (label_index << 32) | fixup_site
		// ECF_ or Expression Context Flags constants: for now only TAIL
		public virtual InterpreterData Compile(CompilerEnvirons compilerEnv, ScriptNode tree, string encodedSource, bool returnFunction)
		{
			this.compilerEnv = compilerEnv;
			new NodeTransformer().Transform(tree);
			if (returnFunction)
			{
				scriptOrFn = tree.GetFunctionNode(0);
			}
			else
			{
				scriptOrFn = tree;
			}
			itsData = new InterpreterData(compilerEnv.GetLanguageVersion(), scriptOrFn.GetSourceName(), encodedSource, ((AstRoot)tree).IsInStrictMode());
			itsData.topLevel = true;
			if (returnFunction)
			{
				GenerateFunctionICode();
			}
			else
			{
				GenerateICodeFromTree(scriptOrFn);
			}
			return itsData;
		}
Esempio n. 6
0
		private static void CollectScriptNodes_r(ScriptNode n, ObjArray x)
		{
			x.Add(n);
			int nestedCount = n.GetFunctionCount();
			for (int i = 0; i != nestedCount; ++i)
			{
				CollectScriptNodes_r(n.GetFunctionNode(i), x);
			}
		}
Esempio n. 7
0
		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);
			}
		}
Esempio n. 8
0
		private static void InitOptFunctions_r(ScriptNode scriptOrFn)
		{
			for (int i = 0, N = scriptOrFn.GetFunctionCount(); i != N; ++i)
			{
				FunctionNode fn = scriptOrFn.GetFunctionNode(i);
				new OptFunctionNode(fn);
				InitOptFunctions_r(fn);
			}
		}
Esempio n. 9
0
		private void Transform(ScriptNode tree)
		{
			InitOptFunctions_r(tree);
			int optLevel = compilerEnv.GetOptimizationLevel();
			IDictionary<string, OptFunctionNode> possibleDirectCalls = null;
			if (optLevel > 0)
			{
				if (tree.GetType() == Token.SCRIPT)
				{
					int functionCount = tree.GetFunctionCount();
					for (int i = 0; i != functionCount; ++i)
					{
						OptFunctionNode ofn = OptFunctionNode.Get(tree, i);
						if (ofn.fnode.GetFunctionType() == FunctionNode.FUNCTION_STATEMENT)
						{
							string name = ofn.fnode.GetName();
							if (name.Length != 0)
							{
								if (possibleDirectCalls == null)
								{
									possibleDirectCalls = new Dictionary<string, OptFunctionNode>();
								}
								possibleDirectCalls.Put(name, ofn);
							}
						}
					}
				}
			}
			if (possibleDirectCalls != null)
			{
				directCallTargets = new ObjArray();
			}
			OptTransformer ot = new OptTransformer(possibleDirectCalls, directCallTargets);
			ot.Transform(tree);
			if (optLevel > 0)
			{
				(new Rhino.Optimizer.Optimizer()).Optimize(tree);
			}
		}
Esempio n. 10
0
		private Exception ReportClassFileFormatException(ScriptNode scriptOrFn, string message)
		{
			string msg = scriptOrFn is FunctionNode ? ScriptRuntime.GetMessage2("msg.while.compiling.fn", ((FunctionNode)scriptOrFn).GetFunctionName(), message) : ScriptRuntime.GetMessage1("msg.while.compiling.script", message);
			return Context.ReportRuntimeError(msg, scriptOrFn.GetSourceName(), scriptOrFn.GetLineno(), null, 0);
		}
Esempio n. 11
0
		public static Rhino.Optimizer.OptFunctionNode Get(ScriptNode scriptOrFn)
		{
			return (Rhino.Optimizer.OptFunctionNode)scriptOrFn.GetCompilerData();
		}
Esempio n. 12
0
		private void TransformCompilationUnit_r(ScriptNode tree, Node parent, Scope scope, bool createScopeObjects, bool inStrictMode)
		{
			Node node = null;
			for (; ; )
			{
				Node previous = null;
				if (node == null)
				{
					node = parent.GetFirstChild();
				}
				else
				{
					previous = node;
					node = node.GetNext();
				}
				if (node == null)
				{
					break;
				}
				int type = node.GetType();
				if (createScopeObjects && (type == Token.BLOCK || type == Token.LOOP || type == Token.ARRAYCOMP) && (node is Scope))
				{
					Scope newScope = (Scope)node;
					if (newScope.GetSymbolTable() != null)
					{
						// transform to let statement so we get a with statement
						// created to contain scoped let variables
						Node let = new Node(type == Token.ARRAYCOMP ? Token.LETEXPR : Token.LET);
						Node innerLet = new Node(Token.LET);
						let.AddChildToBack(innerLet);
						foreach (string name in newScope.GetSymbolTable().Keys)
						{
							innerLet.AddChildToBack(Node.NewString(Token.NAME, name));
						}
						newScope.SetSymbolTable(null);
						// so we don't transform again
						Node oldNode = node;
						node = ReplaceCurrent(parent, previous, node, let);
						type = node.GetType();
						let.AddChildToBack(oldNode);
					}
				}
				switch (type)
				{
					case Token.LABEL:
					case Token.SWITCH:
					case Token.LOOP:
					{
						loops.Push(node);
						loopEnds.Push(((Jump)node).target);
						break;
					}

					case Token.WITH:
					{
						loops.Push(node);
						Node leave = node.GetNext();
						if (leave.GetType() != Token.LEAVEWITH)
						{
							Kit.CodeBug();
						}
						loopEnds.Push(leave);
						break;
					}

					case Token.TRY:
					{
						Jump jump = (Jump)node;
						Node finallytarget = jump.GetFinally();
						if (finallytarget != null)
						{
							hasFinally = true;
							loops.Push(node);
							loopEnds.Push(finallytarget);
						}
						break;
					}

					case Token.TARGET:
					case Token.LEAVEWITH:
					{
						if (!loopEnds.IsEmpty() && loopEnds.Peek() == node)
						{
							loopEnds.Pop();
							loops.Pop();
						}
						break;
					}

					case Token.YIELD:
					{
						((FunctionNode)tree).AddResumptionPoint(node);
						break;
					}

					case Token.RETURN:
					{
						bool isGenerator = tree.GetType() == Token.FUNCTION && ((FunctionNode)tree).IsGenerator();
						if (isGenerator)
						{
							node.PutIntProp(Node.GENERATOR_END_PROP, 1);
						}
						if (!hasFinally)
						{
							break;
						}
						// skip the whole mess.
						Node unwindBlock = null;
						for (int i = loops.Size() - 1; i >= 0; i--)
						{
							Node n = (Node)loops.Get(i);
							int elemtype = n.GetType();
							if (elemtype == Token.TRY || elemtype == Token.WITH)
							{
								Node unwind;
								if (elemtype == Token.TRY)
								{
									Jump jsrnode = new Jump(Token.JSR);
									Node jsrtarget = ((Jump)n).GetFinally();
									jsrnode.target = jsrtarget;
									unwind = jsrnode;
								}
								else
								{
									unwind = new Node(Token.LEAVEWITH);
								}
								if (unwindBlock == null)
								{
									unwindBlock = new Node(Token.BLOCK, node.GetLineno());
								}
								unwindBlock.AddChildToBack(unwind);
							}
						}
						if (unwindBlock != null)
						{
							Node returnNode = node;
							Node returnExpr = returnNode.GetFirstChild();
							node = ReplaceCurrent(parent, previous, node, unwindBlock);
							if (returnExpr == null || isGenerator)
							{
								unwindBlock.AddChildToBack(returnNode);
							}
							else
							{
								Node store = new Node(Token.EXPR_RESULT, returnExpr);
								unwindBlock.AddChildToFront(store);
								returnNode = new Node(Token.RETURN_RESULT);
								unwindBlock.AddChildToBack(returnNode);
								// transform return expression
								TransformCompilationUnit_r(tree, store, scope, createScopeObjects, inStrictMode);
							}
							// skip transformCompilationUnit_r to avoid infinite loop
							goto siblingLoop_continue;
						}
						break;
					}

					case Token.BREAK:
					case Token.CONTINUE:
					{
						Jump jump = (Jump)node;
						Jump jumpStatement = jump.GetJumpStatement();
						if (jumpStatement == null)
						{
							Kit.CodeBug();
						}
						for (int i = loops.Size(); ; )
						{
							if (i == 0)
							{
								// Parser/IRFactory ensure that break/continue
								// always has a jump statement associated with it
								// which should be found
								throw Kit.CodeBug();
							}
							--i;
							Node n = (Node)loops.Get(i);
							if (n == jumpStatement)
							{
								break;
							}
							int elemtype = n.GetType();
							if (elemtype == Token.WITH)
							{
								Node leave = new Node(Token.LEAVEWITH);
								previous = AddBeforeCurrent(parent, previous, node, leave);
							}
							else
							{
								if (elemtype == Token.TRY)
								{
									Jump tryNode = (Jump)n;
									Jump jsrFinally = new Jump(Token.JSR);
									jsrFinally.target = tryNode.GetFinally();
									previous = AddBeforeCurrent(parent, previous, node, jsrFinally);
								}
							}
						}
						if (type == Token.BREAK)
						{
							jump.target = jumpStatement.target;
						}
						else
						{
							jump.target = jumpStatement.GetContinue();
						}
						jump.SetType(Token.GOTO);
						break;
					}

					case Token.CALL:
					{
						VisitCall(node, tree);
						break;
					}

					case Token.NEW:
					{
						VisitNew(node, tree);
						break;
					}

					case Token.LETEXPR:
					case Token.LET:
					{
						Node child = node.GetFirstChild();
						if (child.GetType() == Token.LET)
						{
							// We have a let statement or expression rather than a
							// let declaration
							bool createWith = tree.GetType() != Token.FUNCTION || ((FunctionNode)tree).RequiresActivation();
							node = VisitLet(createWith, parent, previous, node);
							break;
						}
						goto case Token.CONST;
					}

					case Token.CONST:
					case Token.VAR:
					{
						// fall through to process let declaration...
						Node result = new Node(Token.BLOCK);
						for (Node cursor = node.GetFirstChild(); cursor != null; )
						{
							// Move cursor to next before createAssignment gets chance
							// to change n.next
							Node n = cursor;
							cursor = cursor.GetNext();
							if (n.GetType() == Token.NAME)
							{
								if (!n.HasChildren())
								{
									continue;
								}
								Node init = n.GetFirstChild();
								n.RemoveChild(init);
								n.SetType(Token.BINDNAME);
								n = new Node(type == Token.CONST ? Token.SETCONST : Token.SETNAME, n, init);
							}
							else
							{
								// May be a destructuring assignment already transformed
								// to a LETEXPR
								if (n.GetType() != Token.LETEXPR)
								{
									throw Kit.CodeBug();
								}
							}
							Node pop = new Node(Token.EXPR_VOID, n, node.GetLineno());
							result.AddChildToBack(pop);
						}
						node = ReplaceCurrent(parent, previous, node, result);
						break;
					}

					case Token.TYPEOFNAME:
					{
						Scope defining = scope.GetDefiningScope(node.GetString());
						if (defining != null)
						{
							node.SetScope(defining);
						}
						break;
					}

					case Token.TYPEOF:
					case Token.IFNE:
					{
						Node child = node.GetFirstChild();
						if (type == Token.IFNE)
						{
							while (child.GetType() == Token.NOT)
							{
								child = child.GetFirstChild();
							}
							if (child.GetType() == Token.EQ || child.GetType() == Token.NE)
							{
								Node first = child.GetFirstChild();
								Node last = child.GetLastChild();
								if (first.GetType() == Token.NAME && first.GetString().Equals("undefined"))
								{
									child = last;
								}
								else
								{
									if (last.GetType() == Token.NAME && last.GetString().Equals("undefined"))
									{
										child = first;
									}
								}
							}
						}
						if (child.GetType() == Token.GETPROP)
						{
							child.SetType(Token.GETPROPNOWARN);
						}
						break;
					}

					case Token.SETNAME:
					{
						if (inStrictMode)
						{
							node.SetType(Token.STRICT_SETNAME);
						}
						goto case Token.NAME;
					}

					case Token.NAME:
					case Token.SETCONST:
					case Token.DELPROP:
					{
						// Turn name to var for faster access if possible
						if (createScopeObjects)
						{
							break;
						}
						Node nameSource;
						if (type == Token.NAME)
						{
							nameSource = node;
						}
						else
						{
							nameSource = node.GetFirstChild();
							if (nameSource.GetType() != Token.BINDNAME)
							{
								if (type == Token.DELPROP)
								{
									break;
								}
								throw Kit.CodeBug();
							}
						}
						if (nameSource.GetScope() != null)
						{
							break;
						}
						// already have a scope set
						string name = nameSource.GetString();
						Scope defining = scope.GetDefiningScope(name);
						if (defining != null)
						{
							nameSource.SetScope(defining);
							if (type == Token.NAME)
							{
								node.SetType(Token.GETVAR);
							}
							else
							{
								if (type == Token.SETNAME || type == Token.STRICT_SETNAME)
								{
									node.SetType(Token.SETVAR);
									nameSource.SetType(Token.STRING);
								}
								else
								{
									if (type == Token.SETCONST)
									{
										node.SetType(Token.SETCONSTVAR);
										nameSource.SetType(Token.STRING);
									}
									else
									{
										if (type == Token.DELPROP)
										{
											// Local variables are by definition permanent
											Node n = new Node(Token.FALSE);
											node = ReplaceCurrent(parent, previous, node, n);
										}
										else
										{
											throw Kit.CodeBug();
										}
									}
								}
							}
						}
						break;
					}
				}
				TransformCompilationUnit_r(tree, node, node is Scope ? (Scope)node : scope, createScopeObjects, inStrictMode);
siblingLoop_continue: ;
			}
siblingLoop_break: ;
		}
Esempio n. 13
0
		public object Compile(CompilerEnvirons compilerEnv, ScriptNode tree, string encodedSource, bool returnFunction)
		{
			CodeGenerator cgen = new CodeGenerator();
			itsData = cgen.Compile(compilerEnv, tree, encodedSource, returnFunction);
			return itsData;
		}
Esempio n. 14
0
		/// <summary>Sets top current script or function scope</summary>
		public virtual void SetTop(ScriptNode top)
		{
			this.top = top;
		}
Esempio n. 15
0
		internal virtual string GetBodyMethodName(ScriptNode n)
		{
			return "_c_" + CleanName(n) + "_" + GetIndex(n);
		}
Esempio n. 16
0
		internal virtual string GetDirectCtorName(ScriptNode n)
		{
			return "_n" + GetIndex(n);
		}
Esempio n. 17
0
		internal virtual int GetIndex(ScriptNode n)
		{
			return scriptOrFnIndexes.GetExisting(n);
		}
Esempio n. 18
0
		private Node TransformScript(ScriptNode node)
		{
			decompiler.AddToken(Token.SCRIPT);
			if (currentScope != null)
			{
				Kit.CodeBug();
			}
			currentScope = node;
			Node body = new Node(Token.BLOCK);
			foreach (Node kid in node)
			{
				body.AddChildToBack(Transform((AstNode)kid));
			}
			node.RemoveChildren();
			Node children = body.GetFirstChild();
			if (children != null)
			{
				node.AddChildrenToBack(children);
			}
			return node;
		}
Esempio n. 19
0
		internal static bool IsGenerator(ScriptNode node)
		{
			return (node.GetType() == Token.FUNCTION) && ((FunctionNode)node).IsGenerator();
		}
Esempio n. 20
0
		protected internal override void VisitCall(Node node, ScriptNode tree)
		{
			DetectDirectCall(node, tree);
			base.VisitCall(node, tree);
		}
Esempio n. 21
0
		/// <summary>Gets a Java-compatible "informative" name for the the ScriptOrFnNode</summary>
		internal virtual string CleanName(ScriptNode n)
		{
			string result = string.Empty;
			if (n is FunctionNode)
			{
				Name name = ((FunctionNode)n).GetFunctionName();
				if (name == null)
				{
					result = "anonymous";
				}
				else
				{
					result = name.GetIdentifier();
				}
			}
			else
			{
				result = "script";
			}
			return result;
		}
Esempio n. 22
0
		protected internal virtual void VisitCall(Node node, ScriptNode tree)
		{
		}
Esempio n. 23
0
		/// <summary>Sets parent scope</summary>
		public virtual void SetParentScope(Rhino.Ast.Scope parentScope)
		{
			this.parentScope = parentScope;
			this.top = parentScope == null ? (ScriptNode)this : parentScope.top;
		}
Esempio n. 24
0
		internal virtual string GetBodyMethodSignature(ScriptNode n)
		{
			StringBuilder sb = new StringBuilder();
			sb.Append('(');
			sb.Append(mainClassSignature);
			sb.Append("Lorg/mozilla/javascript/Context;" + "Lorg/mozilla/javascript/Scriptable;" + "Lorg/mozilla/javascript/Scriptable;");
			if (n.GetType() == Token.FUNCTION)
			{
				OptFunctionNode ofn = OptFunctionNode.Get(n);
				if (ofn.IsTargetOfDirectCall())
				{
					int pCount = ofn.fnode.GetParamCount();
					for (int i = 0; i != pCount; i++)
					{
						sb.Append("Ljava/lang/Object;D");
					}
				}
			}
			sb.Append("[Ljava/lang/Object;)Ljava/lang/Object;");
			return sb.ToString();
		}
Esempio n. 25
0
		internal virtual string GetCompiledRegexpName(ScriptNode n, int regexpIndex)
		{
			return "_re" + GetIndex(n) + "_" + regexpIndex;
		}
Esempio n. 26
0
		public virtual byte[] CompileToClassFile(CompilerEnvirons compilerEnv, string mainClassName, ScriptNode scriptOrFn, string encodedSource, bool returnFunction)
		{
			this.compilerEnv = compilerEnv;
			Transform(scriptOrFn);
			if (returnFunction)
			{
				scriptOrFn = scriptOrFn.GetFunctionNode(0);
			}
			InitScriptNodesData(scriptOrFn);
			this.mainClassName = mainClassName;
			this.mainClassSignature = ClassFileWriter.ClassNameToSignature(mainClassName);
			try
			{
				return GenerateCode(encodedSource);
			}
			catch (ClassFileWriter.ClassFileFormatException e)
			{
				throw ReportClassFileFormatException(scriptOrFn, e.Message);
			}
		}
Esempio n. 27
0
		private void DetectDirectCall(Node node, ScriptNode tree)
		{
			if (tree.GetType() == Token.FUNCTION)
			{
				Node left = node.GetFirstChild();
				// count the arguments
				int argCount = 0;
				Node arg = left.GetNext();
				while (arg != null)
				{
					arg = arg.GetNext();
					argCount++;
				}
				if (argCount == 0)
				{
					OptFunctionNode.Get(tree).itsContainsCalls0 = true;
				}
				if (possibleDirectCalls != null)
				{
					string targetName = null;
					if (left.GetType() == Token.NAME)
					{
						targetName = left.GetString();
					}
					else
					{
						if (left.GetType() == Token.GETPROP)
						{
							targetName = left.GetFirstChild().GetNext().GetString();
						}
						else
						{
							if (left.GetType() == Token.GETPROPNOWARN)
							{
								throw Kit.CodeBug();
							}
						}
					}
					if (targetName != null)
					{
						OptFunctionNode ofn;
						ofn = possibleDirectCalls.Get(targetName);
						if (ofn != null && argCount == ofn.fnode.GetParamCount() && !ofn.fnode.RequiresActivation())
						{
							// Refuse to directCall any function with more
							// than 32 parameters - prevent code explosion
							// for wacky test cases
							if (argCount <= 32)
							{
								node.PutProp(Node.DIRECTCALL_PROP, ofn);
								if (!ofn.IsTargetOfDirectCall())
								{
									int index = directCallTargets.Size();
									directCallTargets.Add(ofn);
									ofn.SetDirectTargetIndex(index);
								}
							}
						}
					}
				}
			}
		}
Esempio n. 28
0
		public static Rhino.Optimizer.OptFunctionNode Get(ScriptNode scriptOrFn, int i)
		{
			FunctionNode fnode = scriptOrFn.GetFunctionNode(i);
			return (Rhino.Optimizer.OptFunctionNode)fnode.GetCompilerData();
		}