edu.vub.at.objects.natives
Class NATCallframe

java.lang.Object
  extended byedu.vub.at.objects.natives.NATNil
      extended byedu.vub.at.objects.natives.NATByRef
          extended byedu.vub.at.objects.natives.NATCallframe
All Implemented Interfaces:
ATAbstractGrammar, ATConversions, ATExpression, ATNil, ATObject, ATStatement, java.io.Serializable
Direct Known Subclasses:
NATObject

public class NATCallframe
extends NATByRef
implements ATObject

NATCallframe is a native implementation of a callframe. A callframe differs from an ordinary object in the following regards: - it has no dynamic parent - it treats method definition as the addition of a closure to its variables. - it cannot be extended nor cloned Callframes can be regarded as 'field-only' objects. Fields are implemented as follows: - native fields are implemented efficiently using a 'map': the map datastructure maps selectors to indices into a state vector, such that field names can be shared efficiently across clones. - custom fields are collected in a linked list. Their lookup and assignment is slower, and when an object is cloned, the custom field objects are re-instantiated. The new clone is passed as the sole argument to 'new'.

Author:
tvcutsem, smostinc
See Also:
Serialized Form

Field Summary
protected  java.util.LinkedList customFields_
           
protected  ATObject lexicalParent_
          The lexical parent 'scope' of this call frame/object.
protected  java.util.Vector stateVector_
           
protected  FieldMap variableMap_
           
 
Fields inherited from class edu.vub.at.objects.natives.NATNil
_INSTANCE_
 
Constructor Summary
  NATCallframe(ATObject lexicalParent)
           
protected NATCallframe(FieldMap varMap, java.util.Vector stateVector, ATObject lexicalParent, java.util.LinkedList customFields)
          Used internally for cloning a callframe/object.
 
Method Summary
 boolean base_isCallFrame()
           
protected  ATField getLocalCustomField(ATSymbol selector)
           
protected  ATObject getLocalField(ATSymbol selector)
          Reads out the value of either a native or a custom field.
protected  boolean hasLocalCustomField(ATSymbol selector)
           
protected  boolean hasLocalField(ATSymbol selector)
           
protected  boolean hasLocalNativeField(ATSymbol selector)
           
 ATNil meta_addField(ATField field)
          Adds a field slot to an object at runtime.
 ATNil meta_addMethod(ATMethod method)
          Adds a method slot to an object at runtime.
 ATNil meta_assignField(ATObject receiver, ATSymbol name, ATObject value)
          Assigning a call frame's field externally is possible and is treated as if it were a variable assignment.
 ATNil meta_assignVariable(ATSymbol name, ATObject value)
          A field can be assigned in either a call frame or an object.
 ATObject meta_clone()
          Clone the receiver object.
 ATNil meta_defineField(ATSymbol name, ATObject value)
          A field can be added to either a call frame or an object.
 ATObject meta_doesNotUnderstand(ATSymbol selector)
          By default, when a selection is not understood by an AmbientTalk object or call frame, an error is raised.
 ATObject meta_extend(ATClosure code)
          Create an is-a extension of the receiver object.
 ATObject meta_getDynamicParent()
          Objects have a classical dynamic parent chain created using extension primitives.
 ATObject meta_getLexicalParent()
          Objects also have a lexical parent which is the scope in which their definitions are nested.
 ATField meta_grabField(ATSymbol selector)
          Queries an object for one of its field slots.
 ATMethod meta_grabMethod(ATSymbol selector)
          Queries an object for one of its method slots.
 ATObject meta_invoke(ATObject receiver, ATSymbol selector, ATTable arguments)
          Normally, call frames are not used in receiverful method invocation expressions.
 ATBoolean meta_isCloneOf(ATObject original)
          Detects whether this object an the passed parameter are the result of cloning from a common ancestor (possibly either one of the objects itself).
 ATBoolean meta_isRelatedTo(ATObject object)
          Detects whether both objects have a common origin, in other words whether they are related through a combination of the cloning and extension operators.
 ATTable meta_listFields()
          Queries an object for a list of all of its field slots.
 ATTable meta_listMethods()
          Queries an object for a list of all of its method slots.
 ATObject meta_lookup(ATSymbol selector)
          This method is used to evaluate code of the form selector within the scope of this call frame.
 ATObject meta_newInstance(ATTable initargs)
          Create a new instance of the receiver object.
 NATText meta_print()
          Prints out the object in a human-readable way.
 ATBoolean meta_respondsTo(ATSymbol selector)
          respondsTo is a mechanism to ask any object o whether it would respond to the selection o.selector.
 ATObject meta_select(ATObject receiver, ATSymbol selector)
          This method is used in the evaluation of the code o.m.
 ATObject meta_share(ATClosure code)
          Create a shares-a extension of the receiver object.
