001: /***
002: * Values.java
003: *
004: * Description: SWF Action Code instruction opcode constants
005: */package org.openlaszlo.sc;
006:
007: import java.io.*;
008:
009: public class Values {
010: /***
011: * These do double duty as identifiers, and as the typecodes
012: * that are used by PUSH.
013: */
014: public static class PushTypes {
015: public static final byte String = 0;
016: public static final byte Float = 1;
017: public static final byte Null = 2;
018: public static final byte Undefined = 3;
019: public static final byte Register = 4;
020: public static final byte Boolean = 5;
021: public static final byte Integer = 7;
022: public static final byte Double = 6;
023: public static final byte CONSTANT_INDEX8 = 8;
024: public static final byte CONSTANT_INDEX16 = 9;
025: }
026:
027: // TODO: [2004-03-24 ptw] Generalize to any number of registers
028: public static Value r0 = Value.make("r:0", PushTypes.Register,
029: (byte) 0);
030: public static Value r1 = Value.make("r:1", PushTypes.Register,
031: (byte) 1);
032: public static Value r2 = Value.make("r:2", PushTypes.Register,
033: (byte) 2);
034: public static Value r3 = Value.make("r:3", PushTypes.Register,
035: (byte) 3);
036:
037: public static Value Register(int n) {
038: switch (n) {
039: case 0:
040: return r0;
041: case 1:
042: return r1;
043: case 2:
044: return r2;
045: case 3:
046: return r3;
047: default:
048: return Value.make("r:" + n, PushTypes.Register, (byte) n);
049: }
050: }
051:
052: public static boolean isRegister(Object v) {
053: return v instanceof Value
054: && ((Value) v).type == PushTypes.Register;
055: }
056:
057: public static boolean isInteger(Object v) {
058: return v instanceof Number
059: && ((Number) v).intValue() == ((Number) v)
060: .doubleValue();
061: }
062:
063: /***
064: * Runtime Types
065: */
066:
067: public static class Value implements Serializable {
068: public String name;
069: public byte type;
070:
071: public static Value make(String name, byte type) {
072: return new Value(name, type);
073: }
074:
075: public static Value make(String name, byte type, byte value) {
076: return new ParameterizedValue(name, type, value);
077: }
078:
079: private Value(String name, byte type) {
080: this .name = name.intern();
081: this .type = type;
082: }
083:
084: public String toString() {
085: return this .name;
086: }
087:
088: public Object readResolve() throws ObjectStreamException {
089: switch (this .type) {
090: case PushTypes.Undefined:
091: return Values.Undefined;
092: case PushTypes.Null:
093: return Values.Null;
094: default:
095: return this ;
096: }
097: }
098: }
099:
100: public static class ParameterizedValue extends Value {
101: public byte value;
102:
103: private ParameterizedValue(String name, byte type, byte value) {
104: super (name, type);
105: this .value = value;
106: }
107:
108: public Object readResolve() throws ObjectStreamException {
109: switch (this .type) {
110: case PushTypes.Boolean:
111: return this .value == 0 ? Values.False : Values.True;
112: case PushTypes.Register:
113: return Values.Register(this .value);
114: default:
115: return super .readResolve();
116: }
117: }
118: }
119:
120: public static Value True = Value.make("TRUE", PushTypes.Boolean,
121: (byte) 1);
122: public static Value False = Value.make("FALSE", PushTypes.Boolean,
123: (byte) 0);
124: public static Value Undefined = Value.make("UNDEF",
125: PushTypes.Undefined);
126: public static Value Null = Value.make("NULL", PushTypes.Null);
127:
128: // Integers are represented as instances of Long
129:
130: // Strings are represented as instances of String
131: }
|