UIRTextReader.scala 29.8 KB
Newer Older
Kunshan Wang's avatar
Kunshan Wang committed
1
2
3
4
package uvm.ir.textinput

import org.antlr.v4.runtime._
import org.antlr.v4.runtime.tree.TerminalNode
Kunshan Wang's avatar
Kunshan Wang committed
5
import uvm._
Kunshan Wang's avatar
Kunshan Wang committed
6
import uvm.comminsts.CommInsts
Kunshan Wang's avatar
Kunshan Wang committed
7
8
9
10
11
import uvm.ir.textinput.gen.UIRParser._
import uvm.ir.textinput.gen._
import uvm.ssavariables._
import uvm.types._
import scala.collection.JavaConversions._
Kunshan Wang's avatar
Kunshan Wang committed
12
import scala.collection.mutable.ArrayBuffer
13
14
15
import scala.collection.immutable.Stream
import java.io.StringWriter
import java.nio.CharBuffer
Kunshan Wang's avatar
Kunshan Wang committed
16
import uvm.utils.IOHelpers
Kunshan Wang's avatar
Kunshan Wang committed
17
import uvm.utils.IDFactory
Kunshan Wang's avatar
Kunshan Wang committed
18
19
import uvm.utils.AdvancedAntlrHelper
import uvm.utils.AntlrHelpers.AccumulativeAntlrErrorListener
20
21
import org.slf4j.LoggerFactory
import com.typesafe.scalalogging.Logger
Kunshan Wang's avatar
Kunshan Wang committed
22

23
24
25
class UIRTextReader(val idFactory: IDFactory, val recordSourceInfo: Boolean = true) {
  import UIRTextReader._
  
Kunshan Wang's avatar
Kunshan Wang committed
26
  def read(ir: java.io.Reader, globalBundle: GlobalBundle): TrantientBundle = {
27
28
29
    logger.debug("Slurping from reader...")
    val src = IOHelpers.slurp(ir)
    read(src, globalBundle)
Kunshan Wang's avatar
Kunshan Wang committed
30
  }
Kunshan Wang's avatar
Kunshan Wang committed
31

Kunshan Wang's avatar
Kunshan Wang committed
32
  def read(ir: String, globalBundle: GlobalBundle): TrantientBundle = {
33
    logger.debug("Creating ANTLRInputStream...")
Kunshan Wang's avatar
Kunshan Wang committed
34
    val input = new ANTLRInputStream(ir)
35
    read(ir, input, globalBundle)
Kunshan Wang's avatar
Kunshan Wang committed
36
  }
37
38
39
  
  def parse(source: String, ais: ANTLRInputStream): IrContext = {
    logger.debug("Creating AccumulativeAntlrErrorListener...")
40
41
    val ea = new AccumulativeAntlrErrorListener(source)

42
    logger.debug("Creating Antlr Lexer and Parser...")
43
44
45
    val lexer = new UIRLexer(ais)
    lexer.removeErrorListeners()
    lexer.addErrorListener(ea)
Kunshan Wang's avatar
Kunshan Wang committed
46
47
    val tokens = new CommonTokenStream(lexer)
    val parser = new UIRParser(tokens)
Kunshan Wang's avatar
Kunshan Wang committed
48
49
    parser.removeErrorListeners()
    parser.addErrorListener(ea)
50
51
    
    logger.debug("Antlr parsing IR...")
Kunshan Wang's avatar
Kunshan Wang committed
52
    val ast = parser.ir()
Kunshan Wang's avatar
Kunshan Wang committed
53
    if (ea.hasError) {
54
      throw new TextIRParsingException("Syntax error:\n" + ea.getMessages)
Kunshan Wang's avatar
Kunshan Wang committed
55
    }
Kunshan Wang's avatar
Kunshan Wang committed
56
    
57
58
59
60
61
62
63
64
65
66
    ast
  }

  def read(source: String, ais: ANTLRInputStream, globalBundle: GlobalBundle): TrantientBundle = {
    val ast = parse(source, ais)
    logger.debug("Antlr parsed. Reading UIR AST into a Bundle...")
    val instanceReader = new InstanceUIRTextReader(idFactory, source, ast, globalBundle, recordSourceInfo)
    val bundle = instanceReader.read()
    logger.debug("Bundle read from AST.")
    bundle
Kunshan Wang's avatar
Kunshan Wang committed
67
  }
Kunshan Wang's avatar
Kunshan Wang committed
68
}
Kunshan Wang's avatar
Kunshan Wang committed
69

70
71
private[textinput] class InstanceUIRTextReader(idFactory: IDFactory, source: String, ir: IrContext,
    globalBundle: GlobalBundle, val recordSourceInfo: Boolean) extends AdvancedAntlrHelper {
Kunshan Wang's avatar
Kunshan Wang committed
72
73
  import UIRTextReader._
  import uvm.ir.textinput.Later.Laterable
Kunshan Wang's avatar
Kunshan Wang committed
74

Kunshan Wang's avatar
Kunshan Wang committed
75
  def sourceLines = source.lines.toIndexedSeq
Kunshan Wang's avatar
Kunshan Wang committed
76

Kunshan Wang's avatar
Kunshan Wang committed
77
  val bundle = new TrantientBundle()
Kunshan Wang's avatar
Kunshan Wang committed
78

Kunshan Wang's avatar
Kunshan Wang committed
79
80
  // Printing context information (line, column, near some token)

Kunshan Wang's avatar
Kunshan Wang committed
81
  def catchIn[T](ctx: ParserRuleContext, s: => String)(func: => T): T = try {
Kunshan Wang's avatar
Kunshan Wang committed
82
83
84
85
    func
  } catch {
    case e: Exception => throw new TextIRParsingException(inCtx(ctx, s), e)
  }
86

Kunshan Wang's avatar
Kunshan Wang committed
87
88
89
  def resolveByNameAndCatch[T](kind: String, ctx: ParserRuleContext, func: String => T): T = {
    catchIn(ctx, "Unable to resolve %s %s".format(kind, ctx.getText)) { func(ctx.getText) }
  }
Kunshan Wang's avatar
Kunshan Wang committed
90

Kunshan Wang's avatar
Kunshan Wang committed
91
92
  implicit def resTy(ctx: TypeContext): Type = resolveByNameAndCatch("type", ctx, resTyByName)
  def resTyByName(name: String): Type = cascadeLookup(name, bundle.typeNs, globalBundle.typeNs)
Kunshan Wang's avatar
Kunshan Wang committed
93

Kunshan Wang's avatar
Kunshan Wang committed
94
95
  implicit def resSig(ctx: FuncSigContext): FuncSig = resolveByNameAndCatch("function signature", ctx, resSigByName)
  def resSigByName(name: String): FuncSig = cascadeLookup(name, bundle.funcSigNs, globalBundle.funcSigNs)
Kunshan Wang's avatar
Kunshan Wang committed
96

Kunshan Wang's avatar
Kunshan Wang committed
97
98
  implicit def resConst(ctx: ConstantContext): Constant = resolveByNameAndCatch("constant", ctx, resConstByName)
  def resConstByName(name: String): Constant = cascadeLookup(name, bundle.constantNs, globalBundle.constantNs)
Kunshan Wang's avatar
Kunshan Wang committed
99

100
  implicit def resGlobalVar(ctx: GlobalVarContext): GlobalVariable = resolveByNameAndCatch("global variable", ctx, resGlobalVarByName)
Kunshan Wang's avatar
Kunshan Wang committed
101
  def resGlobalVarByName(name: String): GlobalVariable = cascadeLookup(name, bundle.globalVarNs, globalBundle.globalVarNs)
Kunshan Wang's avatar
Kunshan Wang committed
102

103
  implicit def resFunc(ctx: FuncContext): Function = resolveByNameAndCatch("function", ctx, resFuncByName)
Kunshan Wang's avatar
Kunshan Wang committed
104
  def resFuncByName(name: String): Function = cascadeLookup(name, bundle.funcNs, globalBundle.funcNs)
105

Kunshan Wang's avatar
Kunshan Wang committed
106
107
  implicit def convFlag(f: FlagContext): Flag = Flag(f.FLAG().getText)
  implicit def convFlagList(a: FlagListContext): Seq[Flag] = a.flag().map(convFlag)
Kunshan Wang's avatar
Kunshan Wang committed
108

Kunshan Wang's avatar
Kunshan Wang committed
109
110
111
  // Resolve global entities from special structures.
  implicit def resTypeList(a: TypeListContext): Seq[Type] = a.`type`.map(resTy)
  implicit def resFuncSigList(a: FuncSigListContext): Seq[FuncSig] = a.funcSig().map(resSig)
Kunshan Wang's avatar
Kunshan Wang committed
112

Kunshan Wang's avatar
Kunshan Wang committed
113
  // Resolve special structures
Kunshan Wang's avatar
Kunshan Wang committed
114

Kunshan Wang's avatar
Kunshan Wang committed
115
116
  // Resolve global entities. (If any resXxxx is not present, that's because it is simply not currently used)
  // Add entities to namespaces.
117

Kunshan Wang's avatar
Kunshan Wang committed
118
119
120
121
122
123
124
  private def addWithSourceInfo[T <: Identified](ns: Namespace[T], obj: T, sourceInfo: SourceInfo): Unit = {
    try {
      ns.add(obj)
      bundle.sourceInfoRepo(obj) = sourceInfo
    } catch {
      case e: NameConflictException => {
        throw new TextIRParsingException("Name conflict: %s. The newer definition %s:\n%s\nconflicts with older definition %s:\n%s".format(
125
          obj.name.get, e.newItem.repr, sourceInfo.prettyPrint(), e.oldItem.repr, bundle.sourceInfoRepo(e.oldItem).prettyPrint()))
Kunshan Wang's avatar
Kunshan Wang committed
126
127
      }
    }
Kunshan Wang's avatar
Kunshan Wang committed
128
  }
Kunshan Wang's avatar
Kunshan Wang committed
129

Kunshan Wang's avatar
Kunshan Wang committed
130
131
132
133
134
135
136
  def addTy(obj: Type, sourceInfo: SourceInfo): Unit = addWithSourceInfo(bundle.typeNs, obj, sourceInfo)
  def addSig(obj: FuncSig, sourceInfo: SourceInfo): Unit = addWithSourceInfo(bundle.funcSigNs, obj, sourceInfo)
  def addFuncVer(obj: FuncVer, sourceInfo: SourceInfo): Unit = addWithSourceInfo(bundle.funcVerNs, obj, sourceInfo)
  def addConst(obj: Constant, sourceInfo: SourceInfo): Unit = addWithSourceInfo(bundle.constantNs, obj, sourceInfo)
  def addGlobalCell(obj: GlobalCell, sourceInfo: SourceInfo): Unit = addWithSourceInfo(bundle.globalCellNs, obj, sourceInfo)
  def addFunc(obj: Function, sourceInfo: SourceInfo): Unit = addWithSourceInfo(bundle.funcNs, obj, sourceInfo)
  def addExpFunc(obj: ExposedFunc, sourceInfo: SourceInfo): Unit = addWithSourceInfo(bundle.expFuncNs, obj, sourceInfo)
Kunshan Wang's avatar
Kunshan Wang committed
137

Kunshan Wang's avatar
Kunshan Wang committed
138
  // Resolve types, with parse-time checking.
Kunshan Wang's avatar
Kunshan Wang committed
139

Kunshan Wang's avatar
Kunshan Wang committed
140
141
142
143
  def needType[E <: Type](tc: TypeContext, expectedType: Class[E], n: String): E = {
    val t = resTy(tc)
    if (!(expectedType.isAssignableFrom(t.getClass))) {
      throw new UnexpectedTypeException(inCtx(tc, "Expected %s, actually %s.".format(n, t)))
Kunshan Wang's avatar
Kunshan Wang committed
144
    }
Kunshan Wang's avatar
Kunshan Wang committed
145
146
    t.asInstanceOf[E]
  }
Kunshan Wang's avatar
Kunshan Wang committed
147

Kunshan Wang's avatar
Kunshan Wang committed
148
149
150
151
152
153
154
155
156
157
158
159
  def needInt[T <: Type](tc: TypeContext) = needType(tc, classOf[TypeInt], "int")
  def needStruct[T <: Type](tc: TypeContext) = needType(tc, classOf[TypeStruct], "struct")
  def needAbsStruct[T <: Type](tc: TypeContext) = needType(tc, classOf[AbstractStructType], "struct or hybrid")
  def needArray[T <: Type](tc: TypeContext) = needType(tc, classOf[TypeArray], "array")
  def needVector[T <: Type](tc: TypeContext) = needType(tc, classOf[TypeVector], "vector")
  def needHybrid[T <: Type](tc: TypeContext) = needType(tc, classOf[TypeHybrid], "hybrid")
  def needSeq[T <: Type](tc: TypeContext) = needType(tc, classOf[AbstractSeqType], "array or vector")

  def needConstInt64(ctx: ParserRuleContext, cc: ConstantContext): ConstInt = {
    val c = resConst(cc)
    if (!c.isInstanceOf[ConstInt]) {
      throw new UnexpectedTypeException(inCtx(ctx, "Expected 64-bit integer constant, actually %s.".format(c.getClass)))
160
    }
Kunshan Wang's avatar
Kunshan Wang committed
161
162
163
164
    c.asInstanceOf[ConstInt]
  }

  def read(): TrantientBundle = {
165

Kunshan Wang's avatar
Kunshan Wang committed
166
167
    // Make types and sigs

168
    logger.debug("Phase 1")
Kunshan Wang's avatar
Kunshan Wang committed
169
    val phase1 = new Later() // Resolve inter-references between types and sigs
Kunshan Wang's avatar
Kunshan Wang committed
170

Kunshan Wang's avatar
Kunshan Wang committed
171
172
    def mkType(tc: TypeConstructorContext): Type = {
      val ty = tc match {
173
174
175
176
177
178
179
180
181
182
183
        case t: TypeIntContext       => TypeInt(t.length.intValue())
        case t: TypeFloatContext     => TypeFloat()
        case t: TypeDoubleContext    => TypeDouble()
        case t: TypeRefContext       => TypeRef(null).later(phase1) { _.ty = t.ty }
        case t: TypeIRefContext      => TypeIRef(null).later(phase1) { _.ty = t.ty }
        case t: TypeWeakRefContext   => TypeWeakRef(null).later(phase1) { _.ty = t.ty }
        case t: TypeStructContext    => TypeStruct(null).later(phase1) { _.fieldTys = t.fieldTys.map(resTy) }
        case t: TypeArrayContext     => TypeArray(null, t.length.longValue()).later(phase1) { _.elemTy = t.ty }
        case t: TypeHybridContext    => TypeHybrid(null, null).later(phase1) { tt => tt.fieldTys = t.fieldTys.map(resTy); tt.varTy = t.varTy }
        case t: TypeVoidContext      => TypeVoid()
        case t: TypeFuncRefContext   => TypeFuncRef(null).later(phase1) { _.sig = t.funcSig() }
Kunshan Wang's avatar
Kunshan Wang committed
184
        case t: TypeThreadRefContext => TypeThreadRef()
185
186
187
188
189
        case t: TypeStackRefContext  => TypeStackRef()
        case t: TypeTagRef64Context  => TypeTagRef64()
        case t: TypeVectorContext    => TypeVector(null, t.length.longValue()).later(phase1) { _.elemTy = t.ty }
        case t: TypeUPtrContext      => TypeUPtr(null).later(phase1) { _.ty = t.ty }
        case t: TypeUFuncPtrContext  => TypeUFuncPtr(null).later(phase1) { _.sig = t.funcSig }
Kunshan Wang's avatar
Kunshan Wang committed
190
191
192
193
194
195
      }
      return ty
    }

    def mkSig(fsc: FuncSigConstructorContext): FuncSig = {
      val sig = FuncSig(null, null).later(phase1) { sig =>
196
197
        sig.retTys = for (t <- fsc.retTys) yield resTy(t)
        sig.paramTys = for (t <- fsc.paramTys) yield resTy(t)
Kunshan Wang's avatar
Kunshan Wang committed
198
199
200
201
      }
      return sig
    }

202
    logger.debug("Reading types and sigs...")
Kunshan Wang's avatar
Kunshan Wang committed
203
    ir.topLevelDef.map(_.getChild(0)).foreach {
Kunshan Wang's avatar
Kunshan Wang committed
204
205
      case td: TypeDefContext => {
        val ty = mkType(td.typeConstructor)
Kunshan Wang's avatar
Kunshan Wang committed
206
207
        ty.id = idFactory.getID()
        ty.name = Some(td.nam)
Kunshan Wang's avatar
Kunshan Wang committed
208
        addTy(ty, toSourceInfo(td.nam))
Kunshan Wang's avatar
Kunshan Wang committed
209
210
211
      }
      case fsd: FuncSigDefContext => {
        val sig = mkSig(fsd.funcSigConstructor)
Kunshan Wang's avatar
Kunshan Wang committed
212
213
        sig.id = idFactory.getID()
        sig.name = Some(fsd.nam)
Kunshan Wang's avatar
Kunshan Wang committed
214
        addSig(sig, toSourceInfo(fsd.nam))
Kunshan Wang's avatar
Kunshan Wang committed
215
      }
Kunshan Wang's avatar
Kunshan Wang committed
216
      case _ =>
Kunshan Wang's avatar
Kunshan Wang committed
217
218
    }

219
    logger.debug("Resolving types and sigs...")
Kunshan Wang's avatar
Kunshan Wang committed
220
221
    phase1.doAll()

222
    logger.debug("Phase 2")
Kunshan Wang's avatar
Kunshan Wang committed
223
    val phase2 = new Later() // Resolve inter-references from constants to other global variables
Kunshan Wang's avatar
Kunshan Wang committed
224

Kunshan Wang's avatar
Kunshan Wang committed
225
    def mkConst(t: Type, c: ConstConstructorContext): Constant = {
Kunshan Wang's avatar
Kunshan Wang committed
226
      val con = c match {
227
228
        case cc: CtorIntContext    => ConstInt(t, cc.intLiteral)
        case cc: CtorFloatContext  => ConstFloat(t, cc.floatLiteral)
Kunshan Wang's avatar
Kunshan Wang committed
229
        case cc: CtorDoubleContext => ConstDouble(t, cc.doubleLiteral)
230
        case cc: CtorListContext => ConstSeq(t, null).later(phase2) {
Kunshan Wang's avatar
Kunshan Wang committed
231
          _.elems = for (gn <- cc.globalVar()) yield resGlobalVar(gn)
Kunshan Wang's avatar
Kunshan Wang committed
232
        }
Kunshan Wang's avatar
Kunshan Wang committed
233
        case _: CtorNullContext => ConstNull(t)
Kunshan Wang's avatar
Kunshan Wang committed
234
235
236
237
      }
      return con
    }

Kunshan Wang's avatar
Kunshan Wang committed
238
    def mkGlobalCell(t: Type): GlobalCell = GlobalCell(t)
Kunshan Wang's avatar
Kunshan Wang committed
239
240
241
242
243
244
245

    def mkFunc(sig: FuncSig): Function = {
      val func = new Function()
      func.sig = sig
      return func
    }

Kunshan Wang's avatar
Kunshan Wang committed
246
    def mkExpo(c: FuncExpDefContext): ExposedFunc = {
247
      val efun = ExposedFunc(null, c.callConv, null).later(phase2) { ee =>
Kunshan Wang's avatar
Kunshan Wang committed
248
        ee.func = resFunc(c.func)
249
250
251
252
253
        ee.cookie = needConstInt64(c, c.cookie)
      }
      return efun
    }

Kunshan Wang's avatar
Kunshan Wang committed
254
255
    def findOldFunc(name: String): Option[Function] = {
      globalBundle.funcNs.get(name)
Kunshan Wang's avatar
Kunshan Wang committed
256
257
    }

Kunshan Wang's avatar
Kunshan Wang committed
258
    def declFunc(n: String, s: FuncSigContext, sourceInfo: SourceInfo): Function = {
Kunshan Wang's avatar
Kunshan Wang committed
259
260
      val sig = resSig(s)
      val func = mkFunc(sig)
Kunshan Wang's avatar
Kunshan Wang committed
261
      func.id = idFactory.getID()
Kunshan Wang's avatar
Kunshan Wang committed
262
      func.name = Some(n)
Kunshan Wang's avatar
Kunshan Wang committed
263
      addFunc(func, sourceInfo)
Kunshan Wang's avatar
Kunshan Wang committed
264

Kunshan Wang's avatar
Kunshan Wang committed
265
      func
Kunshan Wang's avatar
Kunshan Wang committed
266
267
    }

268
    logger.debug("Reading consts, globals, funcdefs, funcdecls and expfuncs...")
Kunshan Wang's avatar
Kunshan Wang committed
269
    val funcDefs = new ArrayBuffer[(Function, FuncDefContext)]
Kunshan Wang's avatar
Kunshan Wang committed
270

Kunshan Wang's avatar
Kunshan Wang committed
271
    ir.topLevelDef().map(_.getChild(0)).foreach {
Kunshan Wang's avatar
Kunshan Wang committed
272
      case cdctx: ConstDefContext => {
Kunshan Wang's avatar
Kunshan Wang committed
273
        val ty = resTy(cdctx.ty)
Kunshan Wang's avatar
Kunshan Wang committed
274
275
276
        val con = mkConst(ty, cdctx.constConstructor)
        con.id = idFactory.getID()
        con.name = Some(cdctx.nam)
Kunshan Wang's avatar
Kunshan Wang committed
277
        addConst(con, toSourceInfo(cdctx.nam))
Kunshan Wang's avatar
Kunshan Wang committed
278
279
      }
      case gdctx: GlobalDefContext => {
Kunshan Wang's avatar
Kunshan Wang committed
280
        val ty = resTy(gdctx.ty)
Kunshan Wang's avatar
Kunshan Wang committed
281
        val gc = mkGlobalCell(ty)
Kunshan Wang's avatar
Kunshan Wang committed
282
        gc.id = idFactory.getID()
Kunshan Wang's avatar
Kunshan Wang committed
283
        gc.name = Some(gdctx.nam)
Kunshan Wang's avatar
Kunshan Wang committed
284
        addGlobalCell(gc, toSourceInfo(gdctx.nam))
Kunshan Wang's avatar
Kunshan Wang committed
285
286
      }
      case fdecl: FuncDeclContext => {
Kunshan Wang's avatar
Kunshan Wang committed
287
        val name = globalNameToString(fdecl.nam)
Kunshan Wang's avatar
Kunshan Wang committed
288
289
290
        findOldFunc(name) match {
          case Some(oldFunc) =>
            throw new TextIRParsingException(inCtx(fdecl, "Function %s already declared in previous bundles. Old func: %s".format(name, oldFunc.repr)))
Kunshan Wang's avatar
Kunshan Wang committed
291
          case None => declFunc(name, fdecl.funcSig, toSourceInfo(fdecl.nam))
Kunshan Wang's avatar
Kunshan Wang committed
292
        }
Kunshan Wang's avatar
Kunshan Wang committed
293
294
      }
      case fdef: FuncDefContext => {
Kunshan Wang's avatar
Kunshan Wang committed
295
        val func = findOldFunc(fdef.nam).getOrElse(declFunc(fdef.nam, fdef.funcSig, toSourceInfo(fdef.nam)))
Kunshan Wang's avatar
Kunshan Wang committed
296
        //bundle.defFuncNs.add(func)
Kunshan Wang's avatar
Kunshan Wang committed
297
        funcDefs += ((func, fdef))
Kunshan Wang's avatar
Kunshan Wang committed
298
      }
Kunshan Wang's avatar
Kunshan Wang committed
299
      case edef: FuncExpDefContext => {
300
301
302
        val efun = mkExpo(edef)
        efun.id = idFactory.getID()
        efun.name = Some(edef.nam)
Kunshan Wang's avatar
Kunshan Wang committed
303
        addExpFunc(efun, toSourceInfo(edef.nam))
304
      }
Kunshan Wang's avatar
Kunshan Wang committed
305
306
307
      case _ => {}
    }

308
    logger.debug("Resolving global value inter-references")
Kunshan Wang's avatar
Kunshan Wang committed
309
310
    phase2.doAll()

311
    logger.debug("Phase 3")
Kunshan Wang's avatar
Kunshan Wang committed
312
    def defFunc(func: Function, fDefCtx: FuncDefContext) {
313
      logger.trace("Visiting function %s".format(func.name))
Kunshan Wang's avatar
Kunshan Wang committed
314
      val ver = new FuncVer()
Kunshan Wang's avatar
Kunshan Wang committed
315
      val verName = globalize(fDefCtx.ver, func.name.get)
Kunshan Wang's avatar
Kunshan Wang committed
316
      ver.id = idFactory.getID()
Kunshan Wang's avatar
Kunshan Wang committed
317
      ver.name = Some(verName)
Kunshan Wang's avatar
Kunshan Wang committed
318
      addFuncVer(ver, toSourceInfo(fDefCtx.ver))
Kunshan Wang's avatar
Kunshan Wang committed
319

Kunshan Wang's avatar
Kunshan Wang committed
320
      ver.func = func
Kunshan Wang's avatar
Kunshan Wang committed
321
      //func.versions = ver :: func.versions  // Don't override here. Let the MicroVM redefine functions.
Kunshan Wang's avatar
Kunshan Wang committed
322

Kunshan Wang's avatar
Kunshan Wang committed
323
      ver.bbNs = bundle.allNs.makeSubSpace[BasicBlock]("basic block")
324

Kunshan Wang's avatar
Kunshan Wang committed
325
      def addBB(bb: BasicBlock, sourceInfo: SourceInfo): Unit = addWithSourceInfo(ver.bbNs, bb, sourceInfo)
Kunshan Wang's avatar
Kunshan Wang committed
326

Kunshan Wang's avatar
Kunshan Wang committed
327
      def globalizeBB(name: String): String = globalize(name, verName)
Kunshan Wang's avatar
Kunshan Wang committed
328
329
330

      // Resolve function version local entities

Kunshan Wang's avatar
Kunshan Wang committed
331
      implicit def resBB(ctx: BbContext): BasicBlock = catchIn(ctx, "Unable to resolve basic block %s".format(ctx.name.getText)) {
Kunshan Wang's avatar
Kunshan Wang committed
332
333
334
335
336
        resBBByName(ctx.name.getText)
      }
      def resBBByName(name: String): BasicBlock = {
        val globalName = globalize(name, verName)
        ver.bbNs(globalName)
Kunshan Wang's avatar
Kunshan Wang committed
337
338
      }

Kunshan Wang's avatar
Kunshan Wang committed
339
      val phase4 = new Later() // Resolve references from instructions to other variables (global or local) and basic blocks
Kunshan Wang's avatar
Kunshan Wang committed
340

Kunshan Wang's avatar
Kunshan Wang committed
341
      def makeBB(bbCtx: BasicBlockContext): BasicBlock = {
Kunshan Wang's avatar
Kunshan Wang committed
342
343
        val label = bbCtx.label()
        val bbName = globalize(label.name(), verName)
Kunshan Wang's avatar
Kunshan Wang committed
344
        val bb = new BasicBlock()
Kunshan Wang's avatar
Kunshan Wang committed
345
        bb.id = idFactory.getID()
Kunshan Wang's avatar
Kunshan Wang committed
346
        bb.name = Some(bbName)
Kunshan Wang's avatar
Kunshan Wang committed
347
        addBB(bb, toSourceInfo(bbCtx))
Kunshan Wang's avatar
Kunshan Wang committed
348

Kunshan Wang's avatar
Kunshan Wang committed
349
350
351
352
        bb.localVarNs = bundle.allNs.makeSubSpace[LocalVariable]("local variable")
        bb.localInstNs = bundle.allNs.makeSubSpace[Instruction]("instruction")
        def addLocalVar(lv: LocalVariable, sourceInfo: SourceInfo): Unit = addWithSourceInfo(bb.localVarNs, lv, sourceInfo)
        def addInst(inst: Instruction, sourceInfo: SourceInfo): Unit = addWithSourceInfo(bb.localInstNs, inst, sourceInfo)
Kunshan Wang's avatar
Kunshan Wang committed
353

Kunshan Wang's avatar
Kunshan Wang committed
354
355
356
357
358
359
        def mkNorParam(ty: Type, name: String): NorParam = {
          val param = NorParam(ty)
          param.id = idFactory.getID()
          param.name = Some(globalize(name, bbName))
          param
        }
Kunshan Wang's avatar
Kunshan Wang committed
360

Kunshan Wang's avatar
Kunshan Wang committed
361
362
363
364
365
366
        def mkExcParam(name: String): ExcParam = {
          val param = ExcParam()
          param.id = idFactory.getID()
          param.name = Some(globalize(name, bbName))
          param
        }
Kunshan Wang's avatar
Kunshan Wang committed
367

368
        bb.norParams = label.bbParam.map { p =>
Kunshan Wang's avatar
Kunshan Wang committed
369
370
371
372
          val param = mkNorParam(p.`type`(), p.name())
          val sourceInfo = toSourceInfo(p)
          addLocalVar(param, sourceInfo)
          param
373
        }.toIndexedSeq
Kunshan Wang's avatar
Kunshan Wang committed
374
375
376
377
378
379
        bb.excParam = Option(label.excParam).map { p =>
          val param = mkExcParam(p.name())
          val sourceInfo = toSourceInfo(p)
          addLocalVar(param, sourceInfo)
          param
        }
Kunshan Wang's avatar
Kunshan Wang committed
380

Kunshan Wang's avatar
Kunshan Wang committed
381
        // Resolve basic block local entities (variables)
Kunshan Wang's avatar
Kunshan Wang committed
382

Kunshan Wang's avatar
Kunshan Wang committed
383
        def resLocalVar(ctx: ValueContext): LocalVariable = catchIn(ctx, "Unable to resolve local variable %s".format(ctx.getText)) {
Kunshan Wang's avatar
Kunshan Wang committed
384
385
386
387
388
389
          resLocalVarByName(ctx.name)
        }
        def resLocalVarByName(name: String): LocalVariable = {
          val globalName = globalize(name, bbName)
          bb.localVarNs(globalName)
        }
Kunshan Wang's avatar
Kunshan Wang committed
390

Kunshan Wang's avatar
Kunshan Wang committed
391
        implicit def resVar(ctx: ValueContext): SSAVariable = catchIn(ctx, "Unable to resolve variable %s".format(ctx.getText)) {
Kunshan Wang's avatar
Kunshan Wang committed
392
393
394
395
396
397
398
399
          resVarByName(ctx.name)
        }
        def resVarByName(name: String): SSAVariable = {
          val globalName = globalize(name, bbName)
          bb.localVarNs.get(globalName).getOrElse {
            cascadeLookup(globalName, bundle.globalVarNs, globalBundle.globalVarNs)
          }
        }
Kunshan Wang's avatar
Kunshan Wang committed
400

Kunshan Wang's avatar
Kunshan Wang committed
401
        implicit def resArgList(a: ArgListContext): Seq[SSAVariable] = a.value.map(resVar)
Kunshan Wang's avatar
Kunshan Wang committed
402

Kunshan Wang's avatar
Kunshan Wang committed
403
        implicit def resKA(ka: KeepAliveClauseContext): Seq[LocalVariable] = ka.value.map(resLocalVar)
Kunshan Wang's avatar
Kunshan Wang committed
404

Kunshan Wang's avatar
Kunshan Wang committed
405
406
        def resFuncCallBody(fcb: FuncCallBodyContext): (FuncSig, SSAVariable, Seq[SSAVariable]) =
          (fcb.funcSig, fcb.callee, fcb.argList)
Kunshan Wang's avatar
Kunshan Wang committed
407

Kunshan Wang's avatar
Kunshan Wang committed
408
409
410
411
        def asgnFuncCallBody(cl: CallLike, fcb: FuncCallBodyContext): Unit = {
          val (sig, callee, argList) = resFuncCallBody(fcb)
          cl.sig = sig; cl.callee = callee; cl.argList = argList
        }
Kunshan Wang's avatar
Kunshan Wang committed
412

Kunshan Wang's avatar
Kunshan Wang committed
413
414
        implicit def resDestClause(dc: DestClauseContext): DestClause = {
          DestClause(dc.bb, dc.argList())
Kunshan Wang's avatar
Kunshan Wang committed
415
416
        }

Kunshan Wang's avatar
Kunshan Wang committed
417
418
419
420
421
422
        implicit def resExcClause(ec: ExcClauseContext): Option[ExcClause] =
          if (ec.nor == null) {
            None
          } else {
            Some(ExcClause(ec.nor, ec.exc))
          }
Kunshan Wang's avatar
Kunshan Wang committed
423

424
425
426
        implicit def resNewStackClause(nsc: NewStackClauseContext): NewStackAction = {
          nsc match {
            case a: NewStackPassValueContext => PassValues(a.typeList(), a.argList())
427
            case a: NewStackThrowExcContext  => ThrowExc(a.exc)
428
429
430
431
432
433
434
435
436
437
          }
        }

        implicit def resCurStackClause(csc: CurStackClauseContext): CurStackAction = {
          csc match {
            case a: CurStackRetWithContext => RetWith(a.typeList())
            case a: CurStackKillOldContext => KillOld()
          }
        }

Kunshan Wang's avatar
Kunshan Wang committed
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
        // Make instruction

        def mkInst(bb: BasicBlock, instDef: InstContext): Instruction = {

          val inst: Instruction = instDef.instBody match {
            case ii: InstBinOpContext =>
              InstBinOp(BinOptr.withName(ii.binop.getText), ii.`type`, null, null, null).later(phase4) { i =>
                i.op1 = ii.op1; i.op2 = ii.op2; i.excClause = ii.excClause
              }
            case ii: InstCmpContext =>
              InstCmp(CmpOptr.withName(ii.cmpop.getText), ii.`type`, null, null).later(phase4) { i =>
                i.op1 = ii.op1; i.op2 = ii.op2
              }
            case ii: InstConversionContext =>
              InstConv(ConvOptr.withName(ii.convop.getText), ii.fromTy, ii.toTy, null).later(phase4) { i =>
                i.opnd = ii.opnd
              }
            case ii: InstSelectContext =>
              InstSelect(ii.condTy, ii.resTy, null, null, null).later(phase4) { i =>
                i.cond = ii.cond; i.ifTrue = ii.ifTrue; i.ifFalse = ii.ifFalse
              }
            case ii: InstBranchContext =>
              InstBranch(null).later(phase4) { i =>
                i.dest = ii.dest
              }
            case ii: InstBranch2Context =>
              InstBranch2(null, null, null).later(phase4) { i =>
                i.cond = ii.cond; i.ifTrue = ii.ifTrue; i.ifFalse = ii.ifFalse
              }
            case ii: InstSwitchContext =>
              InstSwitch(ii.`type`, null, null, null).later(phase4) { i =>
                i.opnd = ii.opnd; i.defDest = ii.defDest
                i.cases = for ((v, d) <- ii.caseVal.zip(ii.caseDest)) yield (resVar(v), resDestClause(d))
              }
            case ii: InstCallContext =>
              InstCall(null, null, null, null, null).later(phase4) { i =>
                asgnFuncCallBody(i, ii.funcCallBody)
                i.excClause = ii.excClause; i.keepAlives = ii.keepAliveClause
              }
            case ii: InstTailCallContext =>
              InstTailCall(null, null, null).later(phase4) { i =>
                asgnFuncCallBody(i, ii.funcCallBody)
              }
            case ii: InstRetContext =>
              InstRet(ver, null).later(phase4) { i =>
483
                i.retVals = ii.retVals.vals.map(resVar)
Kunshan Wang's avatar
Kunshan Wang committed
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
              }
            case ii: InstThrowContext =>
              InstThrow(null).later(phase4) { i =>
                i.excVal = ii.exc
              }
            case ii: InstExtractValueContext =>
              InstExtractValue(needStruct(ii.`type`), ii.intLiteral.intValue, null).later(phase4) { i =>
                i.opnd = ii.opnd
              }
            case ii: InstInsertValueContext =>
              InstInsertValue(needStruct(ii.`type`), ii.intLiteral.intValue, null, null).later(phase4) { i =>
                i.opnd = ii.opnd; i.newVal = ii.newVal
              }
            case ii: InstExtractElementContext =>
              InstExtractElement(needSeq(ii.seqTy), needInt(ii.indTy), null, null).later(phase4) { i =>
                i.opnd = ii.opnd; i.index = ii.index
              }
            case ii: InstInsertElementContext =>
              InstInsertElement(needSeq(ii.seqTy), needInt(ii.indTy), null, null, null).later(phase4) { i =>
                i.opnd = ii.opnd; i.index = ii.index; i.newVal = ii.newVal
              }
            case ii: InstShuffleVectorContext =>
              InstShuffleVector(needVector(ii.vecTy), needVector(ii.maskTy), null, null, null).later(phase4) { i =>
                i.vec1 = ii.vec1; i.vec2 = ii.vec2; i.mask = ii.mask
              }
            case ii: InstNewContext =>
              InstNew(ii.allocTy, null).later(phase4) { i =>
                i.excClause = ii.excClause
              }
            case ii: InstNewHybridContext =>
              InstNewHybrid(needHybrid(ii.allocTy), needInt(ii.lenTy), null, null).later(phase4) { i =>
                i.length = ii.length; i.excClause = ii.excClause
              }
            case ii: InstAllocaContext =>
              InstAlloca(ii.allocTy, null).later(phase4) { i =>
                i.excClause = ii.excClause
              }
            case ii: InstAllocaHybridContext =>
              InstAllocaHybrid(needHybrid(ii.allocTy), needInt(ii.lenTy), null, null).later(phase4) { i =>
                i.length = ii.length; i.excClause = ii.excClause
              }
            case ii: InstGetIRefContext =>
              InstGetIRef(ii.refTy, null).later(phase4) { i =>
                i.opnd = ii.opnd
              }
            case ii: InstGetFieldIRefContext =>
Kunshan Wang's avatar
Kunshan Wang committed
530
              InstGetFieldIRef(ii.ptr != null, needAbsStruct(ii.refTy), ii.intLiteral.intValue, null).later(phase4) { i =>
Kunshan Wang's avatar
Kunshan Wang committed
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
                i.opnd = ii.opnd
              }
            case ii: InstGetElemIRefContext =>
              InstGetElemIRef(ii.ptr != null, needSeq(ii.refTy), needInt(ii.indTy), null, null).later(phase4) { i =>
                i.opnd = ii.opnd; i.index = ii.index
              }
            case ii: InstShiftIRefContext =>
              InstShiftIRef(ii.ptr != null, ii.refTy, needInt(ii.offTy), null, null).later(phase4) { i =>
                i.opnd = ii.opnd; i.offset = ii.offset
              }
            case ii: InstGetVarPartIRefContext =>
              InstGetVarPartIRef(ii.ptr != null, needHybrid(ii.refTy), null).later(phase4) { i =>
                i.opnd = ii.opnd
              }
            case ii: InstLoadContext =>
              InstLoad(ii.ptr != null, ii.memord, ii.`type`, null, null).later(phase4) { i =>
                i.loc = ii.loc
                i.excClause = ii.excClause
              }
            case ii: InstStoreContext =>
              InstStore(ii.ptr != null, ii.memord, ii.`type`, null, null, null).later(phase4) { i =>
                i.loc = ii.loc; i.newVal = ii.newVal
                i.excClause = ii.excClause
              }
            case ii: InstCmpXchgContext =>
              InstCmpXchg(ii.ptr != null, ii.isWeak != null, ii.ordSucc, ii.ordFail, ii.`type`, null, null, null, null).later(phase4) { i =>
                i.loc = ii.loc; i.expected = ii.expected; i.desired = ii.desired
                i.excClause = ii.excClause
              }
            case ii: InstAtomicRMWContext =>
              InstAtomicRMW(ii.ptr != null, ii.memord, AtomicRMWOptr.withName(ii.atomicrmwop.getText), ii.`type`, null, null, null).later(phase4) { i =>
                i.loc = ii.loc; i.opnd = ii.opnd
                i.excClause = ii.excClause
              }
            case ii: InstFenceContext =>
              InstFence(ii.memord)
            case ii: InstTrapContext =>
568
              InstTrap(ii.typeList(), null, null).later(phase4) { i =>
Kunshan Wang's avatar
Kunshan Wang committed
569
570
571
                i.excClause = ii.excClause; i.keepAlives = ii.keepAliveClause
              }
            case ii: InstWatchPointContext =>
Kunshan Wang's avatar
Kunshan Wang committed
572
              InstWatchPoint(ii.wpid.intValue(), ii.typeList(), null, null, null, null).later(phase4) { i =>
Kunshan Wang's avatar
Kunshan Wang committed
573
574
                i.dis = ii.dis; i.ena = ii.ena; i.exc = Option(ii.wpExc).map(resDestClause); i.keepAlives = ii.keepAliveClause
              }
Kunshan Wang's avatar
Kunshan Wang committed
575
576
577
578
            case ii: InstWPBranchContext =>
              InstWPBranch(ii.wpid.intValue(), null, null).later(phase4) { i =>
                i.dis = ii.dis; i.ena = ii.ena
              }
Kunshan Wang's avatar
Kunshan Wang committed
579
            case ii: InstCCallContext =>
580
581
              InstCCall(ii.callConv, ii.funcTy, ii.funcSig, null, null, null, null).later(phase4) { i =>
                i.callee = ii.callee; i.argList = ii.argList; i.excClause = ii.excClause; i.keepAlives = ii.keepAliveClause
Kunshan Wang's avatar
Kunshan Wang committed
582
              }
583
584
585
586
            case ii: InstNewThreadContext =>
              InstNewThread(null, null, null).later(phase4) { i =>
                i.stack = ii.stack
                i.newStackAction = ii.newStackClause
Kunshan Wang's avatar
Kunshan Wang committed
587
588
589
590
                i.excClause = ii.excClause
              }
            case ii: InstSwapStackContext =>
              InstSwapStack(null, null, null, null, null).later(phase4) { i =>
591
                i.swappee = ii.swappee
Kunshan Wang's avatar
Kunshan Wang committed
592
593
                i.curStackAction = ii.curStackClause
                i.newStackAction = ii.newStackClause
Kunshan Wang's avatar
Kunshan Wang committed
594
595
596
597
598
599
600
601
602
603
                i.excClause = ii.excClause; i.keepAlives = ii.keepAliveClause
              }
            case ii: InstCommInstContext =>
              InstCommInst(CommInsts(ii.nam), Option(ii.flagList()).map(convFlagList).getOrElse(Seq()), null, null, null, null, null).later(phase4) { i =>
                i.typeList = Option(ii.typeList).map(resTypeList).getOrElse(Seq())
                i.funcSigList = Option(ii.funcSigList).map(resFuncSigList).getOrElse(Seq())
                i.argList = Option(ii.argList).map(resArgList).getOrElse(Seq())
                i.excClause = ii.excClause; i.keepAlives = ii.keepAliveClause
              }
          }
Kunshan Wang's avatar
Kunshan Wang committed
604

Kunshan Wang's avatar
Kunshan Wang committed
605
606
          inst.id = idFactory.getID()
          inst.name = Option(instDef.name).map(n => globalize(n.getText, bbName))
Kunshan Wang's avatar
Kunshan Wang committed
607

Kunshan Wang's avatar
Kunshan Wang committed
608
          addInst(inst, toSourceInfo(instDef))
Kunshan Wang's avatar
Kunshan Wang committed
609
610
611
612
613
614
615
616
617

          val instRess: Seq[InstResult] = Option(instDef.instResults) match {
            case None => Seq()
            case Some(r) => for ((instResDef, index) <- r.results.zipWithIndex) yield {
              val resName = globalize(instResDef.getText, bbName)

              val instRes = InstResult(inst, index)
              instRes.id = idFactory.getID()
              instRes.name = Some(resName)
Kunshan Wang's avatar
Kunshan Wang committed
618
              addLocalVar(instRes, toSourceInfo(instResDef))
Kunshan Wang's avatar
Kunshan Wang committed
619

Kunshan Wang's avatar
Kunshan Wang committed
620
621
              instRes
            }
622
623
          }

Kunshan Wang's avatar
Kunshan Wang committed
624
          inst.results = instRess
Kunshan Wang's avatar
Kunshan Wang committed
625

Kunshan Wang's avatar
Kunshan Wang committed
626
          return inst
Kunshan Wang's avatar
Kunshan Wang committed
627
628
        }

629
        bb.insts = bbCtx.inst.map(i => mkInst(bb, i)).toIndexedSeq
630

Kunshan Wang's avatar
Kunshan Wang committed
631
        return bb
Kunshan Wang's avatar
Kunshan Wang committed
632
633
      }

634
      val bbs = fDefCtx.funcBody.basicBlock().map(makeBB).toIndexedSeq
Kunshan Wang's avatar
Kunshan Wang committed
635

Kunshan Wang's avatar
Kunshan Wang committed
636
      ver.bbs = bbs
Kunshan Wang's avatar
Kunshan Wang committed
637
      ver.entry = bbs.head
Kunshan Wang's avatar
Kunshan Wang committed
638
639
640
641

      phase4.doAll()
    }

642
    logger.debug("Starting visiting function definitions...")
Kunshan Wang's avatar
Kunshan Wang committed
643
644
    for ((func, fDefCtx) <- funcDefs) {
      defFunc(func, fDefCtx)
Kunshan Wang's avatar
Kunshan Wang committed
645
646
    }

647
648
    logger.debug("Finished visiting function definitions. Bundle generated.")

Kunshan Wang's avatar
Kunshan Wang committed
649
650
    return bundle
  }
Kunshan Wang's avatar
Kunshan Wang committed
651
652
653
}

object UIRTextReader {
654
655
  val logger = Logger(LoggerFactory.getLogger(getClass.getName()))

Kunshan Wang's avatar
Kunshan Wang committed
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
  implicit def terminalToString(tn: TerminalNode): String = tn.getText()
  implicit def nameToString(name: NameContext): String = name.getText()
  implicit def globalNameToString(gn: GlobalNameContext): String = gn.getText()
  implicit def tokenToString(tok: Token): String = tok.getText()

  val IntRe = """([+-]?)(0x|0|)([0-9a-fA-F]*)""".r

  implicit def IntLiteralToBigInt(il: IntLiteralContext): BigInt = {
    val txt = il.getText()

    txt match {
      case IntRe(sign, prefix, nums) => {
        val neg = sign match {
          case "+" => false
          case "-" => true
671
          case ""  => false
Kunshan Wang's avatar
Kunshan Wang committed
672
673
674
        }
        val abs = prefix match {
          case "0x" => BigInt(nums, 16)
675
676
          case "0"  => if (nums == "") BigInt(0) else BigInt(nums, 8)
          case ""   => BigInt(nums, 10)
Kunshan Wang's avatar
Kunshan Wang committed
677
678
679
680
681
682
683
684
685
686
687
688
689
        }
        return if (neg) -abs else abs
      }
    }
  }

