Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Branch: master
Fetching contributors…

Cannot retrieve contributors at this time

1440 lines (642 sloc) 18.043 kB

Lorito Opcode Definitions

Execution Ops

noop

Valid Forms:

Any

Registers

None

Description

Do nothing. Waste a cycle.

Reason

Sometimes, you just need to be lazy.

end

Valid Forms:

Any

Registers

None

Description

Stop the interperter, cleanly.

Reason

Although this could be dangerous, code should have the ablity to stop execution.

add

Valid Forms:

INT

Registers

$dest, $src1, $src2

Description

Add $src1 and $src2 and store result in $dest.

Reason

Math becomes very difficult without being able to add.

sub

Valid Forms:

INT

Registers

$dest, $src1, $src2

Description

Subtract $src1 and $src2 and store result in $dest.

Reason

Likewise, subtraction is vital to quick and efficient math.

mul

Valid Forms:

INT

Registers

$dest, $src1, $src2

Description

Multiply $src1 and $src2 and store the result into $dest

Reason

Making multiplication a addition loop is unadvisable, no matter how minimal you're trying to be

div

Valid Forms:

INT

Registers

$dest, $src1, $src2

Description

Divide $src1 by $src2 and store the result in $dest. With the Int form, only the quotient is stored in $dest.

Reason

A loop of subtractions would be possible to emulate a div, but that's kind of silly.

mod

Valid Forms:

INT

Registers

$dest, $src1, $src2

Description

Divide $src1 by $src2 and store the remainder in $dest.

Reason

It's up to debate to include this instead of forcing a divide, cast, multiply and subtract. The speed up given by this instruction over how often some common problems need this operator outweighs reducing the operators by one.

and

Valid Forms:

INT

Registers

$dest, $src1, $src2

Description

Performs a binary AND on $src1 and $src2. The result is stored in $dest.

Reason

AND is a basic building block of all logic. Not including this opcode would needlessly complicate all logic.

or

Valid Forms:

INT

Registers

$dest, $src1, $src2

Description

Perfoms a binary OR on $src1 and $src2. The result is stored in $dest.

Reason

Just like AND, OR is a basic logic building block, removing it would be burdensome to users.

xor

Valid Forms:

INT

Registers

$dest, $src1, $src2

Description

Perfoms a binary XOR on $src1 and $src2. The result is stored in $dest.

Reason

XOR is not as fundemental as AND and OR, but simplifies a lot of operations that would otherwise be complicated and happen often and.

not

Valid Forms:

INT

Registers

$dest, $src1

Description

Perfoms a binary NOT on $src1. The result is stored in $dest.

Reason

NOT could be emulated with XOR, and in a fairly simple manner. It would be replaced by two operations instead of one, a load constant and an xor.

shl

Valid Forms:

INT

Registers

$dest, $src1, $src2

Description

Shifts the bits in $src1 by $src2 bits to the left and stores the result in $dest.

Reason

shr

Valid Forms:

INT

Registers

$dest, $src1, $src2

Description

Shifts the bits in $src1 by $src2 bits to the right and stores the result in $dest.

Reason

Comparison Ops

iseq

Valid Forms:

STR INT

Registers

INT($dest), $src1, $src2

Description

This is the equals operator. It takes $src1 and $src2 and checks if they are equal and sets INT($dest) to 1 or 0, depending if they are equal or not. For INT and NUM, it does a mathmatical equavalance. For STR, it will return 1 if the two STRs are identical. For PMC, the two PMCs must point to the exact same PMC.

Reason

We could use a logical operator for the INT version of iseq, but that would not work for NUM, STR and PMC.

isgt

Valid Forms:

INT

Registers

INT($dest), $src1, $src2

Description

Comparse $src1 and $src2. If $src1 is greater than $src2, it sets INT($dest) to 1, otherwise it sets INT($dest) to 0.

Reason

This really has no alternative but to be included. The less than version has been left out since it can be reasonably done by simply reversing $src1 and $src2.

isge

Valid Forms:

INT

Registers

INT($dest), $src1, $src2

Description

This operator is identical to isgt, except it will also set INT($dest) to 1 if $src1 and $src2 are equal.

Reason

This might have been left out in favor of checking isgt and iseq. But that would be ineffecient compared to adding one more op to the group.

Just like isgt, isle is not included since it is easy to emulate by reversing $src1 and $src2.

Flow Control Ops

goto

Valid Forms:

Any

Registers

$imm

Description

Takes an $imm address and moves the program counter there. Execution will start there as the next instruction.

Note that this does not cross code block bounds.

Reason

The machine needs to be able to branch unconditionaly. While it might be possible to get away with only if, goto gives some optimzation possiblities.

if

Valid Forms:

INT

Registers

$src1, $imm

Description

Checks $src1 to be 0. If it is 0, the program counter is unchanged, otherwise the program counter is changed to the value in $imm.

Reason

