Esempio n. 1
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. 2
0
		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);
			}
		}
Esempio n. 3
0
		private void Reflect(Scriptable scope, bool includeProtected, bool includePrivate)
		{
			// We reflect methods first, because we want overloaded field/method
			// names to be allocated to the NativeJavaMethod before the field
			// gets in the way.
			MethodInfo[] methods = DiscoverAccessibleMethods(cl, includeProtected, includePrivate);
			foreach (MethodInfo method in methods)
			{
				int mods = method.Attributes;
				bool isStatic = Modifier.IsStatic(mods);
				IDictionary<string, object> ht = isStatic ? staticMembers : members;
				string name = method.Name;
				object value = ht.Get(name);
				if (value == null)
				{
					ht.Put(name, method);
				}
				else
				{
					ObjArray overloadedMethods;
					if (value is ObjArray)
					{
						overloadedMethods = (ObjArray)value;
					}
					else
					{
						if (!(value is MethodInfo))
						{
							Kit.CodeBug();
						}
						// value should be instance of Method as at this stage
						// staticMembers and members can only contain methods
						overloadedMethods = new ObjArray();
						overloadedMethods.Add(value);
						ht.Put(name, overloadedMethods);
					}
					overloadedMethods.Add(method);
				}
			}
			// replace Method instances by wrapped NativeJavaMethod objects
			// first in staticMembers and then in members
			for (int tableCursor = 0; tableCursor != 2; ++tableCursor)
			{
				bool isStatic = (tableCursor == 0);
				IDictionary<string, object> ht = isStatic ? staticMembers : members;
				foreach (KeyValuePair<string, object> entry in ht.EntrySet())
				{
					MemberBox[] methodBoxes;
					object value = entry.Value;
					if (value is MethodInfo)
					{
						methodBoxes = new MemberBox[1];
						methodBoxes[0] = new MemberBox((MethodInfo)value);
					}
					else
					{
						ObjArray overloadedMethods = (ObjArray)value;
						int N = overloadedMethods.Size();
						if (N < 2)
						{
							Kit.CodeBug();
						}
						methodBoxes = new MemberBox[N];
						for (int i = 0; i != N; ++i)
						{
							MethodInfo method_1 = (MethodInfo)overloadedMethods.Get(i);
							methodBoxes[i] = new MemberBox(method_1);
						}
					}
					NativeJavaMethod fun = new NativeJavaMethod(methodBoxes);
					if (scope != null)
					{
						ScriptRuntime.SetFunctionProtoAndParent(fun, scope);
					}
					ht.Put(entry.Key, fun);
				}
			}
			// Reflect fields.
			FieldInfo[] fields = GetAccessibleFields(includeProtected, includePrivate);
			foreach (FieldInfo field in fields)
			{
				string name = field.Name;
				int mods = field.Attributes;
				try
				{
					bool isStatic = Modifier.IsStatic(mods);
					IDictionary<string, object> ht = isStatic ? staticMembers : members;
					object member = ht.Get(name);
					if (member == null)
					{
						ht.Put(name, field);
					}
					else
					{
						if (member is NativeJavaMethod)
						{
							NativeJavaMethod method_1 = (NativeJavaMethod)member;
							FieldAndMethods fam = new FieldAndMethods(scope, method_1.methods, field);
							IDictionary<string, FieldAndMethods> fmht = isStatic ? staticFieldAndMethods : fieldAndMethods;
							if (fmht == null)
							{
								fmht = new Dictionary<string, FieldAndMethods>();
								if (isStatic)
								{
									staticFieldAndMethods = fmht;
								}
								else
								{
									fieldAndMethods = fmht;
								}
							}
							fmht.Put(name, fam);
							ht.Put(name, fam);
						}
						else
						{
							if (member is FieldInfo)
							{
								FieldInfo oldField = (FieldInfo)member;
								// If this newly reflected field shadows an inherited field,
								// then replace it. Otherwise, since access to the field
								// would be ambiguous from Java, no field should be
								// reflected.
								// For now, the first field found wins, unless another field
								// explicitly shadows it.
								if (oldField.DeclaringType.IsAssignableFrom(field.DeclaringType))
								{
									ht.Put(name, field);
								}
							}
							else
							{
								// "unknown member type"
								Kit.CodeBug();
							}
						}
					}
				}
				catch (SecurityException)
				{
					// skip this field
					Context.ReportWarning("Could not access field " + name + " of class " + cl.FullName + " due to lack of privileges.");
				}
			}
			// Create bean properties from corresponding get/set methods first for
			// static members and then for instance members
			for (int tableCursor_1 = 0; tableCursor_1 != 2; ++tableCursor_1)
			{
				bool isStatic = (tableCursor_1 == 0);
				IDictionary<string, object> ht = isStatic ? staticMembers : members;
				IDictionary<string, BeanProperty> toAdd = new Dictionary<string, BeanProperty>();
				// Now, For each member, make "bean" properties.
				foreach (string name in ht.Keys)
				{
					// Is this a getter?
					bool memberIsGetMethod = name.StartsWith("get");
					bool memberIsSetMethod = name.StartsWith("set");
					bool memberIsIsMethod = name.StartsWith("is");
					if (memberIsGetMethod || memberIsIsMethod || memberIsSetMethod)
					{
						// Double check name component.
						string nameComponent = Sharpen.Runtime.Substring(name, memberIsIsMethod ? 2 : 3);
						if (nameComponent.Length == 0)
						{
							continue;
						}
						// Make the bean property name.
						string beanPropertyName = nameComponent;
						char ch0 = nameComponent[0];
						if (System.Char.IsUpper(ch0))
						{
							if (nameComponent.Length == 1)
							{
								beanPropertyName = nameComponent.ToLower();
							}
							else
							{
								char ch1 = nameComponent[1];
								if (!System.Char.IsUpper(ch1))
								{
									beanPropertyName = System.Char.ToLower(ch0) + Sharpen.Runtime.Substring(nameComponent, 1);
								}
							}
						}
						// If we already have a member by this name, don't do this
						// property.
						if (toAdd.ContainsKey(beanPropertyName))
						{
							continue;
						}
						object v = ht.Get(beanPropertyName);
						if (v != null)
						{
							// A private field shouldn't mask a public getter/setter
							if (!includePrivate || !(v is MemberInfo) || !Modifier.IsPrivate(((MemberInfo)v).Attributes))
							{
								continue;
							}
						}
						// Find the getter method, or if there is none, the is-
						// method.
						MemberBox getter = null;
						getter = FindGetter(isStatic, ht, "get", nameComponent);
						// If there was no valid getter, check for an is- method.
						if (getter == null)
						{
							getter = FindGetter(isStatic, ht, "is", nameComponent);
						}
						// setter
						MemberBox setter = null;
						NativeJavaMethod setters = null;
						string setterName = System.String.Concat("set", nameComponent);
						if (ht.ContainsKey(setterName))
						{
							// Is this value a method?
							object member = ht.Get(setterName);
							if (member is NativeJavaMethod)
							{
								NativeJavaMethod njmSet = (NativeJavaMethod)member;
								if (getter != null)
								{
									// We have a getter. Now, do we have a matching
									// setter?
									Type type = getter.Method().ReturnType;
									setter = ExtractSetMethod(type, njmSet.methods, isStatic);
								}
								else
								{
									// No getter, find any set method
									setter = ExtractSetMethod(njmSet.methods, isStatic);
								}
								if (njmSet.methods.Length > 1)
								{
									setters = njmSet;
								}
							}
						}
						// Make the property.
						BeanProperty bp = new BeanProperty(getter, setter, setters);
						toAdd.Put(beanPropertyName, bp);
					}
				}
				// Add the new bean properties.
				foreach (string key in toAdd.Keys)
				{
					object value = toAdd.Get(key);
					ht.Put(key, value);
				}
			}
			// Reflect constructors
			ConstructorInfo<object>[] constructors = GetAccessibleConstructors(includePrivate);
			MemberBox[] ctorMembers = new MemberBox[constructors.Length];
			for (int i_1 = 0; i_1 != constructors.Length; ++i_1)
			{
				ctorMembers[i_1] = new MemberBox(constructors[i_1]);
			}
			ctors = new NativeJavaMethod(ctorMembers, cl.Name);
		}
