diff --git a/sources/zweic/Generator.scala b/sources/zweic/Generator.scala index 76cb878..94e8fff 100644 --- a/sources/zweic/Generator.scala +++ b/sources/zweic/Generator.scala @@ -43,25 +43,25 @@ 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); + code.emit(ADD, ZERO, ZERO, ZERO, c.name.name + "::" + m.name); } - } + } + + // generate class and function definitions + classes.foreach(gen); - // 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); - // } + //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(); @@ -95,21 +95,18 @@ 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); @@ -297,9 +294,9 @@ 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); @@ -340,48 +337,55 @@ freed = i::freed; } } - - // 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); + genTmp { thisReg => + // get 'receiver' and put it as 'this' on the stack + genLoad(receiver, thisReg); - code.emit(PSH, targetReg, SP, 4); - code.incFrameSize(4); + // 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); - // 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); } + } + + + //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); } - //load method address - code.emit(LDW, targetReg, targetReg, 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"); + //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 + code.decFrameSize(args.length*4+4); // fs = oldframesize - params - this // retrieve all registers from stack for ( val j <- freed ) {