protected  boolean setLocalField(ATSymbol selector, ATObject value)
          Set a given field if it exists.
 
Methods inherited from class edu.vub.at.objects.natives.NATByRef
meta_pass, meta_resolve
 
Methods inherited from class edu.vub.at.objects.natives.NATNil
asAmbientTalkObject, asJavaClassUnderSymbiosis, asJavaObjectUnderSymbiosis, asNativeBoolean, asNativeException, asNativeFarReference, asNativeFraction, asNativeNumber, asNativeNumeric, asNativeTable, asNativeText, base__opeql__opeql_, base_asActorMirror, base_asAsyncMessage, base_asBegin, base_asBoolean, base_asClosure, base_asDefinition, base_asExpression, base_asFarReference, base_asField, base_asHandler, base_asMessage, base_asMessageCreation, base_asMethod, base_asMirror, base_asNumber, base_asSplice, base_asStatement, base_asStripe, base_asSymbol, base_asTable, base_asUnquoteSplice, base_asVariableAssignment, base_init, base_isBoolean, base_isClosure, base_isFarReference, base_isMessageCreation, base_isMethod, base_isMirror, base_isSplice, base_isStripe, base_isSymbol, base_isTable, base_isUnquoteSplice, base_isVariableAssignment, base_new, createChild, equals, isAmbientTalkObject, isJavaObjectUnderSymbiosis, isNativeBoolean, isNativeField, isNativeText, meta_eval, meta_getStripes, meta_isStripedWith, meta_quote, meta_receive, meta_send, readResolve, toString, writeReplace
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface edu.vub.at.objects.ATObject
base__opeql__opeql_, base_init, base_new, meta_eval, meta_getStripes, meta_isStripedWith, meta_pass, meta_quote, meta_receive, meta_resolve, meta_send
 
Methods inherited from interface edu.vub.at.objects.coercion.ATConversions
asAmbientTalkObject, asJavaClassUnderSymbiosis, asJavaObjectUnderSymbiosis, asNativeBoolean, asNativeException, asNativeFarReference, asNativeFraction, asNativeNumber, asNativeNumeric, asNativeTable, asNativeText, base_asActorMirror, base_asAsyncMessage, base_asBegin, base_asBoolean, base_asClosure, base_asDefinition, base_asExpression, base_asFarReference, base_asField, base_asHandler, base_asMessage, base_asMessageCreation, base_asMethod, base_asMirror, base_asNumber, base_asSplice, base_asStatement, base_asStripe, base_asSymbol, base_asTable, base_asUnquoteSplice, base_asVariableAssignment, base_isBoolean, base_isClosure, base_isFarReference, base_isMessageCreation, base_isMethod, base_isMirror, base_isSplice, base_isStripe, base_isSymbol, base_isTable, base_isUnquoteSplice, base_isVariableAssignment, isAmbientTalkObject, isJavaObjectUnderSymbiosis, isNativeBoolean, isNativeField, isNativeText
 

Field Detail

variableMap_

protected FieldMap variableMap_

stateVector_

protected final java.util.Vector stateVector_

lexicalParent_

protected transient ATObject lexicalParent_
The lexical parent 'scope' of this call frame/object. A lexical scope should never travel along with an object when it is serialized, hence it is declared transient. Serializable isolate objects will have to reset this field upon deserialization.