Esempio n. 4
0
		internal OptTransformer(IDictionary<string, OptFunctionNode> possibleDirectCalls, ObjArray directCallTargets)
		{
			this.possibleDirectCalls = possibleDirectCalls;
			this.directCallTargets = directCallTargets;
		}
Esempio n. 5
0
		/// <summary>
		/// Helper function for
		/// <see cref="GetAllFunctions(Rhino.Debug.DebuggableScript)">GetAllFunctions(Rhino.Debug.DebuggableScript)</see>
		/// .
		/// </summary>
		private static void CollectFunctions_r(DebuggableScript function, ObjArray array)
		{
			array.Add(function);
			for (int i = 0; i != function.GetFunctionCount(); ++i)
			{
				CollectFunctions_r(function.GetFunction(i), array);
			}
		}
Esempio n. 6
0
		/// <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;
		}
Esempio n. 7
0
		private static void BuildStatementList_r(Node node, ObjArray statements)
		{
			int type = node.GetType();
			if (type == Token.BLOCK || type == Token.LOCAL_BLOCK || type == Token.LOOP || type == Token.FUNCTION)
			{
				Node child = node.GetFirstChild();
				while (child != null)
				{
					BuildStatementList_r(child, statements);
					child = child.GetNext();
				}
			}
			else
			{
				statements.Add(node);
			}
		}
Esempio n. 8
0
		/// <summary>
		/// Add Information about java variable to use when generating the local
		/// variable table.
		/// </summary>
		/// <remarks>
		/// Add Information about java variable to use when generating the local
		/// variable table.
		/// </remarks>
		/// <param name="name">variable name.</param>
		/// <param name="type">variable type as bytecode descriptor string.</param>
		/// <param name="startPC">
		/// the starting bytecode PC where this variable is live,
		/// or -1 if it does not have a Java register.
		/// </param>
		/// <param name="register">
		/// the Java register number of variable
		/// or -1 if it does not have a Java register.
		/// </param>
		public virtual void AddVariableDescriptor(string name, string type, int startPC, int register)
		{
			int nameIndex = itsConstantPool.AddUtf8(name);
			int descriptorIndex = itsConstantPool.AddUtf8(type);
			int[] chunk = new int[] { nameIndex, descriptorIndex, startPC, register };
			if (itsVarDescriptors == null)
			{
				itsVarDescriptors = new ObjArray();
			}
			itsVarDescriptors.Add(chunk);
		}
Esempio n. 9
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. 10
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. 11
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. 12
0
		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;
		}