Skip to content

Commit eae5fe0

Browse files
committed
Use functions to resolve field pointers
1 parent ffa0713 commit eae5fe0

File tree

1 file changed

+71
-10
lines changed

1 file changed

+71
-10
lines changed

src/compiler/scala/tools/nsc/backend/llvm/GenLLVM.scala

Lines changed: 71 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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)
@@ -1027,6 +1035,21 @@ abstract class GenLLVM extends SubComponent {
10271035
}
10281036
}
10291037

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+
}
10301053

10311054
def genNativeFun(m: IMethod) = {
10321055
val thisarg = ArgSpec(new LocalVariable(".this", symType(c.symbol)))
@@ -1331,27 +1354,36 @@ abstract class GenLLVM extends SubComponent {
13311354
}
13321355
case i@LOAD_FIELD(field, false) => {
13331356
val v = nextvar(symType(field))
1334-
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+
/*
13351368
instFields(field.owner) match {
13361369
case Some(fi) =>
13371370
val fieldidx = fi.indexWhere(f => f.symbol == field)
13381371
assume(fieldidx >= 0)
1339-
val (ivar,isym) = stack.pop
1340-
val instance = cast(ivar,isym,toTypeKind(field.owner.tpe))
1341-
val asobj = getrefptr(instance)
1342-
val instptr = nextvar(classType(field.owner).pointer)
1343-
insns.append(new bitcast(instptr, asobj))
1344-
insns.append(new invoke_void(rtAssertNotNull, Seq(asobj), pass, blockExSelLabel(bb,-2)))
13451372
insns.append(new getelementptr(fieldptr, instptr.asInstanceOf[LMValue[LMPointer]], Seq(new CInt(LMInt.i8,0),new CInt(LMInt.i32,fieldidx+1))))
1346-
insns.append(new load(v, fieldptr))
1347-
stack.push((v,toTypeKind(field.tpe)))
13481373
case None =>
13491374
error("No field info for "+field.owner+" needed to lookup position of "+field)
13501375
m.dump
13511376
stack.push((new CUndef(v.tpe), toTypeKind(field.tpe)))
13521377
}
1378+
*/
13531379
}
13541380
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+
/*
13551387
val v = nextvar(symType(field))
13561388
val fieldptr = nextvar(v.tpe.pointer)
13571389
staticFields(field.owner) match {
@@ -1366,6 +1398,7 @@ abstract class GenLLVM extends SubComponent {
13661398
m.dump
13671399
stack.push((new CUndef(v.tpe), ObjectReference))
13681400
}
1401+
*/
13691402
}
13701403
case LOAD_MODULE(module) => {
13711404
insns.append(new call_void(moduleInitFun(module), Seq.empty))
@@ -1391,6 +1424,16 @@ abstract class GenLLVM extends SubComponent {
13911424
}
13921425
case STORE_FIELD(field, false) => {
13931426
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+
/*
13941437
instFields(field.owner) match {
13951438
case Some(fi) =>
13961439
val fieldidx = fi.indexWhere(f => f.symbol == field)
@@ -1407,9 +1450,14 @@ abstract class GenLLVM extends SubComponent {
14071450
case None =>
14081451
error("No field info for "+field.owner+" needed to lookup position of "+field)
14091452
}
1453+
*/
14101454
}
14111455
case STORE_FIELD(field, true) => {
14121456
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+
/*
14131461
staticFields(field.owner) match {
14141462
case Some(fi) =>
14151463
val fieldidx = fi.indexWhere(f => f.symbol == field)
@@ -1420,6 +1468,7 @@ abstract class GenLLVM extends SubComponent {
14201468
case None =>
14211469
error("No field info for "+field.owner+" needed to lookup position of "+field)
14221470
}
1471+
*/
14231472
}
14241473
case CALL_PRIMITIVE(primitive) => {
14251474
primitive match {
@@ -2011,6 +2060,9 @@ abstract class GenLLVM extends SubComponent {
20112060
val methods = concreteMethods.filter(m => !CodegenAnnotations.exists(a => m.symbol.hasAnnotation(a)))
20122061
val llvmmethods = concreteMethods.filter(_.symbol.hasAnnotation(LlvmimplAnnotSym))
20132062
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
20142066
val llvmmethodFuns = llvmmethods.map(genNativeFun)
20152067
val foreignFuns = c.methods.filter(_.symbol.hasAnnotation(ForeignAnnotSym)).flatMap(genForeignFun)
20162068
val foreignVals = c.methods.filter(_.symbol.hasAnnotation(ForeignValueAnnotSym)).flatMap(genForeignVal)
@@ -2030,6 +2082,7 @@ abstract class GenLLVM extends SubComponent {
20302082
otherModules.keys.map(mod => moduleInitFun(mod).declare),
20312083
classInfo,
20322084
methodFuns,
2085+
fieldFuns,
20332086
llvmmethodFuns,
20342087
exportedFunctions,
20352088
foreignFuns,
@@ -2156,7 +2209,7 @@ abstract class GenLLVM extends SubComponent {
21562209
dir.fileNamed(llvmName(sym) + suffix)
21572210
}
21582211

2159-
/* used escapes: _ D L G S O M R A N */
2212+
/* used escapes: _ D L G S O M R A N F */
21602213

21612214
def encodeName(s: String) = {
21622215
s.replace("_","__")
@@ -2186,6 +2239,14 @@ abstract class GenLLVM extends SubComponent {
21862239
encodeName(sym.simpleName.toString.trim)
21872240
}
21882241

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+
21892250
def blockLabel(bb: BasicBlock) = Label(blockName(bb))
21902251
def blockName(bb: BasicBlock) = "bb."+bb.label
21912252
def blockLabel(bb: BasicBlock, x: Int) = Label(blockName(bb,x))

0 commit comments

Comments
 (0)