asoma.dev · the C reference for libose
libose
the C library every o.se host is built on
Loading...
Searching...
No Matches
ose_vm.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2019-23 John MacCallum Permission is hereby granted,
3 free of charge, to any person obtaining a copy of this software
4 and associated documentation files (the "Software"), to deal in
5 the Software without restriction, including without limitation the
6 rights to use, copy, modify, merge, publish, distribute,
7 sublicense, and/or sell copies of the Software, and to permit
8 persons to whom the Software is furnished to do so, subject to the
9 following conditions:
10
11 The above copyright notice and this permission notice shall be
12 included in all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 DEALINGS IN THE SOFTWARE.
22*/
23
70#ifndef OSE_VM_H
71#define OSE_VM_H
72
73#include "ose_context.h"
74/* osevm_setFault()/osevm_getFault() name `enum ose_errno` in their
75 signatures, and a client that includes this header without
76 ose_stackops.h first has no declaration for it. The enum then has
77 function scope, and the compiler says so. */
78#include "ose_errno.h"
79#include "ose_util.h" /* the runtime OSEVM_INPUT()/STACK()/... read an
80 int32 out of the cache; without this a host that
81 leaves the sizes undefined gets an implicit
82 declaration of ose_readInt32, which is an error
83 under C99 and later */
84#include "osevm_lib.h"
85
86#ifdef __cplusplus
87extern "C" {
88#endif
89
94#define OSEVM_ADDR_INPUT "/_i"
95#define OSEVM_ADDR_STACK "/_s"
96#define OSEVM_ADDR_ENV "/_e"
97#define OSEVM_ADDR_CONTROL "/_c"
98#define OSEVM_ADDR_DUMP "/_d"
99#define OSEVM_ADDR_STDLIB "/_l"
100#define OSEVM_ADDR_HOST "/_x"
101#define OSEVM_ADDR_CACHE "/_0"
102#define OSEVM_ADDR_FAULT "/_h"
112#define OSEVM_ADDR_PROBE "/_k"
122#define OSEVM_ADDR_PARAMS "/_p"
// Built-in Addresses
124
146#define OSEVM_DECL_NREGISTERS 6
147extern const char * const
148osevm_decl_registers[OSEVM_DECL_NREGISTERS];
149
150enum osevm_decl
151{
152 OSEVM_DECL_NONE = 0,
153 OSEVM_DECL_I = 1 << 0,
154 OSEVM_DECL_S = 1 << 1,
155 OSEVM_DECL_E = 1 << 2,
156 OSEVM_DECL_C = 1 << 3,
157 OSEVM_DECL_D = 1 << 4,
158 OSEVM_DECL_P = 1 << 5
159};
160
167int32_t osevm_declares(ose_constbundle src);
168
179int32_t osevm_declaresAtOffset(ose_constbundle B, int32_t offset);
// Declarations
181
186#define OSEVM_ADDR_assign "/@"
187#define OSEVM_ADDR_quote "/'"
188#define OSEVM_ADDR_funcall "/!"
189#define OSEVM_ADDR_lookup "/$"
190#define OSEVM_ADDR_copyRegisterToElem "/>"
191#define OSEVM_ADDR_appendElemToRegister "/<<"
192#define OSEVM_ADDR_replaceRegisterWithElem "/<"
193#define OSEVM_ADDR_moveElemToRegister "/-"
194#define OSEVM_ADDR_toType "/,"
195#define OSEVM_ADDR_toInt32 "/,/i"
196#define OSEVM_ADDR_toFloat "/,/f"
197#define OSEVM_ADDR_toString "/,/s"
198#define OSEVM_ADDR_toBlob "/,/b"
199#define OSEVM_ADDR_appendByte "/&"
// Built-in Prefixes
201
206/* number of 32-bit ints available in the cache message */
207#define OSEVM_CACHE_SIZE 30
208#define OSEVM_CACHE_MSG_SIZE OSE_CONTEXT_MESSAGE_OVERHEAD \
209 + OSE_SIZEWORD_LEN_ + OSE_ADDRESS_ANONVAL_SIZE_ + 32 + (OSEVM_CACHE_SIZE * 4)
210#define OSEVM_CACHE_OFFSET_0 OSE_BUNDLE_HEADER_LEN_ \
211 + OSE_CONTEXT_BUNDLE_OFFSET \
212 + OSE_BUNDLE_HEADER_LEN_ \
213 + OSE_SIZEWORD_LEN + OSE_ADDRESS_ANONVAL_SIZE + 32 /* size, address, typetags */
214#define OSEVM_CACHE_OFFSET_1 OSEVM_CACHE_OFFSET_0 + OSE_SIZEWORD_LEN
215#define OSEVM_CACHE_OFFSET_2 OSEVM_CACHE_OFFSET_1 + OSE_SIZEWORD_LEN
216#define OSEVM_CACHE_OFFSET_3 OSEVM_CACHE_OFFSET_2 + OSE_SIZEWORD_LEN
217#define OSEVM_CACHE_OFFSET_4 OSEVM_CACHE_OFFSET_3 + OSE_SIZEWORD_LEN
218#define OSEVM_CACHE_OFFSET_5 OSEVM_CACHE_OFFSET_4 + OSE_SIZEWORD_LEN
219#define OSEVM_CACHE_OFFSET_6 OSEVM_CACHE_OFFSET_5 + OSE_SIZEWORD_LEN
220#define OSEVM_CACHE_OFFSET_7 OSEVM_CACHE_OFFSET_6 + OSE_SIZEWORD_LEN
221#define OSEVM_CACHE_OFFSET_8 OSEVM_CACHE_OFFSET_7 + OSE_SIZEWORD_LEN
222#define OSEVM_CACHE_OFFSET_9 OSEVM_CACHE_OFFSET_8 + OSE_SIZEWORD_LEN
223#define OSEVM_CACHE_OFFSET_10 OSEVM_CACHE_OFFSET_9 + OSE_SIZEWORD_LEN
224#define OSEVM_CACHE_OFFSET_11 OSEVM_CACHE_OFFSET_10 + OSE_SIZEWORD_LEN
225#define OSEVM_CACHE_OFFSET_12 OSEVM_CACHE_OFFSET_11 + OSE_SIZEWORD_LEN
226#define OSEVM_CACHE_OFFSET_13 OSEVM_CACHE_OFFSET_12 + OSE_SIZEWORD_LEN
227#define OSEVM_CACHE_OFFSET_14 OSEVM_CACHE_OFFSET_13 + OSE_SIZEWORD_LEN
228#define OSEVM_CACHE_OFFSET_15 OSEVM_CACHE_OFFSET_14 + OSE_SIZEWORD_LEN
229#define OSEVM_CACHE_OFFSET_16 OSEVM_CACHE_OFFSET_15 + OSE_SIZEWORD_LEN
230#define OSEVM_CACHE_OFFSET_17 OSEVM_CACHE_OFFSET_16 + OSE_SIZEWORD_LEN
231#define OSEVM_CACHE_OFFSET_18 OSEVM_CACHE_OFFSET_17 + OSE_SIZEWORD_LEN
232#define OSEVM_CACHE_OFFSET_19 OSEVM_CACHE_OFFSET_18 + OSE_SIZEWORD_LEN
233#define OSEVM_CACHE_OFFSET_20 OSEVM_CACHE_OFFSET_19 + OSE_SIZEWORD_LEN
234#define OSEVM_CACHE_OFFSET_21 OSEVM_CACHE_OFFSET_20 + OSE_SIZEWORD_LEN
235#define OSEVM_CACHE_OFFSET_22 OSEVM_CACHE_OFFSET_21 + OSE_SIZEWORD_LEN
236#define OSEVM_CACHE_OFFSET_23 OSEVM_CACHE_OFFSET_22 + OSE_SIZEWORD_LEN
237#define OSEVM_CACHE_OFFSET_24 OSEVM_CACHE_OFFSET_23 + OSE_SIZEWORD_LEN
238#define OSEVM_CACHE_OFFSET_25 OSEVM_CACHE_OFFSET_24 + OSE_SIZEWORD_LEN
239#define OSEVM_CACHE_OFFSET_26 OSEVM_CACHE_OFFSET_25 + OSE_SIZEWORD_LEN
240#define OSEVM_CACHE_OFFSET_27 OSEVM_CACHE_OFFSET_26 + OSE_SIZEWORD_LEN
241#define OSEVM_CACHE_OFFSET_28 OSEVM_CACHE_OFFSET_27 + OSE_SIZEWORD_LEN
242#define OSEVM_CACHE_OFFSET_29 OSEVM_CACHE_OFFSET_28 + OSE_SIZEWORD_LEN
243#define OSEVM_CACHE_OFFSET_30 OSEVM_CACHE_OFFSET_29 + OSE_SIZEWORD_LEN
244
245#define OSEVM_CACHE_POINTER OSEVM_CACHE_OFFSET_0
246#define OSEVM_CACHE_FLAGS OSEVM_CACHE_OFFSET_1
247#define OSEVM_CACHE_OFFSET_INPUT OSEVM_CACHE_OFFSET_2
248#define OSEVM_CACHE_OFFSET_STACK OSEVM_CACHE_OFFSET_3
249#define OSEVM_CACHE_OFFSET_ENV OSEVM_CACHE_OFFSET_4
250#define OSEVM_CACHE_OFFSET_CONTROL OSEVM_CACHE_OFFSET_5
251#define OSEVM_CACHE_OFFSET_DUMP OSEVM_CACHE_OFFSET_6
252#define OSEVM_CACHE_OFFSET_FAULT OSEVM_CACHE_OFFSET_7
253/* 8 and 9 are left to a host, which may keep a pointer there. */
254#define OSEVM_CACHE_OFFSET_PROBE OSEVM_CACHE_OFFSET_10
// Cache Offsets
256
262#ifdef OSE_IN_DOXYGEN
267#define OSE_CONF_VM_INPUT_SIZE
268#define OSE_CONF_VM_STACK_SIZE
269#define OSE_CONF_VM_ENV_SIZE
270#define OSE_CONF_VM_CONTROL_SIZE
271#define OSE_CONF_VM_DUMP_SIZE
272#undef OSE_CONF_VM_INPUT_SIZE
273#undef OSE_CONF_VM_STACK_SIZE
274#undef OSE_CONF_VM_ENV_SIZE
275#undef OSE_CONF_VM_CONTROL_SIZE
276#undef OSE_CONF_VM_DUMP_SIZE
/* conf_vm */
278#endif
279
287#define OSEVM_FAULT_SIZE 128
288
289#if defined(OSE_CONF_PROBE_COUNTS) || defined(OSE_CONF_PROBE_STEPS)
290#define OSEVM_HAVE_PROBES
291#ifdef OSE_CONF_PROBE_STEPS
292/* Smaller on a board, whose internal RAM cannot spare 80 KB of table. */
293#ifndef OSEVM_PROBE_STEPS_N
294#define OSEVM_PROBE_STEPS_N 1024
295#endif
296#ifndef OSEVM_PROBE_STEPS_NAMELEN
297#define OSEVM_PROBE_STEPS_NAMELEN 64
298#endif
299#endif
300/* A blob's bytes are four-byte aligned, so nothing in the record may ask
301 for more: these two read correctly wherever the machine's bytes are. */
302typedef uint64_t osevm_probe_u64 __attribute__((aligned(4)));
303typedef uint64_t (*osevm_probe_clockfn)(void);
304typedef osevm_probe_clockfn osevm_probe_clock __attribute__((aligned(4)));
305#ifdef OSE_CONF_PROBE_STEPS
306struct osevm_probeRow
307{
308 char name[OSEVM_PROBE_STEPS_NAMELEN];
309 osevm_probe_u64 n, ns;
310};
311#endif
315struct osevm_probes
316{
317 /* Control elements applied by this machine. */
318 uint32_t nsteps;
319#ifdef OSE_CONF_PROBE_STEPS
320 int32_t flags;
321 int32_t count;
322 osevm_probe_clock clock;
323 struct osevm_probeRow rows[OSEVM_PROBE_STEPS_N];
324 /* Rows found by the name's hash, so a probe with a few dozen rows costs
325 a hash and a compare a step rather than a walk of all of them --
326 which on a board would be a noticeable part of the step measured. */
327 int16_t index[2 * OSEVM_PROBE_STEPS_N];
328#endif
329};
330/* The register's usable bytes: the record as a blob, with its address,
331 typetags and size word. */
332#define OSEVM_PROBE_SIZE \
333 ((int32_t)(OSE_SIZEWORD_LEN_ + 4 + 4 + OSE_SIZEWORD_LEN_ \
334 + ((sizeof(struct osevm_probes) + 3) & ~3)))
335#define OSEVM_PROBE_REGISTER_SIZE_ \
336 (OSEVM_PROBE_SIZE + OSE_CONTEXT_MESSAGE_OVERHEAD)
337#else
338#define OSEVM_PROBE_REGISTER_SIZE_ 0
339#endif
340
341#if defined(OSE_CONF_VM_INPUT_SIZE) \
342 && defined(OSE_CONF_VM_STACK_SIZE) \
343 && defined(OSE_CONF_VM_ENV_SIZE) \
344 && defined(OSE_CONF_VM_CONTROL_SIZE) \
345 && defined(OSE_CONF_VM_DUMP_SIZE)
346#define OSEVM_HAVE_SIZES
347static const int32_t OSEVM_INPUT_SIZE = OSE_CONF_VM_INPUT_SIZE;
348static const int32_t OSEVM_STACK_SIZE = OSE_CONF_VM_STACK_SIZE;
349static const int32_t OSEVM_ENV_SIZE = OSE_CONF_VM_ENV_SIZE;
350static const int32_t OSEVM_CONTROL_SIZE = OSE_CONF_VM_CONTROL_SIZE;
351static const int32_t OSEVM_DUMP_SIZE = OSE_CONF_VM_DUMP_SIZE;
352
353#include "ose_context.h"
354/* A macro as well, to size an array with: see OSE_BUNDLE_HEADER_LEN_. */
355#define OSEVM_TOTAL_SIZE_ \
356 (OSEVM_CACHE_MSG_SIZE \
357 + OSE_CONF_VM_INPUT_SIZE + OSE_CONTEXT_MESSAGE_OVERHEAD \
358 + OSE_CONF_VM_STACK_SIZE + OSE_CONTEXT_MESSAGE_OVERHEAD \
359 + OSE_CONF_VM_ENV_SIZE + OSE_CONTEXT_MESSAGE_OVERHEAD \
360 + OSE_CONF_VM_CONTROL_SIZE + OSE_CONTEXT_MESSAGE_OVERHEAD \
361 + OSE_CONF_VM_DUMP_SIZE + OSE_CONTEXT_MESSAGE_OVERHEAD \
362 + OSEVM_FAULT_SIZE + OSE_CONTEXT_MESSAGE_OVERHEAD \
363 + OSEVM_PROBE_REGISTER_SIZE_)
364static const int32_t OSEVM_TOTAL_SIZE = OSEVM_TOTAL_SIZE_;
365
366#elif !defined(OSE_CONF_VM_INPUT_SIZE) \
367 && !defined(OSE_CONF_VM_STACK_SIZE) \
368 && !defined(OSE_CONF_VM_ENV_SIZE) \
369 && !defined(OSE_CONF_VM_CONTROL_SIZE) \
370 && !defined(OSE_CONF_VM_DUMP_SIZE)
371#else
372#pragma message ( "Sizes were specified for some, but not all of the VM "\
373 "stacks. Sizes specified will be ignored during compilation, "\
374 "and must be passed to osevm_init() at runtime."\
375 )
376#endif
/* VM Configuration */
378
379#ifdef OSEVM_HAVE_SIZES
380
385#define OSEVM_INPUT_CONTEXT_MESSAGE_OFFSET \
386 OSE_BUNDLE_HEADER_LEN_ + OSEVM_CACHE_MSG_SIZE
387#define OSEVM_INPUT_BUNDLE_OFFSET \
388 OSEVM_INPUT_CONTEXT_MESSAGE_OFFSET + OSE_CONTEXT_BUNDLE_OFFSET
389
390#define OSEVM_STACK_CONTEXT_MESSAGE_OFFSET \
391 OSEVM_INPUT_CONTEXT_MESSAGE_OFFSET \
392 + OSE_CONTEXT_MESSAGE_OVERHEAD + OSEVM_INPUT_SIZE
393#define OSEVM_STACK_BUNDLE_OFFSET \
394 OSEVM_STACK_CONTEXT_MESSAGE_OFFSET + OSE_CONTEXT_BUNDLE_OFFSET
395
396#define OSEVM_ENV_CONTEXT_MESSAGE_OFFSET \
397 OSEVM_STACK_CONTEXT_MESSAGE_OFFSET \
398 + OSE_CONTEXT_MESSAGE_OVERHEAD + OSEVM_STACK_SIZE
399#define OSEVM_ENV_BUNDLE_OFFSET \
400 OSEVM_ENV_CONTEXT_MESSAGE_OFFSET + OSE_CONTEXT_BUNDLE_OFFSET
401
402#define OSEVM_CONTROL_CONTEXT_MESSAGE_OFFSET \
403 OSEVM_ENV_CONTEXT_MESSAGE_OFFSET \
404 + OSE_CONTEXT_MESSAGE_OVERHEAD + OSEVM_ENV_SIZE
405#define OSEVM_CONTROL_BUNDLE_OFFSET \
406 OSEVM_CONTROL_CONTEXT_MESSAGE_OFFSET + OSE_CONTEXT_BUNDLE_OFFSET
407
408#define OSEVM_DUMP_CONTEXT_MESSAGE_OFFSET \
409 OSEVM_CONTROL_CONTEXT_MESSAGE_OFFSET \
410 + OSE_CONTEXT_MESSAGE_OVERHEAD + OSEVM_CONTROL_SIZE
411#define OSEVM_DUMP_BUNDLE_OFFSET \
412 OSEVM_DUMP_CONTEXT_MESSAGE_OFFSET + OSE_CONTEXT_BUNDLE_OFFSET
413
414#define OSEVM_FAULT_CONTEXT_MESSAGE_OFFSET \
415 OSEVM_DUMP_CONTEXT_MESSAGE_OFFSET \
416 + OSE_CONTEXT_MESSAGE_OVERHEAD + OSEVM_DUMP_SIZE
417#define OSEVM_FAULT_BUNDLE_OFFSET \
418 OSEVM_FAULT_CONTEXT_MESSAGE_OFFSET + OSE_CONTEXT_BUNDLE_OFFSET
// VM Bundle Offsets
420
429#define OSEVM_INPUT(osevm) \
430 ose_makeBundle(ose_getBundlePtr(osevm) \
431 + OSEVM_INPUT_BUNDLE_OFFSET)
435#define OSEVM_STACK(osevm) \
436 ose_makeBundle(ose_getBundlePtr(osevm) \
437 + OSEVM_STACK_BUNDLE_OFFSET)
441#define OSEVM_ENV(osevm) \
442 ose_makeBundle(ose_getBundlePtr(osevm) \
443 + OSEVM_ENV_BUNDLE_OFFSET)
447#define OSEVM_CONTROL(osevm) \
448 ose_makeBundle(ose_getBundlePtr(osevm) \
449 + OSEVM_CONTROL_BUNDLE_OFFSET)
453#define OSEVM_DUMP(osevm) \
454 ose_makeBundle(ose_getBundlePtr(osevm) \
455 + OSEVM_DUMP_BUNDLE_OFFSET)
459#define OSEVM_FAULT(osevm) \
460 ose_makeBundle(ose_getBundlePtr(osevm) \
461 + OSEVM_FAULT_BUNDLE_OFFSET)
// Components of the VM
463
481
482#else
483
484#define OSEVM_INPUT(osevm) \
485 ose_makeBundle(ose_getBundlePtr(osevm) \
486 + ose_readInt32(osevm, \
487 OSEVM_CACHE_OFFSET_INPUT))
488#define OSEVM_STACK(osevm) \
489 ose_makeBundle(ose_getBundlePtr(osevm) \
490 + ose_readInt32(osevm, \
491 OSEVM_CACHE_OFFSET_STACK))
492#define OSEVM_ENV(osevm) \
493 ose_makeBundle(ose_getBundlePtr(osevm) \
494 + ose_readInt32(osevm, \
495 OSEVM_CACHE_OFFSET_ENV))
496#define OSEVM_CONTROL(osevm) \
497 ose_makeBundle(ose_getBundlePtr(osevm) \
498 + ose_readInt32(osevm, \
499 OSEVM_CACHE_OFFSET_CONTROL))
500#define OSEVM_DUMP(osevm) \
501 ose_makeBundle(ose_getBundlePtr(osevm) \
502 + ose_readInt32(osevm, \
503 OSEVM_CACHE_OFFSET_DUMP))
504#define OSEVM_FAULT(osevm) \
505 ose_makeBundle(ose_getBundlePtr(osevm) \
506 + ose_readInt32(osevm, \
507 OSEVM_CACHE_OFFSET_FAULT))
508
537 int32_t input_size,
538 int32_t stack_size,
539 int32_t env_size,
540 int32_t control_size,
541 int32_t dump_size);
542#endif
543
569void osevm_setFault(ose_bundle osevm, enum ose_errno e);
570
575
579void osevm_clearFault(ose_bundle osevm);
580
585#define OSEVM_GET_FLAGS(osevm) \
586 ose_readInt32(osevm, OSEVM_CACHE_FLAGS)
587#define OSEVM_SET_FLAGS(osevm, flags) \
588 ose_writeInt32(osevm, OSEVM_CACHE_FLAGS, flags)
589
590#define OSEVM_GET_CACHE_VALUE(osevm, idx) \
591 (ose_assert((idx) < OSEVM_CACHE_SIZE), \
592 ose_readInt32(osevm, OSEVM_CACHE_OFFSET_0 + (4 * (idx))))
593#define OSEVM_SET_CACHE_VALUE(osevm, idx, val) \
594 (ose_assert((idx) < OSEVM_CACHE_SIZE), \
595 ose_writeInt32(osevm, OSEVM_CACHE_OFFSET_0 + (4 * (idx)), val))
// Cache Getters and Setters
597
598/************************************************************
599 * Hooks
600 ************************************************************/
605void osevm_respondToString(ose_bundle osevm);
606void osevm_preInput(ose_bundle osevm);
607void osevm_postInput(ose_bundle osevm);
608void osevm_popInputToControl(ose_bundle osevm);
609void osevm_postControl(ose_bundle osevm);
610void osevm_evalType(ose_bundle osevm);
611/* int32_t osevm_callTypeHook(ose_bundle bundle, */
612/* const char typetag, */
613/* const int32_t msg_offset, */
614/* const int32_t item_offset, */
615/* const int32_t addrlen, */
616/* const char * const addr); */
617
618/* int32_t osevm_getPayloadItemLength_hook(ose_bundle bundle, */
619/* const char typetag, */
620/* const int32_t msg_offset, */
621/* const int32_t item_offset); */
622
623/* int32_t osevm_getPayloadItemSize_hook(ose_bundle bundle, */
624/* const char typetag, */
625/* const int32_t msg_offset, */
626/* const int32_t item_offset); */
627
628/* int32_t osevm_pprintPayloadItem_hook(ose_bundle bundle, */
629/* const char typetag, */
630/* const int32_t msg_offset, */
631/* const int32_t item_offset); */
/* Hooks */
633
644#ifndef OSEVM_ASSIGN
645#define OSEVM_ASSIGN osevm_assignStackToEnv
646#else
647extern void OSEVM_ASSIGN (ose_bundle osevm);
648#endif
649
650#ifndef OSEVM_LOOKUP
651#define OSEVM_LOOKUP osevm_lookupInEnv_impl
652#else
653extern void OSEVM_LOOKUP (ose_bundle osevm);
654#endif
655
656/* OSEVM_RAISE -- CALLED AT A RAISE, BEFORE ANY HANDLER.
657 *
658 * At both raise sites, once the fault is recorded in /_h, the failed code
659 * element has been moved to /_s, the errno pushed, and /!/exception pushed
660 * onto control -- the state a restart undoes -- and before /exception is
661 * looked up. So a host sees every raise, in that state, whatever the
662 * program has bound /exception to: the one place a host can keep a
663 * snapshot of the machine as it faulted without depending on its own
664 * handler being the one that runs. The default does nothing. */
665#ifndef OSEVM_RAISE
666#define OSEVM_RAISE(osevm) ((void)(osevm))
667#else
668extern void OSEVM_RAISE (ose_bundle osevm);
669#endif
670
671#ifndef OSEVM_FUNCALL
672#define OSEVM_FUNCALL osevm_funcall
673#else
674extern void OSEVM_FUNCALL (ose_bundle osevm);
675#endif
676
677#ifndef OSEVM_QUOTE
678#define OSEVM_QUOTE osevm_quote
679#else
680extern void OSEVM_QUOTE (ose_bundle osevm);
681#endif
682
683#ifndef OSEVM_COPYREGISTERTOELEM
684#define OSEVM_COPYREGISTERTOELEM osevm_copyRegisterToElem
685#else
686extern void OSEVM_COPYREGISTERTOELEM (ose_bundle osevm);
687#endif
688
689#ifndef OSEVM_APPENDELEMTOREGISTER
690#define OSEVM_APPENDELEMTOREGISTER osevm_appendElemToRegister
691#else
692extern void OSEVM_APPENDELEMTOREGISTER (ose_bundle osevm);
693#endif
694
695#ifndef OSEVM_REPLACEREGISTERWITHELEM
696#define OSEVM_REPLACEREGISTERWITHELEM osevm_replaceRegisterWithElem
697#else
698extern void OSEVM_REPLACEREGISTERWITHELEM (ose_bundle osevm);
699#endif
700
701#ifndef OSEVM_MOVEELEMTOREGISTER
702#define OSEVM_MOVEELEMTOREGISTER osevm_moveElemToRegister
703#else
704extern void OSEVM_MOVEELEMTOREGISTER (ose_bundle osevm);
705#endif
706
707#ifndef OSEVM_TOTYPE
708#define OSEVM_TOTYPE osevm_toType
709#else
710extern void OSEVM_TOTYPE (ose_bundle osevm);
711#endif
712
713#ifndef OSEVM_TOINT32
714#define OSEVM_TOINT32 osevm_toInt32
715#else
716extern void OSEVM_TOINT32 (ose_bundle osevm);
717#endif
718
719#ifndef OSEVM_TOFLOAT
720#define OSEVM_TOFLOAT osevm_toFloat
721#else
722extern void OSEVM_TOFLOAT (ose_bundle osevm);
723#endif
724
725#ifndef OSEVM_TOSTRING
726#define OSEVM_TOSTRING osevm_toString
727#else
728extern void OSEVM_TOSTRING (ose_bundle osevm);
729#endif
730
731#ifndef OSEVM_TOBLOB
732#define OSEVM_TOBLOB osevm_toBlob
733#else
734extern void OSEVM_TOBLOB (ose_bundle osevm);
735#endif
736
737#ifdef OSE_PROVIDE_TYPE_SYMBOL
738#ifndef OSEVM_TOSYMBOL
739#define OSEVM_TOSYMBOL osevm_toSymbol
740#else
741extern void OSEVM_TOSYMBOL (ose_bundle osevm);
742#endif
743#endif
744
745#ifdef OSE_PROVIDE_TYPE_DOUBLE
746#ifndef OSEVM_TODOUBLE
747#define OSEVM_TODOUBLE osevm_toDouble
748#else
749extern void OSEVM_TODOUBLE (ose_bundle osevm);
750#endif
751#endif
752
753#ifdef OSE_PROVIDE_TYPE_INT8
754#ifndef OSEVM_TOINT8
755#define OSEVM_TOINT8 osevm_toInt8
756#else
757extern void OSEVM_TOINT8 (ose_bundle osevm);
758#endif
759#endif
760
761#ifdef OSE_PROVIDE_TYPE_UINT8
762#ifndef OSEVM_TOUINT8
763#define OSEVM_TOUINT8 osevm_toUInt8
764#else
765extern void OSEVM_TOUINT8 (ose_bundle osevm);
766#endif
767#endif
768
769#ifdef OSE_PROVIDE_TYPE_INT16
770#ifndef OSEVM_TOINT16
771#define OSEVM_TOINT16 osevm_toInt16
772#else
773extern void OSEVM_TOINT16 (ose_bundle osevm);
774#endif
775#endif
776
777#ifdef OSE_PROVIDE_TYPE_UINT16
778#ifndef OSEVM_TOUINT16
779#define OSEVM_TOUINT16 osevm_toUInt16
780#else
781extern void OSEVM_TOUINT16 (ose_bundle osevm);
782#endif
783#endif
784
785#ifdef OSE_PROVIDE_TYPE_UINT32
786#ifndef OSEVM_TOUINT32
787#define OSEVM_TOUINT32 osevm_toUInt32
788#else
789extern void OSEVM_TOUINT32 (ose_bundle osevm);
790#endif
791#endif
792
793#ifdef OSE_PROVIDE_TYPE_INT64
794#ifndef OSEVM_TOINT64
795#define OSEVM_TOINT64 osevm_toInt64
796#else
797extern void OSEVM_TOINT64 (ose_bundle osevm);
798#endif
799#endif
800
801#ifdef OSE_PROVIDE_TYPE_UINT64
802#ifndef OSEVM_TOUINT64
803#define OSEVM_TOUINT64 osevm_toUInt64
804#else
805extern void OSEVM_TOUINT64 (ose_bundle osevm);
806#endif
807#endif
808
809#ifdef OSE_PROVIDE_TYPE_TIMETAG
810#ifndef OSEVM_TOTIMETAG
811#define OSEVM_TOTIMETAG osevm_toTimetag
812#else
813extern void OSEVM_TOTIMETAG (ose_bundle osevm);
814#endif
815#endif
816
817#ifdef OSE_PROVIDE_TYPE_TRUE
818#ifndef OSEVM_TOTRUE
819#define OSEVM_TOTRUE osevm_toTrue
820#else
821extern void OSEVM_TOTRUE (ose_bundle osevm);
822#endif
823#endif
824
825#ifdef OSE_PROVIDE_TYPE_FALSE
826#ifndef OSEVM_TOFALSE
827#define OSEVM_TOFALSE osevm_toFalse
828#else
829extern void OSEVM_TOFALSE (ose_bundle osevm);
830#endif
831#endif
832
833#ifdef OSE_PROVIDE_TYPE_NIL
834#ifndef OSEVM_TONIL
835#define OSEVM_TONIL osevm_toNil
836#else
837extern void OSEVM_TONIL (ose_bundle osevm);
838#endif
839#endif
840
841#ifdef OSE_PROVIDE_TYPE_INFINITUM
842#ifndef OSEVM_TOINFINITUM
843#define OSEVM_TOINFINITUM osevm_toInfinitum
844#else
845extern void OSEVM_TOINFINITUM (ose_bundle osevm);
846#endif
847#endif
848
849#ifndef OSEVM_APPENDBYTE
850#define OSEVM_APPENDBYTE osevm_appendByte
851#else
852extern void OSEVM_APPENDBYTE (ose_bundle osevm);
853#endif
854
855#ifndef OSEVM_RESPONDTOSTRING
856#define OSEVM_RESPONDTOSTRING osevm_respondToString
857#else
858extern void OSEVM_RESPONDTOSTRING (ose_bundle osevm);
859#endif
860
875#ifndef OSEVM_OPCODE
876#define OSEVM_OPCODE osevm_opcode_default
877#else
878extern int OSEVM_OPCODE (ose_bundle osevm);
879#endif
880/* The default, for a libose built without a table: nothing run. A host
881 that numbers instructions names its functions here when it builds
882 libose, as it names its lookup. */
883int osevm_opcode_default(ose_bundle osevm);
884int32_t osevm_readOpcode(ose_bundle osevm);
885
897#ifndef OSEVM_OPCODE_NAME
898#define OSEVM_OPCODE_NAME(b, off, n) osevm_opcodeName(b, off, n)
899#else
900extern const char *OSEVM_OPCODE_NAME (ose_bundle b, int32_t off, int32_t n);
901#endif
902const char *osevm_opcodeName(ose_bundle b, int32_t off, int32_t n);
903
904#ifndef OSEVM_PREINPUT
905#define OSEVM_PREINPUT osevm_preInput
906#else
907extern void OSEVM_PREINPUT (ose_bundle osevm);
908#endif
909
910#ifndef OSEVM_POSTINPUT
911#define OSEVM_POSTINPUT osevm_postInput
912#else
913extern void OSEVM_POSTINPUT (ose_bundle osevm);
914#endif
915
916#ifndef OSEVM_POPINPUTTOCONTROL
917#define OSEVM_POPINPUTTOCONTROL osevm_popInputToControl
918#else
919extern void OSEVM_POPINPUTTOCONTROL (ose_bundle osevm);
920#endif
921
922#ifndef OSEVM_POSTCONTROL
923#define OSEVM_POSTCONTROL osevm_postControl
924#else
925extern void OSEVM_POSTCONTROL (ose_bundle osevm);
926#endif
927
928#define OSEVM_TYPE_ADDR_EVALTYPE_SUFFIX "/EVTY"
929#define OSEVM_EVALTYPE_ADDR \
930 OSE_TYPE_ADDR_PREFIX "%c" OSEVM_TYPE_ADDR_EVALTYPE_SUFFIX
931#define OSEVM_EVALTYPE_ADDR_LEN sizeof(OSEVM_EVALTYPE_ADDR)
932#ifndef OSEVM_EVALTYPE
933void osevm_evalType_hook(ose_bundle osevm);
934#define OSEVM_EVALTYPE osevm_evalType_hook
935#else
936extern void OSEVM_EVALTYPE (ose_bundle osevm);
937#endif
938
/* Hooks */ /* conf_vm_hooks */
941
957int32_t osevm_inputMessages(ose_bundle osevm,
958 int32_t size, const char * const bundle);
959/* The data counterpart of osevm_inputMessages(). Validates bytes from
960 outside and leaves them on the stack as a BLOB, which no client gives an
961 evaluation rule. See the comment in ose_vm.c. */
962int32_t osevm_inputData(ose_bundle osevm,
963 int32_t size, const char * const bundle);
964
972int32_t osevm_inputMessage(ose_bundle osevm,
973 int32_t size, const char * const message);
974
983#ifdef OSEVM_HAVE_PROBES
990struct osevm_probes *osevm_probes(ose_bundle osevm);
997uint32_t osevm_probe_nsteps(ose_bundle osevm);
998#endif
999
1000#ifdef OSE_CONF_PROBE_STEPS
1014#include <stdio.h>
1015#define OSEVM_PROBE_TRACE 1
1016#define OSEVM_PROBE_SIZES 2
1017void osevm_probeSteps_trace(ose_bundle osevm, int flags);
1018void osevm_probeSteps_reset(ose_bundle osevm);
1019void osevm_probeSteps_dump(ose_bundle osevm, FILE *fp);
1020/* For a host with no FILE to print to: the rows, in the order they were
1021 first seen, and their counts and times in the probe clock's unit. */
1022int osevm_probeSteps_rows(ose_bundle osevm);
1023const char *osevm_probeSteps_row(ose_bundle osevm, int i,
1024 uint64_t *n, uint64_t *t);
1025/* The probe's clock, if the host has a better one: a cycle counter. NULL,
1026 the default, is the system's monotonic clock in nanoseconds. */
1027void osevm_probeSteps_setClock(ose_bundle osevm, uint64_t (*clock)(void));
1028/* A zone inside a step, charged under its own name in the same table:
1029 t0 = osevm_probeSteps_time(osevm); ...; osevm_probeSteps_zone(osevm,
1030 "name", osevm_probeSteps_time(osevm) - t0). Its time is also inside the
1031 step's. */
1032uint64_t osevm_probeSteps_time(ose_bundle osevm);
1033void osevm_probeSteps_zone(ose_bundle osevm, const char * const name,
1034 uint64_t t);
1035#endif
1036
1037void osevm_run(ose_bundle bundle);
1038
1050char osevm_step(ose_bundle osevm);
1051#ifdef OSEVM_HAVE_SIZES
1064int32_t osevm_computeSizeReqs(int n, ...);
1065#else
1066int32_t osevm_computeSizeReqs(int32_t input_size,
1067 int32_t stack_size,
1068 int32_t env_size,
1069 int32_t control_size,
1070 int32_t dump_size,
1071 int n, ...);
1072#endif
1073
1081int osevm_controlOp(const char *op, ose_fn *fn, const char **name);
1082
1083
1084
1085#ifdef __cplusplus
1086}
1087#endif
1088
1089#endif
#define OSEVM_OPCODE_NAME(b, off, n)
The name an opcode stands for, or NULL for none. b is the bundle the opcode sits in – the control reg...
Definition ose_vm.h:898
#define OSEVM_OPCODE
What runs an instruction by number (OSETT_OPCODE).
Definition ose_vm.h:876
void(* ose_fn)(ose_bundle)
Function pointer for the basic OSE function that operates on a bundle.
Definition ose.h:435
contains functions that structure an OSC bundle for use with other parts of this library
Status codes for context bundles.
ose_errno
Definition ose_errno.h:37
#define B(...)
Instantiate a top-level OSC bundle.
Definition ose_test_ctosc.h:339
contains basic utilities for reading, writing, and querying an OSC bundle
void osevm_run(ose_bundle bundle)
Run the VM.
Definition ose_vm.c:1944
int32_t osevm_inputMessage(ose_bundle osevm, int32_t size, const char *const message)
Copy a single OSC element into the input bundle of the VM.
Definition ose_vm.c:2248
int32_t osevm_inputMessages(ose_bundle osevm, int32_t size, const char *const bundle)
Copy the contents of an OSC bundle into the input bundle of the VM.
Definition ose_vm.c:2149
ose_bundle osevm_init(ose_bundle bundle)
Initialize the VM.
Definition ose_vm.c:537
void osevm_setFault(ose_bundle osevm, enum ose_errno e)
Record a fault in /_h.
Definition ose_vm.c:439
enum ose_errno osevm_getFault(ose_bundle osevm)
The fault this machine is in, or OSE_ERR_NONE.
Definition ose_vm.c:446
int osevm_controlOp(const char *op, ose_fn *fn, const char **name)
This VM's own operation named op, as /$ names it ("/@", "/,/i").
Definition ose_vm.c:1007
int32_t osevm_declaresAtOffset(ose_bundle B, int32_t offset)
Which registers the bundle ELEMENT at offset declares.
Definition ose_vm.c:366
void osevm_clearFault(ose_bundle osevm)
Declare the fault handled.
Definition ose_vm.c:456
int32_t osevm_computeSizeReqs(int n,...)
Compute the size requirements of the VM given a list of sizes of each of additional VM bundle to be c...
Definition ose_vm.c:2270
char osevm_step(ose_bundle osevm)
Step the VM.
Definition ose_vm.c:1782
int32_t osevm_declares(ose_bundle src)
Which registers src declares.
Definition ose_vm.c:341
Definition ose.h:400