Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Latest commit

 

History

History
History
725 lines (539 loc) · 15.3 KB

File metadata and controls

725 lines (539 loc) · 15.3 KB
Copy raw file
Download raw file
Outline
Edit and raw actions

DeviceScript bytecode spec

This file documents bytecode format for DeviceScript. A C header file and a TypeScript file are generated from it. Additional structures are defined in devs_format.h.

A DeviceScript bytecode file contains magic and version numbers followed by a number of binary sections defining functions, various literals (floats, ASCII strings, Unicode strings, buffers), Jacdac service specifications, and runtime configuration (configureHardware() and built-in servers).

Functions are sequences of opcodes defined below. Opcodes are divided into expressions (with return type) which do not modify state, and statements (no return type; ret_val() expression is used to retrieve the logical result of a last statement). Many opcodes (both expressions and statements) can also throw an exception.

For a more highlevel description of runtime and bytecode, see Runtime implementation page.

Format Constants

img_version_major = 2
img_version_minor = 16
img_version_patch = 4
img_version = $version
magic0 = 0x53766544 // "DevS"
magic1 = 0xf1296e0a
num_img_sections = 10
fix_header_size = 32
section_header_size = 8
function_header_size = 16
ascii_header_size = 2
utf8_header_size = 4
utf8_table_shift = 4
binary_size_align = 32
max_stack_depth = 16
max_call_depth = 100
direct_const_op = 0x80
direct_const_offset = 16
first_multibyte_int = 0xf8
first_non_opcode = 0x10000
first_builtin_function = 50000
max_args_short_call = 8
service_spec_header_size = 16
service_spec_packet_size = 8
service_spec_field_size = 4
role_bits = 15

Ops

Control flow

call0(func) = 2                                   // CALL func()
call1(func, v0) = 3                               // CALL func(v0)
call2(func, v0, v1) = 4                           // CALL func(v0, v1)
call3(func, v0, v1, v2) = 5                       // CALL func(v0, v1, v2)
call4(func, v0, v1, v2, v3) = 6                   // CALL func(v0, v1, v2, v3)
call5(func, v0, v1, v2, v3, v4) = 7               // CALL func(v0, v1, v2, v3, v4)
call6(func, v0, v1, v2, v3, v4, v5) = 8           // CALL func(v0, v1, v2, v3, v4, v5)
call7(func, v0, v1, v2, v3, v4, v5, v6) = 9       // CALL func(v0, v1, v2, v3, v4, v5, v6)
call8(func, v0, v1, v2, v3, v4, v5, v6, v7) = 10  // CALL func(v0, v1, v2, v3, v4, v5, v6, v7)

Call a function with given number of parameters.

call_array(func, args) = 79                        // CALL func(...args)

Passes arguments to a function as an array. The array can be at most max_stack_depth - 1 elements long.

final return(value) = 12

final jmp(*jmpoffset) = 13                // JMP jmpoffset

jmp_z(*jmpoffset, x) = 14                 // JMP jmpoffset IF NOT x

Jump if condition is false.

jmp_ret_val_z(*jmpoffset) = 78            // JMP jmpoffset IF ret_val is nullish

Used in compilation of ?..

try(*jmpoffset) = 80                // TRY jmpoffset

Start try-catch block - catch/finally handler is at the jmpoffset.

final end_try(*jmpoffset) = 81

Try block has to end with this. jmpoffset is for continuation code.

catch() = 82

Has to be the first opcode in the catch handler. Causes error elsewhere. If value throw is JMP rethrows immediately.

finally() = 83

Has to be the first opcode in the finally handler. Finally block should be followed by storing exception value in a local and finish with re_throw of the exception. retval set to null when block executed not due to an exception.

final throw(value) = 84

Throw an exception.

final re_throw(value) = 85

Throw an exception without setting the __stack__ field. Does nothing if value is null.

final throw_jmp(*jmpoffset, level) = 86

Jump to given offset popping level try blocks, activating the finally blocks on the way.

debugger() = 87

Trigger breakpoint when debugger connected. No-op otherwise.

Variables

store_local(*local_idx, value) = 17      // local_idx := value

store_global(*global_idx, value) = 18    // global_idx := value

store_buffer(buffer, numfmt, offset, value) = 19

load_local(*local_idx): any = 21

load_global(*global_idx): any = 22

store_closure(*local_clo_idx, levels, value) = 73

load_closure(*local_clo_idx, levels): any = 74

make_closure(*func_idx): function = 75    // CLOSURE(func_idx)

store_ret_val(x) = 93                     // ret_val := x

Field access

index(object, idx): any = 24              // object[idx]

Read named field or sequence member (depending on type of idx).

index_set(object, index, value) = 25         // object[index] := value

Write named field or sequence member (depending on type of idx).

index_delete(object, index) = 11              // delete object[index]

Remove a named field from an object.

builtin_field(*builtin_idx, obj): any = 26  // {swap}obj.builtin_idx

Shorthand to index(obj, static_builtin_string(builtin_idx))

ascii_field(*ascii_idx, obj): any = 27      // {swap}obj.ascii_idx

Shorthand to index(obj, static_ascii_string(ascii_idx))

utf8_field(*utf8_idx, obj): any = 28        // {swap}obj.utf8_idx

Shorthand to index(obj, static_utf8_string(utf8_idx))

fun math_field(*builtin_idx): any = 29      // Math.builtin_idx

fun ds_field(*builtin_idx): any = 30        // ds.builtin_idx

fun object_field(*builtin_idx): any = 16    // Object.builtin_idx

fun new(func): function = 88                // new func

fun bind(func, obj): function = 15          // func.bind(obj)

Objects

alloc_map() = 31

alloc_array(initial_size) = 32

alloc_buffer(size) = 33

Statics

fun static_spec_proto(*spec_idx): any = 34  // spec_idx.prototype

fun static_buffer(*buffer_idx): buffer = 35

fun static_builtin_string(*builtin_idx): string = 36

fun static_ascii_string(*ascii_idx): string = 37

fun static_utf8_string(*utf8_idx): string = 38

fun static_function(*func_idx): function = 39

fun static_spec(*spec_idx): any = 94

fun literal(*value): number = 40

fun literal_f64(*f64_idx): number = 41

fun builtin_object(*builtin_object): number = 1

Misc

removed_42() = 42

load_buffer(buffer, numfmt, offset): number = 43

ret_val(): any = 44

Return value of query register, call, etc.

fun typeof(object): number = 45

Returns Object_Type enum.

fun typeof_str(object): number = 76

Returns JS-compatible string.

fun undefined(): null = 46  // undefined

Returns undefined value.

fun null(): null = 90        // null

Returns null value.

fun is_undefined(x): bool = 47

Check if object is exactly undefined.

fun instance_of(obj, cls): bool = 89

Check if obj has cls.prototype in its prototype chain.

fun is_nullish(x): bool = 72

Check if value is precisely null or undefined.

Booleans

fun true(): bool = 48

fun false(): bool = 49

fun to_bool(x): bool = 50   // !!x

Math operations

fun nan(): number = 51

fun inf(): number = 20

fun abs(x): number = 52

fun bit_not(x): number = 53   // ~x

fun is_nan(x): bool = 54

fun neg(x): number = 55   // -x

fun uplus(x): number = 23  // +x

fun not(x): bool = 56   // !x

fun to_int(x): number = 57

Same as x | 0.

fun add(x, y): number = 58     // x + y

Note that this also works on strings, etc.

fun sub(x, y): number = 59     // x - y

fun mul(x, y): number = 60     // x * y

fun div(x, y): number = 61     // x / y

fun bit_and(x, y): number = 62 // x & y

fun bit_or(x, y): number = 63  // x | y

fun bit_xor(x, y): number = 64 // x ^ y

fun shift_left(x, y): number = 65      // x << y

fun shift_right(x, y): number = 66      // x >> y

fun shift_right_unsigned(x, y): number = 67      // x >>> y

fun eq(x, y): bool = 68      // x === y

