@@ -681,6 +681,14 @@ abstract class GenLLVM extends SubComponent {
681681 }
682682 }
683683
684+ def externFieldFun (s : Symbol , static : Boolean ) = {
685+ externFuns.getOrElseUpdate(s, {
686+ val fun = fieldPtrfun(s, static)
687+ fun.tpe.argTypes.foreach(recordType)
688+ recordType(fun.tpe.returnType)
689+ fun
690+ })
691+ }
684692 def externFun (s : Symbol ) = {
685693 externFuns.getOrElseUpdate(s, {
686694 val fun = functionForMethodSymbol(s)
@@ -717,12 +725,23 @@ abstract class GenLLVM extends SubComponent {
717725
718726 val virtualMethodCache : mutable.Map [Symbol ,List [Symbol ]] = new mutable.HashMap
719727
728+
729+ /* intp("scala.Some").info.decls.toList filterNot (_.allOverriddenSymbols.headOption exists (_ isDeferred)) */
730+ /*
731+ def vms(s:Symbol):List[(Symbol,List[Symbol])] = if (s == NoSymbol) Nil else { val sms = vms(s.superClass); val mms = s.info.members.filterNot(m => !m.isMethod || m.isConstructor || m.isEffectivelyFinal || m.isOverride || m.allOverriddenSymbols.exists(o => supers(s).contains(o.owner))); sms ++ List((s,(mms.toSet -- sms.flatMap(_._2).toSet).toList)) }
732+ */
720733 def virtualMethods (s : Symbol ): List [Symbol ] = {
721734 virtualMethodCache.getOrElseUpdate(s,
722735 if (s == NoSymbol ) Nil
723736 else {
724- val myvirts = s.info.decls.toList.filter(d => d.isMethod && ! d.isConstructor && ! (d.isOverride && s.superClass.info.members.exists(mem => mem.info <:< d.info && mem.name == d.name)) && (d.isDeferred || ! d.isEffectivelyFinal))
737+ val supers = Stream .iterate(s.superClass)(_.superClass).takeWhile(s => s != NoSymbol ).toList
738+ val mymembers = s.info.members.filterNot(m => ! m.isMethod || m.isConstructor || (! m.isDeferred && m.isEffectivelyFinal) || m.allOverriddenSymbols.exists(o => supers.contains(o.owner)))
739+ val supervirts = virtualMethods(s.superClass)
740+ supervirts ++ (mymembers.toSet -- supervirts.toSet).toList.sortBy(methodSig _)
741+ /*
742+ val myvirts = s.info.decls.toList.filter(d => d.isMethod && !d.isConstructor && !(d.allOverriddenSymbols exists (m => !m.isDeferred)) && (d.isDeferred || !d.isEffectivelyFinal))
725743 (virtualMethods(s.superClass) ++ myvirts.sortBy(methodSig _)).toList
744+ */
726745 }
727746 )
728747 }
@@ -882,8 +901,8 @@ abstract class GenLLVM extends SubComponent {
882901 }
883902
884903 def exportFunction (m : IMethod ): Seq [ModuleComp ] = {
885- m.symbol.getAnnotation(ForeignExportAnnotSym ) match {
886- case Some ( AnnotationInfo (_,List (Literal (Constant (foreignSymbol : String ))),_) ) => {
904+ m.symbol.getAnnotation(ForeignExportAnnotSym ).get match {
905+ case AnnotationInfo (_,List (Literal (Constant (foreignSymbol : String ))),_) => {
887906 val methType = m.symbol.info
888907 if (! m.symbol.isStatic) {
889908 error(" Only object methods can be exported" ); Seq .empty
@@ -1016,6 +1035,21 @@ abstract class GenLLVM extends SubComponent {
10161035 }
10171036 }
10181037
1038+ def genFieldFun (m : IField ,i: Int ) = {
1039+ val static = m.symbol.isStaticMember
1040+ val thisobj = new LocalVariable (" .thisobj" , rtObject.pointer)
1041+ val thisvar = new LocalVariable (" .this" , classType(c.symbol).pointer)
1042+ val fun = fieldPtrfun(m.symbol, static)
1043+ val src = if (static) externStaticP(c.symbol) else thisvar.asInstanceOf [LMValue [LMPointer ]]
1044+ val prep = if (static) Seq () else Seq (new bitcast(thisvar, fun.args(0 ).lmvar))
1045+ val fieldptr = new LocalVariable (" fieldptr" , symType(m.symbol).pointer)
1046+ val idx = new CInt (LMInt .i32,if (static) i else i+ 1 )
1047+ val body = Seq (LMBlock (Some (Label (" start" )), prep ++ Seq (
1048+ new getelementptr(fieldptr, src, Seq (new CInt (LMInt .i8,0 ),idx)),
1049+ new ret(fieldptr)
1050+ )))
1051+ fun.define(body)
1052+ }
10191053
10201054 def genNativeFun (m : IMethod ) = {
10211055 val thisarg = ArgSpec (new LocalVariable (" .this" , symType(c.symbol)))
@@ -1077,7 +1111,7 @@ abstract class GenLLVM extends SubComponent {
10771111 Seq (header) ++ hblocks ++ Seq (footer)
10781112 }
10791113
1080- m.code.blocks.filter(reachable).foreach { bb =>
1114+ m.code.blocks./* filter(reachable).*/ foreach { bb =>
10811115 val stack : mutable.Stack [(LMValue [_<: ConcreteType ],TypeKind )] = mutable.Stack ()
10821116 def popn (n : Int ) {
10831117 for (_ <- 0 until n) stack.pop
@@ -1086,7 +1120,7 @@ abstract class GenLLVM extends SubComponent {
10861120 val pass = Label (" __PASS__" )
10871121 val excpreds = bb.code.blocks.filter(pb => pb.exceptionSuccessors.contains(bb))
10881122 val dirpreds = bb.code.blocks.filter(_.directSuccessors contains bb)
1089- val preds = (excpreds ++ dirpreds).filter(reachable)
1123+ val preds = (excpreds ++ dirpreds)/* .filter(reachable)*/
10901124 insns.append(new icomment(" predecessors: " + preds.map(_.fullString).mkString(" ," )+ " successors: " + bb.successors.map(_.fullString).mkString(" " )))
10911125 def loadobjvtbl (src : LMValue [SomeConcreteType ])(implicit _insns : InstBuffer ): LMValue [SomeConcreteType ] = {
10921126 val asobj = nextvar(rtObject.pointer)
@@ -1244,15 +1278,15 @@ abstract class GenLLVM extends SubComponent {
12441278 recordType(lt)
12451279 if (tpe.isValueType || tpe == ConcatClass ) {
12461280 val reg = new LocalVariable (blockName(bb)+ " .in." + n.toString,lt)
1247- val dirsources = dirpreds.filter(reachable).map(pred => (blockLabel(pred,- 1 ), new LocalVariable (blockName(pred)+ " .out." + n.toString,lt)))
1248- val excsources = excpreds.filter(reachable).map(pred => (blockExSelLabel(pred,pred.method.exh.filter(_.covers(pred)).indexWhere(_.startBlock == bb)), new LocalVariable (blockName(pred)+ " .out." + n.toString,lt)))
1281+ val dirsources = dirpreds/* .filter(reachable)*/ .map(pred => (blockLabel(pred,- 1 ), new LocalVariable (blockName(pred)+ " .out." + n.toString,lt)))
1282+ val excsources = excpreds/* .filter(reachable)*/ .map(pred => (blockExSelLabel(pred,pred.method.exh.filter(_.covers(pred)).indexWhere(_.startBlock == bb)), new LocalVariable (blockName(pred)+ " .out." + n.toString,lt)))
12491283 val sources = dirsources ++ excsources
12501284 insns.append(new phi(reg, sources))
12511285 stack.push((reg, tpe))
12521286 } else {
12531287 val asobj = nextvar(rtReference)
1254- val dirsources = dirpreds.filter(reachable).map(pred => (blockLabel(pred,- 1 ), new LocalVariable (blockName(pred)+ " .out." + n.toString,rtReference)))
1255- val excsources = excpreds.filter(reachable).map(pred => (blockExSelLabel(pred,pred.method.exh.filter(_.covers(pred)).indexWhere(_.startBlock == bb)), new LocalVariable (blockName(pred)+ " .out." + n.toString,rtReference)))
1288+ val dirsources = dirpreds/* .filter(reachable)*/ .map(pred => (blockLabel(pred,- 1 ), new LocalVariable (blockName(pred)+ " .out." + n.toString,rtReference)))
1289+ val excsources = excpreds/* .filter(reachable)*/ .map(pred => (blockExSelLabel(pred,pred.method.exh.filter(_.covers(pred)).indexWhere(_.startBlock == bb)), new LocalVariable (blockName(pred)+ " .out." + n.toString,rtReference)))
12561290 val sources = dirsources ++ excsources
12571291 insns.append(new phi(asobj, sources))
12581292 stack.push((cast(asobj, ObjectReference , tpe)(predcasts), tpe))
@@ -1320,27 +1354,36 @@ abstract class GenLLVM extends SubComponent {
13201354 }
13211355 case i@ LOAD_FIELD (field, false ) => {
13221356 val v = nextvar(symType(field))
1323- val fieldptr = nextvar(v.tpe.pointer)
1357+ val fieldptr = nextvar(symType(field).pointer)
1358+ val (ivar,isym) = stack.pop
1359+ val instance = cast(ivar,isym,toTypeKind(field.owner.tpe))
1360+ val asobj = getrefptr(instance)
1361+ val instptr = nextvar(classType(field.owner).pointer)
1362+ insns.append(new bitcast(instptr, asobj))
1363+ insns.append(new invoke_void(rtAssertNotNull, Seq (asobj), pass, blockExSelLabel(bb,- 2 )))
1364+ insns.append(new call(fieldptr, externFieldFun(field, false ), Seq (asobj)))
1365+ insns.append(new load(v, fieldptr))
1366+ stack.push((v,toTypeKind(field.tpe)))
1367+ /*
13241368 instFields(field.owner) match {
13251369 case Some(fi) =>
13261370 val fieldidx = fi.indexWhere(f => f.symbol == field)
13271371 assume(fieldidx >= 0)
1328- val (ivar,isym) = stack.pop
1329- val instance = cast(ivar,isym,toTypeKind(field.owner.tpe))
1330- val asobj = getrefptr(instance)
1331- val instptr = nextvar(classType(field.owner).pointer)
1332- insns.append(new bitcast(instptr, asobj))
1333- insns.append(new invoke_void(rtAssertNotNull, Seq (asobj), pass, blockExSelLabel(bb,- 2 )))
13341372 insns.append(new getelementptr(fieldptr, instptr.asInstanceOf[LMValue[LMPointer]], Seq(new CInt(LMInt.i8,0),new CInt(LMInt.i32,fieldidx+1))))
1335- insns.append(new load(v, fieldptr))
1336- stack.push((v,toTypeKind(field.tpe)))
13371373 case None =>
13381374 error("No field info for "+field.owner+" needed to lookup position of "+field)
13391375 m.dump
13401376 stack.push((new CUndef(v.tpe), toTypeKind(field.tpe)))
13411377 }
1378+ */
13421379 }
13431380 case LOAD_FIELD (field, true ) => {
1381+ val v = nextvar(symType(field))
1382+ val fieldptr = nextvar(v.tpe.pointer)
1383+ insns.append(new call(fieldptr, externFieldFun(field, true ), Seq ()))
1384+ insns.append(new load(v, fieldptr))
1385+ stack.push((v,toTypeKind(field.tpe)))
1386+ /*
13441387 val v = nextvar(symType(field))
13451388 val fieldptr = nextvar(v.tpe.pointer)
13461389 staticFields(field.owner) match {
@@ -1355,6 +1398,7 @@ abstract class GenLLVM extends SubComponent {
13551398 m.dump
13561399 stack.push((new CUndef(v.tpe), ObjectReference))
13571400 }
1401+ */
13581402 }
13591403 case LOAD_MODULE (module) => {
13601404 insns.append(new call_void(moduleInitFun(module), Seq .empty))
@@ -1380,6 +1424,16 @@ abstract class GenLLVM extends SubComponent {
13801424 }
13811425 case STORE_FIELD (field, false ) => {
13821426 val fieldptr = nextvar(symType(field).pointer)
1427+ val (value,valuesym) = stack.pop
1428+ val (ivar,isym) = stack.pop
1429+ val instance = cast(ivar,isym,toTypeKind(field.owner.tpe))
1430+ val asobj = getrefptr(instance)
1431+ val instptr = nextvar(classType(field.owner).pointer)
1432+ insns.append(new bitcast(instptr, asobj))
1433+ insns.append(new invoke_void(rtAssertNotNull, Seq (asobj), pass, blockExSelLabel(bb,- 2 )))
1434+ insns.append(new call(fieldptr, externFieldFun(field, false ), Seq (asobj)))
1435+ insns.append(new store(cast(value, valuesym, toTypeKind(field.tpe)), fieldptr))
1436+ /*
13831437 instFields(field.owner) match {
13841438 case Some(fi) =>
13851439 val fieldidx = fi.indexWhere(f => f.symbol == field)
@@ -1396,9 +1450,14 @@ abstract class GenLLVM extends SubComponent {
13961450 case None =>
13971451 error("No field info for "+field.owner+" needed to lookup position of "+field)
13981452 }
1453+ */
13991454 }
14001455 case STORE_FIELD (field, true ) => {
14011456 val fieldptr = nextvar(symType(field).pointer)
1457+ val (value,valuesym) = stack.pop
1458+ insns.append(new call(fieldptr, externFieldFun(field, true ), Seq ()))
1459+ insns.append(new store(cast(value, valuesym, toTypeKind(field.tpe)), fieldptr))
1460+ /*
14021461 staticFields(field.owner) match {
14031462 case Some(fi) =>
14041463 val fieldidx = fi.indexWhere(f => f.symbol == field)
@@ -1409,6 +1468,7 @@ abstract class GenLLVM extends SubComponent {
14091468 case None =>
14101469 error("No field info for "+field.owner+" needed to lookup position of "+field)
14111470 }
1471+ */
14121472 }
14131473 case CALL_PRIMITIVE (primitive) => {
14141474 primitive match {
@@ -2000,6 +2060,9 @@ abstract class GenLLVM extends SubComponent {
20002060 val methods = concreteMethods.filter(m => ! CodegenAnnotations .exists(a => m.symbol.hasAnnotation(a)))
20012061 val llvmmethods = concreteMethods.filter(_.symbol.hasAnnotation(LlvmimplAnnotSym ))
20022062 val methodFuns = methods.filter(_.code != NoCode ).map(m => try { genFun(m) } catch { case e => println(e); m.dump; throw e } )
2063+ val staticFieldFuns = c.fields.filter(_.symbol.isStaticMember).zipWithIndex.map((genFieldFun _).tupled)
2064+ val nonstaticFieldFuns = c.fields.filterNot(_.symbol.isStaticMember).zipWithIndex.map((genFieldFun _).tupled)
2065+ val fieldFuns = staticFieldFuns ++ nonstaticFieldFuns
20032066 val llvmmethodFuns = llvmmethods.map(genNativeFun)
20042067 val foreignFuns = c.methods.filter(_.symbol.hasAnnotation(ForeignAnnotSym )).flatMap(genForeignFun)
20052068 val foreignVals = c.methods.filter(_.symbol.hasAnnotation(ForeignValueAnnotSym )).flatMap(genForeignVal)
@@ -2019,6 +2082,7 @@ abstract class GenLLVM extends SubComponent {
20192082 otherModules.keys.map(mod => moduleInitFun(mod).declare),
20202083 classInfo,
20212084 methodFuns,
2085+ fieldFuns,
20222086 llvmmethodFuns,
20232087 exportedFunctions,
20242088 foreignFuns,
@@ -2145,7 +2209,7 @@ abstract class GenLLVM extends SubComponent {
21452209 dir.fileNamed(llvmName(sym) + suffix)
21462210 }
21472211
2148- /* used escapes: _ D L G S O M R A N */
2212+ /* used escapes: _ D L G S O M R A N F */
21492213
21502214 def encodeName (s : String ) = {
21512215 s.replace(" _" ," __" )
@@ -2175,6 +2239,14 @@ abstract class GenLLVM extends SubComponent {
21752239 encodeName(sym.simpleName.toString.trim)
21762240 }
21772241
2242+ def fieldPtrfun (sym : Symbol , static : Boolean ): LMFunction = {
2243+ val prefix = if (static) " static_" else " "
2244+ val funName = llvmName(sym.owner)+ " _F" + llvmName(sym)
2245+ val restype = symType(sym).pointer
2246+ val args = if (static) Nil else List (ArgSpec (new LocalVariable (" t" , rtObject.pointer)))
2247+ new LMFunction (restype, funName, args, false , Externally_visible , Default , Ccc , Seq .empty, Seq .empty, None , None , None )
2248+ }
2249+
21782250 def blockLabel (bb : BasicBlock ) = Label (blockName(bb))
21792251 def blockName (bb : BasicBlock ) = " bb." + bb.label
21802252 def blockLabel (bb : BasicBlock , x : Int ) = Label (blockName(bb,x))
@@ -2211,7 +2283,7 @@ abstract class GenLLVM extends SubComponent {
22112283
22122284 def stackUsage (bb : BasicBlock , memo : immutable.BitSet ): (Seq [TypeKind ],Seq [TypeKind ]) = {
22132285 val (ict,ipt) = internalUsage(bb)
2214- val predextras = bb.predecessors.filter(pb => reachable(pb) && ! memo(pb.label)).headOption match {
2286+ val predextras = bb.predecessors.filter(pb => /* reachable(pb) &&*/ ! memo(pb.label)).headOption match {
22152287 case Some (p) => stackUsage(p, memo+ bb.label)._2.dropRight(ict.length)
22162288 case None => Seq .empty
22172289 }
0 commit comments