Fun 0.41.5
The programming language that makes You have fun
Loading...
Searching...
No Matches
bytecode.c
Go to the documentation of this file.
1/*
2 * This file is part of the Fun programming language.
3 * https://fun-lang.xyz/
4 *
5 * Copyright 2025 Johannes Findeisen <you@hanez.org>
6 * Licensed under the terms of the Apache-2.0 license.
7 * https://opensource.org/license/apache-2-0
8 */
9
10#include "bytecode.h"
11#include <stdio.h>
12#include <stdlib.h>
13
18
28 Bytecode *bc = (Bytecode *)malloc(sizeof(Bytecode));
29 bc->instructions = NULL;
30 bc->instr_count = 0;
31 bc->constants = NULL;
32 bc->const_count = 0;
33 bc->name = NULL;
34 bc->source_file = NULL;
35 return bc;
36}
37
49 bc->constants = (Value *)realloc(bc->constants, sizeof(Value) * (bc->const_count + 1));
51 return bc->const_count++;
52}
53
62int bytecode_add_instruction(Bytecode *bc, OpCode op, int32_t operand) {
63 bc->instructions = (Instruction *)realloc(bc->instructions, sizeof(Instruction) * (bc->instr_count + 1));
64 bc->instructions[bc->instr_count].op = op;
65 bc->instructions[bc->instr_count].operand = operand;
66 return bc->instr_count++;
67}
68
78void bytecode_set_operand(Bytecode *bc, int idx, int32_t operand) {
79 if (idx >= 0 && idx < bc->instr_count) {
80 bc->instructions[idx].operand = operand;
81 }
82}
83
93 if (!bc) return;
94 for (int i = 0; i < bc->const_count; ++i) {
95 free_value(bc->constants[i]);
96 }
97 free(bc->constants);
99 if (bc->name) free((void *)bc->name);
100 if (bc->source_file) free((void *)bc->source_file);
101 free(bc);
102}
103
110static const char *opcode_name(OpCode op) {
111 switch (op) {
112 case OP_NOP:
113 return "NOP";
114 case OP_LOAD_CONST:
115 return "LOAD_CONST";
116 case OP_LOAD_LOCAL:
117 return "LOAD_LOCAL";
118 case OP_STORE_LOCAL:
119 return "STORE_LOCAL";
120 case OP_LOAD_GLOBAL:
121 return "LOAD_GLOBAL";
122 case OP_STORE_GLOBAL:
123 return "STORE_GLOBAL";
124 case OP_ADD:
125 return "ADD";
126 case OP_SUB:
127 return "SUB";
128 case OP_MUL:
129 return "MUL";
130 case OP_DIV:
131 return "DIV";
132 case OP_LT:
133 return "LT";
134 case OP_LTE:
135 return "LTE";
136 case OP_GT:
137 return "GT";
138 case OP_GTE:
139 return "GTE";
140 case OP_EQ:
141 return "EQ";
142 case OP_NEQ:
143 return "NEQ";
144 case OP_POP:
145 return "POP";
146 case OP_JUMP:
147 return "JUMP";
149 return "JUMP_IF_FALSE";
150 case OP_CALL:
151 return "CALL";
152 case OP_RETURN:
153 return "RETURN";
154 case OP_PRINT:
155 return "PRINT";
156 case OP_ECHO:
157 return "ECHO";
158 case OP_HALT:
159 return "HALT";
160 case OP_MOD:
161 return "MOD";
162 case OP_AND:
163 return "AND";
164 case OP_OR:
165 return "OR";
166 case OP_NOT:
167 return "NOT";
168 case OP_DUP:
169 return "DUP";
170 case OP_SWAP:
171 return "SWAP";
172 case OP_MAKE_ARRAY:
173 return "MAKE_ARRAY";
174 case OP_INDEX_GET:
175 return "INDEX_GET";
176 case OP_INDEX_SET:
177 return "INDEX_SET";
178 case OP_LEN:
179 return "LEN";
180 case OP_PUSH:
181 return "ARR_PUSH";
182 case OP_APOP:
183 return "ARR_POP";
184 case OP_SET:
185 return "ARR_SET";
186 case OP_INSERT:
187 return "ARR_INSERT";
188 case OP_REMOVE:
189 return "ARR_REMOVE";
190 case OP_SLICE:
191 return "SLICE";
192 case OP_TO_NUMBER:
193 return "TO_NUMBER";
194 case OP_TO_STRING:
195 return "TO_STRING";
196 case OP_TYPEOF:
197 return "TYPEOF";
198 case OP_CAST:
199 return "CAST";
200 case OP_SPLIT:
201 return "SPLIT";
202 case OP_JOIN:
203 return "JOIN";
204 case OP_SUBSTR:
205 return "SUBSTR";
206 case OP_FIND:
207 return "FIND";
208 case OP_REGEX_MATCH:
209 return "REGEX_MATCH";
210 case OP_REGEX_SEARCH:
211 return "REGEX_SEARCH";
213 return "REGEX_REPLACE";
214 case OP_CONTAINS:
215 return "CONTAINS";
216 case OP_INDEX_OF:
217 return "INDEX_OF";
218 case OP_CLEAR:
219 return "CLEAR";
220 case OP_ENUMERATE:
221 return "ENUMERATE";
222 case OP_ZIP:
223 return "ZIP";
224 case OP_MIN:
225 return "MIN";
226 case OP_MAX:
227 return "MAX";
228 case OP_CLAMP:
229 return "CLAMP";
230 case OP_ABS:
231 return "ABS";
232 case OP_POW:
233 return "POW";
234 case OP_RANDOM_SEED:
235 return "RANDOM_SEED";
236 case OP_RANDOM_INT:
237 return "RANDOM_INT";
238 case OP_MAKE_MAP:
239 return "MAKE_MAP";
240 case OP_KEYS:
241 return "KEYS";
242 case OP_VALUES:
243 return "VALUES";
244 case OP_HAS_KEY:
245 return "HAS_KEY";
246 case OP_READ_FILE:
247 return "READ_FILE";
248 case OP_WRITE_FILE:
249 return "WRITE_FILE";
250 case OP_ENV:
251 return "ENV";
252 case OP_INPUT_LINE:
253 return "INPUT_LINE";
254 case OP_PROC_RUN:
255 return "PROC_RUN";
256 case OP_PROC_SYSTEM:
257 return "PROC_SYSTEM";
258 case OP_TIME_NOW_MS:
259 return "TIME_NOW_MS";
261 return "CLOCK_MONO_MS";
262 case OP_DATE_FORMAT:
263 return "DATE_FORMAT";
264 case OP_ENV_ALL:
265 return "ENV_ALL";
266 case OP_FUN_VERSION:
267 return "FUN_VERSION";
268 case OP_THREAD_SPAWN:
269 return "THREAD_SPAWN";
270 case OP_THREAD_JOIN:
271 return "THREAD_JOIN";
272 case OP_SLEEP_MS:
273 return "SLEEP_MS";
275 return "RANDOM_NUMBER";
276 case OP_BAND:
277 return "BAND";
278 case OP_BOR:
279 return "BOR";
280 case OP_BXOR:
281 return "BXOR";
282 case OP_BNOT:
283 return "BNOT";
284 case OP_SHL:
285 return "SHL";
286 case OP_SHR:
287 return "SHR";
288 case OP_ROTL:
289 return "ROTL";
290 case OP_ROTR:
291 return "ROTR";
292 case OP_JSON_PARSE:
293 return "JSON_PARSE";
295 return "JSON_STRINGIFY";
297 return "JSON_FROM_FILE";
298 case OP_JSON_TO_FILE:
299 return "JSON_TO_FILE";
300 case OP_CURL_GET:
301 return "CURL_GET";
302 case OP_CURL_POST:
303 return "CURL_POST";
305 return "CURL_DOWNLOAD";
306 case OP_SQLITE_OPEN:
307 return "SQLITE_OPEN";
308 case OP_SQLITE_CLOSE:
309 return "SQLITE_CLOSE";
310 case OP_SQLITE_EXEC:
311 return "SQLITE_EXEC";
312 case OP_SQLITE_QUERY:
313 return "SQLITE_QUERY";
315 return "PCSC_ESTABLISH";
316 case OP_PCSC_RELEASE:
317 return "PCSC_RELEASE";
319 return "PCSC_LIST_READERS";
320 case OP_PCSC_CONNECT:
321 return "PCSC_CONNECT";
323 return "PCSC_DISCONNECT";
325 return "PCSC_TRANSMIT";
326 case OP_PCRE2_TEST:
327 return "PCRE2_TEST";
328 case OP_PCRE2_MATCH:
329 return "PCRE2_MATCH";
331 return "PCRE2_FINDALL";
332 case OP_OPENSSL_MD5:
333 return "OPENSSL_MD5";
335 return "OPENSSL_SHA256";
337 return "OPENSSL_SHA512";
339 return "OPENSSL_RIPEMD160";
340 case OP_INI_LOAD:
341 return "INI_LOAD";
342 case OP_INI_FREE:
343 return "INI_FREE";
345 return "INI_GET_STRING";
346 case OP_INI_GET_INT:
347 return "INI_GET_INT";
349 return "INI_GET_DOUBLE";
350 case OP_INI_GET_BOOL:
351 return "INI_GET_BOOL";
352 case OP_INI_SET:
353 return "INI_SET";
354 case OP_INI_UNSET:
355 return "INI_UNSET";
356 case OP_INI_SAVE:
357 return "INI_SAVE";
358 case OP_XML_PARSE:
359 return "XML_PARSE";
360 case OP_XML_ROOT:
361 return "XML_ROOT";
362 case OP_XML_NAME:
363 return "XML_NAME";
364 case OP_XML_TEXT:
365 return "XML_TEXT";
366 case OP_FLOOR:
367 return "FLOOR";
368 case OP_CEIL:
369 return "CEIL";
370 case OP_TRUNC:
371 return "TRUNC";
372 case OP_ROUND:
373 return "ROUND";
374 case OP_SIN:
375 return "SIN";
376 case OP_COS:
377 return "COS";
378 case OP_TAN:
379 return "TAN";
380 case OP_EXP:
381 return "EXP";
382 case OP_LOG:
383 return "LOG";
384 case OP_LOG10:
385 return "LOG10";
386 case OP_SQRT:
387 return "SQRT";
388 case OP_GCD:
389 return "GCD";
390 case OP_LCM:
391 return "LCM";
392 case OP_ISQRT:
393 return "ISQRT";
394 case OP_SIGN:
395 return "SIGN";
396 case OP_FMIN:
397 return "FMIN";
398 case OP_FMAX:
399 return "FMAX";
400 case OP_RUST_HELLO:
401 return "RUST_HELLO";
403 return "RUST_HELLO_ARGS";
405 return "RUST_HELLO_ARGS_RETURN";
406 case OP_RUST_GET_SP:
407 return "RUST_GET_SP";
409 return "RUST_SET_EXIT";
410 default:
411 return "???";
412 }
413}
414
423void bytecode_dump(const Bytecode *bc) {
424 if (!bc) {
425 printf("<null bytecode>\n");
426 return;
427 }
428 printf("Constants (%d):\n", bc->const_count);
429 for (int i = 0; i < bc->const_count; ++i) {
430 printf(" [%d] ", i);
431 print_value(&bc->constants[i]);
432 printf("\n");
433 }
434 printf("Instructions (%d):\n", bc->instr_count);
435 for (int i = 0; i < bc->instr_count; ++i) {
436 const Instruction *ins = &bc->instructions[i];
437 printf(" %3d: %-15s %d\n", i, opcode_name(ins->op), ins->operand);
438 }
439}
Bytecode * bytecode_new(void)
Allocate and initialize an empty Bytecode object.
Definition bytecode.c:27
int bytecode_add_instruction(Bytecode *bc, OpCode op, int32_t operand)
Append a single instruction to the instruction stream.
Definition bytecode.c:62
void bytecode_free(Bytecode *bc)
Free a Bytecode and all memory it owns.
Definition bytecode.c:92
void bytecode_dump(const Bytecode *bc)
Print a human-readable dump of constants and instructions to stdout.
Definition bytecode.c:423
void bytecode_set_operand(Bytecode *bc, int idx, int32_t operand)
Patch the operand of a previously emitted instruction.
Definition bytecode.c:78
int bytecode_add_constant(Bytecode *bc, Value v)
Append a constant to a Bytecode's constant table.
Definition bytecode.c:48
Definitions for the Fun VM bytecode: opcodes, instruction format, and bytecode container API.
OpCode
VM operation codes executed by the Fun virtual machine.
Definition bytecode.h:35
@ OP_OPENSSL_SHA512
Definition bytecode.h:199
@ OP_PCSC_RELEASE
Definition bytecode.h:185
@ OP_GCD
Definition bytecode.h:268
@ OP_JSON_PARSE
Definition bytecode.h:167
@ OP_READ_FILE
Definition bytecode.h:136
@ OP_CLOCK_MONO_MS
Definition bytecode.h:145
@ OP_CALL
Definition bytecode.h:60
@ OP_RUST_HELLO_ARGS_RETURN
Definition bytecode.h:280
@ OP_ROTL
Definition bytecode.h:163
@ OP_TAN
Definition bytecode.h:261
@ OP_OPENSSL_SHA256
Definition bytecode.h:198
@ OP_JSON_STRINGIFY
Definition bytecode.h:168
@ OP_PCSC_TRANSMIT
Definition bytecode.h:189
@ OP_TRUNC
Definition bytecode.h:255
@ OP_CEIL
Definition bytecode.h:254
@ OP_SPLIT
Definition bytecode.h:101
@ OP_CAST
Definition bytecode.h:95
@ OP_EQ
Definition bytecode.h:53
@ OP_PCRE2_MATCH
Definition bytecode.h:193
@ OP_RANDOM_INT
Definition bytecode.h:127
@ OP_LTE
Definition bytecode.h:50
@ OP_NEQ
Definition bytecode.h:54
@ OP_ISQRT
Definition bytecode.h:270
@ OP_FMAX
Definition bytecode.h:275
@ OP_PCSC_ESTABLISH
Definition bytecode.h:184
@ OP_SQLITE_EXEC
Definition bytecode.h:180
@ OP_FMIN
Definition bytecode.h:274
@ OP_SWAP
Definition bytecode.h:76
@ OP_OPENSSL_RIPEMD160
Definition bytecode.h:200
@ OP_PCSC_LIST_READERS
Definition bytecode.h:186
@ OP_BOR
Definition bytecode.h:158
@ OP_CURL_POST
Definition bytecode.h:174
@ OP_XML_NAME
Definition bytecode.h:216
@ OP_REGEX_SEARCH
Definition bytecode.h:108
@ OP_POW
Definition bytecode.h:125
@ OP_NOT
Definition bytecode.h:73
@ OP_SQRT
Definition bytecode.h:265
@ OP_MOD
Definition bytecode.h:70
@ OP_INI_UNSET
Definition bytecode.h:210
@ OP_WRITE_FILE
Definition bytecode.h:137
@ OP_SQLITE_CLOSE
Definition bytecode.h:179
@ OP_FIND
Definition bytecode.h:104
@ OP_SIGN
Definition bytecode.h:271
@ OP_DUP
Definition bytecode.h:75
@ OP_NOP
Definition bytecode.h:36
@ OP_ENV_ALL
Definition bytecode.h:147
@ OP_VALUES
Definition bytecode.h:132
@ OP_RANDOM_NUMBER
Definition bytecode.h:154
@ OP_INDEX_GET
Definition bytecode.h:80
@ OP_LCM
Definition bytecode.h:269
@ OP_LEN
Definition bytecode.h:84
@ OP_THREAD_SPAWN
Definition bytecode.h:151
@ OP_INDEX_OF
Definition bytecode.h:113
@ OP_MIN
Definition bytecode.h:121
@ OP_SLEEP_MS
Definition bytecode.h:153
@ OP_REGEX_REPLACE
Definition bytecode.h:109
@ OP_MAX
Definition bytecode.h:122
@ OP_SQLITE_OPEN
Definition bytecode.h:178
@ OP_XML_PARSE
Definition bytecode.h:214
@ OP_STORE_LOCAL
Definition bytecode.h:39
@ OP_SLICE
Definition bytecode.h:90
@ OP_INI_GET_DOUBLE
Definition bytecode.h:207
@ OP_JOIN
Definition bytecode.h:102
@ OP_COS
Definition bytecode.h:260
@ OP_BAND
Definition bytecode.h:157
@ OP_ECHO
Definition bytecode.h:64
@ OP_ROTR
Definition bytecode.h:164
@ OP_DATE_FORMAT
Definition bytecode.h:146
@ OP_PROC_SYSTEM
Definition bytecode.h:143
@ OP_OPENSSL_MD5
Definition bytecode.h:197
@ OP_ZIP
Definition bytecode.h:118
@ OP_SUB
Definition bytecode.h:45
@ OP_INI_GET_INT
Definition bytecode.h:206
@ OP_XML_ROOT
Definition bytecode.h:215
@ OP_JUMP
Definition bytecode.h:57
@ OP_DIV
Definition bytecode.h:47
@ OP_SHR
Definition bytecode.h:162
@ OP_JSON_TO_FILE
Definition bytecode.h:170
@ OP_LT
Definition bytecode.h:49
@ OP_INI_GET_BOOL
Definition bytecode.h:208
@ OP_ROUND
Definition bytecode.h:256
@ OP_PRINT
Definition bytecode.h:63
@ OP_INI_GET_STRING
Definition bytecode.h:205
@ OP_SHL
Definition bytecode.h:161
@ OP_KEYS
Definition bytecode.h:131
@ OP_RUST_HELLO
Definition bytecode.h:278
@ OP_LOAD_LOCAL
Definition bytecode.h:38
@ OP_CURL_DOWNLOAD
Definition bytecode.h:175
@ OP_PCSC_CONNECT
Definition bytecode.h:187
@ OP_RUST_SET_EXIT
Definition bytecode.h:282
@ OP_ENV
Definition bytecode.h:140
@ OP_PUSH
Definition bytecode.h:85
@ OP_TO_NUMBER
Definition bytecode.h:93
@ OP_LOAD_GLOBAL
Definition bytecode.h:41
@ OP_FUN_VERSION
Definition bytecode.h:148
@ OP_LOAD_CONST
Definition bytecode.h:37
@ OP_ADD
Definition bytecode.h:44
@ OP_CONTAINS
Definition bytecode.h:112
@ OP_INPUT_LINE
Definition bytecode.h:141
@ OP_MUL
Definition bytecode.h:46
@ OP_PCRE2_FINDALL
Definition bytecode.h:194
@ OP_SET
Definition bytecode.h:87
@ OP_PROC_RUN
Definition bytecode.h:142
@ OP_LOG10
Definition bytecode.h:264
@ OP_ENUMERATE
Definition bytecode.h:117
@ OP_PCRE2_TEST
Definition bytecode.h:192
@ OP_SIN
Definition bytecode.h:259
@ OP_TIME_NOW_MS
Definition bytecode.h:144
@ OP_XML_TEXT
Definition bytecode.h:217
@ OP_STORE_GLOBAL
Definition bytecode.h:42
@ OP_SUBSTR
Definition bytecode.h:103
@ OP_INI_SET
Definition bytecode.h:209
@ OP_TO_STRING
Definition bytecode.h:94
@ OP_GT
Definition bytecode.h:51
@ OP_INI_SAVE
Definition bytecode.h:211
@ OP_GTE
Definition bytecode.h:52
@ OP_HALT
Definition bytecode.h:65
@ OP_ABS
Definition bytecode.h:124
@ OP_INI_LOAD
Definition bytecode.h:203
@ OP_TYPEOF
Definition bytecode.h:96
@ OP_RETURN
Definition bytecode.h:61
@ OP_REGEX_MATCH
Definition bytecode.h:107
@ OP_SQLITE_QUERY
Definition bytecode.h:181
@ OP_APOP
Definition bytecode.h:86
@ OP_BNOT
Definition bytecode.h:160
@ OP_THREAD_JOIN
Definition bytecode.h:152
@ OP_CLAMP
Definition bytecode.h:123
@ OP_RUST_HELLO_ARGS
Definition bytecode.h:279
@ OP_CURL_GET
Definition bytecode.h:173
@ OP_MAKE_ARRAY
Definition bytecode.h:79
@ OP_AND
Definition bytecode.h:71
@ OP_CLEAR
Definition bytecode.h:114
@ OP_RANDOM_SEED
Definition bytecode.h:126
@ OP_INDEX_SET
Definition bytecode.h:81
@ OP_LOG
Definition bytecode.h:263
@ OP_INI_FREE
Definition bytecode.h:204
@ OP_REMOVE
Definition bytecode.h:89
@ OP_HAS_KEY
Definition bytecode.h:133
@ OP_OR
Definition bytecode.h:72
@ OP_PCSC_DISCONNECT
Definition bytecode.h:188
@ OP_FLOOR
Definition bytecode.h:253
@ OP_JSON_FROM_FILE
Definition bytecode.h:169
@ OP_INSERT
Definition bytecode.h:88
@ OP_EXP
Definition bytecode.h:262
@ OP_RUST_GET_SP
Definition bytecode.h:281
@ OP_JUMP_IF_FALSE
Definition bytecode.h:58
@ OP_MAKE_MAP
Definition bytecode.h:130
@ OP_POP
Definition bytecode.h:56
@ OP_BXOR
Definition bytecode.h:159
Value v
Definition cast.c:22
int idx
Definition index_of.c:38
free(vals)
Instruction * instructions
Definition bytecode.h:294
const char * source_file
Definition bytecode.h:302
const char * name
Definition bytecode.h:301
Value * constants
Definition bytecode.h:297
int const_count
Definition bytecode.h:298
int instr_count
Definition bytecode.h:295
OpCode op
Definition bytecode.h:289
int32_t operand
Definition bytecode.h:290
Tagged union representing a Fun value.
Definition value.h:68
void print_value(const Value *v)
Print a human-readable representation of a Value to stdout.
Definition value.c:552
void free_value(Value v)
Free dynamic storage owned by a Value.
Definition value.c:517
Value copy_value(const Value *v)
Shallow copy a Value.
Definition value.c:415