fun le(x, y): bool = 69      // x <= y

fun lt(x, y): bool = 70      // x < y

fun ne(x, y): bool = 71      // x !== y

fun approx_eq(x, y): bool = 91  // x == y

fun approx_ne(x, y): bool = 92  // x != y

To be removed (soon)

removed_77() = 77

Enum: StrIdx

buffer = 0
builtin = 1
ascii = 2
utf8 = 3
_shift = 14

Enum: OpCall

sync = 0

Regular call. Unused.

bg = 1

Always start new fiber.

bg_max1 = 2

Start new fiber unless one is already running.

bg_max1_pend1 = 3

If fiber is already running, set a flag for it to be restarted when it finishes. Otherwise, start new fiber.

bg_max1_replace = 4

Start new fiber. If it's already running, replace it.

Enum: BytecodeFlag

num_args_mask = 0xf
is_stmt = 0x10
takes_number = 0x20
is_stateless = 0x40  // fun modifier - only valid when !is_stmt
is_final_stmt = 0x40 // final modifier - only valid when is_stmt

Enum: FunctionFlag

needs_this = 0x01
is_ctor = 0x02
has_rest_arg = 0x04

Enum: NumFmt

Size in bits is: 8 << (fmt & 0b11). Format is ["u", "i", "f", "reserved"](fmt >> 2)

U8 = 0b0000
U16 = 0b0001
U32 = 0b0010
U64 = 0b0011
I8 = 0b0100
I16 = 0b0101
I32 = 0b0110
I64 = 0b0111
F8 = 0b1000 // not supported
F16 = 0b1001 // not supported
F32 = 0b1010
F64 = 0b1011
Special = 0b1100

Enum: NumFmt_Special

empty = 0
bytes = 1
string = 2
string0 = 3
bool = 4
pipe = 5
pipe_port = 6

Enum: PacketSpec_Code

register = 0x1000
event = 0x8000
command = 0x0000
report = 0x2000
MASK = 0xf000

Enum: ServiceSpec_Flag

derive_mask = 0x000f
derive_base = 0x0000
derive_sensor = 0x0001
derive_last = 0x0001

Enum: PacketSpec_Flag

multi_field = 0x01

Enum: FieldSpec_Flag

is_bytes = 0x01
starts_repeats = 0x02

Enum: Object_Type

undefined = 0

Only the undefined value.

number = 1

Integers, doubles, infinity, nan.

map = 2

array = 3

buffer = 4

role = 5

bool = 6

Only true and false values.

fiber = 7

function = 8

string = 9

packet = 10

exotic = 11

null = 12

image = 13

Object_Types only used in static type info

any = 14

void = 15

Enum: BuiltIn_Object

Math = 0
Object = 1
Object_prototype = 2
Array = 3
Array_prototype = 4
Buffer = 5
Buffer_prototype = 6
String = 7
String_prototype = 8
Number = 9
Number_prototype = 10
DsFiber = 11
DsFiber_prototype = 12
DsRole = 13
DsRole_prototype = 14
Function = 15
Function_prototype = 16
Boolean = 17
Boolean_prototype = 18
DsPacket = 19
DsPacket_prototype = 20
DeviceScript = 21
DsPacketInfo_prototype = 22
DsRegister_prototype = 23
DsCommand_prototype = 24
DsEvent_prototype = 25
DsReport_prototype = 26
Error = 27
Error_prototype = 28
TypeError = 29
TypeError_prototype = 30
RangeError = 31
RangeError_prototype = 32
SyntaxError = 33
SyntaxError_prototype = 34
JSON = 35
DsServiceSpec = 36
DsServiceSpec_prototype = 37
DsPacketSpec = 38
DsPacketSpec_prototype = 39
Image = 40
Image_prototype = 41
GPIO = 42
GPIO_prototype = 43

Enum: BuiltIn_String

_empty = 0
MInfinity = 1 // -Infinity
DeviceScript = 2
E = 3
Infinity = 4
LN10 = 5
LN2 = 6
LOG10E = 7
LOG2E = 8
NaN = 9
PI = 10
SQRT1_2 = 11
SQRT2 = 12
abs = 13
alloc = 14
array = 15
blitAt = 16
boolean = 17
buffer = 18
cbrt = 19
ceil = 20
charCodeAt = 21
clamp = 22
exp = 23
false = 24
fillAt = 25
floor = 26
forEach = 27
function = 28
getAt = 29
idiv = 30
imul = 31
isBound = 32
join = 33
length = 34
log = 35
log10 = 36
log2 = 37
map = 38
max = 39
min = 40
next = 41
null = 42
number = 43
onChange = 44
onConnected = 45
onDisconnected = 46
packet = 47
_panic = 48
pop = 49
pow = 50
prev = 51
prototype = 52
push = 53
random = 54
randomInt = 55
read = 56
restart = 57
round = 58
setAt = 59
setLength = 60
shift = 61
signal = 62
slice = 63
splice = 64
sqrt = 65
string = 66
subscribe = 67
toString = 68
true = 69
undefined = 70
unshift = 71
wait = 72
write = 73

sleep = 74
imod = 75
format = 76
insert = 77
start = 78
cloud = 79
main = 80
charAt = 81
object = 82
parseInt = 83
parseFloat = 84
assign = 85
keys = 86
values = 87
__func__ = 88
role = 89
deviceIdentifier = 90
shortId = 91
serviceIndex = 92
serviceCommand = 93
payload = 94
decode = 95
encode = 96
_onPacket = 97
code = 98
name = 99
isEvent = 100
eventCode = 101
isRegSet = 102
isRegGet = 103
regCode = 104
flags = 105
isReport = 106
isCommand = 107
isArray = 108
inline = 109
assert = 110
pushRange = 111
sendCommand = 112
__stack__ = 113
Error = 114
TypeError = 115
RangeError = 116
stack = 117
message = 118
cause = 119
__new__ = 120
setPrototypeOf = 121
getPrototypeOf = 122
constructor = 123
__proto__ = 124
_logRepr = 125
print = 126
everyMs = 127
setInterval = 128
setTimeout = 129
clearInterval = 130
clearTimeout = 131
SyntaxError = 132
JSON = 133
parse = 134
stringify = 135
_dcfgString = 136
isSimulator = 137
_Role = 138 // Role
Fiber = 139
suspend = 140
resume = 141
terminate = 142
self = 143
current = 144
id = 145
_commandResponse = 146
isAction = 147
millis = 148
from = 149
hex = 150
utf8 = 151
utf_8 = 152 // utf-8
suspended = 153
reboot = 154
server = 155
spec = 156
ServiceSpec = 157
classIdentifier = 158
lookup = 159
PacketSpec = 160
parent = 161
response = 162
ServerInterface = 163
_onServerPacket = 164
_serverSend = 165
notImplemented = 166
delay = 167
fromCharCode = 168
_allocRole = 169
spiConfigure = 170
spiXfer = 171
_socketOpen = 172
_socketClose = 173
_socketWrite = 174
_socketOnEvent = 175
open = 176
close = 177
error_ = 178 // error
data = 179
toUpperCase = 180
toLowerCase = 181
indexOf = 182
byteLength = 183
Image = 184
width = 185
height = 186
bpp = 187
get = 188
clone = 189
set = 190
fill = 191
flipX = 192
flipY = 193
transposed = 194
drawImage = 195
drawTransparentImage = 196
overlapsWith = 197
fillRect = 198
drawLine = 199
equals = 200
isReadOnly = 201
fillCircle = 202
blitRow = 203
blit = 204
_i2cTransaction = 205
_twinMessage = 206
spiSendImage = 207
gpio = 208
label = 209
mode = 210
capabilities = 211
value = 212
setMode = 213
fillRandom = 214
encrypt = 215
decrypt = 216
digest = 217
ledStripSend = 218
rotate = 219
register = 220
event = 221
action = 222
report = 223
type = 224
byCode = 225
Morty Proxy This is a proxified and sanitized view of the page, visit original site.