001: /*
002: * TclObject.java
003: *
004: * Copyright (c) 1997 Sun Microsystems, Inc.
005: *
006: * See the file "license.terms" for information on usage and
007: * redistribution of this file, and for a DISCLAIMER OF ALL
008: * WARRANTIES.
009: *
010: * RCS: @(#) $Id: TclObject.java,v 1.8 2006/06/24 00:30:42 mdejong Exp $
011: *
012: */
013:
014: package tcl.lang;
015:
016: import java.util.Hashtable;
017:
018: /**
019: * This class extends TclObjectBase to implement the basic notion of
020: * an object in Tcl.
021: */
022:
023: public final class TclObject extends TclObjectBase {
024:
025: static final boolean saveObjRecords = TclObjectBase.saveObjRecords;
026: static Hashtable objRecordMap = TclObjectBase.objRecordMap;
027:
028: /**
029: * Creates a TclObject with the given InternalRep. This method should be
030: * called only by an InternalRep implementation.
031: *
032: * @param rep the initial InternalRep for this object.
033: */
034: public TclObject(final InternalRep rep) {
035: super (rep);
036: }
037:
038: /**
039: * Creates a TclObject with the given InternalRep and stringRep.
040: * This constructor is used by the TclString class only. No other place
041: * should call this constructor.
042: *
043: * @param rep the initial InternalRep for this object.
044: * @param s the initial string rep for this object.
045: */
046: protected TclObject(final TclString rep, final String s) {
047: super (rep, s);
048: }
049:
050: /**
051: * Creates a TclObject with the given integer value.
052: * This constructor is used by the TclInteger class only. No other place
053: * should call this constructor.
054: *
055: * @param ivalue the integer value
056: */
057: protected TclObject(final int ivalue) {
058: super (ivalue);
059: }
060:
061: /**
062: * Tcl_IncrRefCount -> preserve
063: *
064: * Increments the refCount to indicate the caller's intent to
065: * preserve the value of this object. Each preserve() call must be matched
066: * by a corresponding release() call. This method is Jacl specific
067: * and is intended to be easily inlined in calling code.
068: *
069: * @exception TclRuntimeError if the object has already been deallocated.
070: */
071: public final void preserve() {
072: if (refCount < 0) {
073: throw DEALLOCATED;
074: }
075: refCount++;
076: }
077:
078: /**
079: * Tcl_DecrRefCount -> release
080: *
081: * Decrements the refCount to indicate that the caller is no longer
082: * interested in the value of this object. If the refCount reaches 0,
083: * the object will be deallocated. This method is Jacl specific
084: * an is intended to be easily inlined in calling code.
085: *
086: * @exception TclRuntimeError if the object has already been deallocated.
087: */
088: public final void release() {
089: if (--refCount <= 0) {
090: disposeObject();
091: }
092: }
093:
094: /**
095: * Return a String that describes TclObject and internal
096: * rep type allocations and conversions. The string is
097: * in lines separated by newlines. The saveObjRecords
098: * needs to be set to true and Jacl recompiled for
099: * this method to return a useful value.
100: */
101:
102: public static String getObjRecords() {
103: return TclObjectBase.getObjRecords();
104: }
105:
106: /**
107: * Modify a "recycled" int value so that it
108: * contains a new int value. This optimized
109: * logic is like TclInteger.set() except
110: * that it does not invoke invalidateStringRep().
111: * This method is only invoked from the Interp
112: * class when the TclObject is known to
113: * have a refCount of 1 or when the refCount
114: * is 2 but the interp result holds the
115: * other ref. An object with a refCount of
116: * 2 would normally raise an exception in
117: * invalidateStringRep, but this optimized
118: * case is worth it for this common case.
119: */
120:
121: final void setRecycledIntValue(int i) {
122: if (validate) {
123: if ((refCount != 1) && (refCount != 2)) {
124: throw new TclRuntimeError("Invalid refCount "
125: + refCount);
126: }
127: }
128:
129: if (internalRep != TclInteger.dummy) {
130: setInternalRep(TclInteger.dummy);
131: }
132: ivalue = i;
133: stringRep = null;
134: }
135:
136: /**
137: * Modify a "recycled" double value so that it
138: * contains a new double value. This optimized
139: * logic is like TclDouble.set() except
140: * that it does not invoke invalidateStringRep().
141: * This method is only invoked from the Interp
142: * class when the TclObject is known to
143: * have a refCount of 1 or when the refCount
144: * is 2 but the interp result holds the
145: * other ref. An object with a refCount of
146: * 2 would normally raise an exception in
147: * invalidateStringRep, but this optimized
148: * case is worth it for this common case.
149: */
150:
151: final void setRecycledDoubleValue(double d) {
152: if (validate) {
153: if ((refCount != 1) && (refCount != 2)) {
154: throw new TclRuntimeError("Invalid refCount "
155: + refCount);
156: }
157: }
158:
159: if (!isDoubleType()) {
160: TclDouble.setRecycledInternalRep(this );
161: }
162: ((TclDouble) internalRep).value = d;
163: stringRep = null;
164: }
165: }
|