Пример #1
0
		public void InvokeStaticFunction(string className, string functionName, ExpressionList parameters, int line, int column) {
			SymbolTableEntry cdEntry = SymbolTable.GetInstance().LookupGlobal(className, SymbolTable.CLASS);
			// type is defined in an referenced assembly
			if (cdEntry == null) {
				Type t = SymbolTable.GetInstance().GetExternalType(className);
				IlGen.Emit(OpCodes.Ldstr, t.AssemblyQualifiedName);
				IlGen.Emit(OpCodes.Newobj, typeof(ArrayList).GetConstructor(Type.EmptyTypes));
				foreach (Expression expr in parameters) {
					IlGen.Emit(OpCodes.Dup);
					Visit(expr);
					IlGen.Emit(OpCodes.Call, typeof(ArrayList).GetMethod("Add", new Type[] { typeof(object) }));
					IlGen.Emit(OpCodes.Pop);
				}
				IlGen.Emit(OpCodes.Ldstr, functionName);
				IlGen.Emit(OpCodes.Call, PHPRuntimeCore.GetMethod("InvokeExternalStaticFunction", new Type[] { typeof(string), typeof(ArrayList), typeof(object) }));
			}
			// type is defined in script
			else {
				CLASS_DECLARATION cd = (CLASS_DECLARATION)cdEntry.Node;
				CLASS_DECLARATION tmpCD = cd;
				SymbolTableEntry fdEntry = tmpCD.Scope.Lookup(functionName, SymbolTable.FUNCTION);
				while (fdEntry == null) {
					if (tmpCD.Extends == null)
						break;
					SymbolTableEntry parentCDEntry = SymbolTable.GetInstance().LookupGlobal(tmpCD.Extends, SymbolTable.CLASS);
					tmpCD = (CLASS_DECLARATION)parentCDEntry.Node;
					fdEntry = tmpCD.Scope.Lookup(functionName, SymbolTable.FUNCTION);
					if (fdEntry != null && !((FUNCTION_DECLARATION)fdEntry.Node).Modifiers.Contains(Modifiers.STATIC)) {
						Report.Error(215, functionName, line, column);
						IlGen.Emit(OpCodes.Ldnull);
						return;
					}
					if (fdEntry != null && ((FUNCTION_DECLARATION)fdEntry.Node).Modifiers.Contains(Modifiers.PRIVATE)) {
						Report.Error(217, functionName, line, column);
						IlGen.Emit(OpCodes.Ldnull);
						return;
					}
				}
				if (fdEntry == null) {
					Report.Error(216, functionName, line, column);
					IlGen.Emit(OpCodes.Ldnull);
					return;
				}
				FUNCTION_DECLARATION fd = (FUNCTION_DECLARATION)fdEntry.Node;
				if (!fd.Modifiers.Contains(Modifiers.STATIC)) {
					Report.Error(215, functionName, line, column);
					IlGen.Emit(OpCodes.Ldnull);
					return;
				}
				// pass parameters (only as many as needed)
				int parametersPassedActually = (int)Math.Min(fd.Parameters.Count, parameters.Count());
				for (int i = 0; i < parametersPassedActually; i++) {
					PARAMETER_DECLARATION pd = (PARAMETER_DECLARATION)fd.Parameters[i];
					Expression expr = (Expression)parameters.Get(i);
					// ensure a reference is passed, if a reference is required
					if (pd.ByReference && !(expr is REFERENCE))
						expr = new REFERENCE(expr, expr.Line, expr.Column);
					// process parameter
					Visit(expr);
				}
				// if less parameters actually passed then necessary, pass nulls instead
				for (int i = parametersPassedActually; i < fd.Parameters.Count; i++) {
					PARAMETER_DECLARATION pd = (PARAMETER_DECLARATION)fd.Parameters[i];
					if (pd.DefaultValue == null)
						Report.Warn(300, System.Convert.ToString(i + 1), line, column);
					IlGen.Emit(OpCodes.Ldnull);
				}
				// add function call to call trace
				IlGen.Emit(OpCodes.Ldstr, CD.Name + "->" + fd.Name);
				IlGen.Emit(OpCodes.Call, PHPRuntimeCore.GetMethod("AddFunctionCallToTrace", new Type[] { typeof(string) }));
				// call
				MethodBuilder mb = fd.MthBld;
				IlGen.Emit(OpCodes.Call, mb);
				// remove function call from call trace
				IlGen.Emit(OpCodes.Call, PHPRuntimeCore.GetMethod("RemoveFunctionCallFromTrace", Type.EmptyTypes));
			}
		}
Пример #2
0
		public void PushParameters(ExpressionList parameters, int number) {
			int parametersPushed = 0;
			// push parameters available, until desired number is reached
			while (parametersPushed < number && parametersPushed < parameters.Count())
				Visit(parameters.Get(parametersPushed++));
			// if not enough parameters were available, fill up with nulls
			while (parametersPushed < number) {
				IlGen.Emit(OpCodes.Ldnull);
				parametersPushed++;
			}
		}