Without doing very complicated things with call, this is the only other way to do conditional branching. Therfore, it is extremely vital.

Register Manipulation Ops

set

Valid Forms:

PMC STR NUM INT

Registers
Description
Reason

load_const

Valid Forms:

STR INT

Registers

$dest, INT($src1), INT($src2), $imm

Description

This operator will load data from the context data block into a register. The data loaded will start at $src1+$imm and will read $src2 bytes and store the results into $dest.

In the case that INT($src2) is 0, the "natural" length will be read. For STR, the number of bytes until the first null charecter that is found is used as the length. For INT, the natueral length is 4 bytes, and NUM is 8 bytes.

Example
  $S1 = STR LOAD_CONST :[method_ok]

This will take the string starting at method_ok in the data block and read the entire string until a null charecter or the end of the block into the $S1 register.

  $I1 = INT LOAD_IMM :4;
  $I2 = INT LOAD_IMM :2;
  $I3 = INT LOAD_CONST $I1, $I2;

This will load the first two bytes ($I2) starting at the fourth byte ($I1) of the data block and store the integer into $I3.

Reason

Loading constants from the data block is the only way that you can do useful stuff with by any manner of effenceny.

However, this might be obsolete with a constant PMC that you can load from the context.

load_imm

Valid Forms:

INT

Registers

$dest, $imm

Description

Loads an immediate value from $imm into a register. Because of the size of $imm, the only registers you can load this way are INT types.

Example
  $I1 = INT LOAD_IMM :4;

Loads the number 4 into the register $I1.

Reason

Without the ablity to have and load immediate values, loading data into registers becomes cumbersome, difficult and complex.

coerce_int

Valid Forms:

PMC INT

Registers

$dest, INT($src1)

Description

Convert the int in INT($src1) into the form of $dest and stores the result into $dest.

Can also be used to copy data between registers.

Example
  $P1 = PMC COERCE_INT $I1;

$P1 will contain a boxed integer.

Reason

This is the basic form of integer casting. In order to load data from another type, some kind of basic casting is required. Without this, there would be no way to do any kind of casting.

coerce_num

Valid Forms:

Any

Registers

$dest, NUM($src1)

Description

Convert the floating point number in NUM($src1) into the form of $dest and stores the result into $dest.

Can also be used to copy data between registers.

Example
  $S1 = STR COERCE_NUM $N1;

$N1 will contain string version of $N1.

Reason

Just like the integer casting, we need a way to cast from a number to any other type.

coerce_str

Valid Forms:

Any

Registers

$dest, STR($src1)

Description

Convert the string in STR($src1) into the form of $dest and stores the result into $dest.

Can also be used to copy data between registers.

Example
  $I1 = NUM COERCE_STR $S1;

$I1 will contain the integer version of $S1.

Reason

Just like the integer casting, we need a way to cast from a string to any other type.

PMC Ops

new

Valid Forms:

PMC INT

Registers

PMC($dest), $src1, $imm

Description

This creates a new PMC. The operation of creating the PMC depends on the type of $src1:

Reason

This operator is required since there is no other reasonable way to create new PMCs without it.

store

Valid Forms:

PMC NUM INT

Registers

PMC($dest), $src1, INT($src2), $imm

Description

Store a register into a PMC at a particular address. The first $imm bytes of of the data in $src1 is placed into the $dest PMC at address $src2. If the type of $src1 is an INT or NUM, the INT or NUM is stored. If $src1 is a PMC, a refrence to the PMC is stored in the pmc_ptr table and the slot number used is written.

Example
  $I1 = INT LOAD_IMM :4;
  $P1 = INT STORE $I1, $I1, :2;

Store the first 2 bytes of the integer 4 at address 4 of $P1 data area.

  $I1 = INT LOAD_IMM :8;
  $P2 = PMC STORE $P1, $I1;

Stores $P1 into the pmc_ptr table and stores the slot number starting at byte 8 of $P2 data area.

Reason

A fundamental part of the operation of PMCs is the ablity to treat them as simple chunks of data. There has to be a fast, effecient way to store data into a PMC.

load

Valid Forms:

PMC NUM INT

Registers

$dest, PMC($src1), INT($src2), $imm

Description

Load data in a PMC into a register. This is the opposite of a store. The first $imm bytes of the data in $src1 at offset $src2 are loaded into $dest. If $dest is an INT or NUM, the INT or NUM is loaded into the register. If $dest is a PMC, length is ignored and the integer at offset $src2 is used to lookup the PMC in the pmc_ptr table, and is loaded into $dest.

Example
  $I1 = INT LOAD_IMM :4;
  $I2 = INT LOAD $P1, $I1, :2;

Load the first 2 bytes of $P1 at address 4 into $I2.

  $I1 = INT LOAD_IMM :8;
  $P2 = PMC LOAD $P1, $I1;

Loads the PMC refrenced in the pmc_ptr by the integer stored at byte 8 in $P1 into $P2.

Reason

