All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scala.scalanative.optimizer.pass.MethodLowering.scala Maven / Gradle / Ivy

The newest version!
package scala.scalanative
package optimizer
package pass

import scala.collection.mutable
import analysis.ClassHierarchy._
import analysis.ClassHierarchyExtractors._
import nir._, Inst.Let

/** Translates high-level object-oriented method calls into
 *  low-level dispatch based on vtables for classes
 *  and dispatch tables for interfaces.
 */
class MethodLowering(implicit fresh: Fresh, top: Top) extends Pass {
  override def onInsts(insts: Seq[Inst]) = {
    val buf = new nir.Buffer
    import buf._

    insts.foreach {
      case Let(n, Op.Method(obj, MethodRef(cls: Class, meth)))
          if meth.isVirtual =>
        val vindex  = cls.vtable.index(meth)
        val typeptr = let(Op.Load(Type.Ptr, obj))
        val methptrptr = let(
          Op.Elem(cls.rtti.struct,
                  typeptr,
                  Seq(Val.Int(0),
                      Val.Int(5), // index of vtable in type struct
                      Val.Int(vindex))))

        let(n, Op.Load(Type.Ptr, methptrptr))

      case Let(n, Op.Method(obj, MethodRef(_: Class, meth)))
          if meth.isStatic =>
        let(n, Op.Copy(Val.Global(meth.name, Type.Ptr)))

      case Let(n, Op.Method(obj, MethodRef(trt: Trait, meth))) =>
        val sigid   = top.tables.traitMethodSigs(meth.name.id)
        val typeptr = let(Op.Load(Type.Ptr, obj))
        val idptr   = let(Op.Elem(Rt.Type, typeptr, Seq(Val.Int(0), Val.Int(0))))
        val id      = let(Op.Load(Type.Int, idptr))
        val rowptr = let(
          Op.Elem(Type.Ptr,
                  top.tables.dispatchVal,
                  Seq(Val.Int(top.tables.dispatchOffset(sigid)))))
        val methptrptr =
          let(Op.Elem(Type.Ptr, rowptr, Seq(id)))
        let(n, Op.Load(Type.Ptr, methptrptr))

      case inst =>
        buf += inst
    }

    buf.toSeq
  }
}

object MethodLowering extends PassCompanion {
  override def apply(config: tools.Config, top: Top) =
    new MethodLowering()(top.fresh, top)
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy