You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@daffodil.apache.org by GitBox <gi...@apache.org> on 2021/02/25 13:51:20 UTC

[GitHub] [daffodil] jadams-tresys commented on a change in pull request #473: Implement variable direction property

jadams-tresys commented on a change in pull request #473:
URL: https://github.com/apache/daffodil/pull/473#discussion_r582847166



##########
File path: daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ExpressionEvaluatingUnparsers.scala
##########
@@ -77,30 +78,83 @@ final class SetVariableUnparser(
 
 }
 
+final class NewVariableInstanceSuspendableExpression(
+  override val expr: CompiledExpression[AnyRef],
+  override val rd: VariableRuntimeData)
+  extends SuspendableExpression {
+
+  override protected def processExpressionResult(ustate: UState, v: DataValuePrimitive): Unit = {
+    val vi = ustate.variableMap.find(rd.globalQName)
+    Assert.invariant(vi.isDefined)
+    // Reset original variable's state from VariableInProcess
+    vi.get.setState(vi.get.priorState)
+    ustate.variableMap.newVariableInstance(rd, v)
+  }
+
+  override protected def maybeKnownLengthInBits(ustate: UState) = MaybeULong(0)
+}
+
 // When implemented this almost certainly wants to be a combinator
 // Not two separate unparsers.
-class NewVariableInstanceStartUnparser(override val context: RuntimeData)
+class NewVariableInstanceStartUnparser(override val context: VariableRuntimeData)
   extends PrimUnparserNoData {
 
   override lazy val runtimeDependencies = Vector()
 
   override lazy val childProcessors = Vector()
 
   override def unparse(state: UState) = {
-    val vrd = context.asInstanceOf[VariableRuntimeData]
-    state.newVariableInstance(vrd)
+    if (context.maybeDefaultValueExpr.isDefined) {
+      val maybeVar = state.variableMap.find(context.globalQName)
+      Assert.invariant(maybeVar.isDefined)
+
+      // Set the variable's state to VariableInProcess while waiting for the NVI
+      // expression to complete. When the expression completes, this original
+      // variable instance will have its state reset to its original value.
+      maybeVar.get.setState(VariableInProcess)
+      val suspendableExpression = new NewVariableInstanceSuspendableExpression(context.maybeDefaultValueExpr.get, context)
+      suspendableExpression.run(state)

Review comment:
       So I had been trying to get the approach you described to work for quite a while, but kept running into SuspensionDeadlock issues.  Perhaps I wasn't copying things appropriately when the UState gets cloned for suspension.  I'll take another look at it, but this commit was the first thing that I could get to work and handle scoping properly.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org