GitLab will be upgraded on June 2nd 2020 at 2.00 pm (AEDT) to 3.00 pm (AEDT) due to Critical Security Patch Availability. During the update, GitLab and Mattermost services will not be available. If you have any concerns with this, please talk to local Gitlab admin team.

Commit 96c3d9db authored by Kunshan Wang's avatar Kunshan Wang

Consider multi-bundle loading.

parent ea6be94b
......@@ -7,7 +7,38 @@ class Bundle {
val typeNs = new SimpleNamespace[Type]()
val funcSigNs = new SimpleNamespace[FuncSig]()
val declConstNs = new SimpleNamespace[DeclaredConstant]()
val globalDataNS = new SimpleNamespace[GlobalData]()
val globalDataNs = new SimpleNamespace[GlobalData]()
val funcNs = new SimpleNamespace[Function]()
val globalValueNS = new SimpleNamespace[GlobalValue]()
val globalValueNs = new SimpleNamespace[GlobalValue]()
private def simpleMerge[T <: Identified](oldNs: Namespace[T], newNs: Namespace[T]) {
for (cand <- newNs.all) {
try {
oldNs.add(cand)
} catch {
case e: NameConflictException =>
throw new IllegalRedefinitionException(
"Redefinition of type, function signature, declared constant," +
" global data or global value is not allowed", e);
}
}
}
private def mergeFunc(oldNs: Namespace[Function], newNs: Namespace[Function]) {
for (cand <- newNs.all) {
val id = cand.id
oldNs.get(id) match {
case None => oldNs.add(cand)
case Some(oldObj) => oldObj.cfg = cand.cfg
}
}
}
def merge(newBundle: Bundle) {
simpleMerge(typeNs, newBundle.typeNs)
simpleMerge(funcSigNs, newBundle.funcSigNs)
simpleMerge(declConstNs, newBundle.declConstNs)
simpleMerge(globalDataNs, newBundle.globalDataNs)
simpleMerge(globalValueNs, newBundle.globalValueNs)
mergeFunc(funcNs, newBundle.funcNs)
}
}
......@@ -2,6 +2,10 @@ package uvm
class UvmException(message: String = null, cause: Throwable = null) extends RuntimeException(message, cause)
class TypeResolutionException(message: String = null, cause: Throwable = null) extends UvmException(message, cause)
class BundleLoadingException(message: String = null, cause: Throwable = null) extends UvmException(message, cause)
class NameConflictException(message: String = null, cause: Throwable = null) extends UvmException(message, cause)
\ No newline at end of file
class TypeResolutionException(message: String = null, cause: Throwable = null) extends BundleLoadingException(message, cause)
class IllegalRedefinitionException(message: String = null, cause: Throwable = null) extends BundleLoadingException(message, cause)
class NameConflictException(message: String = null, cause: Throwable = null) extends UvmException(message, cause)
......@@ -5,17 +5,17 @@ import uvm.types._
import uvm.ssavalues._
import uvm.ifuncs._
object UvmIRReader {
object UvmIRReader {
import UvmIRAST._
def read(ir: CharSequence): Bundle = {
def read(ir: CharSequence, globalBundle: Bundle): Bundle = {
val ast = UvmIRParser(ir)
read(ast)
read(ast, globalBundle)
}
def read(ir: java.io.Reader): Bundle = {
def read(ir: java.io.Reader, globalBundle: Bundle): Bundle = {
val ast = UvmIRParser(ir)
read(ast)
read(ast, globalBundle)
}
object IDFactory {
......@@ -57,13 +57,13 @@ object UvmIRReader {
}
}
def read(ir: IR): Bundle = {
def read(ir: IR, globalBundle: Bundle): Bundle = {
val bundle = new Bundle()
val phase1 = new Later()
def resTy(te: TypeExpr): Type = te match {
case ReferredType(g) => bundle.typeNs(g.name)
case ReferredType(g) => bundle.typeNs.get(g.name).getOrElse(globalBundle.typeNs(g.name))
case tc: TypeCons => mkType(tc)
}
......@@ -90,7 +90,7 @@ object UvmIRReader {
}
def resSig(se: FuncSigExpr): FuncSig = se match {
case ReferredFuncSig(g) => bundle.funcSigNs(g.name)
case ReferredFuncSig(g) => bundle.funcSigNs.get(g.name).getOrElse(globalBundle.funcSigNs(g.name))
case FuncSigCons(r, ps) => mkSig(r, ps)
}
......@@ -122,7 +122,7 @@ object UvmIRReader {
val phase2 = new Later()
def resGV(t: Type, ce: ConstExpr): GlobalValue = ce match {
case ReferredConst(g) => bundle.globalValueNS(g.name)
case ReferredConst(g) => bundle.globalValueNs.get(g.name).getOrElse(globalBundle.globalValueNs(g.name))
case c: ConstCons => mkConst(t, c)
}
......@@ -161,16 +161,23 @@ object UvmIRReader {
val fc = ConstFunc(func)
return fc
}
def tryReuseFuncID(name: String): Option[Int] = {
globalBundle.funcNs.get(name).map(_.id)
}
def declFunc(n: GID, s: FuncSigExpr): Function = {
val sig = resSig(s)
val func = mkFunc(sig)
func.id = IDFactory.getID()
val maybeOldID = tryReuseFuncID(n.name)
func.id = maybeOldID.getOrElse(IDFactory.getID())
func.name = Some(n.name)
bundle.funcNs.add(func)
val fc = mkFuncConst(func)
bundle.globalValueNS.add(fc)
if (maybeOldID == None) {
val fc = mkFuncConst(func)
bundle.globalValueNs.add(fc)
}
return func
}
......@@ -183,16 +190,16 @@ object UvmIRReader {
val con = mkConst(ty, c)
con.name = Some(n.name)
bundle.declConstNs.add(con)
bundle.globalValueNS.add(con)
bundle.globalValueNs.add(con)
}
case GlobalDataDef(n, t) => {
val ty = resTy(t)
val gd = mkGlobalData(ty)
gd.name = Some(n.name)
bundle.globalDataNS.add(gd)
bundle.globalDataNs.add(gd)
val gdc = mkGlobalDataConst(gd)
bundle.globalValueNS.add(gdc)
bundle.globalValueNs.add(gdc)
}
case FuncDecl(n, s) => {
declFunc(n, s)
......@@ -245,7 +252,7 @@ object UvmIRReader {
def resVal(ty: Option[Type], ve: ValueExpr): Value = ve match {
case RefValue(id) => id match {
case GID(n) => bundle.globalValueNS(n)
case GID(n) => bundle.globalValueNs(n)
case LID(n) => cfg.lvNs(n)
}
case InlineValue(cc) => ty match {
......
......@@ -5,27 +5,37 @@ import uvm._
trait AbstractReaderSpec extends FlatSpec with Matchers
with TestingBundlesValidators {
def parseFile(fileName: String): Bundle
val EMPTY_BUNDLE = new Bundle()
def parseFile(fileName: String, globalBundle: Bundle): Bundle
def theSubject: String
behavior of theSubject
it should "read simple type definitions" in {
val b = parseFile("tests/uvm-parsing-test/types.uir")
val b = parseFile("tests/uvm-parsing-test/types.uir", EMPTY_BUNDLE)
validateTypes(b)
}
it should "read simple constant definitions" in {
val b = parseFile("tests/uvm-parsing-test/constants.uir")
val b = parseFile("tests/uvm-parsing-test/constants.uir", EMPTY_BUNDLE)
validateConstants(b)
}
it should "read simple function definitions" in {
val b = parseFile("tests/uvm-parsing-test/functions.uir")
val b = parseFile("tests/uvm-parsing-test/functions.uir", EMPTY_BUNDLE)
validateFunctions(b)
}
it should "read simple instruction definitions" in {
val b = parseFile("tests/uvm-parsing-test/instructions.uir")
val b = parseFile("tests/uvm-parsing-test/instructions.uir", EMPTY_BUNDLE)
validateInstructions(b)
}
it should "handle loading of multiple bundles" in {
val gb = parseFile("tests/uvm-parsing-test/redef-base.uir", EMPTY_BUNDLE)
val b = parseFile("tests/uvm-parsing-test/redef-overlay.uir", gb)
validateRedef(gb, b)
gb.merge(b)
validateRedefAfterMerge(gb, b)
}
}
\ No newline at end of file
......@@ -11,9 +11,9 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
implicit class MagicalOur(b: Bundle) {
def ty = b.typeNs
def const = b.globalValueNS
def globalValue = b.globalValueNS
def globalData = b.globalDataNS
def const = b.globalValueNs
def globalValue = b.globalValueNs
def globalData = b.globalDataNs
def sig = b.funcSigNs
def func = b.funcNs
}
......@@ -1007,4 +1007,45 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
}
}
}
def validateRedef(globalBundle: Bundle, bundle: Bundle) {
val ourOld = globalBundle
val ourNew = bundle
in (ourOld func "@meaning_of_life") { (func, cfg) =>
val my = cfg
my inst "%ret" shouldBeA[InstRet] { _.retVal shouldBeAConstIntOf(64, 42) }
}
(ourOld func "@foxsay").cfg shouldBe None
(ourNew func "@meaning_of_life").id shouldEqual (ourOld func "@meaning_of_life").id
(ourNew func "@foxsay").id shouldEqual (ourOld func "@foxsay").id
in (ourNew func "@meaning_of_life") { (func, cfg) =>
val my = cfg
my inst "%ret" shouldBeA[InstRet] { its =>
its.retTy shouldBe (ourOld ty "@i64")
its.retVal shouldBeAConstIntOf(64, 43)
}
}
(ourNew func "@foxsay").cfg shouldNot be(None)
in (ourNew func "@foxsay") { (func, cfg) =>
val my = cfg
my inst "%ret" shouldBeA[InstRet] { _.retVal shouldBeAConstIntOf(64, 99) }
}
}
def validateRedefAfterMerge(globalBundle: Bundle, bundle: Bundle) {
val ourGlobal = globalBundle
val ourNew = bundle
(ourGlobal func "@foxsay").cfg shouldBe (ourNew func "@foxsay").cfg
(ourGlobal func "@meaning_of_life").cfg shouldBe (ourNew func "@meaning_of_life").cfg
}
}
\ No newline at end of file
......@@ -8,8 +8,8 @@ class UvmIRReaderSpec extends AbstractReaderSpec {
override def theSubject = "UvmIRReader"
override def parseFile(fileName: String): Bundle = {
UvmIRReader.read(new java.io.FileReader(fileName))
override def parseFile(fileName: String, globalBundle: Bundle): Bundle = {
UvmIRReader.read(new java.io.FileReader(fileName), globalBundle)
}
......
.typedef @i64 = int<64>
.funcsig @IntReturner = @i64 ()
.funcdef @meaning_of_life <@IntReturner> () {
%ret = RET <@i64> 42
}
.funcdecl @foxsay <@IntReturner>
.funcdef @foxsay <@IntReturner> () {
%ret = RET <@i64> 99
}
.funcdef @meaning_of_life <@IntReturner> () {
%ret = RET <@i64> 43
}
......@@ -9,12 +9,20 @@
.funcsig @noparamsnoret = @void ()
.typedef @funcdumb = func<@noparamsnoret>
.typedef @thread = thread
.typedef @stack = stack
.typedef @tagref64 = tagref64
.const @TRUE <@i64> = 1
.const @FALSE <@i64> = 0
.funcsig @i_ii = @i64 (@i64 @i64)
.typedef @refvoid = ref<@void>
.typedef @irefvoid = iref<@void>
.typedef @weakrefvoid = weakref<@void>
.const @NULLREF <@refvoid> = NULL
.funcdef @binops32 <@void (@i32 @i32)> (%p0 %p1) {
......@@ -351,6 +359,330 @@
THROW @NULLREF
}
.typedef @ArrayBaz = array <@i16 1024>
.const @THREE <@i64> = 3
.typedef @JavaLikeByteArray = hybrid <@i32 @i8>
.const @I64_1024 <@i64> = 1024
.funcdef @memAddressing <@noparamsnoret> () {
%bar_ref = NEW <@StructBar>
%bar_iref = GETIREF <@StructBar> %bar_ref
%bar_3 = GETFIELDIREF <@StructBar 3> %bar_iref
%baz_iref = ALLOCA <@ArrayBaz>
%baz_3 = GETELEMIREF <@ArrayBaz> %baz_iref @THREE
%baz_6 = SHIFTIREF <@i16> %baz_3 @THREE
%ja_ref = NEWHYBRID <@JavaLikeByteArray> @I64_1024
%ja_iref = GETIREF <@JavaLikeByteArray> %ja_ref
%ja_fix = GETFIXEDPARTIREF <@JavaLikeByteArray> %ja_iref
%ja_var = GETVARPARTIREF <@JavaLikeByteArray> %ja_iref
%trap = TRAP <@void> %exit %exit KEEPALIVE (%bar_ref %bar_iref %bar_3
%baz_iref %baz_3 %baz_6 %ja_ref %ja_iref %ja_fix %ja_var)
%exit:
ICALL @uvm.thread_exit ()
THROW @NULLREF
}
.global @g_i8 <@i8>
.global @g_i16 <@i16>
.global @g_i32 <@i32>
.global @g_i64 <@i64>
.global @g_f <@float>
.global @g_d <@double>
.global @g_r <@refvoid>
.global @g_ir <@irefvoid>
.global @g_wr <@weakrefvoid>
.global @g_func <@funcdumb>
.global @g_thr <@thread>
.global @g_sta <@stack>
.global @g_tr64 <@tagref64>
.funcdef @memAccessing <@noparamsnoret> () {
STORE <@i8> @g_i8 41
STORE <@i16> @g_i16 42
STORE <@i32> @g_i32 43
STORE <@i64> @g_i64 44
STORE <@float> @g_f 45.0f
STORE <@double> @g_d 46.0d
%void_r = NEW <@void>
%void_ir = ALLOCA <@void>
STORE <@refvoid> @g_r %void_r
STORE <@irefvoid> @g_ir %void_ir
STORE <@weakrefvoid> @g_wr %void_r
STORE <@funcdumb> @g_func @memAccessing
%li8 = LOAD <@i8> @g_i8
%li16 = LOAD <@i16> @g_i16
%li32 = LOAD <@i32> @g_i32
%li64 = LOAD <@i64> @g_i64
%lf = LOAD <@float> @g_f
%ld = LOAD <@double> @g_d
%lr = LOAD <@refvoid> @g_r
%lir = LOAD <@irefvoid> @g_ir
%lwr = LOAD <@weakrefvoid> @g_wr
%lfunc = LOAD <@funcdumb> @g_func
%trap = TRAP <@void> %exit %exit KEEPALIVE (%void_r %void_ir %li8 %li16
%li32 %li64 %lf %ld %lr %lir %lwr %lfunc)
%exit:
ICALL @uvm.thread_exit ()
THROW @NULLREF
}
.funcdef @memAccessingAtomic <@noparamsnoret> () {
STORE SEQ_CST <@i32> @g_i32 43
STORE SEQ_CST <@i64> @g_i64 44
%void_r = NEW <@void>
%void_r2 = NEW <@void>
%void_r3 = NEW <@void>
STORE <@refvoid> @g_r %void_r
%cx32_1 = CMPXCHG SEQ_CST UNORDERED <@i32> @g_i32 43 53
%cx32_2 = CMPXCHG SEQ_CST UNORDERED <@i32> @g_i32 43 63
%cx64_1 = CMPXCHG SEQ_CST UNORDERED <@i64> @g_i64 44 54
%cx64_2 = CMPXCHG SEQ_CST UNORDERED <@i64> @g_i64 44 64
%l32 = LOAD SEQ_CST <@i32> @g_i32
%l64 = LOAD SEQ_CST <@i64> @g_i64
%cxr_1 = CMPXCHG SEQ_CST UNORDERED <@refvoid> @g_r %void_r %void_r2
%cxr_2 = CMPXCHG SEQ_CST UNORDERED <@refvoid> @g_r %void_r %void_r3
%lr = LOAD <@refvoid> @g_r
STORE <@i64> @g_i64 1
%rmw0 = ATOMICRMW SEQ_CST XCHG <@i64> @g_i64 0x55ab // 1 -> 0x55ab
%rmw1 = ATOMICRMW SEQ_CST ADD <@i64> @g_i64 3 // 0x55ab -> 0x55ae
%rmw2 = ATOMICRMW SEQ_CST SUB <@i64> @g_i64 4 // 0x55ae -> 0x55aa
%rmw3 = ATOMICRMW SEQ_CST AND <@i64> @g_i64 0x5a5a // 0x55aa -> 0x500a
%rmw4 = ATOMICRMW SEQ_CST NAND <@i64> @g_i64 0x5a5a // 0x500a -> ~0x500a
%rmw5 = ATOMICRMW SEQ_CST OR <@i64> @g_i64 0x5000 // ~0x500a -> ~0x000a
%rmw6 = ATOMICRMW SEQ_CST XOR <@i64> @g_i64 0x55aa // ~0x000a -> ~0x55a0
%rmw7 = ATOMICRMW SEQ_CST MIN <@i64> @g_i64 -0x7fffffffffffffde // ~0x55a0 -> -0x7fffffffffffffde
%rmw8 = ATOMICRMW SEQ_CST MAX <@i64> @g_i64 42 // -0x7fffffffffffffde -> 42
%rmw9 = ATOMICRMW SEQ_CST UMIN <@i64> @g_i64 11 // 42 -> 11
%rmwA = ATOMICRMW SEQ_CST UMAX <@i64> @g_i64 0xffffffffffffffde // 11 -> 0xffffffffffffffde
%l64_2 = LOAD SEQ_CST <@i64> @g_i64
%trap = TRAP <@void> %exit %exit KEEPALIVE (%void_r %void_r2 %void_r3
%cx32_1 %cx32_2 %cx64_1 %cx64_2 %l32 %l64 %cxr_1 %cxr_2 %lr
%rmw0 %rmw1 %rmw2 %rmw3 %rmw4 %rmw5 %rmw6 %rmw7 %rmw8 %rmw9 %rmwA %l64_2)
%exit:
ICALL @uvm.thread_exit ()
THROW @NULLREF
}
.funcdef @watchpointtest <@noparamsnoret> () {
BRANCH %head
%head:
%wp = WATCHPOINT 42 <@i64> %dis %ena %enaexc KEEPALIVE ()
%dis:
%trapdis = TRAP <@void> %exit %exit KEEPALIVE ()
%ena:
%trapena = TRAP <@void> %exit %exit KEEPALIVE (%wp)
%enaexc:
%exc = LANDINGPAD
%trapena = TRAP <@void> %exit %exit KEEPALIVE (%exc)
%exit:
ICALL @uvm.thread_exit ()
THROW @NULLREF
}
.funcdef @testswapstack <@noparamsnoret> () {
%valueret = ALLOCA <@i64>
%shouldstop = ALLOCA <@i64> // initially zeroed
%thisstack = ICALL @uvm.current_stack ()
%iter = NEWSTACK <@itersig> @rangeiter (3 %thisstack %valueret %shouldstop)
ICALL @uvm.swap_stack (%iter)
BRANCH %head
%head:
%value = LOAD <@i64> %valueret
%stop = LOAD <@i64> %shouldstop
TRAP <@void> %head2 %head2 KEEPALIVE (%value %stop)
%head2:
%eq = EQ <@i64> %stop 0
BRANCH2 %eq %body %exit
%body:
ICALL @uvm.swap_stack (%iter)
BRANCH %head
%exit:
ICALL @uvm.thread_exit ()
THROW @NULLREF
}
.typedef @irefi64 = iref<@i64>
.typedef @irefstack = iref<@stack>
.funcsig @itersig = @void (@i64 @stack @irefi64 @irefi64)
.funcdef @rangeiter <@itersig> (%n %src %valueret %shouldstop) {
%entry:
BRANCH %head
%head:
%i = PHI <@i64> {
%entry: 0;
%body: %i2;
}
%lt = SLT <@i64> %i %n
BRANCH2 %lt %body %exit
%body:
STORE <@i64> %valueret %i
ICALL @uvm.swap_stack (%src)
%i2 = ADD <@i64> %i 1
BRANCH %head
%exit:
STORE <@i64> %shouldstop 1
ICALL @uvm.swap_and_kill (%src)
THROW @NULLREF // unreachable
}
.const @I64_100 <@i64> = 100
.const @I64_50 <@i64> = 50
.const @I64_0 <@i64> = 0
.typedef @LongAry = hybrid <@void @i64>
.funcdef @testmultithreading <@noparamsnoret> () {
%entry:
%ary_r = NEWHYBRID <@LongAry> @I64_100
%ary_ir = GETIREF <@LongAry> %ary_r
%ary0_ir = GETVARPARTIREF <@LongAry> %ary_ir
BRANCH %head
%head:
%i = PHI <@i64> { %entry: 0; %body: %i2; }
%cmp = SLT <@i64> %i @I64_100
BRANCH2 %cmp %body %next
%body:
%aryi_ir = SHIFTIREF <@i64> %ary0_ir %i
STORE <@i64> %aryi_ir %i
%i2 = ADD <@i64> %i 1
BRANCH %head
%next:
%result0 = ALLOCA <@i64>
%sta0 = NEWSTACK <@summingslavesig> @summingslave (%ary0_ir @I64_50 %result0)
%result1 = ALLOCA <@i64>
%ary50_ir = SHIFTIREF <@i64> %ary0_ir @I64_50
%sta1 = NEWSTACK <@summingslavesig> @summingslave (%ary50_ir @I64_50 %result1)
%thr0 = ICALL @uvm.new_thread (%sta0)
%thr1 = ICALL @uvm.new_thread (%sta1)
BRANCH %wait0
%wait0:
%res0val = LOAD SEQ_CST <@i64> %result0
%cz0 = EQ <@i64> %res0val @I64_0
BRANCH2 %cz0 %wait0 %wait1
%wait1:
%res1val = LOAD SEQ_CST <@i64> %result1
%cz1 = EQ <@i64> %res1val @I64_0
BRANCH2 %cz1 %wait1 %getresult
%getresult:
%sum = ADD <@i64> %res0val %res1val
TRAP <@void> %exit %exit KEEPALIVE (%sum)
%exit:
ICALL @uvm.thread_exit ()
THROW @NULLREF
}
.funcsig @summingslavesig = @void (@irefi64 @i64 @irefi64)
.funcdef @summingslave <@summingslavesig> (%ary %sz %result) {
%entry:
BRANCH %head
%head:
%sum = PHI <@i64> { %entry: 0; %body: %sum2; }
%i = PHI <@i64> { %entry: 0; %body: %i2; }
%cmp = SLT <@i64> %i %sz
BRANCH2 %cmp %body %exit
%body:
%curptr = SHIFTIREF <@i64> %ary %i
%curnum = LOAD <@i64> %curptr
%sum2 = ADD <@i64> %sum %curnum
%i2 = ADD <@i64> %i 1
BRANCH %head
%exit:
STORE SEQ_CST <@i64> %result %sum
ICALL @uvm.thread_exit ()
THROW @NULLREF
}
.typedef @i6 = int<6>
.typedef @i52 = int<52>
.const @I6_31 <@i6> = 31
.const @I52_SAMPLE <@i52> = 0xfedcba9876543
.const @D_42 <@double> = 42.0d
.funcdef @testtr64 <@noparamsnoret> () {
%someobj = NEW <@i64>
%rv = REFCAST <@refi64 @refvoid> %someobj
%f = ICALL @uvm.tr64.from_fp (@D_42)
%i = ICALL @uvm.tr64.from_int (@I52_SAMPLE)
%r = ICALL @uvm.tr64.from_ref (%rv @I6_31)
%f_is_f = ICALL @uvm.tr64.is_fp (%f)
%f_is_i = ICALL @uvm.tr64.is_int (%f)
%f_is_r = ICALL @uvm.tr64.is_ref (%f)
%i_is_f = ICALL @uvm.tr64.is_fp (%i)
%i_is_i = ICALL @uvm.tr64.is_int (%i)
%i_is_r = ICALL @uvm.tr64.is_ref (%i)
%r_is_f = ICALL @uvm.tr64.is_fp (%r)
%r_is_i = ICALL @uvm.tr64.is_int (%r)
%r_is_r = ICALL @uvm.tr64.is_ref (%r)
%fb = ICALL @uvm.tr64.to_fp (%f)
%ib = ICALL @uvm.tr64.to_int (%i)
%rb = ICALL @uvm.tr64.to_ref (%r)
%rt = ICALL @uvm.tr64.to_tag (%r)
TRAP <@void> %exit %exit KEEPALIVE (%rv %f %i %r %f_is_f %f_is_i %f_is_r
%i_is_f %i_is_i %i_is_r %r_is_f %r_is_i %r_is_r %fb %ib %rb %rt)
%exit:
ICALL @uvm.thread_exit ()
THROW @NULLREF
}
///////////////////////// Simple sum
.funcdef @simplesum <@void (@i64 @i64)> (%from %to) {
......
.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 = func<@noparamsnoret>
.typedef @thread = thread
.typedef @stack = stack
.typedef @tagref64 = tagref64
.const @TRUE <@i64> = 1
.const @FALSE <@i64> = 0
.funcsig @i_ii = @i64 (@i64 @i64)
.typedef @refvoid = ref<@void>
.typedef @irefvoid = iref<@void>
.typedef @weakrefvoid = weakref<@void>
.const @NULLREF <@refvoid> = NULL
.typedef @StructFoo = struct <@i32 @i64 @float @double>
.const @STRUCT_FOO <@StructFoo> = {1 2 3.0f 4.0d}
.typedef @refi64 = ref<@i64>
.typedef @irefi64 = iref<@i64>
.typedef @weakrefi64 = weakref<@i64>
.typedef @StructBar = struct <
@i64 @i32 @i16 @i8 @float @double
@refi64 @irefi64 @weakrefi64
>
.typedef @refBar = ref<@StructBar>
.typedef @irefBar = iref<@StructBar>
.typedef @hCharArray = hybrid<@i64 @i8>
.typedef @ArrayBaz = array <@i16 1024>
.const @THREE <@i64> = 3
.typedef @JavaLikeByteArray = hybrid <@i32 @i8>
.const @I64_1024 <@i64> = 1024
.global @g_i8 <@i8>
.global @g_i16 <@i16>
.global @g_i32 <@i32>
.global @g_i64 <@i64>
.global @g_f <@float>
.global @g_d <@double>
.global @g_r <@refvoid>
.global @g_ir <@irefvoid>
.global @g_wr <@weakrefvoid>
.global @g_func <@funcdumb>
.global @g_thr <@thread>
.global @g_sta <@stack>
.global @g_tr64 <@tagref64>
.const @I64_30000 <@i64> = 30000
.const @CRAZY_ALLOC_COUNT <@i64> = 100
.global @g_refi64 <@refi64>
.funcdef @keepglobal <@noparamsnoret> () {
CALL <@noparamsnoret> @storeglobal ()
%gctrap = TRAP <@void> %next %next KEEPALIVE ()