If it's possible to put data into a PMC, then it is only reasonable to be able to get the data back out in a quick and effecient manner.

push_arg

Valid Forms:

PMC INT

Registers

PMC($src1), $src2

Description

Take $src2, box it as a PMC, and push it onto the argument stack for the context PMC($src1). If PMC($src1) is null, the current context is used. The argument stack should be used for arguments and return values.

Reason

There were two options for passing arguments between function calls. Either arguments are passed in registers or passed on a stack. Since passing arguments in registers meant that register pools are leaked between function calls, that's less than desirable. So, the decision was to make everything a PMC and have an argument stack.

pop_arg

Valid Forms:

PMC STR INT

Registers

$dest, PMC($src1)

Description

Pop the next argument off the top of the argument stack for the context in PMC($src1) and store it in $dest, unboxing it if it is not a PMC. If PMC($src1) is null, the current context is used.

Reason

This operator exists since push_arg exists. What use is an argument stack if you can never retrieve the arguments.

call

Valid Forms:

Any

Registers

PMC($src1)

Description

Invoke the context in PMC($src1) by setting it as the current context.

Reason

This is the key operator that allows changing of current context, and thus the ablity to change which code block is running.

Environment Ops

loadlib

Valid Forms:

Any

Registers

PMC($dest), $src1

Description

Take the library refrenced by $src1, make sure it has been loaded into the virtual machine, and put a refrence to the file PMC in PMC($dest).

At this point, $src2 is the file name of the library.

Reason

This allows the loading and inspection of outside libraries.

read

Valid Forms:

Any

Registers

$dest

Description

Read from the input and put the value read into $dest.

Reason

This is a bootstrap op, and may not be available long term.

write

Valid Forms:

STR INT

Registers

$src1

Description

Print the value in $src1 to the output device.

Reason

This is a bootstrap op, and may not be available long term.

say

Valid Forms:

STR INT

Registers

$src1

Description

Print the value in $src1, along with a line terminator, to the output device.

Reason

This is a bootstrap op, and may not be available long term.

gripe

Valid Forms:

STR INT

Registers

$src1

Description

Print the value in $src1 to the error device.

Reason

This is a bootstrap op, and may not be available long term.

PMC Ops

lookup

Valid Forms:

STR

Registers

PMC($dest), PMC($src1), $src2

Description

Perform a lookup on the PMC in $src1. This will invoke the lookup function that is associated with the PMC. This function will be passed the PMC, the vtable saved in the PMC and the boxed paramater passed in $src2. Once the lookup function returns, $dest will hold a code PMC.

Example
  $S1 = STR LOAD_CONST :[method_a];
  $P2 = STR LOOKUP $P1, $S1;

This loads the constant string of method_a into $S1 and uses it to lookup up the method by that name in $P1. $P2 is the method by that name, or null.

Reason

Lorito should not force a particular object model, so a simple compromise was made. Whichever object model is used for a PMC is able to install and use a custom lookup method by implementing this call on a PMC. This gives all users of the PMC the ablity to invoke any method of a PMC/object without having to know and understand the object model.

Also, lookups happen a lot in a dynamic language. As such, having this operator simplifies and speeds up the process of doing method lookups.

ctx

Valid Forms:

PMC

Registers

$dest

Description

Retrieve the current context PMC and puts it into $dest.

Reason

The context is the gateway PMC to the rest of the virtual machine. Anything that is important to get, but not important to have an operator for, can be accessed through this PMC.

block

Valid Forms:

INT

Registers

PMC($dest), $src1, $imm

Description

Look up in the current file the code block refrenced by $src1. If the type of $src1 is INT, lookup is done as $src1 + $imm.

Reason

This is possibly a temporary, bootstrap operator. These look ups could be done with the context PMC. However, it may provide a nice speed boost if this is done often enough.

new_ctx

Valid Forms:

PMC

Registers

$dest, $src1, $src2, $imm

Description

Create a new context. $src1 is the code block that the context is for, $src2 is the result context and $imm is the inital program counter. If $src2 is null, the current context is used instead. The new context is stored in $dest.

Reason

Creating a new context is going to happen quite frequently. While this could have been simply a method off of the context, the question becomes is how do you call a method to create a context if you can't create a context?

push_ret

Valid Forms:

INT

Registers
Description
Reason

pop_ret

Valid Forms:

INT

Registers
Description
Reason

cnt_ret

Valid Forms:

Any

Registers
Description
Reason

PMC Ops

cnt_arg

Valid Forms:

Any

Registers

$dest, $PMC($src1)

Description
Reason

The choice was between being able to clear all of the arguments with clr_arg or have the count of arguments. Since you can do clr_arg with cnt_arg and cnt_arg has more possible uses, cnt_arg was used.

These Ops

hcf

Valid Forms:

Any

Registers

None

Description

Halt, and Catch any instance of skynet on Fire.

Reason

Just in case.

Jump to Line
Something went wrong with that request. Please try again.