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

org.scalajs.linker.backend.wasmemitter.SWasmGen.scala Maven / Gradle / Ivy

/*
 * Scala.js (https://www.scala-js.org/)
 *
 * Copyright EPFL.
 *
 * Licensed under Apache License 2.0
 * (https://www.apache.org/licenses/LICENSE-2.0).
 *
 * See the NOTICE file distributed with this work for
 * additional information regarding copyright ownership.
 */

package org.scalajs.linker.backend.wasmemitter

import org.scalajs.ir.Names._
import org.scalajs.ir.Types._

import org.scalajs.linker.backend.webassembly._
import org.scalajs.linker.backend.webassembly.Instructions._

import VarGen._

/** Scala.js-specific Wasm generators that are used across the board. */
object SWasmGen {

  def genZeroOf(tpe: Type)(implicit ctx: WasmContext): Instr = {
    tpe match {
      case BooleanType | CharType | ByteType | ShortType | IntType =>
        I32Const(0)

      case LongType   => I64Const(0L)
      case FloatType  => F32Const(0.0f)
      case DoubleType => F64Const(0.0)
      case StringType => GlobalGet(genGlobalID.emptyString)
      case UndefType  => GlobalGet(genGlobalID.undef)

      case ClassType(BoxedStringClass, true) =>
        RefNull(Types.HeapType.NoExtern)

      case AnyType | ClassType(_, true) | ArrayType(_, true) | NullType =>
        RefNull(Types.HeapType.None)

      case NothingType | NoType | ClassType(_, false) | ArrayType(_, false) |
          AnyNotNullType | _:RecordType =>
        throw new AssertionError(s"Unexpected type for field: ${tpe.show()}")
    }
  }

  def genLoadTypeData(fb: FunctionBuilder, typeRef: TypeRef): Unit = typeRef match {
    case typeRef: NonArrayTypeRef => genLoadNonArrayTypeData(fb, typeRef)
    case typeRef: ArrayTypeRef    => genLoadArrayTypeData(fb, typeRef)
  }

  def genLoadNonArrayTypeData(fb: FunctionBuilder, typeRef: NonArrayTypeRef): Unit = {
    fb += GlobalGet(genGlobalID.forVTable(typeRef))
  }

  def genLoadArrayTypeData(fb: FunctionBuilder, arrayTypeRef: ArrayTypeRef): Unit = {
    genLoadNonArrayTypeData(fb, arrayTypeRef.base)
    fb += I32Const(arrayTypeRef.dimensions)
    fb += Call(genFunctionID.arrayTypeData)
  }

  /** Gen code to load the vtable and the itable of the given array type. */
  def genLoadVTableAndITableForArray(fb: FunctionBuilder, arrayTypeRef: ArrayTypeRef): Unit = {
    // Load the typeData of the resulting array type. It is the vtable of the resulting object.
    genLoadArrayTypeData(fb, arrayTypeRef)

    // Load the itables for the array type
    fb += GlobalGet(genGlobalID.arrayClassITable)
  }

  def genArrayValue(fb: FunctionBuilder, arrayTypeRef: ArrayTypeRef, length: Int)(
      genElems: => Unit): Unit = {
    genLoadVTableAndITableForArray(fb, arrayTypeRef)

    // Create the underlying array
    genElems
    val underlyingArrayType = genTypeID.underlyingOf(arrayTypeRef)
    fb += ArrayNewFixed(underlyingArrayType, length)

    // Create the array object
    fb += StructNew(genTypeID.forArrayClass(arrayTypeRef))
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy