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

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