001: package gnu.expr;
002:
003: import gnu.bytecode.*;
004: import gnu.mapping.*;
005:
006: public class BindingInitializer extends Initializer {
007: Declaration decl;
008: Expression value;
009:
010: /** Create a BindingInitializer and link it into the correct
011: * intializer chain. */
012: public static void create(Declaration decl, Expression value,
013: Compilation comp) {
014: BindingInitializer init = new BindingInitializer(decl, value);
015: if (decl.field != null && decl.field.getStaticFlag()) {
016: init.next = comp.clinitChain;
017: comp.clinitChain = init;
018: } else {
019: init.next = comp.mainLambda.initChain; // FIXME why mainLambda?
020: comp.mainLambda.initChain = init;
021: }
022: }
023:
024: public BindingInitializer(Declaration decl, Expression value) {
025: this .decl = decl;
026: this .value = value;
027: this .field = decl.field;
028: }
029:
030: public void emit(Compilation comp) {
031: CodeAttr code = comp.getCode();
032:
033: if (value instanceof QuoteExp) {
034: Object val = ((QuoteExp) value).getValue();
035: if (val != null && !(val instanceof String)) {
036: Literal lit = comp.litTable.findLiteral(val);
037: if (lit.field == this .field)
038: return;
039: }
040: }
041:
042: int line = decl.getLineNumber();
043: if (line > 0)
044: code.putLineNumber(decl.getFileName(), line);
045:
046: if (field != null && !field.getStaticFlag())
047: code.emitPushThis();
048:
049: if (value == null) {
050: boolean func = comp.getLanguage()
051: .hasSeparateFunctionNamespace();
052: Object property = func && decl.isProcedureDecl() ? EnvironmentKey.FUNCTION
053: : null;
054:
055: Object name = decl.getSymbol();
056:
057: if (decl.isAlias()) {
058: comp.compileConstant(name, Target.pushObject);
059: code.emitInvokeStatic(makeLocationMethod(name));
060: } else {
061: ClassType t = ClassType
062: .make("gnu.mapping.ThreadLocation");
063: if (decl
064: .getFlag(Declaration.IS_UNKNOWN
065: | Declaration.IS_DYNAMIC
066: | Declaration.IS_FLUID)) {
067: if (name instanceof String)
068: name = Namespace.EmptyNamespace
069: .getSymbol((String) name);
070: comp.compileConstant(name, Target.pushObject);
071: if (property == null)
072: code.emitPushNull();
073: else
074: comp.compileConstant(property,
075: Target.pushObject);
076: code.emitInvokeStatic(t.getDeclaredMethod(
077: "getInstance", 2));
078: } else {
079: Type[] atypes = new Type[1];
080: if (name instanceof Symbol)
081: atypes[0] = Compilation.typeSymbol;
082: else
083: atypes[0] = Type.tostring_type;
084: comp.compileConstant(name, Target.pushObject);
085: code.emitInvokeStatic(t.getDeclaredMethod(
086: "makePrivate", atypes));
087: }
088: }
089: } else {
090: Type type = field == null ? decl.getType() : field
091: .getType();
092: value.compileWithPosition(comp, StackTarget
093: .getInstance(type));
094: }
095:
096: // Optimization of Declaration.compileStore, to avoid swap.
097: if (field == null) {
098: Variable var = decl.getVariable();
099: if (var == null)
100: var = decl.allocateVariable(code);
101: code.emitStore(var);
102: } else if (field.getStaticFlag())
103: code.emitPutStatic(field);
104: else
105: code.emitPutField(field);
106: }
107:
108: public static Method makeLocationMethod(Object name) {
109: Type[] atypes = new Type[1];
110: if (name instanceof Symbol)
111: atypes[0] = Compilation.typeSymbol;
112: else
113: atypes[0] = Type.string_type;
114: return Compilation.typeLocation.getDeclaredMethod("make",
115: atypes);
116: }
117: }
|