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

scala.scalanative.nir.Mangle.scala Maven / Gradle / Ivy

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

import scala.scalanative.nir.Sig.Scope._
import scala.scalanative.util.ShowBuilder.InMemoryShowBuilder

object Mangle {
  def apply(ty: Type): String = {
    val impl = new Impl
    impl.mangleType(ty)
    impl.toString
  }

  def apply(name: Global): String = {
    val impl = new Impl
    impl.mangleGlobal(name)
    impl.toString
  }

  def apply(sig: Sig.Unmangled): String = {
    val impl = new Impl
    impl.mangleUnmangledSig(sig)
    impl.toString
  }

  private class Impl {
    val sb = new InMemoryShowBuilder
    import sb._

    def mangleGlobal(name: Global): Unit = name match {
      case name: Global.Top =>
        sb.str("T")
        mangleIdent(name.id)
      case name: Global.Member =>
        sb.str("M")
        mangleIdent(name.owner.id)
        mangleSig(name.sig)
      case _ =>
        util.unreachable
    }

    def mangleSig(sig: Sig): Unit =
      str(sig.mangle)

    def mangleSigScope(scope: Sig.Scope): Unit = {
      scope match {
        case Public            => str("O")
        case PublicStatic      => str("o")
        case Private(in)       => str("P"); mangleGlobal(in)
        case PrivateStatic(in) => str("p"); mangleGlobal(in)
      }
    }

    def mangleUnmangledSig(sig: Sig.Unmangled): Unit = sig match {
      case Sig.Field(id, scope) =>
        str("F")
        mangleIdent(id)
        mangleSigScope(scope)
      case Sig.Ctor(types) =>
        str("R")
        types.foreach(mangleType)
        str("E")
      case Sig.Clinit =>
        str("I")
        str("E")
      case Sig.Method(id, types, scope) =>
        str("D")
        mangleIdent(id)
        types.foreach(mangleType)
        str("E")
        mangleSigScope(scope)
      case Sig.Proxy(id, types) =>
        str("P")
        mangleIdent(id)
        types.foreach(mangleType)
        str("E")
      case Sig.Extern(id) =>
        str("C")
        mangleIdent(id)
      case Sig.Generated(id) =>
        str("G")
        mangleIdent(id)
      case Sig.Duplicate(sig, types) =>
        str("K")
        mangleSig(sig)
        types.foreach(mangleType)
        str("E")
    }

    def mangleType(ty: Type): Unit = ty match {
      case Type.Vararg => str("v")
      case Type.Ptr    => str("R_")
      case Type.Bool   => str("z")
      case Type.Char   => str("c")
      case i: Type.FixedSizeI =>
        mangleFixedSizeIntegerType(i)
      case Type.Size    => str("w")
      case Type.Float   => str("f")
      case Type.Double  => str("d")
      case Type.Null    => str("l")
      case Type.Nothing => str("n")
      case Type.Unit    => str("u")
      case Type.ArrayValue(ty, n) =>
        str("A")
        mangleType(ty)
        str(n)
        str("_")
      case Type.StructValue(tys) =>
        str("S")
        tys.foreach(mangleType)
        str("E")
      case Type.Function(args, ret) =>
        str("R")
        args.foreach(mangleType)
        mangleType(ret)
        str("E")

      case Type.Array(ty, nullable) =>
        if (nullable) {
          str("L")
        }
        str("A")
        mangleType(ty)
        str("_")
      case Type.Ref(Global.Top(id), exact, nullable) =>
        if (nullable) {
          str("L")
        }
        if (exact) {
          str("X")
        }
        mangleIdent(id)
      case _ =>
        util.unreachable
    }

    /** Appends the mangled representation of `ty` to `this.sb`. */
    def mangleFixedSizeIntegerType(ty: Type.FixedSizeI): Unit = {
      assert(ty.signed, "unsupported unsigned fixed-size integer")
      ty.width match {
        case 8  => str("b")
        case 16 => str("s")
        case 32 => str("i")
        case 64 => str("j")
        case _  => util.unreachable
      }
    }

    def mangleIdent(id: String): Unit = {
      str(id.length)
      if (id.head.isDigit || id.head == '-') str('-')
      str(id)
    }

    override def toString = sb.toString
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy