root/trunk/ProjectFortress/src/com/sun/fortress/interpreter/evaluator/values/Closure.java

Revision 2847, 8.5 kB (checked in by chf, 4 weeks ago)

Closure.java was wrapping abortedexceptions and causing transactions to hang. Added throwing of AbortedException? to thread.java

Line 
1 /*******************************************************************************
2     Copyright 2008 Sun Microsystems, Inc.,
3     4150 Network Circle, Santa Clara, California 95054, U.S.A.
4     All rights reserved.
5
6     U.S. Government Rights - Commercial software.
7     Government users are subject to the Sun Microsystems, Inc. standard
8     license agreement and applicable provisions of the FAR and its supplements.
9
10     Use is subject to license terms.
11
12     This distribution may include materials developed by third parties.
13
14     Sun, Sun Microsystems, the Sun logo and Java are trademarks or registered
15     trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
16  ******************************************************************************/
17
18 package com.sun.fortress.interpreter.evaluator.values;
19
20 import static com.sun.fortress.exceptions.ProgramError.error;
21 import static com.sun.fortress.exceptions.ProgramError.errorMsg;
22
23 import java.util.List;
24
25 import com.sun.fortress.interpreter.evaluator.Environment;
26 import com.sun.fortress.interpreter.evaluator.EvalType;
27 import com.sun.fortress.interpreter.evaluator.Evaluator;
28 import com.sun.fortress.interpreter.evaluator.scopes.Scope;
29 import com.sun.fortress.interpreter.evaluator.types.BottomType;
30 import com.sun.fortress.interpreter.evaluator.types.FType;
31 import com.sun.fortress.interpreter.evaluator.types.FTypeArrow;
32 import com.sun.fortress.interpreter.glue.NativeApp;
33 import com.sun.fortress.nodes.Expr;
34 import com.sun.fortress.nodes.FnAbsDeclOrDecl;
35 import com.sun.fortress.nodes.IdOrOpOrAnonymousName;
36 import com.sun.fortress.nodes.Modifier;
37 import com.sun.fortress.nodes.ModifierOverride;
38 import com.sun.fortress.nodes.Param;
39 import com.sun.fortress.nodes.Type;
40 import com.sun.fortress.nodes_util.Applicable;
41 import com.sun.fortress.nodes_util.NodeUtil;
42 import com.sun.fortress.useful.HasAt;
43 import com.sun.fortress.useful.NI;
44 import com.sun.fortress.useful.Useful;
45
46 import com.sun.fortress.exceptions.transactions.AbortedException;
47 import com.sun.fortress.exceptions.transactions.OrphanedException;
48 import com.sun.fortress.exceptions.FortressException;
49
50 import edu.rice.cs.plt.tuple.Option;
51
52 /**
53  * A Closure value is a function, plus some environment information.
54  */
55 public class Closure extends NonPrimitive implements Scope {
56
57     protected FType returnType;
58     protected List<FType> instArgs;
59     protected Applicable def;
60
61     public Closure(Environment e, Applicable fndef) {
62         super(e); // TODO verify that this is the proper environment
63         def = NativeApp.checkAndLoadNative(fndef);
64     }
65
66     public Closure(Environment e, Applicable fndef, boolean isFunctionalMethod) {
67         super(e); // TODO verify that this is the proper environment
68         def = NativeApp.checkAndLoadNative(fndef,isFunctionalMethod);
69     }
70
71     protected Closure(Environment e, Applicable fndef, List<FType> args) {
72         super(e);
73         def = NativeApp.checkAndLoadNative(fndef);
74         instArgs = args;
75     }
76
77     /*
78      * Just like the PartiallyDefinedMethod, but used a specific environemnt
79      */
80     public Closure(TraitMethod method, Environment environment) {
81         super(environment);
82         def = NativeApp.checkAndLoadNative(method.def);
83         instArgs = method.instArgs;
84         setParamsAndReturnType(method.getParameters(), method.returnType);
85     }
86
87 //    public Closure(BetterEnv e, FnExpr x, Option<Type> return_type,
88 //            List<Param> params) {
89 //        super(e);
90 //        def = NativeApp.checkAndLoadNative(x);
91 //        EvalType et = new EvalType(e);
92 //        setParamsAndReturnType(
93 //                et.paramsToParameters(e, params),
94 //                return_type.isPresent() ? et.evalType(return_type.getVal()) : BottomType.ONLY
95 //                );
96 //    }
97
98     @Override
99     public boolean isOverride() {
100         if (def instanceof FnAbsDeclOrDecl) {
101             List<Modifier> mods = ((FnAbsDeclOrDecl) def).getMods();
102             for (Modifier mod : mods)
103                 if (mod instanceof ModifierOverride)
104                     return true;
105         }
106         return false;
107     }
108
109     /* (non-Javadoc)
110      * @see com.sun.fortress.interpreter.evaluator.values.Fcn#getFnName()
111      */
112     @Override
113     public IdOrOpOrAnonymousName getFnName() {
114         return def.getName();
115     }
116
117     protected HasAt getAt() {
118         return def;
119     }
120
121     public String stringName() {
122         return def.stringName();
123     }
124
125     public boolean hasSelfDotMethodInvocation() {
126         return false;
127     }
128
129     public String selfName() {
130         return NI.na();
131     }
132
133     public String toString() {
134         return ((instArgs == null ? s(def) :
135             (s(def) + Useful.listInOxfords(instArgs))) + " " +
136             (type() != null ? type() : "NULL")) + " " + def.at();
137     }
138
139     public boolean seqv(FValue v) {
140         if (!(v instanceof Closure)) return false;
141         Closure c = (Closure) v;
142         if (getDef() != c.getDef()) return false;
143         if (type()   != c.type()) return false;
144         if (getEnv() == c.getEnv()) return true;
145         // TODO: environment walking and matching.  Worth it??
146         // We'd need to compute FV(body).
147         return false;
148     }
149
150     public int hashCode() {
151         return def.hashCode() +
152         System.identityHashCode(getEnv()) +
153         (instArgs == null ? 0 : instArgs.hashCode());
154     }
155
156     public boolean equals(Object o) {
157         if (this == o) return true;
158         if (o.getClass().equals(this.getClass())) {
159             Closure oc = (Closure) o;
160             return def == oc.def &&
161             getEnv() == oc.getEnv() &&
162             (instArgs == null ? (oc.instArgs == null) :
163                 oc.instArgs == null ? false : instArgs.equals(oc.instArgs));
164         }
165         return false;
166     }
167
168     private void setReturnType(FType rt) {
169         // TODO need to get this test right
170         if (this.returnType != null && !this.returnType.equals(rt)) {
171             throw new IllegalStateException(
172                     "Attempted second set of closure return type");
173         }
174         returnType = rt;
175     }
176
177
178     public Applicable getDef() {
179         return def;
180     }
181
182     /**
183      * @return Returns the closure_body.
184      */
185     public Expr getBody() {
186         Option<Expr> optBody = NodeUtil.getBody(def);
187         assert(optBody.isSome());
188         return optBody.unwrap();
189     }
190
191     public Expr getBodyNull() {
192         Option<Expr> optBody = NodeUtil.getBody(def);
193         return optBody.unwrap(null);
194     }
195
196
197     public FValue applyInner(List<FValue> args, HasAt loc,
198                              Environment envForInference) {
199         if (def instanceof NativeApp) {
200             args = typecheckParams(args,loc);
201             try {
202                 return ((NativeApp)def).applyToArgs(args);
203             } catch (AbortedException ae) {
204                 throw ae;
205             } catch (OrphanedException oe) {
206                 throw oe;
207             } catch (FortressException fe) {
208                 throw fe;
209             } catch (RuntimeException ex) {
210                 return error(loc, errorMsg("Wrapped exception ", ex.toString()), ex);
211             } catch (Error ex) {
212                 return error(loc, errorMsg("Wrapped error ", ex.toString()), ex);
213             }
214         } else {
215             Evaluator eval = new Evaluator(buildEnvFromParams(args, loc));
216             return eval.eval(getBody());
217         }
218     }
219
220     /**
221      * The environment, sort of, in which the closure's name is bound.
222      */
223     public Environment getEnv() {
224         return getWithin();
225     }
226
227     /**
228      * The environment used to evaluate the closure.
229      */
230     public Environment getEvalEnv() {
231         return getWithin();
232     }
233
234     /**
235      * Call this for Closures, not setParams.
236      * @param fparams
237      * @param ft
238      */
239     public void setParamsAndReturnType(List<Parameter> fparams, FType ft) {
240         setReturnType(ft);
241         setParams(fparams);
242     }
243
244     protected void setValueType() {
245         setFtype(FTypeArrow.make(getDomain(), returnType));
246     }
247
248     public void finishInitializing() {
249         // This needs to be done right with a generic.
250         Applicable x = getDef();
251         List<Param> params = x.getParams();
252         Option<Type> rt = x.getReturnType();
253         Environment env = getEvalEnv(); // should need this for types,
254                                     // below.
255         FType ft = EvalType.getFTypeFromOption(rt, env, BottomType.ONLY);
256         List<Parameter> fparams = EvalType.paramsToParameters(env, params);
257
258         setParamsAndReturnType(fparams, ft);
259
260         return; //  this;
261     }
262
263     @Override
264     boolean getFinished() {
265        return returnType != null;
266     }
267
268
269 }
Note: See TracBrowser for help on using the browser.