  implicit def floatLiteralToFloat(fl: FloatLiteralContext): Float = fl match {
    case num: FloatNumberContext => num.FP_NUM.getText.toFloat
    case fi: FloatInfContext => {
      if (fi.getText.startsWith("-"))
        java.lang.Float.NEGATIVE_INFINITY
      else java.lang.Float.POSITIVE_INFINITY
    }
690
    case _: FloatNanContext     => java.lang.Float.NaN
Kunshan Wang's avatar
Kunshan Wang committed
691
692
693
694
695
696
697
698
699
700
    case bits: FloatBitsContext => java.lang.Float.intBitsToFloat(bits.intLiteral().intValue())
  }

  implicit def doubleLiteralToDouble(dl: DoubleLiteralContext): Double = dl match {
    case num: DoubleNumberContext => num.FP_NUM.getText.toDouble
    case fi: DoubleInfContext => {
      if (fi.getText.startsWith("-"))
        java.lang.Double.NEGATIVE_INFINITY
      else java.lang.Double.POSITIVE_INFINITY
    }
701
    case _: DoubleNanContext     => java.lang.Double.NaN
Kunshan Wang's avatar
Kunshan Wang committed
702
703
704
705
706
707
    case bits: DoubleBitsContext => java.lang.Double.longBitsToDouble(bits.intLiteral().longValue())
  }

  def cascadeLookup[T <: Identified](name: String, ns1: Namespace[T], ns2: Namespace[T]): T =
    ns1.get(name).getOrElse(ns2(name))

Kunshan Wang's avatar
Kunshan Wang committed
708
  def globalize(name: String, parentName: String): String = {
Kunshan Wang's avatar
Kunshan Wang committed
709
710
    val sigil = name.charAt(0)
    sigil match {
711
      case '@' => name
Kunshan Wang's avatar
Kunshan Wang committed
712
      case '%' => parentName + "." + name.substring(1)
713
      case _   => throw new UvmException("Illegal name '%s'. Name must begin with either '@' or '%%'".format(name))
Kunshan Wang's avatar
Kunshan Wang committed
714
715
    }
  }
Kunshan Wang's avatar
Kunshan Wang committed
716
717
718
719
720
721
722
723
724

  implicit def resOrd(ord: MemordContext): MemoryOrder.Value = {
    if (ord == null) {
      MemoryOrder.NOT_ATOMIC
    } else {
      MemoryOrder.withName(ord.getText)
    }
  }
}