/interpreter/tags/at2-build060407/src/edu/vub/at/objects/mirrors/NATMirage.java
Java | 524 lines | 347 code | 92 blank | 85 comment | 2 complexity | 974aca1b1cb9fd2e03a3c87f5c16f3d2 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.ATStripe; 42import edu.vub.at.objects.ATTable; 43import edu.vub.at.objects.coercion.NativeStripes; 44import edu.vub.at.objects.grammar.ATSymbol; 45import edu.vub.at.objects.natives.FieldMap; 46import edu.vub.at.objects.natives.MethodDictionary; 47import edu.vub.at.objects.natives.NATNil; 48import edu.vub.at.objects.natives.NATObject; 49import edu.vub.at.objects.natives.NATTable; 50import edu.vub.at.objects.natives.NATText; 51import edu.vub.at.objects.natives.grammar.AGSymbol; 52 53import java.util.LinkedList; 54import java.util.Vector; 55 56/** 57 * A NATMirage is an object that forwards all meta-operations invoked upon it (at 58 * the java-level) to its designated mirror object. To cut off infinite meta-regress 59 * it also has magic_ variants of them which delegate to the default implementation. 60 * 61 * Mirages can currently only be created for 'objects', not for 'isolates'. 62 * Allowing isolates to be mirrored would require the introduction of 'isolate mirrors', since an isolate 63 * can only be copied if its mirror can be copied. 64 * 65 * @author smostinc 66 */ 67public class NATMirage extends NATObject { 68 69 // Whenever this field is set, the object should be tested for the _MIRROR_ native stripe 70 private ATObject mirror_; 71 72 public static NATMirage createMirage(ATClosure code, ATObject dynamicParent, boolean parentType, ATStripe[] stripes, ATObject mirror) throws InterpreterException { 73 if (mirror.meta_isStripedWith(NativeStripes._MIRROR_).asNativeBoolean().javaValue) { 74 // create a new, uninitialized mirage 75 NATMirage newMirage = new NATMirage(dynamicParent, code.base_getContext().base_getLexicalScope(), parentType, stripes); 76 77 // create a new instance of the mirror with the uninitialized mirage, this implicitly clones 78 // the mirror and re-initializes it, setting the base field to this new mirage 79 // def mirrorClone := mirror.new(<uninitialized mirage>) 80 // the init method of the mirror root will normally 81 ATObject mirrorClone = mirror.meta_invoke(mirror, NATObject._NEW_NAME_, NATTable.of(newMirage)); 82 83 // set the mirage's mirror to the cloned mirror 84 newMirage.initializeWithMirror(mirrorClone); 85 return newMirage; 86 } else { 87 throw new XIllegalArgument("Object used as a mirror without having the Mirror stripe: " + mirror); 88 } 89 } 90 91 /** 92 * Dedicated constructor for creating the initial empty mirage tied to the mirror root prototype. 93 */ 94 protected NATMirage(OBJMirrorRoot mirror) { 95 super(); 96 mirror_ = mirror; 97 } 98 99 public NATMirage(ATObject dynamicParent, ATObject lexParent, boolean parentType, ATStripe[] stripes) { 100 super(dynamicParent, lexParent, parentType, stripes); 101 mirror_ = NATNil._INSTANCE_; // set to nil while not initialized 102 } 103 104 /** 105 * Private setter to be used in OBJMirrorRoot.init to break the chicken-and-egg cycle when 106 * having to create both a mirror and its mirage simultaneously. The sequence is as follows: 107 * 1) a new empty 'uninitialized' mirage is created, with mirror as nil 108 * 2) a mirror is instantiated, leading to the invocation of its init method 109 * 3) the initialization of a new OBJMirrorRoot assigns the uninitialized mirage to its 'base' field 110 * 4) the mirror field of the uninitialized mirage is set to the newly created mirror, using this method. 111 */ 112 private void initializeWithMirror(ATObject realMirror) { 113 mirror_ = realMirror; 114 } 115 116 /** 117 * Constructs a new ambienttalk mirage as a clone of an existing one. This results in a new 118 * uninitialized mirage (i.e. a mirage whose mirror points to nil). The code that clones the 119 * mirage must ensure that the mirror is correctly bound to a new instance of the cloned mirage's mirror. 120 121 * 122 * 123 */ 124 protected NATMirage(FieldMap map, 125 Vector state, 126 LinkedList customFields, 127 MethodDictionary methodDict, 128 ATObject dynamicParent, 129 ATObject lexicalParent, 130 byte flags, 131 ATStripe[] stripes) throws InterpreterException { 132 super(map, state, customFields, methodDict, dynamicParent, lexicalParent, flags, stripes); 133 mirror_ = NATNil._INSTANCE_; 134 } 135 136 public NATMirage asMirage() throws XTypeMismatch { 137 return this; 138 } 139 140 // Called by the default NATObject Cloning algorithm 141 protected NATObject createClone(FieldMap map, 142 Vector state, 143 LinkedList customFields, 144 MethodDictionary methodDict, 145 ATObject dynamicParent, 146 ATObject lexicalParent, 147 byte flags, ATStripe[] stripes) throws InterpreterException { 148 NATMirage clonedMirage = new NATMirage(map, 149 state, 150 customFields, 151 methodDict, 152 dynamicParent, 153 lexicalParent, 154 flags, 155 stripes); 156 // clonedMirage.mirror := myMirror.new(clonedMirage) 157 clonedMirage.mirror_ = mirror_.meta_invoke(mirror_, NATObject._NEW_NAME_, NATTable.of(clonedMirage)); 158 return clonedMirage; 159 } 160 161 /** 162 * Access to the mirage's mirror, to enable a mirage to be 'upped' to a mirror value. 163 */ 164 protected ATObject getMirror() { 165 return mirror_; 166 } 167 168 // MAGIC METHODS 169 // Cut-off for infinite meta-regress 170 171 public ATNil magic_addMethod(ATMethod method) throws InterpreterException { 172 return super.meta_addMethod(method); 173 } 174 175 public ATNil magic_assignField(ATObject receiver, ATSymbol selector, ATObject value) throws InterpreterException { 176 return super.meta_assignField(receiver, selector, value); 177 } 178 179 public ATObject magic_clone() throws InterpreterException { 180 return super.meta_clone(); 181 } 182 183 /* 184 if(cloneMirror.meta_isStripedWith(NativeStripes._MIRROR_).asNativeBoolean().javaValue) { 185 NATMirage clone = (NATMirage)super.meta_clone(); 186 clone.mirror_ = cloneMirror; 187 return clone; 188 } else { 189 throw new XIllegalArgument("Stratification violation : attempted to create a mirage from an object which is not striped to be a valid mirror."); 190 } 191 }*/ 192 193 public ATNil magic_defineField(ATSymbol name, ATObject value) throws InterpreterException { 194 return super.meta_defineField(name, value); 195 } 196 197 public ATMethod magic_grabMethod(ATSymbol selector) throws InterpreterException { 198 return super.meta_grabMethod(selector); 199 } 200 201 public ATObject magic_invoke(ATObject receiver, ATSymbol selector, ATTable arguments) throws InterpreterException { 202 return super.meta_invoke(receiver, selector, arguments); 203 } 204 205 public ATTable magic_listMethods() throws InterpreterException { 206 return super.meta_listMethods(); 207 } 208 209 public ATObject magic_lookup(ATSymbol selector) throws InterpreterException { 210 return super.meta_lookup(selector); 211 } 212 213 public ATObject magic_newInstance(ATTable initargs) throws InterpreterException { 214 return super.meta_newInstance(initargs); 215 } 216 217 public NATText magic_print() throws InterpreterException { 218 return super.meta_print(); 219 } 220 221 public ATObject magic_receive(ATAsyncMessage message) throws InterpreterException { 222 return super.meta_receive(message); 223 } 224 225 public ATBoolean magic_respondsTo(ATSymbol selector) throws InterpreterException { 226 return super.meta_respondsTo(selector); 227 } 228 229 public ATObject magic_select(ATObject receiver, ATSymbol selector) throws InterpreterException { 230 return super.meta_select(receiver, selector); 231 } 232 233 public ATNil magic_addField(ATField field) throws InterpreterException { 234 return super.meta_addField(field); 235 } 236 237 238 public ATNil magic_assignVariable(ATSymbol name, ATObject value) throws InterpreterException { 239 return super.meta_assignVariable(name, value); 240 } 241 242 243 public ATObject magic_doesNotUnderstand(ATSymbol selector) throws InterpreterException { 244 return super.meta_doesNotUnderstand(selector); 245 } 246 247 248 public ATField magic_grabField(ATSymbol selector) throws InterpreterException { 249 return super.meta_grabField(selector); 250 } 251 252 253 public ATTable magic_listFields() throws InterpreterException { 254 return super.meta_listFields(); 255 } 256 257 258 public ATObject magic_send(ATAsyncMessage message) throws InterpreterException { 259 return super.meta_send(message); 260 } 261 262 263 public ATObject magic_eval(ATContext ctx) throws InterpreterException { 264 return super.meta_eval(ctx); 265 } 266 267 268 public ATObject magic_quote(ATContext ctx) throws InterpreterException { 269 return super.meta_quote(ctx); 270 } 271 272 public ATBoolean magic_isExtensionOfParent() throws InterpreterException { 273 return super.meta_isExtensionOfParent(); 274 } 275 276 public ATObject magic_getLexicalParent() throws InterpreterException { 277 return super.meta_getLexicalParent(); 278 } 279 280 public ATObject magic_pass() throws InterpreterException { 281 return super.meta_pass(); 282 } 283 284 public ATObject magic_resolve() throws InterpreterException { 285 return super.meta_resolve(); 286 } 287 288 public ATBoolean magic_isStripedWith(ATStripe stripe) throws InterpreterException { 289 return super.meta_isStripedWith(stripe); 290 } 291 292 public ATTable magic_getStripes() throws InterpreterException { 293 return super.meta_getStripes(); 294 } 295 296 public ATBoolean magic_isCloneOf(ATObject original) throws InterpreterException { 297 return super.meta_isCloneOf(original); 298 } 299 300 public ATBoolean magic_isRelatedTo(ATObject object) throws InterpreterException { 301 return super.meta_isRelatedTo(object); 302 } 303 304 /* ======================================================================== 305 * Each meta_x method defined in ATObject is implemented in a mirage as a 306 * forwarding method that asks its mirror to perform the operation on itself 307 * instead. 308 * ======================================================================== */ 309 310 public ATNil meta_addMethod(ATMethod method) throws InterpreterException { 311 mirror_.meta_invoke( 312 mirror_, 313 AGSymbol.jAlloc("addMethod"), 314 NATTable.atValue(new ATObject[] { method }) 315 ); 316 317 return NATNil._INSTANCE_; 318 } 319 320 public ATNil meta_assignField(ATObject receiver, ATSymbol selector, ATObject value) throws InterpreterException { 321 mirror_.meta_invoke( 322 mirror_, 323 AGSymbol.jAlloc("assignField"), 324 NATTable.atValue(new ATObject[] { receiver, selector, value }) 325 ); 326 327 return NATNil._INSTANCE_; 328 } 329 330 public ATObject meta_clone() throws InterpreterException { 331 return mirror_.meta_invoke( 332 mirror_, 333 AGSymbol.jAlloc("clone"), 334 NATTable.EMPTY); 335 } 336 337 public ATNil meta_defineField(ATSymbol name, ATObject value) throws InterpreterException { 338 mirror_.meta_invoke( 339 mirror_, 340 AGSymbol.jAlloc("defineField"), 341 NATTable.atValue(new ATObject[] { name, value })); 342 return NATNil._INSTANCE_; 343 } 344 345 public ATMethod meta_grabMethod(ATSymbol selector) throws InterpreterException { 346 return mirror_.meta_invoke( 347 mirror_, 348 AGSymbol.jAlloc("grabMethod"), 349 NATTable.atValue(new ATObject[] { selector }) 350 ).asMethod(); 351 } 352 353 public ATObject meta_invoke(ATObject receiver, ATSymbol selector, ATTable arguments) throws InterpreterException { 354 return mirror_.meta_invoke( 355 mirror_, 356 AGSymbol.jAlloc("invoke"), 357 NATTable.atValue(new ATObject[] { receiver, selector, arguments })); 358 } 359 360 public ATTable meta_listMethods() throws InterpreterException { 361 return mirror_.meta_invoke( 362 mirror_, 363 AGSymbol.jAlloc("listMethods"), 364 NATTable.EMPTY 365 ).asTable(); 366 } 367 368 public ATObject meta_lookup(ATSymbol selector) throws InterpreterException { 369 return mirror_.meta_invoke( 370 mirror_, 371 AGSymbol.jAlloc("lookup"), 372 NATTable.atValue(new ATObject[] { selector })); 373 } 374 375 public ATObject meta_newInstance(ATTable initargs) throws InterpreterException { 376 return mirror_.meta_invoke( 377 mirror_, 378 AGSymbol.jAlloc("newInstance"), 379 NATTable.atValue(new ATObject[] { initargs })); 380 } 381 382 public NATText meta_print() throws InterpreterException { 383 return mirror_.meta_invoke( 384 mirror_, 385 AGSymbol.jAlloc("print"), 386 NATTable.EMPTY).asNativeText(); 387 } 388 389 public ATObject meta_receive(ATAsyncMessage message) throws InterpreterException { 390 return mirror_.meta_invoke( 391 mirror_, 392 AGSymbol.jAlloc("receive"), 393 NATTable.atValue(new ATObject[] { message })); 394 } 395 396 public ATBoolean meta_respondsTo(ATSymbol selector) throws InterpreterException { 397 return mirror_.meta_invoke( 398 mirror_, 399 AGSymbol.jAlloc("respondsTo"), 400 NATTable.atValue(new ATObject[] { selector }) 401 ).asBoolean(); 402 } 403 404 public ATObject meta_select(ATObject receiver, ATSymbol selector) throws InterpreterException { 405 return mirror_.meta_invoke( 406 mirror_, 407 AGSymbol.jAlloc("select"), 408 NATTable.atValue(new ATObject[] { receiver, selector })); 409 } 410 411 public ATNil meta_addField(ATField field) throws InterpreterException { 412 mirror_.meta_invoke( 413 mirror_, 414 AGSymbol.jAlloc("addField"), 415 NATTable.atValue(new ATObject[] { field })); 416 return NATNil._INSTANCE_; 417 } 418 419 420 public ATNil meta_assignVariable(ATSymbol name, ATObject value) throws InterpreterException { 421 mirror_.meta_invoke( 422 mirror_, 423 AGSymbol.jAlloc("assignVariable"), 424 NATTable.atValue(new ATObject[] { name, value })); 425 return NATNil._INSTANCE_; 426 } 427 428 429 public ATObject meta_doesNotUnderstand(ATSymbol selector) throws InterpreterException { 430 return mirror_.meta_invoke( 431 mirror_, 432 AGSymbol.jAlloc("doesNotUnderstand"), 433 NATTable.atValue(new ATObject[] { selector })); 434 } 435 436 437 public ATField meta_grabField(ATSymbol selector) throws InterpreterException { 438 return mirror_.meta_invoke( 439 mirror_, 440 AGSymbol.jAlloc("grabField"), 441 NATTable.atValue(new ATObject[] { selector })).asField(); 442 } 443 444 445 public ATTable meta_listFields() throws InterpreterException { 446 return mirror_.meta_invoke( 447 mirror_, 448 AGSymbol.jAlloc("listFields"), 449 NATTable.EMPTY).asTable(); 450 } 451 452 453 public ATObject meta_send(ATAsyncMessage message) throws InterpreterException { 454 mirror_.meta_invoke( 455 mirror_, 456 AGSymbol.jAlloc("send"), 457 NATTable.atValue(new ATObject[] { message })); 458 return NATNil._INSTANCE_; 459 } 460 461 462 public ATObject meta_eval(ATContext ctx) throws InterpreterException { 463 return mirror_.meta_invoke( 464 mirror_, 465 AGSymbol.jAlloc("eval"), 466 NATTable.atValue(new ATObject[] { ctx })); 467 } 468 469 470 public ATObject meta_quote(ATContext ctx) throws InterpreterException { 471 return mirror_.meta_invoke( 472 mirror_, 473 AGSymbol.jAlloc("quote"), 474 NATTable.atValue(new ATObject[] { ctx })); 475 } 476 477 public ATBoolean meta_isExtensionOfParent() throws InterpreterException { 478 return mirror_.meta_select( 479 mirror_, 480 AGSymbol.jAlloc("isExtensionOfParent")).asBoolean(); 481 } 482 483 public ATObject meta_getLexicalParent() throws InterpreterException { 484 return mirror_.meta_select( 485 mirror_, 486 AGSymbol.jAlloc("lexicalParent")); 487 } 488 489 public ATObject meta_pass() throws InterpreterException { 490 return mirror_.meta_invoke( 491 mirror_, AGSymbol.jAlloc("pass"), NATTable.EMPTY); 492 } 493 494 public ATObject meta_resolve() throws InterpreterException { 495 return mirror_.meta_invoke( 496 mirror_, AGSymbol.jAlloc("resolve"), NATTable.EMPTY); 497 } 498 499 public ATBoolean meta_isStripedWith(ATStripe stripe) throws InterpreterException { 500 return mirror_.meta_invoke( 501 mirror_, AGSymbol.jAlloc("isStripedWith"), NATTable.of(stripe)).asBoolean(); 502 } 503 504 public ATTable meta_getStripes() throws InterpreterException { 505 return mirror_.meta_select( 506 mirror_, 507 AGSymbol.jAlloc("stripes")).asTable(); 508 } 509 510 public ATBoolean meta_isCloneOf(ATObject original) throws InterpreterException { 511 return mirror_.meta_invoke( 512 mirror_, 513 AGSymbol.jAlloc("isCloneOf"), 514 NATTable.atValue(new ATObject[] { original })).asBoolean(); 515 } 516 517 public ATBoolean meta_isRelatedTo(ATObject object) throws InterpreterException { 518 return mirror_.meta_invoke( 519 mirror_, 520 AGSymbol.jAlloc("isRelatedTo"), 521 NATTable.atValue(new ATObject[] { object })).asBoolean(); 522 } 523 524}