@@ -681,6 +681,14 @@ abstract class GenLLVM extends SubComponent {
681
681
}
682
682
}
683
683
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
+ }
684
692
def externFun (s : Symbol ) = {
685
693
externFuns.getOrElseUpdate(s, {
686
694
val fun = functionForMethodSymbol(s)
@@ -1027,6 +1035,21 @@ abstract class GenLLVM extends SubComponent {
1027
1035
}
1028
1036
}
1029
1037
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
+ }
1030
1053
1031
1054
def genNativeFun (m : IMethod ) = {
1032
1055
val thisarg = ArgSpec (new LocalVariable (" .this" , symType(c.symbol)))
@@ -1331,27 +1354,36 @@ abstract class GenLLVM extends SubComponent {
1331
1354
}
1332
1355
case i@ LOAD_FIELD (field, false ) => {
1333
1356
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
+ /*
1335
1368
instFields(field.owner) match {
1336
1369
case Some(fi) =>
1337
1370
val fieldidx = fi.indexWhere(f => f.symbol == field)
1338
1371
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 )))
1345
1372
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)))
1348
1373
case None =>
1349
1374
error("No field info for "+field.owner+" needed to lookup position of "+field)
1350
1375
m.dump
1351
1376
stack.push((new CUndef(v.tpe), toTypeKind(field.tpe)))
1352
1377
}
1378
+ */
1353
1379
}
1354
1380
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
+ /*
1355
1387
val v = nextvar(symType(field))
1356
1388
val fieldptr = nextvar(v.tpe.pointer)
1357
1389
staticFields(field.owner) match {
@@ -1366,6 +1398,7 @@ abstract class GenLLVM extends SubComponent {
1366
1398
m.dump
1367
1399
stack.push((new CUndef(v.tpe), ObjectReference))
1368
1400
}
1401
+ */
1369
1402
}
1370
1403
case LOAD_MODULE (module) => {
1371
1404
insns.append(new call_void(moduleInitFun(module), Seq .empty))
@@ -1391,6 +1424,16 @@ abstract class GenLLVM extends SubComponent {
1391
1424
}
1392
1425
case STORE_FIELD (field, false ) => {
1393
1426
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
+ /*
1394
1437
instFields(field.owner) match {
1395
1438
case Some(fi) =>
1396
1439
val fieldidx = fi.indexWhere(f => f.symbol == field)
@@ -1407,9 +1450,14 @@ abstract class GenLLVM extends SubComponent {
1407
1450
case None =>
1408
1451
error("No field info for "+field.owner+" needed to lookup position of "+field)
1409
1452
}
1453
+ */
1410
1454
}
1411
1455
case STORE_FIELD (field, true ) => {
1412
1456
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
+ /*
1413
1461
staticFields(field.owner) match {
1414
1462
case Some(fi) =>
1415
1463
val fieldidx = fi.indexWhere(f => f.symbol == field)
@@ -1420,6 +1468,7 @@ abstract class GenLLVM extends SubComponent {
1420
1468
case None =>
1421
1469
error("No field info for "+field.owner+" needed to lookup position of "+field)
1422
1470
}
1471
+ */
1423
1472
}
1424
1473
case CALL_PRIMITIVE (primitive) => {
1425
1474
primitive match {
@@ -2011,6 +2060,9 @@ abstract class GenLLVM extends SubComponent {
2011
2060
val methods = concreteMethods.filter(m => ! CodegenAnnotations .exists(a => m.symbol.hasAnnotation(a)))
2012
2061
val llvmmethods = concreteMethods.filter(_.symbol.hasAnnotation(LlvmimplAnnotSym ))
2013
2062
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
2014
2066
val llvmmethodFuns = llvmmethods.map(genNativeFun)
2015
2067
val foreignFuns = c.methods.filter(_.symbol.hasAnnotation(ForeignAnnotSym )).flatMap(genForeignFun)
2016
2068
val foreignVals = c.methods.filter(_.symbol.hasAnnotation(ForeignValueAnnotSym )).flatMap(genForeignVal)
@@ -2030,6 +2082,7 @@ abstract class GenLLVM extends SubComponent {
2030
2082
otherModules.keys.map(mod => moduleInitFun(mod).declare),
2031
2083
classInfo,
2032
2084
methodFuns,
2085
+ fieldFuns,
2033
2086
llvmmethodFuns,
2034
2087
exportedFunctions,
2035
2088
foreignFuns,
@@ -2156,7 +2209,7 @@ abstract class GenLLVM extends SubComponent {
2156
2209
dir.fileNamed(llvmName(sym) + suffix)
2157
2210
}
2158
2211
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 */
2160
2213
2161
2214
def encodeName (s : String ) = {
2162
2215
s.replace(" _" ," __" )
@@ -2186,6 +2239,14 @@ abstract class GenLLVM extends SubComponent {
2186
2239
encodeName(sym.simpleName.toString.trim)
2187
2240
}
2188
2241
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
+
2189
2250
def blockLabel (bb : BasicBlock ) = Label (blockName(bb))
2190
2251
def blockName (bb : BasicBlock ) = " bb." + bb.label
2191
2252
def blockLabel (bb : BasicBlock , x : Int ) = Label (blockName(bb,x))
0 commit comments