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

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