LEOInstructions

Includes:
"LEOInstructions.h"
"LEOValue.h"
"LEOInterpreter.h"
"LEOScript.h"
"LEOContextGroup.h"
"UTF8UTF32Utilities.h"
"LEOStringUtilities.h"
<sys/types.h>
<stdlib.h>
<stdio.h>
<math.h>
<string.h>

Introduction

These functions implement the actual instructions the Leonie bytecode interpreter actually understands. Or at least those that are portable between platforms.



Functions

LEOAddIntegerInstruction
LEOAddNumberInstruction
LEOAssignChunkArrayInstruction
LEOAssignIntegerEndInstruction
LEOAssignStringFromTableInstruction
LEOCallHandlerInstruction
LEOCleanUpHandlerParametersFromEndOfStack
LEOCleanUpHandlerStackInstruction
LEOConcatenateValuesInstruction
LEOCountChunksInstruction
LEOExitToTopInstruction
LEOGetArrayItemCountInstruction
LEOGetArrayItemInstruction
LEOGetParameterAtIndexFromEndOfStack
LEOInvalidInstruction
LEOJumpRelativeIfFalseInstruction
LEOJumpRelativeIfGreaterSameThanZeroInstruction
LEOJumpRelativeIfGreaterThanZeroInstruction
LEOJumpRelativeIfLessSameThanZeroInstruction
LEOJumpRelativeIfLessThanZeroInstruction
LEOJumpRelativeIfTrueInstruction
LEOJumpRelativeInstruction
LEOLineMarkerInstruction
LEONoOpInstruction
LEOParameterCountInstruction
LEOParameterInstruction
LEOParameterKeepRefsInstruction
LEOParseErrorInstruction
LEOPopSimpleValueInstruction
LEOPopValueInstruction
LEOPushArrayConstantInstruction
LEOPushBooleanInstruction
LEOPushChunkInstruction
LEOPushChunkPropertyInstruction
LEOPushChunkReferenceInstruction
LEOPushIntegerInstruction
LEOPushIntegerStartInstruction
LEOPushNumberInstruction
LEOPushParametersInstruction
LEOPushReferenceInstruction
LEOPushStringFromTableInstruction
LEOPushStringVariantFromTableInstruction
LEOPushUnsetValueInstruction
LEOReturnFromHandlerInstruction
LEOSetChunkPropertyInstruction
LEOSetReturnValueInstruction
LEOSetStringInstruction

LEOAddIntegerInstruction


Discussion

Add a LEOInteger to a value (ADD_INTEGER_INSTR)

param1 - The basePtr-relative offset of the value to add to, or BACK_OF_STACK.

param2 - The int32_t to add to the value (typecast to a uint32_t).


LEOAddNumberInstruction


void LEOAddNumberInstruction(
    LEOContext *inContext ) 
Discussion

Add a LEONumber to a value (ADD_NUMBER_INSTR)

param1 - The basePtr-relative offset of the value to add to, or BACK_OF_STACK.

param2 - The LEONumber to add to the value (typecast to a uint32_t).


LEOAssignChunkArrayInstruction


Discussion

Build an array containing each chunk item (i.e. item, line or word) in a given value's string representation. You must push the value whose chunks you want to get (or a reference to it) on the stack before calling this.

param1 - BP-relative address of at which you want the array to be created, or BACK_OF_STACK to push it on the back of the stack. param2 - The chunk type to use.


LEOAssignIntegerEndInstruction


Discussion

Push half of the given 64-bit LEOInteger on the stack (ASSIGN_INTEGER_END_INSTR)