customFields_

protected java.util.LinkedList customFields_
Constructor Detail

NATCallframe

public NATCallframe(ATObject lexicalParent)

NATCallframe

protected NATCallframe(FieldMap varMap,
                       java.util.Vector stateVector,
                       ATObject lexicalParent,
                       java.util.LinkedList customFields)
Used internally for cloning a callframe/object.

Method Detail

meta_invoke

public ATObject meta_invoke(ATObject receiver,
                            ATSymbol selector,
                            ATTable arguments)
                     throws InterpreterException
Normally, call frames are not used in receiverful method invocation expressions. That is, normally, the content of call frames is accessed via the meta_lookup operation. A meta_invoke operation on call frames is much more ad hoc than on real objects. A call frame responds to an invocation by looking up the selector in its own fields (without delegating!) and by applying the closure bound to that field. The 'receiver' argument should always equal 'this' because call frames do not delegate!

Specified by:
meta_invoke in interface ATObject
Overrides:
meta_invoke in class NATNil
Throws:
InterpreterException

meta_respondsTo

public ATBoolean meta_respondsTo(ATSymbol selector)
                          throws InterpreterException
respondsTo is a mechanism to ask any object o whether it would respond to the selection o.selector. A call frame implements respondsTo by checking whether it contains a public field corresponding to the selector. A call frame does not delegate to other objects to check whether it can respond to a certain selector.

Specified by:
meta_respondsTo in interface ATObject
Overrides:
meta_respondsTo in class NATNil
Throws:
InterpreterException

meta_doesNotUnderstand

public ATObject meta_doesNotUnderstand(ATSymbol selector)
                                throws InterpreterException
By default, when a selection is not understood by an AmbientTalk object or call frame, an error is raised. Warning: this method overrides its parent method which has the exact same implementation. This is done for purposes of clarity, by making NATCallframe implement all ATObject methods directly, even if NATNil already provides a suitable implementation for these.

Specified by:
meta_doesNotUnderstand in interface ATObject
Overrides:
meta_doesNotUnderstand in class NATNil
Throws:
InterpreterException

meta_select

public ATObject meta_select(ATObject receiver,
                            ATSymbol selector)
                     throws InterpreterException
This method is used in the evaluation of the code o.m. When o is a call frame, the call frame is searched for a field 'm'. If it is not found, a call frame does not delegate to any dynamic parent, and yields an error.

Specified by:
meta_select in interface ATObject
Overrides:
meta_select in class NATNil
Throws:
InterpreterException

meta_lookup

public ATObject meta_lookup(ATSymbol selector)
                     throws InterpreterException
This method is used to evaluate code of the form selector within the scope of this call frame. A call frame resolves such a lookup request by checking whether a field corresponding to the selector exists locally. If it does, the result is returned. If it does not, the search continues recursively in the call frame's lexical parent.

Specified by:
meta_lookup in interface ATObject
Overrides:
meta_lookup in class NATNil
Throws:
InterpreterException

meta_defineField

public ATNil meta_defineField(ATSymbol name,
                              ATObject value)
                       throws InterpreterException
A field can be added to either a call frame or an object. In both cases, it is checked whether the field does not already exist. If it does not, a new field is created and its value set to the given initial value.

Specified by:
meta_defineField in interface ATObject
Overrides:
meta_defineField in class NATNil
Throws:
InterpreterException

meta_assignVariable

public ATNil meta_assignVariable(ATSymbol name,
                                 ATObject value)
                          throws InterpreterException
A field can be assigned in either a call frame or an object. In both cases, if the field exists locally, it is set to the new value. If it does not exist locally, the assignment is performed on the lexical parent.

Specified by:
meta_assignVariable in interface ATObject
Overrides:
meta_assignVariable in class NATNil
Throws:
InterpreterException

meta_assignField

public ATNil meta_assignField(ATObject receiver,
                              ATSymbol name,
                              ATObject value)
                       throws InterpreterException
