001: // Copyright (c) 2000, 2001 Per M.A. Bothner.
002: // This is free software; for terms and warranty disclaimer see ./COPYING.
003:
004: package gnu.expr;
005:
006: import gnu.bytecode.*;
007: import gnu.mapping.*;
008:
009: /** The value in the result (as a sequence of values) is passed to a function.
010: */
011:
012: public class SeriesTarget extends Target {
013: /** Where to place each value. */
014: public Variable value;
015:
016: /** A function to call (using jsr/jsr_w). */
017: public Label function;
018:
019: /** Where to go when done. */
020: public Label done;
021:
022: public void compileFromStackSimple(Compilation comp, Type stackType) {
023: CodeAttr code = comp.getCode();
024: StackTarget.convert(comp, stackType, value.getType());
025: code.emitStore(value);
026: code.emitJsr(function);
027: }
028:
029: public void compileFromStack(Compilation comp, Type stackType) {
030: CodeAttr code = comp.getCode();
031:
032: if (isSingletonType(stackType)) {
033: compileFromStackSimple(comp, stackType);
034: return;
035: }
036:
037: /* emit the following:
038: int index = 0;
039: for (;;)
040: {
041: int next = Values.nextIndex(values, index);
042: if (next < 0)
043: goto done;
044: Values.nextValue(values, index);
045: compileFromStackSimple(comp, Type.pointerType);
046: index = value;
047: }
048: */
049: Variable indexVar = code.addLocal(Type.int_type);
050: Variable valuesVar = code.addLocal(Type.pointer_type);
051: Variable nextVar = code.addLocal(Type.int_type);
052: StackTarget.convert(comp, stackType, Type.pointer_type);
053: code.emitStore(valuesVar);
054: code.emitPushInt(0);
055: code.emitStore(indexVar);
056:
057: Label top = new Label(code);
058: top.define(code);
059: code.emitLoad(valuesVar);
060: code.emitLoad(indexVar);
061: code.emitInvokeStatic(Compilation.typeValues.getDeclaredMethod(
062: "nextIndex", 2));
063: code.emitDup(Type.int_type);
064: code.emitStore(nextVar);
065: code.emitGotoIfIntLtZero(done);
066: code.emitLoad(valuesVar);
067: code.emitLoad(indexVar);
068: code.emitInvokeStatic(Compilation.typeValues.getDeclaredMethod(
069: "nextValue", 2));
070: compileFromStackSimple(comp, Type.pointer_type);
071: code.emitLoad(nextVar);
072: code.emitStore(indexVar);
073: code.emitGoto(top);
074:
075: /*
076: if (stackType is singleton type)
077: compileFromStackSimple(comp, stackType);
078: else
079: {
080: code.emitDup(stackType);
081: emit[if TOP instanceof Values];
082: emit loop [Values, get, ...];
083: code.emitElse();
084: compileFromStackSimple(comp, stackType);
085: code.emitFi();
086: }
087: */
088: }
089:
090: public Type getType() {
091: return Type.pointer_type;
092: }
093:
094: public static boolean isSingletonType(Type type) {
095: if (type instanceof PrimType)
096: return !type.isVoid();
097: if (type instanceof ArrayType)
098: return true;
099: if (type instanceof ClassType) {
100: int cmp = type.compare(Compilation.typeValues);
101: if (cmp == -3)
102: return true;
103: }
104: return false;
105: }
106:
107: }
|