1/*
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 *
6 * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
7 */
8
9/*
10 * Author M. Kersten
11 * The MAL Interpreter
12 */
13
14#ifndef _MAL_INTERPRET_H
15#define _MAL_INTERPRET_H
16
17#include "mal_client.h"
18#include "mal_factory.h"
19#include "mal_profiler.h"
20
21/*
22 * Activation of a thread requires construction of the argument list
23 * to be passed by a handle.
24 */
25
26/* #define DEBUG_FLOW */
27
28mal_export MalStkPtr prepareMALstack(MalBlkPtr mb, int size);
29mal_export str runMAL(Client c, MalBlkPtr mb, MalBlkPtr mbcaller, MalStkPtr env);
30mal_export str runMALsequence(Client cntxt, MalBlkPtr mb, int startpc, int stoppc, MalStkPtr stk, MalStkPtr env, InstrPtr pcicaller);
31mal_export str reenterMAL(Client cntxt, MalBlkPtr mb, int startpc, int stoppc, MalStkPtr stk);
32mal_export str callMAL(Client cntxt, MalBlkPtr mb, MalStkPtr *glb, ValPtr argv[], char debug);
33mal_export void garbageElement(Client cntxt, ValPtr v);
34mal_export void garbageCollector(Client cntxt, MalBlkPtr mb, MalStkPtr stk, int flag);
35mal_export str malCommandCall(MalStkPtr stk, InstrPtr pci);
36mal_export int isNotUsedIn(InstrPtr p, int start, int a);
37
38mal_export ptr getArgReference(MalStkPtr stk, InstrPtr pci, int k);
39#if !defined(NDEBUG) && defined(__GNUC__)
40/* for ease of programming and debugging (assert reporting a useful
41 * location), we use a GNU C extension to check the type of arguments,
42 * and of course only when assertions are enabled */
43#define getArgReference_TYPE(s, pci, k, TYPE) \
44 ({ \
45 assert((s)->stk[(pci)->argv[k]].vtype == TYPE_##TYPE); \
46 (TYPE *) getArgReference((s), (pci), (k)); \
47 })
48#define getArgReference_bit(s, pci, k) \
49 ({ \
50 ValRecord *v = &(s)->stk[(pci)->argv[k]]; \
51 assert(v->vtype == TYPE_bit); \
52 (bit *) &v->val.btval; \
53 })
54#define getArgReference_sht(s, pci, k) \
55 ({ \
56 ValRecord *v = &(s)->stk[(pci)->argv[k]]; \
57 assert(v->vtype == TYPE_sht); \
58 &v->val.shval; \
59 })
60#define getArgReference_bat(s, pci, k) \
61 ({ \
62 ValRecord *v = &(s)->stk[(pci)->argv[k]]; \
63 assert(v->vtype == TYPE_bat); \
64 &v->val.bval; \
65 })
66#define getArgReference_int(s, pci, k) \
67 ({ \
68 ValRecord *v = &(s)->stk[(pci)->argv[k]]; \
69 assert(v->vtype == TYPE_int); \
70 &v->val.ival; \
71 })
72#define getArgReference_bte(s, pci, k) \
73 ({ \
74 ValRecord *v = &(s)->stk[(pci)->argv[k]]; \
75 assert(v->vtype == TYPE_bte); \
76 &v->val.btval; \
77 })
78#define getArgReference_oid(s, pci, k) \
79 ({ \
80 ValRecord *v = &(s)->stk[(pci)->argv[k]]; \
81 assert(v->vtype == TYPE_oid || v->vtype == TYPE_void); \
82 &v->val.oval; \
83 })
84#define getArgReference_ptr(s, pci, k) \
85 ({ \
86 ValRecord *v = &(s)->stk[(pci)->argv[k]]; \
87 assert(v->vtype == TYPE_ptr); \
88 &v->val.pval; \
89 })
90#define getArgReference_flt(s, pci, k) \
91 ({ \
92 ValRecord *v = &(s)->stk[(pci)->argv[k]]; \
93 assert(v->vtype == TYPE_flt); \
94 &v->val.fval; \
95 })
96#define getArgReference_dbl(s, pci, k) \
97 ({ \
98 ValRecord *v = &(s)->stk[(pci)->argv[k]]; \
99 assert(v->vtype == TYPE_dbl); \
100 &v->val.dval; \
101 })
102#define getArgReference_lng(s, pci, k) \
103 ({ \
104 ValRecord *v = &(s)->stk[(pci)->argv[k]]; \
105 assert(v->vtype == TYPE_lng); \
106 &v->val.lval; \
107 })
108#ifdef HAVE_HGE
109#define getArgReference_hge(s, pci, k) \
110 ({ \
111 ValRecord *v = &(s)->stk[(pci)->argv[k]]; \
112 assert(v->vtype == TYPE_hge); \
113 &v->val.hval; \
114 })
115#endif
116#define getArgReference_str(s, pci, k) \
117 ({ \
118 ValRecord *v = &(s)->stk[(pci)->argv[k]]; \
119 assert(v->vtype == TYPE_str); \
120 &v->val.sval; \
121 })
122#else
123#define getArgReference_TYPE(s, pci, k, TYPE) ((TYPE *) getArgReference(s, pci, k))
124#define getArgReference_bit(s, pci, k) ((bit *) &(s)->stk[(pci)->argv[k]].val.btval)
125#define getArgReference_sht(s, pci, k) (&(s)->stk[(pci)->argv[k]].val.shval)
126#define getArgReference_bat(s, pci, k) (&(s)->stk[(pci)->argv[k]].val.bval)
127#define getArgReference_int(s, pci, k) (&(s)->stk[(pci)->argv[k]].val.ival)
128#define getArgReference_bte(s, pci, k) (&(s)->stk[(pci)->argv[k]].val.btval)
129#define getArgReference_oid(s, pci, k) (&(s)->stk[(pci)->argv[k]].val.oval)
130#define getArgReference_ptr(s, pci, k) (&(s)->stk[(pci)->argv[k]].val.pval)
131#define getArgReference_flt(s, pci, k) (&(s)->stk[(pci)->argv[k]].val.fval)
132#define getArgReference_dbl(s, pci, k) (&(s)->stk[(pci)->argv[k]].val.dval)
133#define getArgReference_lng(s, pci, k) (&(s)->stk[(pci)->argv[k]].val.lval)
134#ifdef HAVE_HGE
135#define getArgReference_hge(s, pci, k) (&(s)->stk[(pci)->argv[k]].val.hval)
136#endif
137#define getArgReference_str(s, pci, k) (&(s)->stk[(pci)->argv[k]].val.sval)
138#endif
139
140#endif /* _MAL_INTERPRET_H*/
141