before changing gencond
1 parent 08de234 commit a195530f45cb548f96f6b9fb9f02676730f1329a
@glproj03 glproj03 authored on 4 Feb 2006
Showing 1 changed file
View
160
sources/zweic/Generator.scala
val init = code.getLabel();
code.emit(BEQ,ZERO,init);
 
// go initialize the VMTs
var offset = code.pc();
for ( val c <- classes ) {
var offset = code.pc();
for ( val c <- classes ) {
c.name.sym.offset = offset;
offset = offset + c.name.sym.asInstanceOf[ClassSymbol].allMethods.length*4;
//XXX: no +4 for empty top entry
for ( val m <- c.name.sym.asInstanceOf[ClassSymbol].allMethods ) {
code.emit(ADD, ZERO, ZERO, ZERO, c.name.name + "::" + m.name);
}
}
 
// generate class and function definitions
classes.foreach(gen);
 
//TODO: what was that??? its writing some stuff in fromt of the program...
//TODO: allocation what????
//genTmp { tmpReg =>
// emitLoadConstant(tmpReg, offset);
// code.emit(SYSCALL, tmpReg, tmpReg, SYS_GC_ALLOC);
// }
code.emit(ADD, ZERO, ZERO, ZERO, c.name.name + "::" + m.name);
}
}
// generate class and function definitions
classes.foreach(gen);
 
//TODO: what was that??? its writing some stuff in fromt of the program...
//TODO: allocation what????
//genTmp { tmpReg =>
// emitLoadConstant(tmpReg, offset);
// code.emit(SYSCALL, tmpReg, tmpReg, SYS_GC_ALLOC);
// }
 
// generate main expression
val start = code.getLabel();
code.anchorLabel(start);
code.freeRegister(r2);
code.freeRegister(r3);
 
 
// populate VMTs
genTmp { classHeader =>
 
for ( val ClassDef(cname, _, members) <- classes ) {
emitLoadConstant(classHeader, cname.sym.offset);
for ( val m <- cname.sym.asInstanceOf[ClassSymbol].allMethods ) {
//TODO: why use LNK here? don't we use a normal register???
emitLoadConstant(LNK, m.address);
code.emit(STW, LNK, classHeader, m.offset,
cname.name + "::" + m.name);
// populate VMTs
genTmp { classHeader =>
for ( val ClassDef(cname, _, members) <- classes ) {
emitLoadConstant(classHeader, cname.sym.offset);
for ( val m <- cname.sym.asInstanceOf[ClassSymbol].allMethods ) {
//TODO: why use LNK here? don't we use a normal register???
emitLoadConstant(LNK, m.address);
code.emit(STW, LNK, classHeader, m.offset,
cname.name + "::" + m.name);
}
}
}
}
 
 
// jump to main expression
code.emit(BEQ, ZERO, start);
 
}
 
case New(name, args) =>
val af = name.sym.asInstanceOf[ClassSymbol].allFields;
emitLoadConstant(targetReg, 4+af.length*4);
code.emit(SYSCALL, targetReg, targetReg, SYS_GC_ALLOC, "new "+name);
 
emitLoadConstant(targetReg, 4+af.length*4);
code.emit(SYSCALL, targetReg, targetReg, SYS_GC_ALLOC, "new "+name);
genTmp { tmpReg =>
/* pointer to class header */
emitLoadConstant(tmpReg, name.sym.offset);
code.emit(STW, tmpReg, targetReg, 0);
code.freeRegister(i);
freed = i::freed;
}
}
 
genTmp { thisReg =>
// get 'receiver' and put it as 'this' on the stack
genLoad(receiver, thisReg);
 
// check receiver != null
val okLabel = code.getLabel();
code.emit(BNE, thisReg, okLabel);
emitLoadConstant(thisReg, 1);
code.emit(SYSCALL, thisReg, ZERO, SYS_EXIT);
code.anchorLabel(okLabel);
 
//put 'this' on stack
code.emit(PSH, thisReg, SP, 4);
code.incFrameSize(4);
// get 'receiver' and put it as 'this' on the stack
genLoad(receiver, targetReg);
 
// check receiver != null
val okLabel = code.getLabel();
code.emit(BNE, targetReg, okLabel);
emitLoadConstant(targetReg, 1);
code.emit(SYSCALL, targetReg, ZERO, SYS_EXIT);
code.anchorLabel(okLabel);
 
code.emit(PSH, targetReg, SP, 4);
code.incFrameSize(4);
// put args on stack
genTmp { tmpReg =>
// put args on stack
genTmp { tmpReg =>
for ( val a <- args ) {
genLoad(a, tmpReg);
code.emit(PSH, tmpReg, SP, 4);
code.incFrameSize(4);
genLoad(a, tmpReg);
code.emit(PSH, tmpReg, SP, 4);
code.incFrameSize(4);
}
}
//load method address
code.emit(LDW, targetReg, targetReg, method.sym.offset);
}
 
 
//TODO: bizarr: twice method.sym.offset....
//load vmt pos
code.emit(LDW, thisReg, thisReg, method.sym.offset);
 
//load method address
code.emit(LDW, targetReg, thisReg, method.sym.offset);
}
 
// //TODO
// // check receiver.method() != null
// val okLabel2 = code.getLabel();
// code.emit(BNE, targetReg, okLabel2);
// emitLoadConstant(targetReg, 1);
// code.emit(SYSCALL, targetReg, ZERO, SYS_EXIT);
// code.anchorLabel(okLabel2);
 
//call function
code.emit(ADD, 1, ZERO, ZERO, "call " +
method.sym.name.toString() + " offset:" + method.sym.offset.toString());
code.emit(RET, targetReg);
 
//store return value
code.emit(ADD, targetReg, ZERO, RES, "store return value to target reg");
 
code.decFrameSize(args.length*4+4); // fs = oldframesize - params - this
 
 
//save current position + 8 (after RET)
code.emit(ORIU, LNK, ZERO, code.pc() + 8, "call " +
method.sym.name.toString() + " offset:" + method.sym.offset.toString());
//call function
code.emit(RET, targetReg);
// //TODO store return value
// code.emit(ADD, targetReg, ZERO, RES, "store return value to target reg");
 
code.decFrameSize(args.length*4+4); // fs = oldframesize - params - this
// retrieve all registers from stack
for ( val j <- freed ) {
code.getRegister(j);