PageRenderTime 44ms CodeModel.GetById 14ms app.highlight 25ms RepoModel.GetById 1ms app.codeStats 0ms

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

http://ambienttalk.googlecode.com/
Java | 612 lines | 409 code | 99 blank | 104 comment | 8 complexity | bd4a45b6168bd25a7b44f42af51d3b73 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.eval.Evaluator;
 32import edu.vub.at.exceptions.InterpreterException;
 33import edu.vub.at.exceptions.XIllegalArgument;
 34import edu.vub.at.exceptions.XTypeMismatch;
 35import edu.vub.at.objects.ATBoolean;
 36import edu.vub.at.objects.ATClosure;
 37import edu.vub.at.objects.ATContext;
 38import edu.vub.at.objects.ATField;
 39import edu.vub.at.objects.ATMethod;
 40import edu.vub.at.objects.ATMethodInvocation;
 41import edu.vub.at.objects.ATNil;
 42import edu.vub.at.objects.ATObject;
 43import edu.vub.at.objects.ATTable;
 44import edu.vub.at.objects.ATTypeTag;
 45import edu.vub.at.objects.coercion.NativeTypeTags;
 46import edu.vub.at.objects.grammar.ATAssignmentSymbol;
 47import edu.vub.at.objects.grammar.ATSymbol;
 48import edu.vub.at.objects.natives.FieldMap;
 49import edu.vub.at.objects.natives.MethodDictionary;
 50import edu.vub.at.objects.natives.NATCallframe;
 51import edu.vub.at.objects.natives.NATMethodInvocation;
 52import edu.vub.at.objects.natives.NATNil;
 53import edu.vub.at.objects.natives.NATObject;
 54import edu.vub.at.objects.natives.NATTable;
 55import edu.vub.at.objects.natives.NATText;
 56import edu.vub.at.objects.natives.grammar.AGSymbol;
 57
 58import java.util.LinkedList;
 59import java.util.Vector;
 60
 61/**
 62 * A NATMirage is an object that forwards all meta-operations invoked upon it (at
 63 * the java-level) to its designated mirror object. To cut off infinite meta-regress
 64 * it also has magic_ variants of them which delegate to the default implementation.
 65 *
 66 * @author smostinc
 67 */
 68public class NATMirage extends NATObject {
 69
 70	// Whenever this field is set, the object should be tested for the _MIRROR_ native type tag
 71	private ATObject mirror_;
 72	
 73	public static NATMirage createMirage(ATClosure code, ATObject dynamicParent, boolean parentType, ATTypeTag[] types, ATObject mirror) throws InterpreterException {
 74		// create a new, uninitialized mirage
 75		NATMirage newMirage = new NATMirage(dynamicParent, code.base_context().base_lexicalScope(), parentType, types);
 76			
 77		ATObject theMirror;
 78		if (mirror.meta_isTaggedAs(NativeTypeTags._CLOSURE_).asNativeBoolean().javaValue) {
 79			// the mirror argument is a constructor closure: the mirror to be used
 80			// is the return value of applying the closure
 81			theMirror = mirror.asClosure().base_apply(NATTable.of(newMirage));
 82		} else {
 83			// create a new instance of the mirror prototype with the uninitialized mirage,
 84			// this implicitly clones the mirror and re-initializes it, setting the base field
 85			// to this new mirage
 86			// def mirrorClone := mirror.new(<uninitialized mirage>)
 87			theMirror = mirror.impl_invoke(mirror, NATNil._NEW_NAME_, NATTable.of(newMirage));	
 88		}
 89
 90		if (theMirror.meta_isTaggedAs(NativeTypeTags._MIRROR_).asNativeBoolean().javaValue) {
 91			// set the mirage's mirror to the cloned mirror
 92			newMirage.initializeWithMirror(theMirror);
 93			return newMirage;
 94		} else {
 95			throw new XIllegalArgument("Object used as a mirror without having the Mirror type tag: " + theMirror);
 96		}
 97	}
 98	
 99	/**
100	 * Dedicated constructor for creating the initial empty mirage tied to the mirror root prototype.
101	 */
102	protected NATMirage(NATMirrorRoot mirror) {
103		super();
104		mirror_ = mirror;
105	}
106	
107	public NATMirage(ATObject dynamicParent, ATObject lexParent, boolean parentType, ATTypeTag[] types) {
108		super(dynamicParent, lexParent, parentType, types);
109		mirror_ = Evaluator.getNil(); // set to nil while not initialized
110	}
111	
112	/**
113	 * Private setter to be used in OBJMirrorRoot.init to break the chicken-and-egg cycle when
114	 * having to create both a mirror and its mirage simultaneously. The sequence is as follows:
115	 *  1) a new empty 'uninitialized' mirage is created, with mirror as nil
116	 *  2) a mirror is instantiated, leading to the invocation of its init method
117	 *  3) the initialization of a new OBJMirrorRoot assigns the uninitialized mirage to its 'base' field
118	 *  4) the mirror field of the uninitialized mirage is set to the newly created mirror, using this method.
119	 */
120	private void initializeWithMirror(ATObject realMirror) {
121		mirror_ = realMirror;
122	}
123	
124	/**
125	 * Constructs a new ambienttalk mirage as a clone of an existing one. This results in a new
126	 * uninitialized mirage (i.e. a mirage whose mirror points to nil). The code that clones the
127	 * mirage must ensure that the mirror is correctly bound to a new instance of the cloned mirage's mirror.
128	
129	 * 
130	 * 
131	 */
132	protected NATMirage(FieldMap map,
133			         Vector state,
134			         LinkedList customFields,
135			         MethodDictionary methodDict,
136			         ATObject dynamicParent,
137			         ATObject lexicalParent,
138			         byte flags,
139			         ATTypeTag[] types) throws InterpreterException {
140		super(map, state, customFields, methodDict, dynamicParent, lexicalParent, flags, types);
141		mirror_ = Evaluator.getNil();
142	}
143	
144    public boolean isMirage() {
145    	return true;
146    }
147	
148	public NATMirage asMirage() throws XTypeMismatch {
149		return this;
150	}
151	
152	// Called by the default NATObject Cloning algorithm
153	protected NATObject createClone(FieldMap map,
154			Vector state,
155			LinkedList customFields,
156			MethodDictionary methodDict,
157			ATObject dynamicParent,
158			ATObject lexicalParent,
159			byte flags, ATTypeTag[] types) throws InterpreterException {
160		NATMirage clonedMirage = new NATMirage(map,
161				state,
162				customFields,
163				methodDict,
164				dynamicParent,
165				lexicalParent,
166				flags,
167				types);
168        // clonedMirage.mirror := myMirror.new(clonedMirage)
169		clonedMirage.mirror_ = mirror_.impl_invoke(mirror_, NATNil._NEW_NAME_, NATTable.of(clonedMirage));
170		return clonedMirage;
171	}
172	
173	/**
174	 * Access to the mirage's mirror, to enable a mirage to be 'upped' to a mirror value.
175	 */
176	protected ATObject getMirror() {
177		return mirror_;
178	}
179	
180	// MAGIC METHODS 
181	// Cut-off for infinite meta-regress
182	
183	public ATNil magic_addMethod(ATMethod method) throws InterpreterException {
184		return super.meta_addMethod(method);
185	}
186
187	public ATObject magic_clone() throws InterpreterException {
188		return super.meta_clone();
189	}
190	
191	public ATNil magic_defineField(ATSymbol name, ATObject value) throws InterpreterException {
192		return super.meta_defineField(name, value);
193	}
194
195	public ATMethod magic_grabMethod(ATSymbol selector) throws InterpreterException {
196		return super.meta_grabMethod(selector);
197	}
198
199	/**
200	 * <tt>invoke</tt> deviates from the default super-calling behaviour because
201	 * the inherited <tt>invoke</tt> implementation from {@link NATCallframe}
202	 * performs a self-send to {@link this#impl_selectAccessor(ATObject, ATSymbol)}
203	 * or {@link this#impl_selectMutator(ATObject, ATAssignmentSymbol)}. However,
204	 * these methods are overridden in the mirage to transform the impl methods into
205	 * <tt>invoke</tt> methods, which causes an infinite loop.
206	 * To break the loop, the inherited implementation is duplicated here, and the
207	 * self-sends are replaced by static super-sends, such that the native implementation
208	 * of the impl methods can be reused.
209	 */
210	public ATObject magic_invoke(ATObject receiver, ATMethodInvocation inv) throws InterpreterException {
211		ATSymbol selector = inv.base_selector();
212		ATTable arguments = inv.base_arguments();
213		//return super.meta_invoke(receiver, selector, arguments);
214		// If the selector is an assignment symbol (i.e. `field:=) try to assign the corresponding field
215		if (selector.isAssignmentSymbol()) {
216			return super.impl_invokeMutator(receiver, selector.asAssignmentSymbol(), arguments);
217		} else {
218			return super.impl_invokeAccessor(receiver, selector, arguments);
219		}
220	}
221
222	public ATTable magic_listMethods() throws InterpreterException {
223		return super.meta_listMethods();
224	}
225
226	public ATObject magic_newInstance(ATTable initargs) throws InterpreterException {
227		return super.meta_newInstance(initargs);
228	}
229
230	public NATText magic_print() throws InterpreterException {
231		return super.meta_print();
232	}
233
234	public ATObject magic_receive(ATAsyncMessage message) throws InterpreterException {
235		return super.meta_receive(message);
236	}
237
238	public ATBoolean magic_respondsTo(ATSymbol selector) throws InterpreterException {
239		return super.meta_respondsTo(selector);
240	}
241
242	/**
243	 * <tt>select</tt> deviates from the default super-calling behaviour because
244	 * the inherited <tt>select</tt> implementation from {@link NATCallframe}
245	 * performs a self-send to {@link this#impl_selectAccessor(ATObject, ATSymbol)}
246	 * or {@link this#impl_selectMutator(ATObject, ATAssignmentSymbol)}. However,
247	 * these methods are overridden in the mirage to transform the impl methods into
248	 * <tt>select</tt> methods, which causes an infinite loop.
249	 * To break the loop, the inherited implementation is duplicated here, and the
250	 * self-sends are replaced by static super-sends, such that the native implementation
251	 * of the impl methods can be reused.
252	 */
253	public ATClosure magic_select(ATObject receiver, ATSymbol selector) throws InterpreterException {
254		//return super.meta_select(receiver, selector);
255		if (selector.isAssignmentSymbol()) {
256			return super.impl_selectMutator(receiver, selector.asAssignmentSymbol());
257		} else {
258			return super.impl_selectAccessor(receiver, selector);
259		}
260	}
261
262	
263	public ATClosure magic_doesNotUnderstand(ATSymbol selector) throws InterpreterException {
264		return super.meta_doesNotUnderstand(selector);
265	}
266	
267	
268	public ATNil magic_addField(ATField field) throws InterpreterException {
269		return super.meta_addField(field);
270	}
271
272	
273	public ATField magic_grabField(ATSymbol selector) throws InterpreterException {
274		return super.meta_grabField(selector);
275	}
276
277	
278	public ATTable magic_listFields() throws InterpreterException {
279		return super.meta_listFields();
280	}
281	
282	public ATNil magic_addSlot(ATMethod slot) throws InterpreterException {
283		return super.meta_addSlot(slot);
284	}
285
286	
287	public ATMethod magic_grabSlot(ATSymbol selector) throws InterpreterException {
288		return super.meta_grabSlot(selector);
289	}
290
291	public ATObject magic_removeSlot(ATSymbol selector) throws InterpreterException {
292		return super.meta_removeSlot(selector);
293	}
294	
295	public ATTable magic_listSlots() throws InterpreterException {
296		return super.meta_listSlots();
297	}
298
299
300	public ATObject magic_send(ATObject receiver, ATAsyncMessage message) throws InterpreterException {
301		return super.meta_send(receiver, message);
302	}
303
304
305	public ATObject magic_eval(ATContext ctx) throws InterpreterException {
306		return super.meta_eval(ctx);
307	}
308
309
310	public ATObject magic_quote(ATContext ctx) throws InterpreterException {
311		return super.meta_quote(ctx);
312	}
313	
314	public ATBoolean magic_isExtensionOfParent() throws InterpreterException {
315		return super.meta_isExtensionOfParent();
316	}
317
318	public ATObject magic_invokeField(ATObject rcv, ATSymbol sym) throws InterpreterException {
319		return super.meta_invokeField(rcv, sym);
320	}
321	
322	public ATObject magic_pass() throws InterpreterException {
323		return super.meta_pass();
324	}
325	
326	public ATObject magic_resolve() throws InterpreterException {
327		return super.meta_resolve();
328	}
329	
330	public ATBoolean magic_isTaggedAs(ATTypeTag type) throws InterpreterException {
331		return super.meta_isTaggedAs(type);
332	}
333	
334	public ATTable magic_typeTags() throws InterpreterException {
335		return super.meta_typeTags();
336	}
337
338	public ATBoolean magic_isCloneOf(ATObject original) throws InterpreterException {
339		return super.meta_isCloneOf(original);
340	}
341
342	public ATBoolean magic_isRelatedTo(ATObject object) throws InterpreterException {
343		return super.meta_isRelatedTo(object);
344	}
345	
346	/* ========================================================================
347	 * Each meta_x method defined in ATObject is implemented in a mirage as a
348	 * forwarding method that asks its mirror to perform the operation on itself
349	 * instead.
350	 * ======================================================================== */
351
352	public ATNil meta_addMethod(ATMethod method) throws InterpreterException {
353		mirror_.impl_invoke(
354				mirror_,
355				AGSymbol.jAlloc("addMethod"),
356				NATTable.atValue(new ATObject[] { method })
357				);
358			
359		return Evaluator.getNil();
360	}
361
362	public ATObject meta_clone() throws InterpreterException {
363		return mirror_.impl_invoke(
364				mirror_,
365				AGSymbol.jAlloc("clone"),
366				NATTable.EMPTY);
367	}
368
369	public ATNil meta_defineField(ATSymbol name, ATObject value) throws InterpreterException {
370		mirror_.impl_invoke(
371				mirror_,
372				AGSymbol.jAlloc("defineField"),
373				NATTable.atValue(new ATObject[] { name, value }));
374		return Evaluator.getNil();
375	}
376	
377	public ATMethod meta_grabMethod(ATSymbol selector) throws InterpreterException {
378		return mirror_.impl_invoke(
379				mirror_,
380				AGSymbol.jAlloc("grabMethod"),
381				NATTable.atValue(new ATObject[] { selector })
382				).asMethod();
383	}
384
385	public ATObject meta_invoke(ATObject delegate, ATMethodInvocation inv) throws InterpreterException {
386		return mirror_.impl_invoke(
387				mirror_,
388				AGSymbol.jAlloc("invoke"),
389				NATTable.atValue(new ATObject[] { delegate, inv }));
390	}
391
392	public ATTable meta_listMethods() throws InterpreterException {
393		return mirror_.impl_invoke(
394				mirror_,
395				AGSymbol.jAlloc("listMethods"),
396				NATTable.EMPTY
397				).asTable();
398	}
399
400	public ATObject meta_newInstance(ATTable initargs) throws InterpreterException {
401		return mirror_.impl_invoke(
402				mirror_,
403				AGSymbol.jAlloc("newInstance"),
404				NATTable.atValue(new ATObject[] { initargs }));
405	}
406
407	public NATText meta_print() throws InterpreterException {
408		return mirror_.impl_invoke(
409					mirror_,
410					AGSymbol.jAlloc("print"),
411					NATTable.EMPTY).asNativeText();
412	}
413
414	public ATObject meta_receive(ATAsyncMessage message) throws InterpreterException {
415		return mirror_.impl_invoke(
416				mirror_,
417				AGSymbol.jAlloc("receive"),
418				NATTable.atValue(new ATObject[] { message }));
419	}
420	
421	public ATBoolean meta_respondsTo(ATSymbol selector) throws InterpreterException {
422		return mirror_.impl_invoke(
423				mirror_,
424				AGSymbol.jAlloc("respondsTo"),
425				NATTable.atValue(new ATObject[] { selector })
426				).asBoolean();
427	}
428
429	public ATClosure meta_select(ATObject receiver, ATSymbol selector) throws InterpreterException {
430		return mirror_.impl_invoke(
431				mirror_,
432				AGSymbol.jAlloc("select"),
433				NATTable.atValue(new ATObject[] { receiver, selector })).asClosure();
434	}
435
436	public ATNil meta_addField(ATField field) throws InterpreterException {
437		mirror_.impl_invoke(
438				mirror_,
439				AGSymbol.jAlloc("addField"),
440				NATTable.atValue(new ATObject[] { field }));
441		return Evaluator.getNil();
442	}
443
444	public ATField meta_grabField(ATSymbol selector) throws InterpreterException {
445		return mirror_.impl_invoke(
446				mirror_,
447				AGSymbol.jAlloc("grabField"),
448				NATTable.atValue(new ATObject[] { selector })).asField();
449	}
450
451
452	public ATTable meta_listFields() throws InterpreterException {
453		return mirror_.impl_invoke(
454				mirror_,
455				AGSymbol.jAlloc("listFields"),
456				NATTable.EMPTY).asTable();
457	}
458	
459	public ATNil meta_addSlot(ATMethod slot) throws InterpreterException {
460		mirror_.impl_invoke(
461				mirror_,
462				AGSymbol.jAlloc("addSlot"),
463				NATTable.atValue(new ATObject[] { slot }));
464		return Evaluator.getNil();
465	}
466
467	public ATMethod meta_grabSlot(ATSymbol selector) throws InterpreterException {
468		return mirror_.impl_invoke(
469				mirror_,
470				AGSymbol.jAlloc("grabSlot"),
471				NATTable.atValue(new ATObject[] { selector })).asMethod();
472	}
473
474
475	public ATTable meta_listSlots() throws InterpreterException {
476		return mirror_.impl_invoke(
477				mirror_,
478				AGSymbol.jAlloc("listSlots"),
479				NATTable.EMPTY).asTable();
480	}
481	
482    public ATObject meta_removeSlot(ATSymbol selector) throws InterpreterException {
483		return mirror_.impl_invoke(
484				mirror_,
485				AGSymbol.jAlloc("removeSlot"),
486				NATTable.of(selector));
487    }
488
489	public ATClosure meta_doesNotUnderstand(ATSymbol selector) throws InterpreterException {
490		return mirror_.impl_invoke(
491				mirror_,
492				AGSymbol.jAlloc("doesNotUnderstand"),
493				NATTable.atValue(new ATObject[] { selector })).asClosure();
494	}
495
496
497	public ATObject meta_send(ATObject receiver, ATAsyncMessage message) throws InterpreterException {
498		return mirror_.impl_invoke(
499				mirror_,
500				AGSymbol.jAlloc("send"),
501				NATTable.atValue(new ATObject[] { receiver, message }));
502	}
503
504
505	public ATObject meta_eval(ATContext ctx) throws InterpreterException {
506		return mirror_.impl_invoke(
507				mirror_,
508				AGSymbol.jAlloc("eval"),
509				NATTable.atValue(new ATObject[] { ctx }));
510	}
511
512
513	public ATObject meta_quote(ATContext ctx) throws InterpreterException {
514		return mirror_.impl_invoke(
515				mirror_,
516				AGSymbol.jAlloc("quote"),
517				NATTable.atValue(new ATObject[] { ctx }));
518	}
519
520	public ATBoolean meta_isExtensionOfParent() throws InterpreterException {
521		return mirror_.impl_invoke(
522				mirror_,
523				AGSymbol.jAlloc("isExtensionOfParent"),
524				NATTable.EMPTY).asBoolean();
525	}
526
527	public ATObject meta_invokeField(ATObject rcv, ATSymbol sym) throws InterpreterException {
528		return mirror_.impl_invoke(
529				mirror_,
530				AGSymbol.jAlloc("invokeField"),
531				NATTable.atValue(new ATObject[] { rcv, sym }));
532	}
533	
534    public ATObject meta_pass() throws InterpreterException {
535    	return mirror_.impl_invoke(
536				mirror_, AGSymbol.jAlloc("pass"), NATTable.EMPTY);
537    }
538    
539    public ATObject meta_resolve() throws InterpreterException {
540    	return mirror_.impl_invoke(
541				mirror_, AGSymbol.jAlloc("resolve"), NATTable.EMPTY);
542    }
543    
544    public ATBoolean meta_isTaggedAs(ATTypeTag type) throws InterpreterException {
545    	return mirror_.impl_invoke(
546				mirror_, AGSymbol.jAlloc("isTaggedAs"), NATTable.of(type)).asBoolean();
547    }
548    
549    public ATTable meta_typeTags() throws InterpreterException {
550		return mirror_.impl_invoke(
551				mirror_,
552				AGSymbol.jAlloc("typeTags"),
553				NATTable.EMPTY).asTable();
554    }
555	
556	public ATBoolean meta_isCloneOf(ATObject original) throws InterpreterException {
557		return mirror_.impl_invoke(
558				mirror_,
559				AGSymbol.jAlloc("isCloneOf"),
560				NATTable.atValue(new ATObject[] { original })).asBoolean();
561	}
562
563	public ATBoolean meta_isRelatedTo(ATObject object) throws InterpreterException {
564		return mirror_.impl_invoke(
565				mirror_,
566				AGSymbol.jAlloc("isRelatedTo"),
567				NATTable.atValue(new ATObject[] { object })).asBoolean();
568	}
569
570	/** implementation-level method is mapped onto regular MOP method */
571	public ATObject impl_invoke(ATObject receiver, ATSymbol selector, ATTable arguments) throws InterpreterException {
572		return mirror_.impl_invoke(
573				mirror_,
574				AGSymbol.jAlloc("invoke"),
575				NATTable.atValue(new ATObject[] { receiver, new NATMethodInvocation(selector, arguments, NATTable.EMPTY) }));
576	}
577	
578	/** implementation-level method is mapped onto regular MOP method */
579	public ATObject impl_invokeAccessor(ATObject receiver, ATSymbol selector, ATTable arguments) throws InterpreterException {
580		return mirror_.impl_invoke(
581				mirror_,
582				AGSymbol.jAlloc("invoke"),
583				NATTable.atValue(new ATObject[] { receiver, new NATMethodInvocation(selector, arguments, NATTable.EMPTY) }));
584	}
585
586	/** implementation-level method is mapped onto regular MOP method */
587	public ATObject impl_invokeMutator(ATObject receiver, ATAssignmentSymbol selector, ATTable arguments) throws InterpreterException {
588		return mirror_.impl_invoke(
589				mirror_,
590				AGSymbol.jAlloc("invoke"),
591				NATTable.atValue(new ATObject[] { receiver, new NATMethodInvocation(selector, arguments, NATTable.EMPTY) }));
592	}
593
594	/** implementation-level method is mapped onto regular MOP method */
595	public ATClosure impl_selectAccessor(ATObject receiver, ATSymbol selector) throws InterpreterException {
596		return mirror_.impl_invoke(
597				mirror_,
598				AGSymbol.jAlloc("select"),
599				NATTable.atValue(new ATObject[] { receiver, selector })).asClosure();
600	}
601
602	/** implementation-level method is mapped onto regular MOP method */
603	public ATClosure impl_selectMutator(ATObject receiver, ATAssignmentSymbol selector) throws InterpreterException {
604		return mirror_.impl_invoke(
605				mirror_,
606				AGSymbol.jAlloc("select"),
607				NATTable.atValue(new ATObject[] { receiver, selector })).asClosure();
608	}
609	
610	
611	
612}