This class rewrites the parse tree into an IR suitable for codegen.
This class rewrites the parse tree into an IR suitable for codegen.
Inheritance: Parser
Exemple #1
0
			/// <summary>
			/// Compiles
			/// <code>source</code>
			/// and returns the transformed and optimized
			/// <see cref="Rhino.Ast.ScriptNode">Rhino.Ast.ScriptNode</see>
			/// </summary>
			protected internal virtual ScriptNode Compile(CharSequence source)
			{
				string mainMethodClassName = "Main";
				string scriptClassName = "Main";
				CompilerEnvirons compilerEnv = new CompilerEnvirons();
				compilerEnv.InitFromContext(cx);
				ErrorReporter compilationErrorReporter = compilerEnv.GetErrorReporter();
				Parser p = new Parser(compilerEnv, compilationErrorReporter);
				AstRoot ast = p.Parse(source.ToString(), "<eval>", 1);
				IRFactory irf = new IRFactory(compilerEnv);
				ScriptNode tree = irf.TransformTree(ast);
				Codegen codegen = new Codegen();
				codegen.SetMainMethodClass(mainMethodClassName);
				codegen.CompileToClassFile(compilerEnv, scriptClassName, tree, tree.GetEncodedSource(), false);
				return tree;
			}
Exemple #2
0
		/// <exception cref="System.IO.IOException"></exception>
		private object CompileImpl(Scriptable scope, TextReader sourceReader, string sourceString, string sourceName, int lineno, object securityDomain, bool returnFunction, Evaluator compiler, ErrorReporter compilationErrorReporter)
		{
			if (sourceName == null)
			{
				sourceName = "unnamed script";
			}
			if (securityDomain != null && GetSecurityController() == null)
			{
				throw new ArgumentException("securityDomain should be null if setSecurityController() was never called");
			}
			// One of sourceReader or sourceString has to be null
			if (!(sourceReader == null ^ sourceString == null))
			{
				Kit.CodeBug();
			}
			// scope should be given if and only if compiling function
			if (!(scope == null ^ returnFunction))
			{
				Kit.CodeBug();
			}
			CompilerEnvirons compilerEnv = new CompilerEnvirons();
			compilerEnv.InitFromContext(this);
			if (compilationErrorReporter == null)
			{
				compilationErrorReporter = compilerEnv.GetErrorReporter();
			}
			if (debugger != null)
			{
				if (sourceReader != null)
				{
					sourceString = Kit.ReadReader(sourceReader);
					sourceReader = null;
				}
			}
			Parser p = new Parser(compilerEnv, compilationErrorReporter);
			if (returnFunction)
			{
				p.calledByCompileFunction = true;
			}
			AstRoot ast;
			if (sourceString != null)
			{
				ast = p.Parse(sourceString, sourceName, lineno);
			}
			else
			{
				ast = p.Parse(sourceReader, sourceName, lineno);
			}
			if (returnFunction)
			{
				// parser no longer adds function to script node
				if (!(ast.GetFirstChild() != null && ast.GetFirstChild().GetType() == Token.FUNCTION))
				{
					// XXX: the check just looks for the first child
					// and allows for more nodes after it for compatibility
					// with sources like function() {};;;
					throw new ArgumentException("compileFunction only accepts source with single JS function: " + sourceString);
				}
			}
			IRFactory irf = new IRFactory(compilerEnv, compilationErrorReporter);
			ScriptNode tree = irf.TransformTree(ast);
			// discard everything but the IR tree
			p = null;
			ast = null;
			irf = null;
			if (compiler == null)
			{
				compiler = CreateCompiler();
			}
			object bytecode = compiler.Compile(compilerEnv, tree, tree.GetEncodedSource(), returnFunction);
			if (debugger != null)
			{
				if (sourceString == null)
				{
					Kit.CodeBug();
				}
				if (bytecode is DebuggableScript)
				{
					DebuggableScript dscript = (DebuggableScript)bytecode;
					NotifyDebugger_r(this, dscript, sourceString);
				}
				else
				{
					throw new Exception("NOT SUPPORTED");
				}
			}
			object result;
			if (returnFunction)
			{
				result = compiler.CreateFunctionObject(this, scope, bytecode, securityDomain);
			}
			else
			{
				result = compiler.CreateScriptObject(bytecode, securityDomain);
			}
			return result;
		}
Exemple #3
0
		/// <summary>Compile JavaScript source into one or more Java class files.</summary>
		/// <remarks>
		/// Compile JavaScript source into one or more Java class files.
		/// The first compiled class will have name mainClassName.
		/// If the results of
		/// <see cref="GetTargetExtends()">GetTargetExtends()</see>
		/// or
		/// <see cref="GetTargetImplements()">GetTargetImplements()</see>
		/// are not null, then the first compiled
		/// class will extend the specified super class and implement
		/// specified interfaces.
		/// </remarks>
		/// <returns>
		/// array where elements with even indexes specifies class name
		/// and the following odd index gives class file body as byte[]
		/// array. The initial element of the array always holds
		/// mainClassName and array[1] holds its byte code.
		/// </returns>
		public virtual object[] CompileToClassFiles(string source, string sourceLocation, int lineno, string mainClassName)
		{
			Parser p = new Parser(compilerEnv);
			AstRoot ast = p.Parse(source, sourceLocation, lineno);
			IRFactory irf = new IRFactory(compilerEnv);
			ScriptNode tree = irf.TransformTree(ast);
			// release reference to original parse tree & parser
			irf = null;
			ast = null;
			p = null;
			Type superClass = GetTargetExtends();
			Type[] interfaces = GetTargetImplements();
			string scriptClassName;
			bool isPrimary = (interfaces == null && superClass == null);
			if (isPrimary)
			{
				scriptClassName = mainClassName;
			}
			else
			{
				scriptClassName = MakeAuxiliaryClassName(mainClassName, "1");
			}
			Codegen codegen = new Codegen();
			codegen.SetMainMethodClass(mainMethodClassName);
			byte[] scriptClassBytes = codegen.CompileToClassFile(compilerEnv, scriptClassName, tree, tree.GetEncodedSource(), false);
			if (isPrimary)
			{
				return new object[] { scriptClassName, scriptClassBytes };
			}
			int functionCount = tree.GetFunctionCount();
			ObjToIntMap functionNames = new ObjToIntMap(functionCount);
			for (int i = 0; i != functionCount; ++i)
			{
				FunctionNode ofn = tree.GetFunctionNode(i);
				string name = ofn.GetName();
				if (name != null && name.Length != 0)
				{
					functionNames.Put(name, ofn.GetParamCount());
				}
			}
			if (superClass == null)
			{
				superClass = ScriptRuntime.ObjectClass;
			}
			byte[] mainClassBytes = JavaAdapter.CreateAdapterCode(functionNames, mainClassName, superClass, interfaces, scriptClassName);
			return new object[] { mainClassName, mainClassBytes, scriptClassName, scriptClassBytes };
		}