param1 - The LEOUnit for this integer (kLEOUnitNone if it's really just a number). param2 - The second 32 bits of the LEOInteger to push.


LEOAssignStringFromTableInstruction


Discussion

Take a string from a strings table and assign it to the value in the given slot on the stack, or on the back of the stack. (ASSIGN_STRING_FROM_TABLE_INSTR)

param1 - The basePtr-relative offset of the instruction, or BACK_OF_STACK.

param2 - The index of the given string in the current context group's strings table.


LEOCallHandlerInstruction


Discussion

Call a given handler (CALL_HANDLER_INSTR)

This saves off the current base pointer and the address of the next instruction so returning from the handler can restore the previous state, and retains the current script in case the script deletes its owner.

This can be used to send a totally new message, or to pass a message up the message path.

Push a value to hold the result of this call on the stack first, followed by the parameters in reverse order, and finally the parameter count. After this instruction returns, it is your responsibility to remove the pushed parameters, count and result from the stack again, e.g. by generating the requisite POP_VALUE_INSTR instructions.

param1 - Flags from eLEOCallHandlerFlags enum. param2 - The LEOHandlerID of the handler to call.

See Also


LEOCleanUpHandlerParametersFromEndOfStack


Discussion

Clean up the stack so that the parameters allocated by LEOCallHandlerInstruction will be popped off the stack, leaving only the return value.

This helper function is intended for the case where we attempted to call a handler but couldn't find it, and the handler has not set up its base pointer yet or allocated local variables, and we want to gracefully recover from this in some way.

You could e.g. use this in your callNonexistentHandlerProc to clean up the stack after forwarding the parameters to and retrieving the return value from a native code plugin (in HyperCard parlance, an XCMD).

See Also


LEOCleanUpHandlerStackInstruction


Discussion

Clean up the stack so that the parameters and local variables and temporaries allocated by LEOCallHandlerInstruction and the handler's actual code will be popped off the stack, leaving only the return value. (CLEAN_UP_HANDLER_STACK_INSTR)

This method is intended for use by an actual handler that has been called and now wants to clean up behind itself without having to remember how many parameters it receives or what to do.

This instruction ignores currentInstruction, making it safe to call from other instructions without it looking at the wrong parameters, however it does advance the instruction pointer when it's done.

See Also


LEOConcatenateValuesInstruction


Discussion

(CONCATENATE_VALUES_INSTR)


LEOCountChunksInstruction


Discussion

Determine the number of chunks of the given type in a value's string representation and push it on the stack.

(COUNT_CHUNKS_INSTR)

param2 - The chunk type to use.


LEOExitToTopInstruction


void LEOExitToTopInstruction(
    LEOContext *inContext ) 
Discussion

Abort execution of the current script without an error. (EXIT_TO_TOP_INSTR)


LEOGetArrayItemCountInstruction


Discussion

Write the number of items in an array to a value. (GET_ARRAY_ITEM_COUNT_INSTR) The the array value must have been pushed on the stack before.

param1 - Destination BP-relative address, or BACK_OF_STACK.


LEOGetArrayItemInstruction


Discussion

Fetch an item out of an array, or an empty string if there is no such item. The key for the array item to be fetched, and the array value, must have been pushed on the stack before. (GET_ARRAY_ITEM_INSTR)

param1 - Destination BP-relative address, or BACK_OF_STACK.


LEOGetParameterAtIndexFromEndOfStack


Discussion

Grab the given parameter off the stack. May return NULL if there is no parameter at the given (zero-based) index.

This helper function is intended for the case where we attempted to call a handler but couldn't find it, and the handler has not set up its base pointer yet or allocated local variables, and we want to gracefully recover from this in some way and need to look at the parameters to do that.

You could e.g. use this in your callNonexistentHandlerProc to forward the parameters to and retrieving the return value from a native code plugin (in HyperCard parlance, an XCMD).

See Also


LEOInvalidInstruction


void LEOInvalidInstruction(
    LEOContext *inContext ) 
Discussion

Whenever an invalid instruction opcode is encountered in bytecode, this instruction will be executed. It terminates execution and provides an error message indicating what instruction opcode was invalid. (INVALID_INSTR)


LEOJumpRelativeIfFalseInstruction


Discussion

Jump to another instruction relative to this one if the given value is FALSE (JUMP_RELATIVE_IF_FALSE_INSTR)

param1 - The basePtr-relative offset of the value to examine, or BACK_OF_STACK.

param2 - The number of instructions to jump by.


LEOJumpRelativeIfGreaterSameThanZeroInstruction


Discussion

Jump to another instruction relative to this one if the given value is >= 0 (JUMP_RELATIVE_IF_GT_SAME_ZERO_INSTR)

param1 - The basePtr-relative offset of the value to examine, or BACK_OF_STACK.

param2 - The number of instructions to jump by.


LEOJumpRelativeIfGreaterThanZeroInstruction


Discussion

Jump to another instruction relative to this one if the given value is > 0 (JUMP_RELATIVE_IF_GT_ZERO_INSTR)

param1 - The basePtr-relative offset of the value to examine, or BACK_OF_STACK.

param2 - The number of instructions to jump by.


LEOJumpRelativeIfLessSameThanZeroInstruction


Discussion

Jump to another instruction relative to this one if the given value is <= 0 (JUMP_RELATIVE_IF_LT_SAME_ZERO_INSTR)

param1 - The basePtr-relative offset of the value to examine, or BACK_OF_STACK.

param2 - The number of instructions to jump by.


LEOJumpRelativeIfLessThanZeroInstruction


Discussion

Jump to another instruction relative to this one if the given value is < 0 (JUMP_RELATIVE_IF_LT_ZERO_INSTR)

param1 - The basePtr-relative offset of the value to examine, or BACK_OF_STACK.

param2 - The number of instructions to jump by.


LEOJumpRelativeIfTrueInstruction


Discussion

Jump to another instruction relative to this one if the given value is TRUE (JUMP_RELATIVE_IF_TRUE_INSTR)

param1 - The basePtr-relative offset of the value to examine, or BACK_OF_STACK.

param2 - The number of instructions to jump by.


LEOJumpRelativeInstruction


Discussion

Jump to another instruction relative to this one (JUMP_RELATIVE_INSTR)

param2 - The number of instructions to jump by. A value of 1 would make this identical to NO_OP_INSTR.


LEOLineMarkerInstruction


Discussion

This instruction does nothing. It just advances to the next instruction. (LINE_MARKER_INSTR)

param2 - The line number.


LEONoOpInstruction


void LEONoOpInstruction(
    LEOContext *inContext ) 
Discussion

This instruction does nothing. It just advances to the next instruction. (NO_OP_INSTR)


LEOParameterCountInstruction


Discussion

Determine the number of parameters that have been passed to this function (PARAMETER_COUNT_INSTR)

param1 - The basePtr-relative offset of the value to be overwritten, or BACK_OF_STACK if you want the value to be pushed on the stack.

See Also


LEOParameterInstruction


void LEOParameterInstruction(
    LEOContext *inContext ) 
Discussion

Copy the value of the parameter at given index into the given value on the stack. If no parameter of that index has been passed, this returns an empty string. (PARAMETER_INSTR)

param1 - The basePtr-relative offset of the value to be overwritten, or BACK_OF_STACK if you want the value to be pushed on the stack.

param2 - The number of the parameter to retrieve, as a 1-based index. If this is 0, grab the index from the back of the stack.

See Also


LEOParameterKeepRefsInstruction


Discussion

Copy the value of the parameter at given index into the given value on the stack. If no parameter of that index has been passed, this returns an empty string. (PARAMETER_KEEPREFS_INSTR)

param1 - The basePtr-relative offset of the value to be overwritten, or BACK_OF_STACK if you want the value to be pushed on the stack.

param2 - The number of the parameter to retrieve, as a 1-based index. If this is 0, grab the index from the back of the stack.

See Also


LEOParseErrorInstruction


Discussion

Abort execution of the current script with an error message. (PARSE_ERROR_INSTR)


LEOPopSimpleValueInstruction


Discussion

Pop the last value off the stack. (POP_SIMPLE_VALUE_INSTR)

param1 - If this is not BACK_OF_STACK, we copy the simple value of the last value on the stack to that bp-relative stack location before we pop it.


LEOPopValueInstruction


void LEOPopValueInstruction(
    LEOContext *inContext ) 
Discussion

Pop the last value off the stack. (POP_VALUE_INSTR)

param1 - If this is not BACK_OF_STACK, we copy the value to that bp-relative stack location before we pop it.


LEOPushArrayConstantInstruction


Discussion

Push an array containing the given key/value pairs on the stack. (PUSH_ARRAY_CONSTANT_INSTR)


LEOPushBooleanInstruction


Discussion

Push a boolean on the stack. (PUSH_BOOLEAN_INSTR)

param2 - The boolean to push on the stack.


LEOPushChunkInstruction


void LEOPushChunkInstruction(
    LEOContext *inContext ) 
Discussion

Push a chunk out of a larger value onto the stack as a string value. (PUSH_CHUNK_INSTR)

The chunk end and chunk start are popped off the back of the stack (in that order).

param1 - The basePtr-relative offset of the value to be referenced. If this is BACK_OF_STACK it will get the value from the stack, and expects it to have been pushed as the very first parameter.

param2 - The LEOChunkType of this chunk expression.

See Also


LEOPushChunkPropertyInstruction


Discussion

Push the value of a property of a chunk out of a larger value onto the stack as a string value. (PUSH_CHUNK_PROPERTY_INSTR)

The name, chunk end and chunk start are popped off the back of the stack (in that order).

param1 - The basePtr-relative offset of the value to be referenced. If this is BACK_OF_STACK it will get the value from the stack, and expects it to have been pushed as the very first parameter.

param2 - The LEOChunkType of this chunk expression.

See Also


LEOPushChunkReferenceInstruction


Discussion

Push a reference to a chunk out of a larger value onto the stack. (PUSH_CHUNK_REFERENCE_INSTR)

The chunk end and chunk start are popped off the back of the stack (in that order).

param1 - The basePtr-relative offset of the value to be referenced.

param2 - The LEOChunkType of this chunk expression.

See Also


LEOPushIntegerInstruction


Discussion

Push the given 32-bit LEOInteger on the stack (PUSH_INTEGER_INSTR)

param1 - The LEOUnit for this integer (kLEOUnitNone if it's really just a number). param2 - The LEOInteger (typecast to a uint32_t) to push.


LEOPushIntegerStartInstruction


Discussion

Push half of the given 64-bit LEOInteger on the stack (PUSH_INTEGER_START_INSTR)

param1 - The LEOUnit for this integer (kLEOUnitNone if it's really just a number). param2 - The first 32 bits of the LEOInteger to push.


LEOPushNumberInstruction


Discussion

Push the given LEONumber floating point quantity on the stack (PUSH_NUMBER_INSTR)

param1 - The LEOUnit for this number (kLEOUnitNone if it's really just a number). param2 - The LEONumber (typecast to a uint32_t) to push.


LEOPushParametersInstruction


Discussion

Copy all parameters as an array and push it on the stack. (PUSH_PARAMETERS_INSTR)

See Also


LEOPushReferenceInstruction


Discussion

Push a reference to the given value onto the stack (PUSH_REFERENCE_INSTR)

param1 - The basePtr-relative offset of the value to be referenced, or BACK_OF_STACK.


LEOPushStringFromTableInstruction


Discussion

Take a string in the current script's string table and push it on the stack as a LEOStringValue. (PUSH_STR_FROM_TABLE_INSTR)

param2 - The index of the string table entry to retrieve.


LEOPushStringVariantFromTableInstruction


Discussion

Take a string in the current script's string table and push it on the stack as a LEOStringValue. (PUSH_STR_VARIANT_FROM_TABLE_INSTR)

param2 - The index of the string table entry to retrieve.


LEOPushUnsetValueInstruction


Discussion

Push the "unset" value on the stack as a LEOStringValue. (PUSH_UNSET_VALUE_INSTR)


LEOReturnFromHandlerInstruction


Discussion

Return to the calling handler (RETURN_FROM_HANDLER_INSTR)

This restores the previously-saved base pointer, jumps to the saved return address and releases its ownership of the current script (as established by CALL_HANDLER_INSTR).

This instruction ignores currentInstruction, making it safe to call from other instructions without it looking at the wrong parameters.

See Also


LEOSetChunkPropertyInstruction


Discussion

Change a property of a sub-range of an object. (SET_CHUNK_PROPERTY_INSTR)

The property name, value, chunk end and chunk start are popped off the back of the stack (in that order).

param1 - The basePtr-relative offset of the value to be referenced. If this is BACK_OF_STACK it will get the value from the stack, and expects it to have been pushed as the very first parameter.

param2 - The LEOChunkType of this chunk expression.

See Also


LEOSetReturnValueInstruction


Discussion

Pop a value off the back of the stack and copy it to the return value that our caller will look at when we return. (SET_RETURN_VALUE_INSTR)


LEOSetStringInstruction


void LEOSetStringInstruction(
    LEOContext *inContext ) 
Discussion

Pop the last value off the stack, evaluate it as a string, and then assign it to the value at the given bp-relative address. If param1 is BACK_OF_STACK, the penultimate item on the stack will be used, and popped off as well. (SET_STRING_INSTRUCTION)