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

scala.scalanative.codegen.Metadata.scala Maven / Gradle / Ivy

There is a newer version: 0.5.5
Show newest version
package scala.scalanative
package codegen

import scala.collection.mutable
import scalanative.nir._
import scalanative.linker.{Trait, Class}

class Metadata(val linked: linker.Result, proxies: Seq[Defn]) {
  val rtti = mutable.Map.empty[linker.Info, RuntimeTypeInformation]
  val vtable = mutable.Map.empty[linker.Class, VirtualTable]
  val layout = mutable.Map.empty[linker.Class, FieldLayout]
  val dynmap = mutable.Map.empty[linker.Class, DynamicHashMap]
  val ids = mutable.Map.empty[linker.ScopeInfo, Int]
  val ranges = mutable.Map.empty[linker.Class, Range]

  val classes = initClassIdsAndRanges()
  val traits = initTraitIds()
  val moduleArray = new ModuleArray(this)
  val dispatchTable = new TraitDispatchTable(this)
  val hasTraitTables = new HasTraitTables(this)

  val Rtti = Type.StructValue(Seq(Type.Ptr, Type.Int, Type.Int, Type.Ptr))
  val RttiClassIdIndex = Seq(Val.Int(0), Val.Int(1))
  val RttiTraitIdIndex = Seq(Val.Int(0), Val.Int(2))
  val RttiVtableIndex =
    Seq(Val.Int(0), Val.Int(if (linked.dynsigs.isEmpty) 4 else 5))
  val RttiDynmapIndex =
    Seq(Val.Int(0), Val.Int(if (linked.dynsigs.isEmpty) -1 else 4))

  initClassMetadata()
  initTraitMetadata()

  def initTraitIds(): Seq[Trait] = {
    val traits =
      linked.infos.valuesIterator
        .collect { case info: Trait => info }
        .toIndexedSeq
        .sortBy(_.name.show)
    traits.zipWithIndex.foreach {
      case (node, id) =>
        ids(node) = id
    }
    traits
  }

  def initClassIdsAndRanges(): Seq[Class] = {
    val out = mutable.UnrolledBuffer.empty[Class]
    var id = 0

    def loop(node: Class): Unit = {
      out += node
      val start = id
      id += 1
      val directSubclasses =
        node.subclasses.filter(_.parent == Some(node)).toArray
      directSubclasses.sortBy(_.name.show).foreach { subcls => loop(subcls) }
      val end = id - 1
      ids(node) = start
      ranges(node) = start to end
    }

    loop(linked.infos(Rt.Object.name).asInstanceOf[Class])

    out.toSeq
  }

  def initClassMetadata(): Unit = {
    classes.foreach { node =>
      vtable(node) = new VirtualTable(this, node)
      layout(node) = new FieldLayout(this, node)
      if (linked.dynsigs.nonEmpty) {
        dynmap(node) = new DynamicHashMap(this, node, proxies)
      }
      rtti(node) = new RuntimeTypeInformation(this, node)
    }
  }

  def initTraitMetadata(): Unit = {
    traits.foreach { node =>
      rtti(node) = new RuntimeTypeInformation(this, node)
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy