Skip to content

👾 An incomplete v8 bytecode interpreter / virtual machine for a subset of instructions

License

Notifications You must be signed in to change notification settings

maciejsmolinski/v8-bytecode-vm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

83 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

V8 ByteCode Virtual Machine

An incomplete v8 bytecode interpreter / virtual machine for a subset of instructions. Plus, a tiny playground for profiling javascript code and inspecting the corresponding bytecode.

Ambitions

This project's ambition is building an incomplete virtual machine capable of executing a subset of byte code supported by V8 JavaScript engine as pictured below. Largely as a challenge of building a register machine capable of executing different operations, highly practical, as well as to better understand the inner-workings of the most popular and battle-tested JavaScript engine and optimizations happening behind the scenes.

graph TD

JS[JavaScript]
BC[V8 Byte Code]
VM[Virtual Machine]
IO[Output]
V8[JavaScript<br> Engine]

JS-->BC
BC-->VM
VM-->IO

JS-->V8
V8-->IO

style VM fill:blue
Loading

Running virtual machine

Note: Does not currently parse .bytecode files, the VM is currently work in progress

$ make start

Running test suites

Install dependencies with make install and execute

$ make test # or make tdd

Running tests with high verbosity logs from executor

$ EXPLAIN=1 DEBUG=1 make test # or make tdd

Generating bytecode

Generate .bytecode file for each javascript file in the examples/ directory

$ make

Clean all .bytecode files in the examples/ directory

$ make clean

Interaction Example

$ make
✓ Generated examples/earlyReturn.bytecode
$ cat examples/earlyReturn.bytecode | head -20
[generated bytecode for function: main (0x26a884854fb9 <SharedFunctionInfo main>)]
Bytecode length: 49
Parameter count 2
Register count 3
Frame size 24
OSR nesting level: 0
Bytecode Age: 0
   71 S> 0x26a8848559ce @    0 : 0c                LdaZero
   77 E> 0x26a8848559cf @    1 : 6c 03 00          TestLessThan a0, [0]
         0x26a8848559d2 @    4 : 98 19             JumpIfFalse [25] (0x26a8848559eb @ 29)
   88 S> 0x26a8848559d4 @    6 : 21 00 01          LdaGlobal [0], [1]
         0x26a8848559d7 @    9 : c2                Star1
   96 E> 0x26a8848559d8 @   10 : 2d f9 01 03       LdaNamedProperty r1, [1], [3]
         0x26a8848559dc @   14 : c3                Star0
         0x26a8848559dd @   15 : 13 02             LdaConstant [2]
         0x26a8848559df @   17 : c1                Star2
   96 E> 0x26a8848559e0 @   18 : 5d fa f9 f8 05    CallProperty1 r0, r1, r2, [5]
  123 S> 0x26a8848559e5 @   23 : 0b 03             Ldar a0
  132 E> 0x26a8848559e7 @   25 : 46 ff 07          MulSmi [-1], [7]
  137 S> 0x26a8848559ea @   28 : a8                Return
$ make start
[DEBUG] OP [ 'Jump', [ 3 ] ]
[DEBUG] OP [ 'LdaZero' ]
[DEBUG] OP [ 'LdaGlobal', [ 0 ], [ 1 ] ]
[DEBUG] OP [ 'Star0' ]
[DEBUG] OP [ 'LdaNamedProperty', 'r0', [ 1 ], [ 3 ] ]
[DEBUG] OP [ 'Star1' ]
[DEBUG] OP [ 'LdaConstant', [ 2 ] ]
[DEBUG] OP [ 'Star2' ]
[DEBUG] OP [ 'CallProperty1', 'r1', 'r0', 'r2', [ 5 ] ]
•• Hello World ••
[DEBUG] OP [ 'LdaSmi', [ 6 ] ]
[DEBUG] OP [ 'Star0' ]
[DEBUG] OP [ 'TestLessThan', 'r0', [ 0 ] ]
[DEBUG] OP [ 'MulSmi', [ 5 ], [ 0 ] ]
[DEBUG] OP [ 'Return' ]
[DEBUG] ST {
  registers: {
    accumulator: 30,
    r0: 6,
    r1: [Function: log],
    r2: '•• Hello World ••',
    a0: undefined,
    a1: undefined,
    a2: undefined
  },
  flags: { boolean: false },
  constants: [ 'console', 'log', '•• Hello World ••', 1 ],
  ip: 14,
  return: 30
}

Resources

About

👾 An incomplete v8 bytecode interpreter / virtual machine for a subset of instructions

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published