예제 #1
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.Newobj, PHPNull.GetConstructor(Type.EmptyTypes));
         parametersPushed++;
     }
 }
예제 #2
0
 public void InvokeStaticFunction(string className, string functionName, ExpressionList parameters, int line, int column)
 {
     SymbolTableEntry cdEntry = SymbolTable.getInstance().lookupGlobal(className.ToLower(), SymbolTable.CLASS);
     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.ToLower(), 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.Newobj, PHPNull.GetConstructor(Type.EmptyTypes));
             return;
         }
         if (fdEntry != null && ((FUNCTION_DECLARATION)fdEntry.node).modifiers.Contains(Modifiers.PRIVATE)) {
             Report.Error(217, functionName, line, column);
             ilGen.Emit(OpCodes.Newobj, PHPNull.GetConstructor(Type.EmptyTypes));
             return;
         }
     }
     if (fdEntry == null) {
         Report.Error(216, functionName, line, column);
         ilGen.Emit(OpCodes.Newobj, PHPNull.GetConstructor(Type.EmptyTypes));
         return;
     }
     FUNCTION_DECLARATION fd = (FUNCTION_DECLARATION)fdEntry.node;
     if (!fd.modifiers.Contains(Modifiers.STATIC)) {
         Report.Error(215, functionName, line, column);
         ilGen.Emit(OpCodes.Newobj, PHPNull.GetConstructor(Type.EmptyTypes));
         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);
         Visit(expr);
         // clone if value semantics is desired
         if (!pd.by_reference && !(expr is REFERENCE))
             ilGen.Emit(OpCodes.Call, PHPCoreLang.GetMethod("Clone", new Type[] { PHPMixed }));
     }
     // if less parameters actually passed then necessary, pass Null objects instead
     for (int i = parametersPassedActually; i < fd.parameters.Count; i++) {
         PARAMETER_DECLARATION pd = (PARAMETER_DECLARATION)fd.parameters[i];
         if (pd.default_value == null)
             Report.Warn(300, System.Convert.ToString(i + 1), line, column);
         ilGen.Emit(OpCodes.Newobj, PHPNull.GetConstructor(Type.EmptyTypes));
     }
     // ensure parameters passed by reference are variables
     for (int i = 0; i < parametersPassedActually; i++) {
         PARAMETER_DECLARATION pd = (PARAMETER_DECLARATION)fd.parameters[i];
         Expression variableSupplied = (Expression)parameters.Get(i);
         if (pd.by_reference || variableSupplied is REFERENCE)
             if (!(variableSupplied is VARIABLE || variableSupplied is REFERENCE))
                 Report.Error(301, System.Convert.ToString(i + 1), line, column);
     }
     // add function call to call trace
     ilGen.Emit(OpCodes.Ldstr, cd.name + "->" + fd.name);
     ilGen.Emit(OpCodes.Call, PHPCoreRuntime.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, PHPCoreRuntime.GetMethod("RemoveFunctionCallFromTrace", Type.EmptyTypes));
 }