Assigning a call frame's field externally is possible and is treated as if it were a variable assignment. Hence, if o is a call frame, then o.m := x follows the same evaluation semantics as those of m := x when performed in the scope of o.

Specified by:
meta_assignField in interface ATObject
Overrides:
meta_assignField in class NATNil
Throws:
InterpreterException

meta_clone

public ATObject meta_clone()
                    throws InterpreterException
Description copied from interface: ATObject
Clone the receiver object. This cloning closely corresponds to the allocation phase in class-based OO languages. In class-based languages, instance creation is based on the equation = () (i.e. first allocate a new instance, then initialize it). In our object-based model, allocation is replaced by cloning. When an object is asked to clone itself, it will also clone its dynamic parent if it extends this parent in an 'is-a' relationship. This is similar to the observation that, in class-based languages, allocating a new object of a subclass entails allocating space for the state of the superclass. Triggers the objectCloned event on this object's beholders (mirror observers). Initializing the clone is the responsibility of the method named .

Specified by:
meta_clone in interface ATObject
Overrides:
meta_clone in class NATNil
Throws:
InterpreterException

meta_newInstance

public ATObject meta_newInstance(ATTable initargs)
                          throws InterpreterException
Description copied from interface: ATObject
Create a new instance of the receiver object. AmbientTalk mimics the initialization protocol of Class-based languages like Smalltalk. In a typical CBL, object initialization equals class allocation + new instance initialization. In AmbientTalk, class allocation is replaced by cloning via the meta_clone operation. Object initialization itself differs from cloning in that it additionally initializes the clone. For standard AmbientTalk objects, this happens by invoking a method named 'init' on the newly created instance.

Specified by:
meta_newInstance in interface ATObject
Overrides:
meta_newInstance in class NATNil
Throws:
InterpreterException

meta_extend

public ATObject meta_extend(ATClosure code)
                     throws InterpreterException
Description copied from interface: ATObject
Create an is-a extension of the receiver object. The base-level code is represented at the meta-level by Triggers the objectExtended event on this object's beholders (mirror observers).

Specified by:
meta_extend in interface ATObject
Overrides:
meta_extend in class NATNil
Throws:
InterpreterException

meta_share

public ATObject meta_share(ATClosure code)
                    throws InterpreterException
Description copied from interface: ATObject
Create a shares-a extension of the receiver object. The base-level code obj.share { code } is represented at the meta-level by mirror(obj).meta_share(code) Triggers the objectShared event on this object's beholders (mirror observers).

Specified by:
meta_share in interface ATObject
Overrides:
meta_share in class NATNil
Throws:
InterpreterException

meta_addField

public ATNil meta_addField(ATField field)
                    throws InterpreterException
Description copied from interface: ATObject
Adds a field slot to an object at runtime. Triggers the fieldAdded event on this object's beholders (mirror observers) if the field is added successfully.

Specified by:
meta_addField in interface ATObject
Overrides:
meta_addField in class NATNil
Throws:
InterpreterException

meta_addMethod

public ATNil meta_addMethod(ATMethod method)
                     throws InterpreterException
Description copied from interface: ATObject
Adds a method slot to an object at runtime. Triggers the methodAdded event on this object's beholders (mirror observers) if the method is added successfully.

Specified by:
meta_addMethod in interface ATObject
Overrides:
meta_addMethod in class NATNil
Throws:
InterpreterException

meta_grabField

public ATField meta_grabField(ATSymbol selector)
                       throws InterpreterException
Description copied from interface: ATObject
Queries an object for one of its field slots. Triggers the fieldAccessed event on this object's beholders (mirror observers).

Specified by:
meta_grabField in interface ATObject
Overrides:
meta_grabField in class NATNil
Throws:
InterpreterException

meta_grabMethod

public ATMethod meta_grabMethod(ATSymbol selector)
                         throws InterpreterException
Description copied from interface: ATObject
Queries an object for one of its method slots. Triggers the methodAccessed event on this object's beholders (mirror observers).

Specified by:
meta_grabMethod in interface ATObject
Overrides:
meta_grabMethod in class NATNil
Throws:
InterpreterException

