PageRenderTime 50ms CodeModel.GetById 24ms app.highlight 21ms RepoModel.GetById 1ms app.codeStats 0ms

/interpreter/tags/at2dist170907/src/edu/vub/at/objects/mirrors/NATMirage.java

http://ambienttalk.googlecode.com/
Java | 543 lines | 354 code | 88 blank | 101 comment | 6 complexity | 8ca1ae4cd73c5bd44cda9e4903094b06 MD5 | raw file
  1/**
  2 * AmbientTalk/2 Project
  3 * NATMirage.java created on Oct 2, 2006 at 10:08:12 PM
  4 * (c) Programming Technology Lab, 2006 - 2007
  5 * Authors: Tom Van Cutsem & Stijn Mostinckx
  6 * 
  7 * Permission is hereby granted, free of charge, to any person
  8 * obtaining a copy of this software and associated documentation
  9 * files (the "Software"), to deal in the Software without
 10 * restriction, including without limitation the rights to use,
 11 * copy, modify, merge, publish, distribute, sublicense, and/or
 12 * sell copies of the Software, and to permit persons to whom the
 13 * Software is furnished to do so, subject to the following
 14 * conditions:
 15 *
 16 * The above copyright notice and this permission notice shall be
 17 * included in all copies or substantial portions of the Software.
 18 *
 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 21 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 22 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 23 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 26 * OTHER DEALINGS IN THE SOFTWARE.
 27 */
 28package edu.vub.at.objects.mirrors;
 29
 30import edu.vub.at.actors.ATAsyncMessage;
 31import edu.vub.at.exceptions.InterpreterException;
 32import edu.vub.at.exceptions.XIllegalArgument;
 33import edu.vub.at.exceptions.XTypeMismatch;
 34import edu.vub.at.objects.ATBoolean;
 35import edu.vub.at.objects.ATClosure;
 36import edu.vub.at.objects.ATContext;
 37import edu.vub.at.objects.ATField;
 38import edu.vub.at.objects.ATMethod;
 39import edu.vub.at.objects.ATNil;
 40import edu.vub.at.objects.ATObject;
 41import edu.vub.at.objects.ATTypeTag;
 42import edu.vub.at.objects.ATTable;
 43import edu.vub.at.objects.coercion.NativeTypeTags;
 44import edu.vub.at.objects.grammar.ATAssignmentSymbol;
 45import edu.vub.at.objects.grammar.ATSymbol;
 46import edu.vub.at.objects.natives.FieldMap;
 47import edu.vub.at.objects.natives.MethodDictionary;
 48import edu.vub.at.objects.natives.NATCallframe;
 49import edu.vub.at.objects.natives.OBJNil;
 50import edu.vub.at.objects.natives.NATObject;
 51import edu.vub.at.objects.natives.NATTable;
 52import edu.vub.at.objects.natives.NATText;
 53import edu.vub.at.objects.natives.grammar.AGSymbol;
 54
 55import java.util.LinkedList;
 56import java.util.Vector;
 57
 58/**
 59 * A NATMirage is an object that forwards all meta-operations invoked upon it (at
 60 * the java-level) to its designated mirror object. To cut off infinite meta-regress
 61 * it also has magic_ variants of them which delegate to the default implementation.
 62 *
 63 * @author smostinc
 64 */
 65public class NATMirage extends NATObject {
 66
 67	// Whenever this field is set, the object should be tested for the _MIRROR_ native type tag
 68	private ATObject mirror_;
 69	
 70	public static NATMirage createMirage(ATClosure code, ATObject dynamicParent, boolean parentType, ATTypeTag[] types, ATObject mirror) throws InterpreterException {
 71		if (mirror.meta_isTaggedAs(NativeTypeTags._MIRROR_).asNativeBoolean().javaValue) {
 72			// create a new, uninitialized mirage
 73			NATMirage newMirage = new NATMirage(dynamicParent, code.base_context().base_lexicalScope(), parentType, types);
 74			
 75			// create a new instance of the mirror with the uninitialized mirage, this implicitly clones
 76			// the mirror and re-initializes it, setting the base field to this new mirage
 77			// def mirrorClone := mirror.new(<uninitialized mirage>)
 78			// the init method of the mirror root will normally 
 79			ATObject mirrorClone = mirror.meta_invoke(mirror, NATObject._NEW_NAME_, NATTable.of(newMirage));
 80			
 81			// set the mirage's mirror to the cloned mirror
 82			newMirage.initializeWithMirror(mirrorClone);
 83			return newMirage;
 84		} else {
 85			throw new XIllegalArgument("Object used as a mirror without having the Mirror type tag: " + mirror);
 86		}
 87	}
 88	
 89	/**
 90	 * Dedicated constructor for creating the initial empty mirage tied to the mirror root prototype.
 91	 */
 92	protected NATMirage(OBJMirrorRoot mirror) {
 93		super();
 94		mirror_ = mirror;
 95	}
 96	
 97	public NATMirage(ATObject dynamicParent, ATObject lexParent, boolean parentType, ATTypeTag[] types) {
 98		super(dynamicParent, lexParent, parentType, types);
 99		mirror_ = OBJNil._INSTANCE_; // set to nil while not initialized
100	}
101	
102	/**
103	 * Private setter to be used in OBJMirrorRoot.init to break the chicken-and-egg cycle when
104	 * having to create both a mirror and its mirage simultaneously. The sequence is as follows:
105	 *  1) a new empty 'uninitialized' mirage is created, with mirror as nil
106	 *  2) a mirror is instantiated, leading to the invocation of its init method
107	 *  3) the initialization of a new OBJMirrorRoot assigns the uninitialized mirage to its 'base' field
108	 *  4) the mirror field of the uninitialized mirage is set to the newly created mirror, using this method.
109	 */
110	private void initializeWithMirror(ATObject realMirror) {
111		mirror_ = realMirror;
112	}
113	
114	/**
115	 * Constructs a new ambienttalk mirage as a clone of an existing one. This results in a new
116	 * uninitialized mirage (i.e. a mirage whose mirror points to nil). The code that clones the
117	 * mirage must ensure that the mirror is correctly bound to a new instance of the cloned mirage's mirror.
118	
119	 * 
120	 * 
121	 */
122	protected NATMirage(FieldMap map,
123			         Vector state,
124			         LinkedList customFields,
125			         MethodDictionary methodDict,
126			         ATObject dynamicParent,
127			         ATObject lexicalParent,
128			         byte flags,
129			         ATTypeTag[] types) throws InterpreterException {
130		super(map, state, customFields, methodDict, dynamicParent, lexicalParent, flags, types);
131		mirror_ = OBJNil._INSTANCE_;
132	}
133	
134	public NATMirage asMirage() throws XTypeMismatch {
135		return this;
136	}
137	
138	// Called by the default NATObject Cloning algorithm
139	protected NATObject createClone(FieldMap map,
140			Vector state,
141			LinkedList customFields,
142			MethodDictionary methodDict,
143			ATObject dynamicParent,
144			ATObject lexicalParent,
145			byte flags, ATTypeTag[] types) throws InterpreterException {
146		NATMirage clonedMirage = new NATMirage(map,
147				state,
148				customFields,
149				methodDict,
150				dynamicParent,
151				lexicalParent,
152				flags,
153				types);
154        // clonedMirage.mirror := myMirror.new(clonedMirage)
155		clonedMirage.mirror_ = mirror_.meta_invoke(mirror_, NATObject._NEW_NAME_, NATTable.of(clonedMirage));
156		return clonedMirage;
157	}
158	
159	/**
160	 * Access to the mirage's mirror, to enable a mirage to be 'upped' to a mirror value.
161	 */
162	protected ATObject getMirror() {
163		return mirror_;
164	}
165	
166	// MAGIC METHODS 
167	// Cut-off for infinite meta-regress
168	
169	public ATNil magic_addMethod(ATMethod method) throws InterpreterException {
170		return super.meta_addMethod(method);
171	}
172
173	public ATObject magic_clone() throws InterpreterException {
174		return super.meta_clone();
175	}
176	
177	public ATNil magic_defineField(ATSymbol name, ATObject value) throws InterpreterException {
178		return super.meta_defineField(name, value);
179	}
180
181	public ATMethod magic_grabMethod(ATSymbol selector) throws InterpreterException {
182		return super.meta_grabMethod(selector);
183	}
184
185	/**
186	 * <tt>invoke</tt> deviates from the default super-calling behaviour because
187	 * the inherited <tt>invoke</tt> implementation from {@link NATCallframe}
188	 * performs a self-send to {@link this#impl_selectAccessor(ATObject, ATSymbol)}
189	 * or {@link this#impl_selectMutator(ATObject, ATAssignmentSymbol)}. However,
190	 * these methods are overridden in the mirage to transform the impl methods into
191	 * <tt>invoke</tt> methods, which causes an infinite loop.
192	 * To break the loop, the inherited implementation is duplicated here, and the
193	 * self-sends are replaced by static super-sends, such that the native implementation
194	 * of the impl methods can be reused.
195	 */
196	public ATObject magic_invoke(ATObject receiver, ATSymbol selector, ATTable arguments) throws InterpreterException {
197		//return super.meta_invoke(receiver, selector, arguments);
198		// If the selector is an assignment symbol (i.e. `field:=) try to assign the corresponding field
199		if (selector.isAssignmentSymbol()) {
200			return super.impl_invokeMutator(receiver, selector.asAssignmentSymbol(), arguments);
201		} else {
202			return super.impl_invokeAccessor(receiver, selector, arguments);
203		}
204	}
205
206	public ATTable magic_listMethods() throws InterpreterException {
207		return super.meta_listMethods();
208	}
209
210	public ATObject magic_newInstance(ATTable initargs) throws InterpreterException {
211		return super.meta_newInstance(initargs);
212	}
213
214	public NATText magic_print() throws InterpreterException {
215		return super.meta_print();
216	}
217
218	public ATObject magic_receive(ATAsyncMessage message) throws InterpreterException {
219		return super.meta_receive(message);
220	}
221
222	public ATBoolean magic_respondsTo(ATSymbol selector) throws InterpreterException {
223		return super.meta_respondsTo(selector);
224	}
225
226	/**
227	 * <tt>select</tt> deviates from the default super-calling behaviour because
228	 * the inherited <tt>select</tt> implementation from {@link NATCallframe}
229	 * performs a self-send to {@link this#impl_selectAccessor(ATObject, ATSymbol)}
230	 * or {@link this#impl_selectMutator(ATObject, ATAssignmentSymbol)}. However,
231	 * these methods are overridden in the mirage to transform the impl methods into
232	 * <tt>select</tt> methods, which causes an infinite loop.
233	 * To break the loop, the inherited implementation is duplicated here, and the
234	 * self-sends are replaced by static super-sends, such that the native implementation
235	 * of the impl methods can be reused.
236	 */
237	public ATObject magic_select(ATObject receiver, ATSymbol selector) throws InterpreterException {
238		//return super.meta_select(receiver, selector);
239		if (selector.isAssignmentSymbol()) {
240			return super.impl_selectMutator(receiver, selector.asAssignmentSymbol());
241		} else {
242			return super.impl_selectAccessor(receiver, selector);
243		}
244	}
245
246	public ATNil magic_addField(ATField field) throws InterpreterException {
247		return super.meta_addField(field);
248	}
249
250
251	public ATObject magic_doesNotUnderstand(ATSymbol selector) throws InterpreterException {
252		return super.meta_doesNotUnderstand(selector);
253	}
254
255
256	public ATField magic_grabField(ATSymbol selector) throws InterpreterException {
257		return super.meta_grabField(selector);
258	}
259
260
261	public ATTable magic_listFields() throws InterpreterException {
262		return super.meta_listFields();
263	}
264
265
266	public ATObject magic_send(ATObject receiver, ATAsyncMessage message) throws InterpreterException {
267		return super.meta_send(receiver, message);
268	}
269
270
271	public ATObject magic_eval(ATContext ctx) throws InterpreterException {
272		return super.meta_eval(ctx);
273	}
274
275
276	public ATObject magic_quote(ATContext ctx) throws InterpreterException {
277		return super.meta_quote(ctx);
278	}
279	
280	public ATBoolean magic_isExtensionOfParent() throws InterpreterException {
281		return super.meta_isExtensionOfParent();
282	}
283
284	public ATObject magic_invokeField(ATObject rcv, ATSymbol sym) throws InterpreterException {
285		return super.meta_invokeField(rcv, sym);
286	}
287	
288	public ATObject magic_pass() throws InterpreterException {
289		return super.meta_pass();
290	}
291	
292	public ATObject magic_resolve() throws InterpreterException {
293		return super.meta_resolve();
294	}
295	
296	public ATBoolean magic_isTaggedAs(ATTypeTag type) throws InterpreterException {
297		return super.meta_isTaggedAs(type);
298	}
299	
300	public ATTable magic_typeTags() throws InterpreterException {
301		return super.meta_typeTags();
302	}
303
304	public ATBoolean magic_isCloneOf(ATObject original) throws InterpreterException {
305		return super.meta_isCloneOf(original);
306	}
307
308	public ATBoolean magic_isRelatedTo(ATObject object) throws InterpreterException {
309		return super.meta_isRelatedTo(object);
310	}
311	
312	/* ========================================================================
313	 * Each meta_x method defined in ATObject is implemented in a mirage as a
314	 * forwarding method that asks its mirror to perform the operation on itself
315	 * instead.
316	 * ======================================================================== */
317
318	public ATNil meta_addMethod(ATMethod method) throws InterpreterException {
319		mirror_.meta_invoke(
320				mirror_,
321				AGSymbol.jAlloc("addMethod"),
322				NATTable.atValue(new ATObject[] { method })
323				);
324			
325		return OBJNil._INSTANCE_;
326	}
327
328	public ATObject meta_clone() throws InterpreterException {
329		return mirror_.meta_invoke(
330				mirror_,
331				AGSymbol.jAlloc("clone"),
332				NATTable.EMPTY);
333	}
334
335	public ATNil meta_defineField(ATSymbol name, ATObject value) throws InterpreterException {
336		mirror_.meta_invoke(
337				mirror_,
338				AGSymbol.jAlloc("defineField"),
339				NATTable.atValue(new ATObject[] { name, value }));
340		return OBJNil._INSTANCE_;
341	}
342	
343	public ATMethod meta_grabMethod(ATSymbol selector) throws InterpreterException {
344		return mirror_.meta_invoke(
345				mirror_,
346				AGSymbol.jAlloc("grabMethod"),
347				NATTable.atValue(new ATObject[] { selector })
348				).asMethod();
349	}
350
351	public ATObject meta_invoke(ATObject receiver, ATSymbol selector, ATTable arguments) throws InterpreterException {
352		return mirror_.meta_invoke(
353				mirror_,
354				AGSymbol.jAlloc("invoke"),
355				NATTable.atValue(new ATObject[] { receiver, selector, arguments }));
356	}
357
358	public ATTable meta_listMethods() throws InterpreterException {
359		return mirror_.meta_invoke(
360				mirror_,
361				AGSymbol.jAlloc("listMethods"),
362				NATTable.EMPTY
363				).asTable();
364	}
365
366	public ATObject meta_newInstance(ATTable initargs) throws InterpreterException {
367		return mirror_.meta_invoke(
368				mirror_,
369				AGSymbol.jAlloc("newInstance"),
370				NATTable.atValue(new ATObject[] { initargs }));
371	}
372
373	public NATText meta_print() throws InterpreterException {
374		return mirror_.meta_invoke(
375					mirror_,
376					AGSymbol.jAlloc("print"),
377					NATTable.EMPTY).asNativeText();
378	}
379
380	public ATObject meta_receive(ATAsyncMessage message) throws InterpreterException {
381		return mirror_.meta_invoke(
382				mirror_,
383				AGSymbol.jAlloc("receive"),
384				NATTable.atValue(new ATObject[] { message }));
385	}
386	
387	public ATBoolean meta_respondsTo(ATSymbol selector) throws InterpreterException {
388		return mirror_.meta_invoke(
389				mirror_,
390				AGSymbol.jAlloc("respondsTo"),
391				NATTable.atValue(new ATObject[] { selector })
392				).asBoolean();
393	}
394
395	public ATClosure meta_select(ATObject receiver, ATSymbol selector) throws InterpreterException {
396		return mirror_.meta_invoke(
397				mirror_,
398				AGSymbol.jAlloc("select"),
399				NATTable.atValue(new ATObject[] { receiver, selector })).asClosure();
400	}
401
402	public ATNil meta_addField(ATField field) throws InterpreterException {
403		mirror_.meta_invoke(
404				mirror_,
405				AGSymbol.jAlloc("addField"),
406				NATTable.atValue(new ATObject[] { field }));
407		return OBJNil._INSTANCE_;
408	}
409
410
411	public ATClosure meta_doesNotUnderstand(ATSymbol selector) throws InterpreterException {
412		return mirror_.meta_invoke(
413				mirror_,
414				AGSymbol.jAlloc("doesNotUnderstand"),
415				NATTable.atValue(new ATObject[] { selector })).asClosure();
416	}
417
418
419	public ATField meta_grabField(ATSymbol selector) throws InterpreterException {
420		return mirror_.meta_invoke(
421				mirror_,
422				AGSymbol.jAlloc("grabField"),
423				NATTable.atValue(new ATObject[] { selector })).asField();
424	}
425
426
427	public ATTable meta_listFields() throws InterpreterException {
428		return mirror_.meta_invoke(
429				mirror_,
430				AGSymbol.jAlloc("listFields"),
431				NATTable.EMPTY).asTable();
432	}
433
434
435	public ATObject meta_send(ATObject receiver, ATAsyncMessage message) throws InterpreterException {
436		mirror_.meta_invoke(
437				mirror_,
438				AGSymbol.jAlloc("send"),
439				NATTable.atValue(new ATObject[] { message }));
440		return OBJNil._INSTANCE_;
441	}
442
443
444	public ATObject meta_eval(ATContext ctx) throws InterpreterException {
445		return mirror_.meta_invoke(
446				mirror_,
447				AGSymbol.jAlloc("eval"),
448				NATTable.atValue(new ATObject[] { ctx }));
449	}
450
451
452	public ATObject meta_quote(ATContext ctx) throws InterpreterException {
453		return mirror_.meta_invoke(
454				mirror_,
455				AGSymbol.jAlloc("quote"),
456				NATTable.atValue(new ATObject[] { ctx }));
457	}
458
459	public ATBoolean meta_isExtensionOfParent() throws InterpreterException {
460		return mirror_.meta_invoke(
461				mirror_,
462				AGSymbol.jAlloc("isExtensionOfParent"),
463				NATTable.EMPTY).asBoolean();
464	}
465
466	public ATObject meta_invokeField(ATObject rcv, ATSymbol sym) throws InterpreterException {
467		return mirror_.meta_invoke(
468				mirror_,
469				AGSymbol.jAlloc("invokeField"),
470				NATTable.atValue(new ATObject[] { rcv, sym }));
471	}
472	
473    public ATObject meta_pass() throws InterpreterException {
474    	return mirror_.meta_invoke(
475				mirror_, AGSymbol.jAlloc("pass"), NATTable.EMPTY);
476    }
477    
478    public ATObject meta_resolve() throws InterpreterException {
479    	return mirror_.meta_invoke(
480				mirror_, AGSymbol.jAlloc("resolve"), NATTable.EMPTY);
481    }
482    
483    public ATBoolean meta_isTaggedAs(ATTypeTag type) throws InterpreterException {
484    	return mirror_.meta_invoke(
485				mirror_, AGSymbol.jAlloc("isTaggedAs"), NATTable.of(type)).asBoolean();
486    }
487    
488    public ATTable meta_typeTags() throws InterpreterException {
489		return mirror_.meta_invoke(
490				mirror_,
491				AGSymbol.jAlloc("typeTags"),
492				NATTable.EMPTY).asTable();
493    }
494	
495	public ATBoolean meta_isCloneOf(ATObject original) throws InterpreterException {
496		return mirror_.meta_invoke(
497				mirror_,
498				AGSymbol.jAlloc("isCloneOf"),
499				NATTable.atValue(new ATObject[] { original })).asBoolean();
500	}
501
502	public ATBoolean meta_isRelatedTo(ATObject object) throws InterpreterException {
503		return mirror_.meta_invoke(
504				mirror_,
505				AGSymbol.jAlloc("isRelatedTo"),
506				NATTable.atValue(new ATObject[] { object })).asBoolean();
507	}
508
509	/** implementation-level method is mapped onto regular MOP method */
510	public ATObject impl_invokeAccessor(ATObject receiver, ATSymbol selector, ATTable arguments) throws InterpreterException {
511		return mirror_.meta_invoke(
512				mirror_,
513				AGSymbol.jAlloc("invoke"),
514				NATTable.atValue(new ATObject[] { receiver, selector, arguments }));
515	}
516
517	/** implementation-level method is mapped onto regular MOP method */
518	public ATObject impl_invokeMutator(ATObject receiver, ATAssignmentSymbol selector, ATTable arguments) throws InterpreterException {
519		return mirror_.meta_invoke(
520				mirror_,
521				AGSymbol.jAlloc("invoke"),
522				NATTable.atValue(new ATObject[] { receiver, selector, arguments }));
523	}
524
525	/** implementation-level method is mapped onto regular MOP method */
526	public ATClosure impl_selectAccessor(ATObject receiver, ATSymbol selector) throws InterpreterException {
527		return mirror_.meta_invoke(
528				mirror_,
529				AGSymbol.jAlloc("select"),
530				NATTable.atValue(new ATObject[] { receiver, selector })).asClosure();
531	}
532
533	/** implementation-level method is mapped onto regular MOP method */
534	public ATClosure impl_selectMutator(ATObject receiver, ATAssignmentSymbol selector) throws InterpreterException {
535		return mirror_.meta_invoke(
536				mirror_,
537				AGSymbol.jAlloc("select"),
538				NATTable.atValue(new ATObject[] { receiver, selector })).asClosure();
539	}
540	
541	
542	
543}