Procedure p = new Procedure(cons);
p.setModifier(Mod2.FINAL);
p.setNameCi(cons.getCprocName(get0Ci));
p.setDescCi(cons.getCprocDesc(get0Ci));
int i0 = csn - 1;
Instruction s = new Instruction(cons, 250);
s.ins0(ALOAD0); // this
s.ins0(ILOAD1);
long sw = s.insSwitchTable( -i0, i0);
s.switchTableHere(sw, -1);
s.switchTableHere(sw, i0);
int sw0 = s.addr;
s.ins0(ACONSTNULL);
s.ins0(ARETURN);
int swObj = s.addr;
s.insU2(GETSTATIC, ossCi);
s.ins0(ILOAD1);
s.ins0(AALOAD);
s.ins0(ICONST0);
s.ins0(AALOAD); // oss[i][0]
s.ins0(ARETURN);
int swObj_ = s.addr;
s.insU2(GETSTATIC, ossCi);
s.ins0(ILOAD1);
s.ins0(INEG);
s.ins0(AALOAD);
s.ins0(ICONST0);
s.ins0(AALOAD); // oss[-i][0]
s.ins0(ARETURN);
int circle = s.addr;
s.insU2(NEW, cons.addClass(ClassCircularityError.class));
s.ins0(DUPI);
s.ins0(SWAP);
s.insU2(INVOKESPECIAL, cons.addProc(Class2.ctor(ClassCircularityError.class,
String.class)));
s.ins0(ATHROW);
int maxParamN = 0;
for (int i = 1; i < csn; i++) // always actual bind
{
Bind.Clazz c = cs[i];
maxParamN = Math.max(maxParamN, c.maxParamN);
if (c.cla == Container.class)
{
s.switchTableHere(sw, i0 + i);
s.switchTable(sw, i0 - i, sw0); // never happen
s.ins0(ARETURN);
}
else if (c.mode == null) // static object
{
s.switchTable(sw, i0 + i, oss[i][0] == null ? sw0 : swObj);
s.switchTable(sw, i0 - i, oss[i][0] == null ? sw0 : swObj_);
}
else if (c.t != null) // New and Single
{
s.switchTableHere(sw, i0 + i);
if (c.mode == Single.class)
{
s.ins0(DUP);
s.insU2(GETFIELD, fCis[i]);
s.ins0(DUP);
int j = s.insJump(IFNULL);
s.ins0(ARETURN);
s.jumpHere(j);
s.ins0(POP);
}
s.switchTableHere(sw, i0 - i);
s.insU2(NEW, cons.putClass(c.cla));
s.ins0(DUP);
int x = 1;
for (int cb = 0; cb < c.t.ps.length; cb++)
x = makeGet0_fp(i, s, c.t.ps[cb], oss[i], x);
s.insU2(INVOKESPECIAL, cons.putProc(c.t.t));
if (c.mode == Single.class)
{
s.ins0(ILOAD1);
int j = s.insJump(IFIL0);
if (c.t.ps.length > 0)
{ // never happen if ctor no parameter
s.ins0(ALOAD0);
s.insU2(GETFIELD, fCis[i]);
int jj = s.insJump(IFNULL);
s.insU2(LDCW, cons.addString(c.cla.getName()));
s.jump(s.insJump(GOTO), circle);
s.jumpHere(jj);
}
s.ins0(DUP);
s.ins0(ALOAD0);
s.ins0(SWAP); // o, this, o
s.insU2(PUTFIELD, fCis[i]); // single
s.jumpHere(j);
}
for (Bind.FM fm: c.fms)
if (fm.f != null)
{
s.ins0(DUP);
x = makeGet0_fp(i, s, fm, oss[i], x);
s.insU2(PUTFIELD, cons.addField(fm.f));
}
else
{
s.ins0(DUP);
for (Bind mp: fm.ps)
x = makeGet0_fp(i, s, mp, oss[i], x);
s.insU2(INVOKEVIRTUAL, cons.addProc(fm.m));
}
s.ins0(ARETURN);
}
else if (c.mode == Set.class)
{
s.switchTableHere(sw, i0 + i);
s.switchTableHere(sw, i0 - i);
s.insU2(GETFIELD, fCis[i]);
s.ins0(ARETURN);
}
else if (c.mode == Parent.class)
{
s.switchTableHere(sw, i0 - i);
s.ins0(DUP);
s.insU2(GETFIELD, fCis[i]);
s.ins0(DUP);
int j = s.insJump(IFNULL);
s.ins0(ARETURN);
s.jumpHere(j);
s.ins0(POP);
s.switchTableHere(sw, i0 + i);
int loop = s.addr; // n
s.insU2(GETFIELD, parentCi); // n
s.ins0(DUP);
s.insU2(LDCW, cCis[i]);
s.insU2(INVOKEVIRTUAL, indexCi); // n, j
s.ins0(DUP);
s.ins0(ISTORE2);
s.jump(s.insJump(IFIE0), loop);
s.ins0(ILOAD1);
j = s.insJump(IFIL0);
s.ins0(ILOAD2);
s.ins0(INEG); // -j
s.insU2(INVOKEVIRTUAL, get0Ci); // get0
s.ins0(ARETURN);
s.jumpHere(j);
s.ins0(ILOAD2); // j
s.insU2(INVOKEVIRTUAL, get0Ci); // get0
s.ins0(DUP);
s.ins0(ILOAD2);
j = s.insJump(IFIL0);
s.ins0(ALOAD0);
s.ins0(SWAP); // o, this, o
s.insU2(PUTFIELD, fCis[i]); // cache
s.ins0(ARETURN);
s.jumpHere(j);
s.ins0(ARETURN);
}
else
throw new AssertionError();
}
p.getCode().setIns(s, false);