Skip to content
This repository has been archived by the owner on Jul 12, 2024. It is now read-only.

Commit

Permalink
Implement monomorphic array
Browse files Browse the repository at this point in the history
  • Loading branch information
tanishiking committed Mar 14, 2024
1 parent a03e78b commit 07ac844
Show file tree
Hide file tree
Showing 8 changed files with 283 additions and 183 deletions.
2 changes: 1 addition & 1 deletion cli/src/main/scala/TestSuites.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ object TestSuites {
val suites = List(
TestSuite("testsuite.core.simple.Simple", "simple"),
TestSuite("testsuite.core.add.Add", "add"),
TestSuite("testsuite.core.add.Add", "add"),
TestSuite("testsuite.core.array.ArrayTest", "array"),
TestSuite("testsuite.core.virtualdispatch.VirtualDispatch", "virtualDispatch"),
TestSuite("testsuite.core.interfacecall.InterfaceCall", "interfaceCall"),
TestSuite("testsuite.core.asinstanceof.AsInstanceOfTest", "asInstanceOf"),
Expand Down
95 changes: 6 additions & 89 deletions sample/src/main/scala/Sample.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,98 +5,15 @@ import scala.annotation.tailrec
import scala.scalajs.js
import scala.scalajs.js.annotation._

//
// class Base {
// def sqrt(x: Int) = x * x
// }
//
object Main {
@JSExportTopLevel("test")
def test() = {
val i = 4
val loopFib = fib(new LoopFib {}, i)
val recFib = fib(new RecFib {}, i)
val tailrecFib = fib(new TailRecFib {}, i)
js.Dynamic.global.console.log(s"loopFib: $loopFib -- recFib: $recFib -- tailrecFib: $tailrecFib")
val date = new js.Date(0)
js.Dynamic.global.console.log(date)
loopFib == recFib && loopFib == tailrecFib
}
def fib(fib: Fib, n: Int): Int = fib.fib(n)
}
val a = Array(Array(1), Array(2), Array(3))
a(0) = Array(100) // Assign(ArraySelect(...), ...)
a(0)(0) == 100 // ArraySelect(...)


trait LoopFib extends Fib {
def fib(n: Int): Int = {
var a = 0
var b = 1
var i = 0
while (i < n) {
val temp = b
b = a + b
a = temp
i += 1
}
a
val a1 = Array.emptyBooleanArray
val a2 = new Array[Int](10)
val nested = new Array[Array[Array[Int]]](5)
}

}

trait RecFib extends Fib {
def fib(n: Int): Int =
if (n <= 1) {
n
} else {
fib(n - 1) + fib(n - 2)
}
}

trait TailRecFib extends Fib {
def fib(n: Int): Int = fibLoop(n, 0, 1)

@tailrec
final def fibLoop(n: Int, a: Int, b: Int): Int =
if (n == 0) a
else fibLoop(n - 1, b, a + b)
}

trait Fib {
def fib(n: Int): Int
// = {
// if (n <= 1) {
// n
// } else {
// fib(n - 1) + fib(n - 2)
// }
// }

}

//
//
// object Bar {
// def bar(b: Base) = b.base
// }

// class Base extends Incr {
// override def incr(x: Int) = foo(x) + 1
// }
//
// trait Incr extends BaseTrait {
// // val one = 1
// def incr(x: Int): Int
// }
//
// trait BaseTrait {
// def foo(x: Int) = x
// }

// object Foo {
// def foo =
// Main.ident(1)
// }
//
// class Derived(override val i: Int) extends Base(i) {
// def derived(x: Int) = x * i
// override def base(x: Int): Int = x * i
// }
36 changes: 36 additions & 0 deletions test-suite/src/main/scala/testsuite/core/ArrayTest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package testsuite.core.array

import scala.scalajs.js.annotation._

object ArrayTest {
def main(): Unit = { val _ = test() }
@JSExportTopLevel("array")
def test(): Boolean = {
testLength() && testSelect() && testNew()
}

def testLength(): Boolean = {
Array(1, 2, 3).length == 3 &&
(Array(Array(1, 2), Array(2), Array(3))).length == 3
}

def testSelect(): Boolean = {
val a = Array(Array(1), Array(2), Array(3))
a(0)(0) == 1 && {
a(0)(0) = 100 // Assign(ArraySelect(...), ...)
a(0)(0) == 100 // ArraySelect(...)
} && {
a(1) = Array(1, 2, 3)
a(1).length == 3 && a(1)(0) == 1
}
}

def testNew(): Boolean = {
(Array.emptyBooleanArray.length == 0) &&
(new Array[Int](10)).length == 10 &&
(new Array[Int](1))(0) == 0 &&
(new Array[Array[Array[Int]]](5))(0) == null
}

// TODO: Array.ofDim[T](...)
}
56 changes: 25 additions & 31 deletions wasm/src/main/scala/ir2wasm/TypeTransformer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ object TypeTransformer {
def transformFunctionType(
// clazz: WasmContext.WasmClassInfo,
method: WasmContext.WasmFunctionInfo
)(implicit ctx: FunctionTypeWriterWasmContext): WasmFunctionType = {
)(implicit ctx: TypeDefinableWasmContext): WasmFunctionType = {
// val className = clazz.name
val name = method.name
val receiverType = makeReceiverType
Expand Down Expand Up @@ -43,41 +43,35 @@ object TypeTransformer {
t match {
case IRTypes.AnyType => Types.WasmAnyRef

case tpe @ IRTypes.ArrayType(IRTypes.ArrayTypeRef(elemType, size)) =>
// TODO
// val wasmElemTy =
// elemType match {
// case IRTypes.ClassRef(className) =>
// // val gcTypeSym = context.gcTypes.reference(Ident(className.nameString))
// Types.WasmRefType(Types.WasmHeapType.Type(Names.WasmGCTypeName.fromIR(className)))
// case IRTypes.PrimRef(tpe) =>
// transform(tpe)
// }
// val field = WasmStructField("TODO", wasmElemTy, isMutable = false)
// val arrayTySym =
// context.gcTypes.define(WasmArrayType(Names.WasmGCTypeName.fromIR(tpe), field))
// Types.WasmRefType(Types.WasmHeapType.Type(arrayTySym))
???
case clazz @ IRTypes.ClassType(className) =>
className match {
case _ =>
val info = ctx.getClassInfo(clazz.className)
if (info.isAncestorOfHijackedClass)
Types.WasmAnyRef
else if (info.isInterface)
Types.WasmRefNullType(Types.WasmHeapType.ObjectType)
else
Types.WasmRefNullType(
Types.WasmHeapType.Type(Names.WasmTypeName.WasmStructTypeName(className))
)
}
case IRTypes.RecordType(fields) => ???
case tpe: IRTypes.ArrayType =>
Types.WasmRefNullType(
Types.WasmHeapType.Type(Names.WasmTypeName.WasmArrayTypeName(tpe))
)
case IRTypes.ClassType(className) => transformClassByName(className)
case IRTypes.RecordType(fields) => ???
case IRTypes.StringType | IRTypes.UndefType =>
Types.WasmRefType.any
case p: IRTypes.PrimTypeWithRef => transformPrimType(p)
}

def transformPrimType(
private def transformClassByName(
className: IRNames.ClassName
)(implicit ctx: ReadOnlyWasmContext): Types.WasmType = {
className match {
case _ =>
val info = ctx.getClassInfo(className)
if (info.isAncestorOfHijackedClass)
Types.WasmAnyRef
else if (info.isInterface)
Types.WasmRefNullType(Types.WasmHeapType.ObjectType)
else
Types.WasmRefNullType(
Types.WasmHeapType.Type(Names.WasmTypeName.WasmStructTypeName(className))
)
}
}

private def transformPrimType(
t: IRTypes.PrimTypeWithRef
): Types.WasmType =
t match {
Expand Down
Loading

0 comments on commit 07ac844

Please sign in to comment.