KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > quercus > program > Function


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.quercus.program;
31
32 import com.caucho.quercus.Location;
33 import com.caucho.quercus.env.Env;
34 import com.caucho.quercus.env.NullValue;
35 import com.caucho.quercus.env.Value;
36 import com.caucho.quercus.env.Var;
37 import com.caucho.quercus.expr.Expr;
38 import com.caucho.quercus.expr.ExprFactory;
39 import com.caucho.util.L10N;
40
41 import java.util.ArrayList JavaDoc;
42 import java.util.HashMap JavaDoc;
43 import java.util.logging.Logger JavaDoc;
44
45 /**
46  * Represents sequence of statements.
47  */

48 public class Function extends AbstractFunction {
49   private static final Logger JavaDoc log = Logger.getLogger(Function.class.getName());
50   private static final L10N L = new L10N(Function.class);
51
52   protected final FunctionInfo _info;
53   protected final boolean _isReturnsReference;
54
55   protected final String JavaDoc _name;
56   protected final Arg []_args;
57   protected final Statement _statement;
58
59   protected boolean _isStatic = true;
60
61   protected boolean _hasReturn;
62
63   Function(Location location,
64            String JavaDoc name,
65            FunctionInfo info,
66            Arg []args,
67            Statement []statements)
68   {
69     super(location);
70     
71     _name = name.intern();
72     _info = info;
73     _info.setFunction(this);
74     _isReturnsReference = info.isReturnsReference();
75     _args = args;
76     _statement = new BlockStatement(location, statements);
77
78     setGlobal(info.isPageStatic());
79   }
80
81   public Function(ExprFactory exprFactory,
82           Location location,
83                   String JavaDoc name,
84                   FunctionInfo info,
85                   ArrayList JavaDoc<Arg> argList,
86                   ArrayList JavaDoc<Statement> statementList)
87   {
88     super(location);
89     
90     _name = name.intern();
91     _info = info;
92     _info.setFunction(this);
93     _isReturnsReference = info.isReturnsReference();
94
95     _args = new Arg[argList.size()];
96     argList.toArray(_args);
97
98     Statement []statements = new Statement[statementList.size()];
99     statementList.toArray(statements);
100
101     _statement = exprFactory.createBlock(location, statements);
102
103     setGlobal(info.isPageStatic());
104   }
105
106   /**
107    * Returns the name.
108    */

109   public String JavaDoc getName()
110   {
111     return _name;
112   }
113
114   /**
115    * Returns the args.
116    */

117   public Arg []getArgs()
118   {
119     return _args;
120   }
121
122   public void setStatic(boolean isStatic)
123   {
124     _isStatic = isStatic;
125   }
126
127   public boolean isStatic()
128   {
129     return _isStatic;
130   }
131
132   public boolean isObjectMethod()
133   {
134     return false;
135   }
136
137   /**
138    * True for a returns reference.
139    */

140   public boolean isReturnsReference()
141   {
142     return _isReturnsReference;
143   }
144
145   public String JavaDoc getClassName()
146   {
147     throw new UnsupportedOperationException JavaDoc();
148   }
149
150   public Value execute(Env env)
151   {
152     return null;
153   }
154
155   /**
156    * Evaluates a function's argument, handling ref vs non-ref
157    */

158   @Override JavaDoc
159   public Value []evalArguments(Env env, Expr fun, Expr []args)
160   {
161     Value []values = new Value[args.length];
162
163     for (int i = 0; i < args.length; i++) {
164       Arg arg = null;
165
166       if (i < _args.length)
167         arg = _args[i];
168
169       if (arg == null)
170         values[i] = args[i].eval(env).copy();
171       else if (arg.isReference())
172         values[i] = args[i].evalRef(env);
173       else {
174         // php/0d04
175
values[i] = args[i].eval(env);
176       }
177     }
178
179     return values;
180   }
181
182   public Value call(Env env, Expr []args)
183   {
184     return callImpl(env, args, false);
185   }
186
187   public Value callCopy(Env env, Expr []args)
188   {
189     return callImpl(env, args, false);
190   }
191
192   public Value callRef(Env env, Expr []args)
193   {
194     return callImpl(env, args, true);
195   }
196
197   private Value callImpl(Env env, Expr []args, boolean isRef)
198   {
199     HashMap JavaDoc<String JavaDoc,Var> map = new HashMap JavaDoc<String JavaDoc,Var>();
200
201     Value []values = new Value[args.length];
202
203     for (int i = 0; i < args.length; i++) {
204       Arg arg = null;
205
206       if (i < _args.length) {
207         arg = _args[i];
208       }
209
210       if (arg == null) {
211         values[i] = args[i].eval(env).copy();
212       }
213       else if (arg.isReference()) {
214         values[i] = args[i].evalRef(env);
215
216         map.put(arg.getName(), values[i].toRefVar());
217       }
218       else {
219         // php/0d04
220
values[i] = args[i].eval(env);
221
222         Var var = values[i].toVar();
223
224         map.put(arg.getName(), var);
225
226         values[i] = var.toValue();
227       }
228     }
229
230     for (int i = args.length; i < _args.length; i++) {
231       Arg arg = _args[i];
232
233       Expr defaultExpr = arg.getDefault();
234
235       if (defaultExpr == null)
236         return env.error("expected default expression");
237       else if (arg.isReference())
238         map.put(arg.getName(), defaultExpr.evalRef(env).toVar());
239       else {
240         map.put(arg.getName(), defaultExpr.eval(env).copy().toVar());
241       }
242     }
243
244     HashMap JavaDoc<String JavaDoc,Var> oldMap = env.pushEnv(map);
245     Value []oldArgs = env.setFunctionArgs(values); // php/0476
246

247     try {
248       Value value = _statement.execute(env);
249
250       if (value == null)
251         return NullValue.NULL;
252       else if (_isReturnsReference && isRef)
253         return value;
254       else
255         return value.copyReturn();
256     } finally {
257       env.restoreFunctionArgs(oldArgs);
258       env.popEnv(oldMap);
259     }
260   }
261
262   public Value call(Env env, Value []args)
263   {
264     return callImpl(env, args, false);
265   }
266
267   public Value callCopy(Env env, Value []args)
268   {
269     return callImpl(env, args, false);
270   }
271
272   public Value callRef(Env env, Value []args)
273   {
274     return callImpl(env, args, true);
275   }
276
277   private Value callImpl(Env env, Value []args, boolean isRef)
278   {
279     HashMap JavaDoc<String JavaDoc,Var> map = new HashMap JavaDoc<String JavaDoc,Var>();
280
281     for (int i = 0; i < args.length; i++) {
282       Arg arg = null;
283
284       if (i < _args.length) {
285         arg = _args[i];
286       }
287
288       if (arg == null) {
289       }
290       else if (arg.isReference())
291         map.put(arg.getName(), args[i].toRefVar());
292       else {
293         // quercus/0d04
294
map.put(arg.getName(), args[i].copy().toVar());
295       }
296     }
297
298     for (int i = args.length; i < _args.length; i++) {
299       Arg arg = _args[i];
300
301       Expr defaultExpr = arg.getDefault();
302
303       if (defaultExpr == null)
304         return env.error("expected default expression");
305       else if (arg.isReference())
306         map.put(arg.getName(), defaultExpr.evalRef(env).toVar());
307       else {
308         map.put(arg.getName(), defaultExpr.eval(env).copy().toVar());
309       }
310     }
311
312     HashMap JavaDoc<String JavaDoc,Var> oldMap = env.pushEnv(map);
313     Value []oldArgs = env.setFunctionArgs(args);
314
315     try {
316       Value value = _statement.execute(env);
317
318       if (value == null)
319         return NullValue.NULL;
320       else if (_isReturnsReference && isRef)
321         return value;
322       else
323         return value.copyReturn();
324     } finally {
325       env.restoreFunctionArgs(oldArgs);
326       env.popEnv(oldMap);
327     }
328   }
329
330   private boolean isVariableArgs()
331   {
332     return _info.isVariableArgs() || _args.length > 5;
333   }
334
335   private boolean isVariableMap()
336   {
337     // return _info.isVariableVar();
338
// php/3254
339
return _info.isUsesSymbolTable() || _info.isVariableVar();
340   }
341
342   public String JavaDoc toString()
343   {
344     return "Function[" + _name + "]";
345   }
346 }
347
348
Popular Tags