001: /*=============================================================================
002: * Copyright Texas Instruments 2000-2004. All Rights Reserved.
003: *
004: * This program is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2 of the License, or (at your option) any later version.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: * $ProjectHeader: OSCRIPT 0.155 Fri, 20 Dec 2002 18:34:22 -0800 rclark $
019: */
020:
021: package oscript.data;
022:
023: import oscript.exceptions.*;
024:
025: /**
026: * The <code>ForkScope</code> is used to implement a fork in the scope
027: * chain. This is needed because when evaluating a superFxn, or a
028: * method defined in the superFxn, the scope chain should use the scope
029: * that the superFxn is defined in, rather than the scope of the
030: * derived function.
031: * <p>
032: * This is basically just a simple wrapper for the <code>obj</code>,
033: * with the exception that lookupInScope uses <code>env</code> as the
034: * previous instead. This means that any member created in this scope
035: * is actually created in the <code>obj</code> scope.
036: *
037: * @author Rob Clark (rob@ti.com)
038: */
039: public class ForkScope extends Scope {
040: private Scope obj;
041: private Scope env;
042:
043: // XXX for debugging, determine if this is a scope that is safe to hold
044: // a reference to after it is left
045: public boolean isSafe() {
046: if (!(obj.isSafe() && env.isSafe())) {
047: System.err.println(" -> " + this + " ("
048: + getClass().getName() + ", " + findDesc(this )
049: + ")");
050: return false;
051: }
052: return true;
053: }
054:
055: /*=======================================================================*/
056: /**
057: *
058: * @param obj the object
059: * @param env the environment
060: */
061: ForkScope(Scope obj, Scope env) {
062: this (simplify(obj), env, false);
063: }
064:
065: private ForkScope(Scope obj, Scope env, boolean bogus) {
066: super (obj);
067:
068: this .obj = obj;
069: this .env = env;
070: }
071:
072: // get rid of nested ForkScope, ie from multiple levels of extends...
073: private static Scope simplify(Scope obj) {
074: while (obj instanceof ForkScope)
075: obj = ((ForkScope) obj).obj;
076:
077: return obj;
078: }
079:
080: /*=======================================================================*/
081: /**
082: * Get the type of this object. The returned type doesn't have to take
083: * into account the possibility of a script type extending a built-in
084: * type, since that is handled by {@link #getType}.
085: *
086: * @return the object's type
087: */
088: protected Value getTypeImpl() {
089: return Type.HIDDEN_TYPE;
090: }
091:
092: /*=======================================================================*/
093: /**
094: * In case a scope has any resource allocated from a source which will
095: * no long be valid after a stack frame has returned (ie. resource
096: * allocated from stack), return a copy of the scope that is safe to
097: * keep after the stack frame returns.
098: */
099: public Scope getSafeCopy() {
100: obj = obj.getSafeCopy();
101: env = env.getSafeCopy();
102: return super .getSafeCopy();
103: }
104:
105: /*=======================================================================*/
106: /**
107: * Lookup the "super" within a scope. Within a function body, "super"
108: * is the overriden function (if there is one).
109: *
110: * @return the "this" ScriptObject within this scope
111: */
112: public Value getSuper() {
113: return obj.getSuper();
114: }
115:
116: /*=======================================================================*/
117: /**
118: * Create a member of this object with the specified value.
119: *
120: * @param id the id of the symbol that maps to the member
121: * @param attr the attributes of the object (see <code>Reference</code>.)
122: * @see Reference
123: */
124: public Value createMember(int id, int attr) {
125: return obj.createMember(id, attr);
126: }
127:
128: /*=======================================================================*/
129: /**
130: * "mixin" the specified variable into the current scope.
131: *
132: * @param val the value to mixin to this scope
133: */
134: public void mixin(Value val) {
135: obj.mixin(val);
136: }
137:
138: /*=======================================================================*/
139: /**
140: * Get a member of this object.
141: *
142: * @param id the id of the symbol that maps to the member
143: * @param exception whether an exception should be thrown if the
144: * member object is not resolved
145: * @return a reference to the member
146: * @throws PackagedScriptObjectException(NoSuchMethodException)
147: * @throws PackagedScriptObjectException(NoSuchMemberException)
148: */
149: public Value getMember(int id, boolean exception)
150: throws PackagedScriptObjectException {
151: return obj.getMember(id, exception);
152: }
153:
154: // only for use by wrapper class (oscript.classwrap.ClassWrapGen)
155: public Value __getInstanceMember(int id) {
156: return obj.__getInstanceMember(id);
157: }
158:
159: /*=======================================================================*/
160: /**
161: * Get a member from this scope. This is used to access local variables
162: * and object attributes from methods of the object. If the attribute
163: * isn't in this node in the scope chain, then the <code>previous</code>
164: * node in the scope chain is checked.
165: *
166: * @param id the id of the symbol that maps to the member
167: * @throws PackagedScriptObjectException(NoSuchMemberException)
168: */
169: public Value lookupInScope(int id)
170: throws PackagedScriptObjectException {
171: Value val = obj.getMemberImpl(id);
172:
173: if (val == null)
174: val = env.lookupInScope(id); // use env instead of obj.previous
175:
176: if (val == null)
177: throw noSuchMember(Symbol.getSymbol(id).castToString());
178:
179: return val;
180: }
181:
182: /*=======================================================================*/
183: /**
184: * Indicate that this scope is no longer needed
185: */
186: public void free() {
187: System.err.println("probably shouldn't get here... tell rob");
188: obj.free();
189: env.free();
190: }
191: }
192:
193: /*
194: * Local Variables:
195: * tab-width: 2
196: * indent-tabs-mode: nil
197: * mode: java
198: * c-indentation-style: java
199: * c-basic-offset: 2
200: * eval: (c-set-offset 'substatement-open '0)
201: * eval: (c-set-offset 'case-label '+)
202: * eval: (c-set-offset 'inclass '+)
203: * eval: (c-set-offset 'inline-open '0)
204: * End:
205: */
|