meta_listFields

public ATTable meta_listFields()
                        throws InterpreterException
Description copied from interface: ATObject
Queries an object for a list of all of its field slots. TODO(beholders) should this method trigger beholders? if so, using a single 'fieldsQueried' event or by invoking 'fieldAccessed' for each field in the list returned?

Specified by:
meta_listFields in interface ATObject
Overrides:
meta_listFields in class NATNil
Throws:
InterpreterException

meta_listMethods

public ATTable meta_listMethods()
                         throws InterpreterException
Description copied from interface: ATObject
Queries an object for a list of all of its method slots. TODO(beholders) should this method trigger beholders? if so, using a single 'methodsQueried' event or by invoking 'methodAccessed' for each field in the list returned?

Specified by:
meta_listMethods in interface ATObject
Overrides:
meta_listMethods in class NATNil
Throws:
InterpreterException

meta_print

public NATText meta_print()
                   throws InterpreterException
Description copied from interface: ATObject
Prints out the object in a human-readable way.

Specified by:
meta_print in interface ATObject
Overrides:
meta_print in class NATNil
Throws:
InterpreterException

meta_getDynamicParent

public ATObject meta_getDynamicParent()
                               throws InterpreterException
Description copied from interface: ATObject
Objects have a classical dynamic parent chain created using extension primitives. This getter method allows accessing the parent alongside this dynamic parent chain to be accessed as a field of the object's mirror.

Specified by:
meta_getDynamicParent in interface ATObject
Overrides:
meta_getDynamicParent in class NATNil
Throws:
InterpreterException

meta_getLexicalParent

public ATObject meta_getLexicalParent()
                               throws InterpreterException
Description copied from interface: ATObject
Objects also have a lexical parent which is the scope in which their definitions are nested. This scope is visible using receiverless messages. This getter method allows accessing the parent alongside the lexical nesting chain to be accessed as a field of the object's mirror.

Specified by:
meta_getLexicalParent in interface ATObject
Overrides:
meta_getLexicalParent in class NATNil
Throws:
InterpreterException

base_isCallFrame

public boolean base_isCallFrame()
Specified by:
base_isCallFrame in interface ATConversions
Overrides:
base_isCallFrame in class NATNil

meta_isCloneOf

public ATBoolean meta_isCloneOf(ATObject original)
                         throws InterpreterException
Description copied from interface: ATObject
Detects whether this object an the passed parameter are the result of cloning from a common ancestor (possibly either one of the objects itself).

Specified by:
meta_isCloneOf in interface ATObject
Overrides:
meta_isCloneOf in class NATNil
Throws:
InterpreterException

meta_isRelatedTo

public ATBoolean meta_isRelatedTo(ATObject object)
                           throws InterpreterException
Description copied from interface: ATObject
Detects whether both objects have a common origin, in other words whether they are related through a combination of the cloning and extension operators.

Specified by:
meta_isRelatedTo in interface ATObject
Overrides:
meta_isRelatedTo in class NATNil
Throws:
InterpreterException

hasLocalField

protected boolean hasLocalField(ATSymbol selector)
                         throws InterpreterException
Throws:
InterpreterException

hasLocalNativeField

protected boolean hasLocalNativeField(ATSymbol selector)

hasLocalCustomField

protected boolean hasLocalCustomField(ATSymbol selector)
                               throws InterpreterException
Throws:
InterpreterException

getLocalField

protected ATObject getLocalField(ATSymbol selector)
                          throws InterpreterException
Reads out the value of either a native or a custom field.

Throws:
XSelectorNotFound - if no native or custom field with the given name exists locally.
InterpreterException

getLocalCustomField

protected ATField getLocalCustomField(ATSymbol selector)
                               throws InterpreterException
Returns:
a custom field matching the given selector or null if such a field does not exist
Throws:
InterpreterException

setLocalField

protected boolean setLocalField(ATSymbol selector,
                                ATObject value)
                         throws InterpreterException
Set a given field if it exists.

Returns:
whether the field existed (and the assignment has been performed)
Throws:
InterpreterException