hamzaremmal/amy

View on GitHub
compiler/src/main/scala/amyc/backend/wasm/Instructions.scala

Summary

Maintainability
A
0 mins
Test Coverage
F
40%
package amyc.backend.wasm

import amyc.backend.wasm.Indices.*
import amyc.backend.wasm.Values.*
import amyc.backend.wasm.Types.*

import scala.annotation.targetName

// A subset of instructions defined by the WASM standard
object Instructions :

  sealed abstract class Instruction:
    @targetName("concat")
    def <:>(i: Instruction): Code = (this, i) match
      case (Code(rhs), Code(lhs)) => Code(rhs ::: lhs)
      case (Code(rhs), _) => Code(rhs :+ i)
      case (_, Code(lhs)) => Code(this +: lhs)
      case _ => Code(this :: i :: Nil)

  // Represents a sequence of instructions
  case class Code(instructions: List[Instruction]) extends Instruction

  // Comment
  case class Comment(msg: String) extends Instruction

  // ==============================================================================================
  // =================== Useful implicit conversions to construct Code objects ====================
  // ==============================================================================================

  implicit def is2c(is: List[Instruction]): Code = is.foldRight(Code(Nil))(_ <:> _)
  implicit def cs2c(cs: List[Code]): Code = cs.foldRight(Code(Nil))(_ <:> _)
  implicit def i2c(i: Instruction): Code = i match
    case c:Code => c
    case _ => Code(List(i))

  // ==============================================================================================
  // ============================= ??? ============================================================
  // ==============================================================================================

  // Control instructions
  @deprecated
  case class Loop(label: String, tpe: Option[result] = None)  extends Instruction // A block of instructions with a label at the beginning
  @deprecated
  case class Block(label: String) extends Instruction // A block of instructions with a label at the end

  // ==============================================================================================
  //
  // ==============================================================================================

  /**
    * https://webassembly.github.io/spec/core/text/instructions.html#variable-instructions
    */
  object global:
    case class get(idx: globalidx) extends Instruction
    case class set(idx: globalidx) extends Instruction

  object local:

    case class get(idx: localidx) extends Instruction
    case class set(idx: localidx) extends Instruction
    case class tee(idx: localidx) extends Instruction

  /**
    * https://webassembly.github.io/spec/core/text/instructions.html#table-instructions
    */
  object table:
    case class get(idx: tableidx = 0) extends Instruction
    case class set(idx: tableidx = 0) extends Instruction
    case class size(idx: tableidx = 0) extends Instruction
    case class grow(idx: tableidx = 0) extends Instruction
    case class fill(idx: tableidx = 0) extends Instruction
    case class copy(x: tableidx = 0, y: tableidx = 0) extends Instruction
    case class init(x: tableidx = 0, y: elemidx) extends Instruction

  object elem:
    case class drop(x: elemidx) extends Instruction


  /**
    * https://webassembly.github.io/spec/core/text/instructions.html#reference-instructions
    */
  object ref:
    // TODO HR : Fix parameter type
    case class `null`(t: Any) extends Instruction
    case object is_null extends Instruction
    case class func(idx: funcidx) extends Instruction

  /**
    * https://webassembly.github.io/spec/core/text/instructions.html#parametric-instructions
    */

  case object drop extends Instruction

  // TODO HR : Add select instructions

  /**
    * https://webassembly.github.io/spec/core/text/instructions.html#memory-instructions
    */

  object memory:
    case object size extends Instruction
    case object grow extends Instruction
    case object fill extends Instruction
    case object copy extends Instruction
    case class init(x: dataidx) extends Instruction

  object data:
    case class drop(x: dataidx) extends Instruction

  /**
    * https://webassembly.github.io/spec/core/text/instructions.html#control-instructions
    */

  // ================================================================================================
  // ================================ PLAIN INSTRUCTIONS ============================================
  // ================================================================================================

  case object unreachable extends Instruction
  case object nop extends Instruction
  case class br(l: labelidx) extends Instruction
  case class br_if(l: labelidx) extends Instruction
  case class br_table(l: List[labelidx], ln: labelidx) extends Instruction
  case object `return` extends Instruction
  case class call(x: funcidx) extends Instruction
  case class call_indirect(tpe: typeuse, x: tableidx = 0) extends Instruction
  case object end extends Instruction

  // ================================================================================================
  // =================================== BLOCK INSTRUCTIONS =========================================
  // ================================================================================================

  case class `if`(label: Option[id] = None, blocktype: Option[result] = None) extends Instruction
  case class `else`(l: Option[id] = None) extends Instruction

  /**
    * For Numeric Instructions : https://webassembly.github.io/spec/core/text/instructions.html#numeric-instructions
    * For Memory Instructions : https://webassembly.github.io/spec/core/text/instructions.html#memory-instructions
    */
  case object i32 extends numtype:
    // === NUMERIC INSTRUCTIONS ===
    case class const(value: Int) extends Instruction
    case object add extends Instruction
    case object sub extends Instruction
    case object mul extends Instruction
    case object div_u extends Instruction
    case object div_s extends Instruction
    case object rem_u extends Instruction
    case object rem_s extends Instruction
    case object and extends Instruction
    case object or extends Instruction
    case object xor extends Instruction
    case object shl extends Instruction
    case object shr_u extends Instruction
    case object shr_s extends Instruction
    case object rotl extends Instruction
    case object rotr extends Instruction
    case object eq extends Instruction
    case object eqz extends Instruction
    case object ne extends Instruction
    case object ge_s extends Instruction
    case object ge_u extends Instruction
    case object gt_s extends Instruction
    case object gt_u extends Instruction
    case object le_s extends Instruction
    case object le_u extends Instruction
    case object lt_s extends Instruction
    case object lt_u extends Instruction
    case object clz extends Instruction
    case object ctz extends Instruction
    case object popcnt extends Instruction
    case object extend8_s extends Instruction
    case object extend16_s extends Instruction
    case object wrap_i64 extends Instruction
    case object trunc_f32_s extends Instruction
    case object trunc_f32_u extends Instruction
    case object trunc_f64_s extends Instruction
    case object trunc_f64_u extends Instruction
    case object trunc_sat_f32_s extends Instruction
    case object trunc_sat_f32_u extends Instruction
    case object trunc_sat_f64_s extends Instruction
    case object trunc_sat_f64_u extends Instruction
    case object reinterpret_f32 extends Instruction
    // === MEMORY INSTRUCTIONS ===
    case object load extends Instruction
    case object load8_s extends Instruction
    case object load8_u extends Instruction
    case object load16_s extends Instruction
    case object load16_u extends Instruction
    case object store extends Instruction
    case object store8 extends Instruction
    case object store16 extends Instruction

  case object i64 extends numtype:
    // TODO HR : Add missing instructions
    ???

  case object f32 extends numtype:
    // TODO HR : Add missing instructions
    ???

  case object f64 extends numtype:
    // TODO HR : Add missing instructions
    ???

  case object v128 extends vectype:
    // TODO HR : Add missing instructions
    ???