/* [<][>][^][v][top][bottom][index][help] */
1 /*
2 * code.h - Virtual machine code
3 *
4 * Copyright (c) 2005 Shiro Kawai, All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the authors nor the names of its contributors
18 * may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * $Id: code.h,v 1.6 2005/05/24 23:29:09 shirok Exp $
34 */
35
36 #ifndef GAUCHE_CODE_H
37 #define GAUCHE_CODE_H
38
39 #include <gauche/vm.h>
40
41 /*
42 * Compiled code packet
43 */
44
45 struct ScmCompiledCodeRec {
46 SCM_HEADER;
47 ScmWord *code; /* Code vector (*1). This is allocated as
48 atomic, to prevent GC from scanning it.
49 (*2) */
50 ScmObj *constants; /* Constant vector. this isn't used during
51 execution, but kept here so that the
52 constants in the code vector won't be
53 GC-ed. (*2) */
54 int codeSize; /* size of code vector */
55 int constantSize; /* size of constant vector (*2) */
56 int maxstack; /* maximum runtime stack depth */
57 u_short requiredArgs; /* # of required args, if this code is the
58 body of a closure. Otherwise 0. */
59 u_short optionalArgs; /* 1 if this code is the body of a closure.
60 that takes rest arg. Otherwise 0. */
61 ScmObj name; /* If this is the body of a closure, holds
62 its name. Otherwise #f. */
63 ScmObj info; /* debug info. alist of instruction offset
64 and info. */
65 ScmObj argInfo; /* If this code is the body of the closure,
66 keeps a list of args. #f otherwise. (*3) */
67 ScmObj parent; /* ScmCompiledCode if this code is compiled
68 within other code chunk. #f otherwise. */
69 ScmObj intermediateForm; /* A packed IForm of the body (see compile.scm
70 for the details of IForm). It is used
71 to inline this procedure. Only set if
72 the procedure is defined with define-inline.
73 #f otherwise. (*4) */
74 void *builder; /* An opaque data used during consturcting
75 the code vector. Usually NULL. */
76 };
77
78 /* Footnotes on ScmCompiledCodeRec
79 *
80 * *1) This may be NULL if this compiled code is "partially compiled"---
81 * that is, the compiler only runs pass1 and put the intermediate
82 * form in intermediateForm field.
83 * *2) For the C-dumped code, the code vector is located in a static data
84 * area, subject to GC scanning. In that case, the constants pointer
85 * is NULL.
86 * *3) This info isn't set for the time being.
87 * *4) This IForm is a direct result of Pass1, i.e. non-optimized form.
88 * Pass2 scans it When IForm is inlined into the caller site.
89 */
90
91 SCM_CLASS_DECL(Scm_CompiledCodeClass);
92 #define SCM_CLASS_COMPILED_CODE (&Scm_CompiledCodeClass)
93
94 #define SCM_COMPILED_CODE(obj) ((ScmCompiledCode*)(obj))
95 #define SCM_COMPILED_CODE_P(obj) SCM_XTYPEP(obj, SCM_CLASS_COMPILED_CODE)
96 #define SCM_COMPILED_CODE_ARG_INFO(obj) (SCM_COMPILED_CODE(obj)->argInfo)
97 #define SCM_COMPILED_CODE_REQUIRED_ARGS(obj) \
98 (SCM_COMPILED_CODE(obj)->requiredArgs)
99 #define SCM_COMPILED_CODE_OPTIONAL_ARGS(obj) \
100 (SCM_COMPILED_CODE(obj)->optionalArgs)
101
102 #define SCM_COMPILED_CODE_CONST_INITIALIZER(code, codesize, maxstack, reqargs, optargs, name, info, arginfo, parent, iform) \
103 { { SCM_CLASS2TAG(SCM_CLASS_COMPILED_CODE) }, \
104 (code), NULL, (codesize), 0, (maxstack), \
105 (reqargs), (optargs), (name), (info), (arginfo), \
106 (parent), (iform) }
107
108 SCM_EXTERN void Scm_CompiledCodeDump(ScmCompiledCode *cc);
109 SCM_EXTERN ScmObj Scm_CompiledCodeToList(ScmCompiledCode *cc);
110 SCM_EXTERN ScmObj Scm_CompiledCodeFullName(ScmCompiledCode *cc);
111 SCM_EXTERN void Scm_VMExecuteToplevels(ScmCompiledCode *cv[]);
112
113 /* Builder API */
114 SCM_EXTERN ScmObj Scm_MakeCompiledCodeBuilder(int reqargs, int optargs,
115 ScmObj name, ScmObj parent,
116 ScmObj intForm);
117 SCM_EXTERN ScmObj Scm_CompiledCodeCurrentInsn(ScmCompiledCode *cc);
118 SCM_EXTERN void Scm_CompiledCodeReplaceInsn(ScmCompiledCode *cc,
119 ScmObj insn,
120 ScmObj operand,
121 ScmObj info);
122 SCM_EXTERN void Scm_CompiledCodeFlushInsn(ScmCompiledCode *cc);
123 SCM_EXTERN void Scm_CompiledCodePutInsn(ScmCompiledCode *cc,
124 ScmObj insn,
125 ScmObj operand,
126 ScmObj info);
127 SCM_EXTERN ScmObj Scm_CompiledCodeNewLabel(ScmCompiledCode *cc);
128 SCM_EXTERN void Scm_CompiledCodeSetLabel(ScmCompiledCode *cc, ScmObj label);
129 SCM_EXTERN void Scm_CompiledCodeFinishBuilder(ScmCompiledCode *cc,
130 int maxstack);
131 SCM_EXTERN void Scm_CompiledCodeEmit(ScmCompiledCode *cc,
132 int code,
133 int arg0,
134 int arg1,
135 ScmObj operand,
136 ScmObj info);
137
138 /*
139 * VM instructions
140 */
141 #define SCM_VM_INSN_ARG_MAX ((1L<<(32-13))-1)
142 #define SCM_VM_INSN_ARG_MIN (-SCM_VM_INSN_ARG_MAX)
143 #define SCM_VM_INSN_ARG_FITS(k) \
144 (((k)<=SCM_VM_INSN_ARG_MAX)&&((k)>=SCM_VM_INSN_ARG_MIN))
145
146 /* Macros for transition to the packed code vector of NVM.
147 In the packed code vector, VM insns are stored untagged.
148 It eliminates the shift in the dispatcher. */
149 #define SCM_VM_INSN_CODE(obj) (SCM_WORD(obj)&0x0ff)
150 #define SCM_VM_INSN_ARG(obj) ((signed long)SCM_WORD(obj) >> 8)
151 #define SCM_VM_INSN_ARG0(obj) ((SCM_WORD(obj) >> 8) & 0x03ff)
152 #define SCM_VM_INSN_ARG1(obj) ((SCM_WORD(obj) >> 18) & 0x03ff)
153
154 #define SCM_VM_INSN(code) SCM_WORD(code)
155 #define SCM_VM_INSN1(code, arg) SCM_WORD((long)((arg)<<8) | (code))
156 #define SCM_VM_INSN2(code, arg0, arg1) \
157 SCM_WORD((long)((arg1) << 18) | ((arg0) << 8) | (code))
158
159 /* Operand type */
160 enum {
161 SCM_VM_OPERAND_NONE, /* take no operand */
162 SCM_VM_OPERAND_OBJ, /* take ScmObj */
163 SCM_VM_OPERAND_CODE, /* take ScmCompiledCode */
164 SCM_VM_OPERAND_CODES, /* take a list of ScmCompiledCodes */
165 SCM_VM_OPERAND_ADDR, /* take address of next code */
166 SCM_VM_OPERAND_OBJ_ADDR /* take an object and address of next code */
167 };
168
169 SCM_EXTERN const char *Scm_VMInsnName(u_int code);
170 SCM_EXTERN int Scm_VMInsnNumParams(u_int code);
171 SCM_EXTERN int Scm_VMInsnOperandType(u_int code);
172 SCM_EXTERN int Scm_VMInsnNameToCode(ScmObj name);
173 SCM_EXTERN ScmWord Scm_VMInsnBuild(ScmObj insn);
174
175
176
177 #endif /* GAUCHE_CODE_H */