PULL Instruction - craterdog-archives/js-bali-virtual-machine GitHub Wiki
PULL
The PULL
instruction causes the component (or the exception handler address) that is currently
on top of the component (or the exception handler) stack to be pulled off and potentially used
for a specific purpose that depends on the specified modifier:
An operand is never specified for this instruction.
PULL HANDLER
The PULL
instruction with a HANDLER
modifier pulls the handler address that is currently
on the handler stack off and discards it. The bytecode for this instruction has the form:
[01000000][00000000]
The following pseudo-code defines this instruction:
context.handlers.pop() -- discard the top handler address
context.address = context.address + 1
Example Context Before Execution
Example Context After Execution
PULL COMPONENT
The PULL
instruction with a COMPONENT
modifier pulls the component that is currently on
the component stack off and discards it. The bytecode for this instruction has the form:
[01001000][00000000]
The following pseudo-code defines this instruction:
task.components.pop()
context.address = context.address + 1
Example Context Before Execution
Example Context After Execution
PULL RESULT
The PULL
instruction with a RESULT
modifier pulls the component that is currently on
the component stack off and passed it as the result of the calling execution context. The
bytecode for this instruction has the form:
[01010000][00000000]
The following pseudo-code defines this instruction:
if task.contexts.isNotEmpty() then {
-- pass result on top of the stack to calling context
task.context = task.contexts.pop()
} else {
-- the task is done return the result
task.result = task.components.pop()
task.status = $completed
}
Example Context Before Execution
Example Context After Execution
PULL EXCEPTION
The PULL
instruction with an EXCEPTION
modifier pulls the exception handler address
that is currently on the handler stack off and uses it as the address of the next
instruction to be executed. If the handler stack is empty, the context that is on top
of the context stack is used to replace the current context and its handler stack is
used. If there are no more contexts, the exception that is on top of the component
stack is returned as an unhandled exception. The bytecode for this
instruction has the form:
[01011000][00000000]
The following pseudo-code defines this instruction:
while context do {
if context.handlers.isNotEmpty() then {
-- try the each handler for this context
context.address = context.handlers.pop()
break loop
} else if task.contexts.isNotEmpty() then {
-- try the handlers for the calling context
task.context = task.contexts.pop()
} else {
-- no more handlers to try, unhandled exception
task.exception = task.components.pop()
task.status = $abandoned
break loop
}
}