GitLab will be upgraded to the 12.10.14-ce.0 on 28 Sept 2020 at 2.00pm (AEDT) to 2.30pm (AEDT). During the update, GitLab and Mattermost services will not be available. If you have any concerns with this, please talk to us at N110 (b) CSIT building.

Commit fea12c70 authored by Kunshan Wang's avatar Kunshan Wang

Fixed gc, sum, big tests.

parent 76a66fcf
......@@ -7,5 +7,10 @@ $SED -i 's/NEWSTACK\s*<\(@\w\+\)>\s*\(@\w\+\)/COMMINST @uvm.new_stack <[\1]> (\2
$SED -i 's/COMMINST\s*@uvm\.new_thread\s*(\([@%]\w\+\))/NEWTHREAD \1 PASS_VALUES /g' $FN
$SED -i 's/TRAP\s*<@void>/TRAP <>/g' $FN
$SED -i 's/noparamsnoret/v_v/g' $FN
$SED -i 's/@void\s*(\([^)]*\))/(\1) -> ()/g' $FN
#$SED -i 's/@void\s*(\([^)]*\))/(\1) -> ()/g' $FN
$SED -i '/\.funcsig/ {s/=\s*\(@\w\+\)\s*(\([^)]*\))/= (\2) -> (\1)/}' $FN
$SED -i 's/@funcdumb/@frv_v/g' $FN
$SED -i 's/@i_ii/@ii_i/g' $FN
$SED -i 's/RET @VOID/RET ()/g' $FN
$SED -i 's/hybrid\s*<@void\s*/hybrid</g' $FN
......@@ -84,7 +84,7 @@ class GlobalBundle extends Bundle {
case e: NameConflictException =>
throw new IllegalRedefinitionException(
"Redefinition of type, function signature, constant or" +
" global cell is not allowed", e);
" global cell is not allowed: %s".format(cand.repr), e);
}
}
}
......
......@@ -116,7 +116,13 @@ trait InterpreterThreadState {
protected def resultBoxes: Seq[ValueBox] = curInst.results.map(boxOf)
/** Get one result box of the current instruction. */
protected def resultBox(index: Int): ValueBox = boxOf(curInst.results(index))
protected def resultBox(index: Int): ValueBox = try {
boxOf(curInst.results(index))
} catch {
case e: IndexOutOfBoundsException => throw new UvmRefImplException(
"Instruction %s is declared to have only %d results. Result %d is requested.".format(
curInst, curInst.results.length, index), e)
}
}
/**
......
......@@ -21,25 +21,34 @@ object MemoryDataScanner extends StrictLogging {
val tag = HeaderUtils.getTag(objRef)
logger.debug("Obj 0x%x, tag 0x%x".format(objRef, tag))
val ty = HeaderUtils.getType(microVM, tag)
logger.debug("Type: %s".format(ty.repr))
logger.debug {
if (ty.isInstanceOf[TypeHybrid]) {
val len = HeaderUtils.getVarLength(objRef)
val size = TypeSizes.hybridSizeOf(ty.asInstanceOf[TypeHybrid], len)
"Type: %s, varLen: %d, hybridSizeOf: %d".format(ty.repr, len, size)
} else {
"Type: %s".format(ty.repr)
}
}
scanField(ty, objRef, objRef, handler)
}
def scanField(ty: Type, objRef: Word, iRef: Word, handler: RefFieldHandler)(implicit microVM: MicroVM, memorySupport: MemorySupport) {
def logField(kind: String, toObj: Word): String = "%s field [0x%x + 0x%x] = 0x%x -> 0x%x".format(kind, objRef, iRef - objRef, iRef, toObj)
ty match {
case t: TypeRef => {
val toObj = memorySupport.loadLong(iRef)
logger.debug(s"Ref field ${iRef} -> ${toObj}")
logger.debug(logField("Ref", toObj))
handler.memToHeap(objRef, iRef, toObj, false, false)
}
case t: TypeIRef => {
val toObj = memorySupport.loadLong(iRef)
logger.debug(s"IRef field ${iRef} -> ${toObj}")
logger.debug(logField("IRef", toObj))
handler.memToHeap(objRef, iRef, toObj, false, false)
}
case t: TypeWeakRef => {
val toObj = memorySupport.loadLong(iRef)
logger.debug(s"WeakRef field ${iRef} -> ${toObj}")
logger.debug(logField("WeakRef", toObj))
handler.memToHeap(objRef, iRef, toObj, true, false)
}
case t: TypeTagRef64 => {
......@@ -47,16 +56,16 @@ object MemoryDataScanner extends StrictLogging {
if (paranoiaLogger.underlying.isDebugEnabled()) {
paranoiaLogger.debug(s"Tagref bits ${bits}")
if (OpHelper.tr64IsFp(bits)) {
paranoiaLogger.debug(s"Tagref is FP: ${OpHelper.tr64ToFp(bits)}")
paranoiaLogger.debug("Tagref is FP: %f".format(OpHelper.tr64ToFp(bits)))
} else if (OpHelper.tr64IsInt(bits)) {
paranoiaLogger.debug(s"Tagref is Int: ${OpHelper.tr64ToInt(bits)}")
paranoiaLogger.debug("Tagref is Int: %d".format(OpHelper.tr64ToInt(bits)))
} else if (OpHelper.tr64IsRef(bits)) {
paranoiaLogger.debug(s"Tagref is Ref: ${OpHelper.tr64ToRef(bits)} tag: ${OpHelper.tr64ToTag(bits)}")
paranoiaLogger.debug("Tagref is Ref: 0x%x tag: %d".format(OpHelper.tr64ToRef(bits), OpHelper.tr64ToTag(bits)))
}
}
if (OpHelper.tr64IsRef(bits)) {
val toObj = OpHelper.tr64ToRef(bits)
logger.debug(s"TagRef64 field ${iRef} -> ${toObj} tag: ${OpHelper.tr64ToTag(bits)}")
logger.debug(logField("TagRef64", toObj))
handler.memToHeap(objRef, iRef, toObj, false, true)
}
}
......@@ -92,9 +101,10 @@ object MemoryDataScanner extends StrictLogging {
scanField(fieldTy, objRef, curAddr, handler)
curAddr += TypeSizes.sizeOf(fieldTy)
}
curAddr = TypeSizes.alignUp(curAddr, varAlign)
for (i <- 0L until varLength) {
curAddr = TypeSizes.alignUp(curAddr + varSize, varAlign)
scanField(varTy, objRef, curAddr, handler)
curAddr = TypeSizes.alignUp(curAddr + varSize, varAlign)
}
}
case t: TypeStackRef => {
......
......@@ -45,6 +45,8 @@ case class InstResult(inst: Instruction, index: Int) extends LocalVariable
abstract class Instruction extends IdentifiedSettable {
var results: Seq[InstResult] = Seq()
override def toString = "%s %s".format(this.repr, this.getClass.getSimpleName)
}
/// enumerations
......
......@@ -19,7 +19,7 @@ class UvmInterpreterGCTests extends UvmBundleTesterBase {
"uvm.refimpl.itpr" -> DEBUG,
"uvm.refimpl.mem" -> DEBUG)
preloadBundles("tests/uvm-refimpl-test/gc-tests.uir")
preloadBundles("tests/uvm-refimpl-test/primitives.uir", "tests/uvm-refimpl-test/gc-tests.uir")
def gc() = microVM.memoryManager.heap.mutatorTriggerAndWaitForGCEnd(false)
......@@ -40,176 +40,176 @@ class UvmInterpreterGCTests extends UvmBundleTesterBase {
}
"The memory manager" should "retain global reference between gc." in {
val ca = microVM.newClientAgent()
val ctx = microVM.newContext()
val func = ca.putFunction("@keepglobal")
testFunc(ca, func, Seq()) { (ca, th, st, wp) =>
nameOf(ca.currentInstruction(st, 0)) match {
val func = ctx.handleFromFunc("@keepglobal")
testFunc(ctx, func, Seq()) { (ctx, th, st, wp) =>
nameOf(ctx.curInst(st, 0)) match {
case "@keepglobal_v1.entry.gctrap" => {
gc()
TrapRebindPassVoid(st)
returnFromTrap(st)
}
case "@keepglobal_v1.entry.checktrap" => {
val Seq(obj2, obj2val) = ca.dumpKeepalives(st, 0)
val Seq(obj2, obj2val) = ctx.dumpKeepalives(st, 0)
obj2.vb.asRef shouldNot be(0L)
obj2val.vb.asSInt(64) shouldBe 42
TrapRebindPassVoid(st)
returnFromTrap(st)
}
}
}
ca.close()
ctx.closeContext()
}
"The memory manager" should "not retain references in dead alloca cells between gc." in {
val ca = microVM.newClientAgent()
val ctx = microVM.newContext()
val func = ca.putFunction("@nokeepalloca")
testFunc(ca, func, Seq()) { (ca, th, st, wp) =>
nameOf(ca.currentInstruction(st, 0)) match {
val func = ctx.handleFromFunc("@nokeepalloca")
testFunc(ctx, func, Seq()) { (ctx, th, st, wp) =>
nameOf(ctx.curInst(st, 0)) match {
case "@nokeepalloca_v1.entry.gctrap" => {
gc()
TrapRebindPassVoid(st)
returnFromTrap(st)
}
case "@allocatest_v1.entry.gctrap" => {
gc()
TrapRebindPassVoid(st)
returnFromTrap(st)
}
}
}
ca.close()
ctx.closeContext()
}
"The large object space" should "withstand repeated non-retained allocations" in {
val ca = microVM.newClientAgent()
val ctx = microVM.newContext()
quiet {
val func = ca.putFunction("@crazy_allocation_test")
testFunc(ca, func, Seq()) { (ca, th, st, wp) =>
val func = ctx.handleFromFunc("@crazy_allocation_test")
testFunc(ctx, func, Seq()) { (ctx, th, st, wp) =>
fail("No traps in this test")
}
}
ca.close()
ctx.closeContext()
gc()
}
"The small object space" should "withstand repeated fragmented allocations" in {
val ca = microVM.newClientAgent()
val ctx = microVM.newContext()
quiet {
val func = ca.putFunction("@breadcrumbs")
testFunc(ca, func, Seq()) { (ca, th, st, wp) =>
val func = ctx.handleFromFunc("@breadcrumbs")
testFunc(ctx, func, Seq()) { (ctx, th, st, wp) =>
fail("No traps in this test")
}
}
ca.close()
ctx.closeContext()
gc()
}
"The garbage collector" should "nullify weak references if there is no strong references to the referent" in {
val ca = microVM.newClientAgent()
val ctx = microVM.newContext()
val func = ca.putFunction("@testweakref")
testFunc(ca, func, Seq()) { (ca, th, st, wp) =>
nameOf(ca.currentInstruction(st, 0)) match {
val func = ctx.handleFromFunc("@testweakref")
testFunc(ctx, func, Seq()) { (ctx, th, st, wp) =>
nameOf(ctx.curInst(st, 0)) match {
case "@testweakref_v1.entry.gctrap" => {
gc()
TrapRebindPassVoid(st)
returnFromTrap(st)
}
case "@peekweakref_v1.entry.checknztrap" => {
val Seq(refval) = ca.dumpKeepalives(st, 0)
val Seq(refval) = ctx.dumpKeepalives(st, 0)
refval.vb.asRef shouldNot be(0L)
TrapRebindPassVoid(st)
returnFromTrap(st)
}
case "@testweakref_v1.entry.checkztrap" => {
val Seq(refval) = ca.dumpKeepalives(st, 0)
val Seq(refval) = ctx.dumpKeepalives(st, 0)
refval.vb.asRef should be(0L)
TrapRebindPassVoid(st)
returnFromTrap(st)
}
}
}
ca.close()
ctx.closeContext()
gc()
}
"The garbage collector" should "treat tagref64 as reference when it actually is" in {
val ca = microVM.newClientAgent()
val ctx = microVM.newContext()
val func = ca.putFunction("@testtagrefgc")
testFunc(ca, func, Seq()) { (ca, th, st, wp) =>
nameOf(ca.currentInstruction(st, 0)) match {
val func = ctx.handleFromFunc("@testtagrefgc")
testFunc(ctx, func, Seq()) { (ctx, th, st, wp) =>
nameOf(ctx.curInst(st, 0)) match {
case "@testtagrefgc_v1.entry.gctrap" => {
gc()
TrapRebindPassVoid(st)
returnFromTrap(st)
}
case "@testtagrefgc_v1.entry.checktrap" => {
val Seq(tr, refv, tagv, iv) = ca.dumpKeepalives(st, 0)
val Seq(tr, refv, tagv, iv) = ctx.dumpKeepalives(st, 0)
ca.toInt(tagv) shouldBe 13
ca.toInt(iv) shouldBe 42
ctx.handleToUInt(tagv.asInstanceOf[MuIntValue]) shouldBe 13
ctx.handleToUInt(iv.asInstanceOf[MuIntValue]) shouldBe 42
TrapRebindPassVoid(st)
returnFromTrap(st)
}
}
}
ca.close()
ctx.closeContext()
gc()
}
"The garbage collector" should "scan tagref64 references in the memory" in {
val ca = microVM.newClientAgent()
val ctx = microVM.newContext()
val func = ca.putFunction("@testtagrefgcmem")
testFunc(ca, func, Seq()) { (ca, th, st, wp) =>
nameOf(ca.currentInstruction(st, 0)) match {
val func = ctx.handleFromFunc("@testtagrefgcmem")
testFunc(ctx, func, Seq()) { (ctx, th, st, wp) =>
nameOf(ctx.curInst(st, 0)) match {
case "@testtagrefgcmem_v1.entry.gctrap" => {
gc()
TrapRebindPassVoid(st)
returnFromTrap(st)
}
case "@testtagrefgcmem_v1.entry.checktrap" => {
val Seq(tr, refv, tagv, iv) = ca.dumpKeepalives(st, 0)
val Seq(tr, refv, tagv, iv) = ctx.dumpKeepalives(st, 0)
ca.toInt(tagv) shouldBe 13
ca.toInt(iv) shouldBe 42
ctx.handleToUInt(tagv.asInstanceOf[MuIntValue]) shouldBe 13
ctx.handleToUInt(iv.asInstanceOf[MuIntValue]) shouldBe 42
TrapRebindPassVoid(st)
returnFromTrap(st)
}
}
}
ca.close()
ctx.closeContext()
gc()
}
"The small object space" should "withstand repeated fragmented allocations when objects are referred by tagref64" in {
val ca = microVM.newClientAgent()
val ctx = microVM.newContext()
quiet {
val func = ca.putFunction("@breadcrumbstr64")
testFunc(ca, func, Seq()) { (ca, th, st, wp) =>
val func = ctx.handleFromFunc("@breadcrumbstr64")
testFunc(ctx, func, Seq()) { (ctx, th, st, wp) =>
fail("No traps in this test")
}
}
ca.close()
ctx.closeContext()
gc()
}
......
package uvm.refimpl.itpr
import org.scalatest._
import java.io.FileReader
import ch.qos.logback.classic.Level._
import uvm._
import uvm.types._
import uvm.ssavariables._
import uvm.refimpl._
import uvm.refimpl.itpr._
import MemoryOrder._
import AtomicRMWOptr._
import uvm.refimpl.mem.TypeSizes.Word
import ch.qos.logback.classic.Level._
import uvm.refimpl.UvmBundleTesterBase
import uvm.refimpl.itpr._
import uvm.ssavariables._
import uvm.ssavariables.AtomicRMWOptr._
import uvm.ssavariables.MemoryOrder._
import uvm.types._
class UvmInterpreterSimpleSumTest extends UvmBundleTesterBase {
setLogLevels(
......@@ -22,39 +21,39 @@ class UvmInterpreterSimpleSumTest extends UvmBundleTesterBase {
"tests/uvm-refimpl-test/simple-sum.uir")
"Simple sum" should "work" in {
val ca = microVM.newClientAgent()
val ctx = microVM.newContext()
val from = 1L
val to = 1000000L
val expectedSum = (from + to) * (to - from + 1L) / 2L
val hFrom = ca.putInt("@i64", from)
val hTo = ca.putInt("@i64", to)
val hFrom = ctx.handleFromInt64(from)
val hTo = ctx.handleFromInt64(to)
val func = ca.putFunction("@simplesum")
val func = ctx.handleFromFunc("@simplesum")
var t1: Long = 0L
var t2: Long = 0L
testFunc(ca, func, Seq(hFrom, hTo)) { (ca, th, st, wp) =>
nameOf(ca.currentInstruction(st, 0)) match {
testFunc(ctx, func, Seq(hFrom, hTo)) { (ctx, th, st, wp) =>
nameOf(ctx.curInst(st, 0)) match {
case "@simplesum_v1.entry.starttrap" => {
t1 = System.currentTimeMillis()
TrapRebindPassVoid(st)
returnFromTrap(st)
}
case "@simplesum_v1.exit.exittrap" => {
t2 = System.currentTimeMillis()
val Seq(sum) = ca.dumpKeepalives(st, 0)
val Seq(sum) = ctx.dumpKeepalives(st, 0)
sum.vb.asSInt(64) shouldBe expectedSum
TrapRebindPassVoid(st)
returnFromTrap(st)
}
}
}
ca.close()
ctx.closeContext()
val timeDiff = t2 - t1
printf("Time: %d ms".format(timeDiff))
......
......@@ -19,7 +19,7 @@ class UvmInterpreterStackGCTests extends UvmBundleTesterBase {
"uvm.refimpl.itpr" -> DEBUG,
"uvm.refimpl.mem" -> DEBUG)
preloadBundles("tests/uvm-refimpl-test/gc-tests.uir")
preloadBundles("tests/uvm-refimpl-test/primitives.uir", "tests/uvm-refimpl-test/gc-tests.uir")
def gc() = microVM.memoryManager.heap.mutatorTriggerAndWaitForGCEnd(false)
......@@ -43,20 +43,20 @@ class UvmInterpreterStackGCTests extends UvmBundleTesterBase {
override def makeMicroVM = new MicroVM(heapSize = 2L * 1024L * 1024L, stackSize = 63L * 1024L)
"The memory manager" should "collect unreachable stacks." in {
val ca = microVM.newClientAgent()
val ctx = microVM.newContext()
val nStacks = ca.putInt("@i64", 13)
val nStacks = ctx.handleFromInt64( 13)
val func = ca.putFunction("@stackcollecttest")
testFunc(ca, func, Seq(nStacks)) { (ca, th, st, wp) =>
nameOf(ca.currentInstruction(st, 0)) match {
val func = ctx.handleFromFunc("@stackcollecttest")
testFunc(ctx, func, Seq(nStacks)) { (ctx, th, st, wp) =>
nameOf(ctx.curInst(st, 0)) match {
case "@stackcollecttest_v1.endloop.trap" => {
gc()
TrapRebindPassVoid(st)
returnFromTrap(st)
}
}
}
ca.close()
ctx.closeContext()
}
}
\ No newline at end of file
......@@ -22,56 +22,55 @@ class UvmInterpreterTestBigFunc extends UvmBundleTesterBase {
preloadBundles("tests/uvm-refimpl-test/extra-big-func.uir")
"The extra big function" should "execute properly" in {
val ca = microVM.newClientAgent()
val ctx = microVM.newContext()
val func = ca.putFunction("@big")
val hParam = ca.putInt("@i64", 0)
val func = ctx.handleFromFunc("@big")
val hParam = ctx.handleFromInt64(0)
testFunc(ca, func, Seq(hParam)) { (ca, th, st, wp) =>
val Seq(i) = ca.dumpKeepalives(st, 0)
testFunc(ctx, func, Seq(hParam)) { (ctx, th, st, wp) =>
val Seq(i) = ctx.dumpKeepalives(st, 0)
ca.toInt(i, true) shouldEqual 200
ctx.handleToSInt(i.asInstanceOf[MuIntValue]) shouldEqual 200
TrapRebindPassVoid(st)
returnFromTrap(st)
}
ca.close()
ctx.closeContext()
}
"The Micro VM" should "sustain frequent bundle loading" in {
val ca = microVM.newClientAgent()
for(i <- 0 until 1000) {
val ctx = microVM.newContext()
for (i <- 0 until 1000) {
val miniBundle = s".global @h${i} <@i64>"
ca.loadBundle(miniBundle)
ctx.loadBundle(miniBundle)
}
val sb = new StringBuilder()
sb ++= ".funcdef @bigger VERSION @bigger.v1 <@big.sig> {\n"
sb ++= " %entry(<@i64> %p):\n"
for(i <- 0 until 1000) {
sb ++= s" %r${i} = STORE <@i64> @h${i} %p\n"
for (i <- 0 until 1000) {
sb ++= s" [%s${i}] STORE <@i64> @h${i} %p\n"
}
sb ++= " TRAP <@void>\n"
sb ++= " TRAP <>\n"
sb ++= " COMMINST @uvm.thread_exit\n"
sb ++= "}"
ca.loadBundle(sb.toString())
val func = ca.putFunction("@bigger")
val hParam = ca.putInt("@i64", 42)
testFunc(ca, func, Seq(hParam)) { (ca, th, st, wp) =>
val hr = ca.putGlobal("@h12")
val hv = ca.load(MemoryOrder.NOT_ATOMIC, hr)
val v = ca.toInt(hv, true).toInt
ctx.loadBundle(sb.toString())
val func = ctx.handleFromFunc("@bigger")
val hParam = ctx.handleFromInt64(42)
testFunc(ctx, func, Seq(hParam)) { (ctx, th, st, wp) =>
val hr = ctx.handleFromGlobal("@h12")
val hv = ctx.load(MemoryOrder.NOT_ATOMIC, hr)
val v = ctx.handleToSInt(hv.asInstanceOf[MuIntValue]).toInt
v shouldEqual 42
TrapRebindPassVoid(st)
returnFromTrap(st)
}
ca.close()
ctx.closeContext()
}
}
\ No newline at end of file
.typedef @i64 = int<64>
.typedef @void = void
.const @I64_1 <@i64> = 1
......@@ -105,7 +104,7 @@
.global @g99 <@i64>
.funcsig @big.sig = @void (@i64)
.funcsig @big.sig = (@i64) -> ()
.funcdef @big VERSION @big_v1 <@big.sig> {
%entry(<@i64> %p):
%i0 = ADD <@i64> %p @I64_1
......@@ -339,6 +338,6 @@
%r28 = LOAD <@i64> @g28
%r29 = LOAD <@i64> @g29
%trap = TRAP <@void> KEEPALIVE (%i199)
[%trap] TRAP <> KEEPALIVE (%i199)
COMMINST @uvm.thread_exit
}
.typedef @i8 = int<8>
.typedef @i16 = int<16>
.typedef @i32 = int<32>
.typedef @i64 = int<64>
.typedef @float = float
.typedef @double = double
.typedef @void = void
.funcsig @noparamsnoret = @void ()
.typedef @funcdumb = funcref<@noparamsnoret>
.typedef @thread = threadref
.typedef @stack = stackref
.typedef @tagref64 = tagref64
.const @TRUE <@i64> = 1
.const @FALSE <@i64> = 0
.const @I32_0 <@i32> = 0
.const @I32_1 <@i32> = 1
.const @I32_2 <@i32> = 2
.const @I32_3 <@i32> = 3
.const @I32_4 <@i32> = 4
.const @I32_5 <@i32> = 5
.const @I32_6 <@i32> = 6
.const @I32_7 <@i32> = 7
.const @I64_0 <@i64> = 0
.const @I64_1 <@i64> = 1
.const @I64_2 <@i64> = 2
.const @I64_3 <@i64> = 3
.const @I64_4 <@i64> = 4
.const @I64_5 <@i64> = 5
.const @I64_6 <@i64> = 6
.const @I64_7 <@i64> = 7
// require "primitives.uir"
.const @I64_42 <@i64> = 42
.const @I64_1024 <@i64> = 1024
.const @I64_30000 <@i64> = 30000
.const @F_0 <@float> = 0.0f
.const @F_1 <@float> = 1.0f
.const @F_2 <@float> = 2.0f
.const @F_3 <@float> = 3.0f
.const @F_4 <@float> = 4.0f
.const @F_5 <@float> = 5.0f
.const @F_6 <@float> = 6.0f
.const @F_7 <@float> = 7.0f
.const @D_0 <@double> = 0.0d
.const @D_1 <@double> = 1.0d
.const @D_2 <@double> = 2.0d
.const @D_3 <@double> = 3.0d
.const @D_4 <@double> = 4.0d
.const @D_5 <@double> = 5.0d
.const @D_6 <@double> = 6.0d
.const @D_7 <@double> = 7.0d
.funcsig @i_ii = @i64 (@i64 @i64)
.typedef @refvoid = ref<@void>
.typedef @irefvoid = iref<@void>
.typedef @weakrefvoid = weakref<@void>
.const @NULLREF <@refvoid> = NULL
.const @VOID <@void> = NULL
.typedef @StructFoo = struct <@i32 @i64 @float @double>
.const @STRUCT_FOO <@StructFoo> = {@I32_1 @I64_2 @F_3 @D_4}
.typedef @refi64 = ref<@i64>
.typedef @irefi64 = iref<@i64>
.typedef @weakrefi64 = weakref<@i64>
.typedef @StructBar = struct <
@i64 @i32 @i16 @i8 @float @double
@refi64 @irefi64 @weakrefi64
......@@ -98,60 +32,58 @@
.global @g_ir <@irefvoid>
.global @g_wr <@weakrefvoid>
.global @g_func <@funcdumb>
.global @g_func <@frv_v>
.global @g_thr <@thread>
.global @g_sta <@stack>
.global @g_tr64 <@tagref64>
.const @RI64_NULL <@refi64> = NULL
.global @g_refi64 <@refi64>