L1VM - status

I did write two encryption modules. One for “ciphersaber” algorithm and one with the “libsodium” library. And the file module got a read/write array function. There are other recent changes.

I did make Brackets variable type safe. And did insert range checks to the “set” variable definitions:

(set byte 1 foobar 256)

This will result into an error message:

error: line 10: byte value out of range!
>     (set byte 1 foobar 256)

The range for byte goes from 0 to 255!

I did some benchmarks, which showed that my L1VM can be faster as Node.js: Primes benchmark posting This benchmark was ran without the L1VM JIT-compiler!

Here is the Benchmark 04 where my VM is as fast as Node.js running a double floating point math test.
It uses the new “(no-var-pull-on)” flag to optimize the programs assembly output:

// double-test-optimized.l1com
//
// (no-var-pull-on) (no-var-pull-off) optimization demo
//
(main func)
    (set int64 1 zero 0)
    (set double 1 zerod 0.0)
    (set double 1 x 23.0)
    (set double 1 y 42.0)
    (set int64 1 max 10000000Q)
    (set int64 1 loop 0)
    (set int64 1 one 1)
    (set double 1 count 1.0)
    (set int64 1 f 0)
    (optimize-if)
    (:loop)
    (no-var-pull-on)

    {count = (count + x)}
    {count = (count + x)}
    {count = (count + x)}
    {count = (count + x)}
    {count = (count + x)}
    {count = (count + x)}
    {count = (count + x)}
    {count = (count + x)}
    {count = (count + x)}
    {count = (count + x)}

    {count = (count + x)}
    {count = (count + x)}
    {count = (count + x)}
    {count = (count + x)}
    {count = (count + x)}
    {count = (count + x)}
    {count = (count + x)}
    {count = (count + x)}
    {count = (count + x)}
    {count = (count + x)}

    {count = (count + y)}
    {count = (count + y)}
    {count = (count + y)}
    {count = (count + y)}
    {count = (count + y)}

    {count = (count + y)}
    {count = (count + y)}
    {count = (count + y)}
    {count = (count + y)}
    {count = (count + y)}

    (no-var-pull-off)
    ((count zerod +d) count =)

    ((loop one +) loop =)
    (((loop max <=) f =) f if)
        (:loop jmp)
    (endif)

    (5 count 0 0 intr0)
    (7 0 0 0 intr0)
    (255 0 0 0 intr0)
(funcend)

This program compiles to this assembly code:

.data
Q, 1, zero
@, 0Q, 0
F, 1, zerod
@, 8Q, 0.0
F, 1, x
@, 16Q, 23.0
F, 1, y
@, 24Q, 42.0
Q, 1, max
@, 32Q, 10000000Q
Q, 1, loop
@, 40Q, 0
Q, 1, one
@, 48Q, 1
F, 1, count
@, 56Q, 1.0
Q, 1, f
@, 64Q, 0
.dend
.code
:main
loada zero, 0, 0
:loop
loadd count, 0, 1
loadd x, 0, 2
addd 1, 2, 3
addd 3, 2, 1
addd 1, 2, 3
addd 3, 2, 1
addd 1, 2, 3
addd 3, 2, 1
addd 1, 2, 3
addd 3, 2, 1
addd 1, 2, 3
addd 3, 2, 1
addd 1, 2, 3
addd 3, 2, 1
addd 1, 2, 3
addd 3, 2, 1
addd 1, 2, 3
addd 3, 2, 1
addd 1, 2, 3
addd 3, 2, 1
addd 1, 2, 3
addd 3, 2, 1
loadd y, 0, 3
addd 1, 3, 4
addd 4, 3, 1
addd 1, 3, 4
addd 4, 3, 1
addd 1, 3, 4
addd 4, 3, 1
addd 1, 3, 4
addd 4, 3, 1
addd 1, 3, 4
addd 4, 3, 1
loadd zerod, 0, 4
addd 1, 4, 5
load count, 0, 6
pulld 5, 6, 0
loada loop, 0, 1
loada one, 0, 2
addi 1, 2, 3
load loop, 0, 4
pullqw 3, 4, 0
loada loop, 0, 1
loada max, 0, 5
lseqi 1, 5, 6
jmpi 6, :if_0
jmp :endif_0
:if_0
jmp :loop
:endif_0
loadd count, 0, 1
intr0 5, 1, 0, 0
intr0 7, 0, 0, 0
intr0 255, 0, 0, 0
rts
.cend

In the Brackets code:

{count = (count + x)}

We get this assembly code:

addd 1, 2, 3

That is as good as hand written assembly code, done by the compiler!
Don’t forget to do: “(no-var-pull-off)” to make it turned off after your code block!