/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- ScmEnvFrame
- ScmContFrame
- ScmSyntacticClosure
- ScmIdentifier
- ScmCStack
- ScmEscapePoint
- ScmVMParameterTable
- ScmSignalQueue
- ScmVMStat
- ScmCContinuation
1 /*
2 * vm.h - Virtual machine
3 *
4 * Copyright (c) 2000-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: vm.h,v 1.105 2005/08/13 06:51:53 shirok Exp $
34 */
35
36 #ifndef GAUCHE_VM_H
37 #define GAUCHE_VM_H
38
39 /* Size of stack per VM (in words). */
40 #define SCM_VM_STACK_SIZE 10000
41
42 /* Maximum # of values allowed for multiple value return */
43 #define SCM_VM_MAX_VALUES 20
44
45 /* Signal queue size */
46 #define SCM_VM_SIGQ_SIZE 32
47
48 /* Finalizer queue size */
49 #define SCM_VM_FINQ_SIZE 32
50
51 /* QueueNotEmpty flag */
52 #define SCM_VM_SIGQ_MASK 1
53 #define SCM_VM_FINQ_MASK 2
54
55 #define SCM_PCTYPE ScmWord*
56
57 #if defined(ITIMER_PROF) && defined(SIGPROF)
58 /* define if you want to use profiler */
59 #define GAUCHE_PROFILE
60 #endif /* defined(ITIMER_PROF) && defined(SIGPROF) */
61
62 /* Actual structure is defined in code.h */
63 typedef struct ScmCompiledCodeRec ScmCompiledCode;
64
65 /*
66 * Environment frame
67 *
68 * : :
69 * +--------+
70 * | size=N |
71 * | info |
72 * |...up...|<--- ScmEnvFrame* envp
73 * |arg[N-1]|
74 * |arg[N-2]|
75 * : :
76 * | arg[0] |
77 * +--------+
78 * : :
79 */
80
81 typedef struct ScmEnvFrameRec {
82 struct ScmEnvFrameRec *up; /* static link */
83 ScmObj info; /* reserved */
84 ScmWord size; /* size of the frame (excluding header) */
85 } ScmEnvFrame;
86
87 #define ENV_HDR_SIZE 3 /* envframe header size */
88 #define ENV_SIZE(size) ((size)+ENV_HDR_SIZE)
89 #define ENV_FP(env) (((ScmObj*)(env))-((env)->size))
90 #define ENV_DATA(env, num) (*(((ScmObj*)(env))-(num)-1))
91
92 /*
93 * Continuation frame
94 *
95 * Continuation is represented as a chain of ScmContFrames.
96 * If argp == NULL && size >= 0, the frame is C continuation.
97 */
98
99 typedef struct ScmContFrameRec {
100 struct ScmContFrameRec *prev; /* previous frame */
101 ScmEnvFrame *env; /* saved environment */
102 ScmObj *argp; /* saved argument pointer */
103 int size; /* size of argument frame */
104 SCM_PCTYPE pc; /* next PC */
105 ScmCompiledCode *base; /* base register value */
106 } ScmContFrame;
107
108 #define CONT_FRAME_SIZE (sizeof(ScmContFrame)/sizeof(ScmObj))
109
110 SCM_EXTERN void Scm_CallCC(ScmObj body);
111
112 /*
113 * Syntactic closure
114 *
115 * Syntactic closure encapsulates compile-time environment for
116 * hygienic macro expansion.
117 * See Bawden & Rees, Syntactic Closures, MIT AI Memo 1049, June 1988.
118 */
119
120 typedef struct ScmSyntacticClosureRec {
121 ScmObj env; /* compile-time environment */
122 ScmObj literals; /* literal symbols */
123 ScmObj expr; /* expression */
124 } ScmSyntacticClosure;
125
126 SCM_CLASS_DECL(Scm_SyntacticClosureClass);
127 #define SCM_CLASS_SYNTACTIC_CLOSURE (&Scm_SyntacticClosureClass)
128
129 #define SCM_SYNTACTIC_CLOSURE(obj) ((ScmSyntacticClosure*)(obj))
130 #define SCM_SYNTACTIC_CLOSURE_P(obj) SCM_XTYPEP(obj, SCM_CLASS_SYNTACTIC_CLOSURE)
131
132 SCM_EXTERN ScmObj Scm_MakeSyntacticClosure(ScmObj env,
133 ScmObj literals,
134 ScmObj expr);
135
136 /*
137 * Identifier
138 *
139 * Identifier wraps a symbol with its lexical environment. This
140 * object is used in hygienic macro expansion (see macro.c), and
141 * also used as a placeholder in a global variable reference/assignment
142 * (see compile.c).
143 *
144 * NB: Identifier's API and usage will likely be changed in future.
145 * It shouldn't be used directly from applications.
146 */
147
148 typedef struct ScmIdentifierRec {
149 SCM_HEADER;
150 ScmSymbol *name;
151 ScmModule *module;
152 ScmObj env;
153 } ScmIdentifier;
154
155 SCM_CLASS_DECL(Scm_IdentifierClass);
156 #define SCM_CLASS_IDENTIFIER (&Scm_IdentifierClass)
157
158 #define SCM_IDENTIFIER(obj) ((ScmIdentifier*)(obj))
159 #define SCM_IDENTIFIERP(obj) SCM_XTYPEP(obj, SCM_CLASS_IDENTIFIER)
160
161 SCM_EXTERN ScmObj Scm_MakeIdentifier(ScmSymbol *name, ScmModule *mod,
162 ScmObj env);
163 SCM_EXTERN ScmObj Scm_CopyIdentifier(ScmIdentifier *id);
164 SCM_EXTERN int Scm_IdentifierBindingEqv(ScmIdentifier *id, ScmSymbol *sym,
165 ScmObj env);
166 SCM_EXTERN int Scm_FreeVariableEqv(ScmObj var, ScmObj sym, ScmObj env);
167
168 /*
169 * Escape handling
170 */
171
172 /*
173 * C stack record
174 */
175 typedef struct ScmCStackRec {
176 struct ScmCStackRec *prev;
177 ScmContFrame *cont;
178 sigjmp_buf jbuf;
179 } ScmCStack;
180
181 /*
182 * Escape point
183 *
184 * EscapePoint (EP) structure keeps certain point of continuation chain
185 * where control can be transferred. This structure is used for
186 * saved continuations, as well as error handlers.
187 *
188 * Normally EPs forms a single list, linked by the prev pointer.
189 * vm->escapePoint points a 'current' EP, whose ehandler is the current
190 * error handler.
191 *
192 * However, this simple structure does not work in all cases.
193 * When an error is signalled, we pop EP before executing the error
194 * handler so that an error raised within the error handler will be
195 * handled by the handler of outer EP.
196 *
197 * Suppose the current EP is EP0.
198 *
199 * (with-error-handler ;; <- (1)this installs EP1. EP1->cont captures
200 * ;; one-shot continuation of this expr.
201 * (lambda (e) ...) ;; <- (3)this is executed while EP0 is current
202 * (lambda () ...) ;; <- (2)this is executed while EP1 is current
203 *
204 * If the error handler returns, we pass its result to the continuation of
205 * with-error-handler, which is kept in EP1->cont. The problem arises
206 * if a stack overflow occurs within the error handler, continuation frames
207 * in the stack are relocated to the heap, but EP1->cont isn't updated
208 * since it is out of vm->escapePoint chain.
209 *
210 * 'Floating' pointer is used to catch such case. When an EP is popped
211 * before an error handler is ivoked, EP0's floating pointer is set to
212 * point EP1. When a new EP is pushed, it inherits the previous EP's
213 * floating pointer. With this scheme, active floating EPs are always
214 * reachable from vm->esapePoint->floating chain. (NB: the chain length
215 * can be more than 1, if with-error-handler is used within an error handler
216 * and an error is signalled in its body.
217 */
218 typedef struct ScmEscapePointRec {
219 struct ScmEscapePointRec *prev;
220 struct ScmEscapePointRec *floating;
221 ScmObj ehandler; /* handler closure */
222 ScmContFrame *cont; /* saved continuation */
223 ScmObj handlers; /* saved dynamic handler chain */
224 ScmCStack *cstack; /* C stack */
225 ScmObj xhandler; /* saved exception handler */
226 int errorReporting; /* state of SCM_VM_ERROR_REPORTING flag
227 when this ep is captured. The flag status
228 should be restored when the control
229 transferred to this escape point. */
230 } ScmEscapePoint;
231
232 /* Link management */
233 #define SCM_VM_FLOATING_EP(vm) \
234 ((vm)->escapePoint? (vm)->escapePoint->floating : vm->escapePointFloating)
235 #define SCM_VM_FLOATING_EP_SET(vm, ep) \
236 do { \
237 if ((vm)->escapePoint) { \
238 (vm)->escapePoint->floating = (ep); \
239 } else { \
240 (vm)->escapePointFloating = (ep); \
241 } \
242 } while (0)
243
244 /* Escape types */
245 #define SCM_VM_ESCAPE_NONE 0
246 #define SCM_VM_ESCAPE_ERROR 1
247 #define SCM_VM_ESCAPE_CONT 2
248 #define SCM_VM_ESCAPE_EXIT 3
249
250 /*
251 * Parameters
252 *
253 * Parameters keep thread-local state. It is called 'fluids' in some
254 * Scheme implementations. A thread inherits the parameters from its
255 * creator.
256 */
257
258 typedef struct ScmVMParameterTableRec {
259 int numParameters;
260 int numAllocated;
261 ScmObj *vector;
262 int *ids;
263 } ScmVMParameterTable;
264
265 SCM_EXTERN void Scm_ParameterTableInit(ScmVMParameterTable *table,
266 ScmVM *base);
267
268 SCM_EXTERN int Scm_MakeParameterSlot(ScmVM *vm, int *newid);
269 SCM_EXTERN ScmObj Scm_ParameterRef(ScmVM *vm, int index, int id);
270 SCM_EXTERN ScmObj Scm_ParameterSet(ScmVM *vm, int index, int id, ScmObj value);
271
272 /*
273 * Signal queue
274 *
275 * Gauche installs singnal handlers that simply queues the signal.
276 * See signal.c for the implementaiton.
277 * Signal queue is a fixed size, since we can't really extend it
278 * within the system's signal handler. For the time being, overflowed
279 * signals are simply discarded.
280 */
281
282 typedef struct ScmSignalQueueRec {
283 int queue[SCM_VM_SIGQ_SIZE];/* Ring buffer for pending signals */
284 unsigned int head; /* points to the queue head */
285 unsigned int tail; /* points to the queue tail */
286 unsigned int overflow; /* flag to indicate queue overflow */
287 ScmObj pending; /* pending signal handlers */
288 } ScmSignalQueue;
289
290 SCM_EXTERN void Scm_SignalQueueInit(ScmSignalQueue* q);
291
292 /* NB: Obsoleted macro, but kept for backward compatibility.
293 Better API should be provided in future. */
294 #define SCM_SIGPENDING(vm) \
295 ((vm)->queueNotEmpty&SCM_VM_SIGQ_MASK)
296
297 #define SCM_SIGCHECK(vm) \
298 do { if (vm->queueNotEmpty&SCM_VM_SIGQ_MASK) Scm_SigCheck(vm); } while (0)
299
300 SCM_EXTERN void Scm_SigCheck(ScmVM *vm);
301
302 /*
303 * Finalizers
304 *
305 * Finalizers are queued inside GC. We disable automatic finalizer
306 * invocation of GC and only set the flag on VM when finalizers are
307 * queued. VM loop check the flag and calls Scm_VMFinalizerRun()
308 * to run the finalizers. (If VM is not running, C library must
309 * call it explicitly to run finalizers).
310 */
311
312 SCM_EXTERN ScmObj Scm_VMFinalizerRun(ScmVM *vm);
313
314 /*
315 * Statistics
316 *
317 * Not much stats are collected yet, but will grow in future.
318 * Stats collections are only active if SCM_COLLECT_VM_STATS
319 * runtime flag is TRUE.
320 * Stats are collected per-VM (i.e. per-thread), but currently
321 * we don't have an API to gather them.
322 */
323
324 typedef struct ScmVMStatRec {
325 /* Stack overflow handler */
326 u_long sovCount; /* # of stack overflow */
327 double sovTime; /* cumulated time of stack ov handling */
328 } ScmVMStat;
329
330 /* The profiler structure is defined in prof.h */
331 typedef struct ScmVMProfilerRec ScmVMProfiler;
332
333 /*
334 * VM structure
335 *
336 * In Gauche, each thread has a VM. Indeed, the Scheme object
337 * <thread> is ScmVM in C.
338 *
339 * Most fields of VM are private to the thread that owns the VM.
340 * Only the fields marked as "PUBLIC" should be modified by other
341 * thread, and only with obtaining the lock by VMLOCK mutex.
342 *
343 * Note that some fields like "name" and "specific" are not marked
344 * as PUBLIC although they can be referenced or modified by other
345 * thread (via Scheme call thread-specific-set! etc.) It is the
346 * user program's responsibility to use a mutex.
347 * When you should introspect other thread (like stack trace), make
348 * sure you stopped that thread, or you may get inconsistent result.
349 */
350
351 struct ScmVMRec {
352 SCM_HEADER;
353 #ifdef GAUCHE_USE_PTHREADS
354 pthread_t thread; /* the thread executing this VM. */
355 #endif /*!GAUCHE_USE_PTHREADS*/
356 int state; /* thread state. PUBLIC. */
357 ScmInternalMutex vmlock; /* mutex to be used to lock this VM
358 structure. PUBLIC. */
359 ScmInternalCond cond; /* the condition variable to wait for state
360 change of this VM. PUBLIC. */
361 ScmVM *canceller; /* the thread that called thread-terminate!
362 on this thread. PUBLIC. */
363 ScmObj name; /* Scheme thread name. */
364 ScmObj specific; /* Scheme thread specific data. */
365 ScmProcedure *thunk; /* Entry point of this VM. */
366 ScmObj result; /* Result of thunk. */
367 ScmObj resultException; /* Exception that causes the thread to terminate.*/
368 ScmModule *module; /* current global namespace. note that this
369 is used only in compilation. */
370 ScmCStack *cstack; /* current escape point. see the comment of
371 "C stack rewinding" below. */
372 unsigned int runtimeFlags; /* Runtime flags */
373 unsigned int compilerFlags; /* Compiler flags */
374 unsigned int queueNotEmpty; /* Bitmask if sigq or finq is not empty */
375
376 ScmPort *curin; /* current input port */
377 ScmPort *curout; /* current output port */
378 ScmPort *curerr; /* current error port */
379 ScmVMParameterTable parameters; /* parameter table */
380
381 /* Registers */
382 ScmCompiledCode *base; /* Current executing closure's code packet. */
383 SCM_PCTYPE pc; /* Program pointer. Points into the code
384 vector. (base->code) */
385 ScmEnvFrame *env; /* Current environment. */
386 ScmContFrame *cont; /* Current continuation. */
387 ScmObj *argp; /* Current argument pointer. Points
388 to the incomplete environment frame
389 being accumulated. This is a part of
390 continuation. */
391 ScmObj val0; /* Value register. */
392 ScmObj vals[SCM_VM_MAX_VALUES]; /* Value register for multiple values */
393 int numVals; /* # of values */
394
395 ScmObj handlers; /* chain of active dynamic handlers */
396
397 ScmObj *sp; /* stack pointer */
398 ScmObj *stack; /* bottom of allocated stack area */
399 ScmObj *stackBase; /* base of current stack area */
400 ScmObj *stackEnd; /* end of current stack area */
401
402 /* Escape handling */
403 ScmObj exceptionHandler; /* the current exception handler installed by
404 with-exception-handler. */
405 ScmEscapePoint *escapePoint;/* chain of escape points (a kind of one-shot
406 continuation). used by system's default
407 exception handler to escape from the error
408 handlers. */
409 ScmEscapePoint *escapePointFloating;
410 /* reverse link of escape point chain
411 to keep 'active' EPs.
412 See ScmEscapePoint definition above. */
413 int escapeReason; /* temporary storage to pass data across
414 longjmp(). */
415 void *escapeData[2]; /* ditto. */
416
417 /* Custom debugger */
418 ScmObj defaultEscapeHandler;
419
420 /* Program information */
421 ScmObj load_next; /* list of the directories to be searched */
422 ScmObj load_history; /* history of the nested load */
423 ScmObj load_port; /* current port from which we are loading */
424 int evalSituation; /* eval situation (related to eval-when) */
425
426 /* Signal information */
427 ScmSignalQueue sigq;
428 sigset_t sigMask; /* current signal mask */
429
430 /* Statistics */
431 ScmVMStat stat;
432 int profilerRunning;
433 ScmVMProfiler *prof;
434 };
435
436 SCM_EXTERN ScmVM *Scm_NewVM(ScmVM *proto, ScmObj name);
437 SCM_EXTERN int Scm_AttachVM(ScmVM *vm);
438 SCM_EXTERN void Scm_VMDump(ScmVM *vm);
439 SCM_EXTERN void Scm_VMDefaultExceptionHandler(ScmObj exc);
440 SCM_EXTERN ScmObj Scm_VMThrowException(ScmVM *vm, ScmObj exc);
441 SCM_EXTERN ScmObj Scm_VMGetSourceInfo(ScmCompiledCode *code, SCM_PCTYPE pc);
442 SCM_EXTERN ScmObj Scm_VMGetBindInfo(ScmCompiledCode *code, SCM_PCTYPE pc);
443
444 SCM_CLASS_DECL(Scm_VMClass);
445 #define SCM_CLASS_VM (&Scm_VMClass)
446
447 #ifdef GAUCHE_USE_PTHREADS
448 SCM_EXTERN pthread_key_t Scm_VMKey(void);
449 #endif
450
451 /* Value of vm->state */
452 enum {
453 SCM_VM_NEW, /* This VM is just created and not attached
454 to the running thread. vm->thread is not
455 initialized. */
456 SCM_VM_RUNNABLE, /* This VM is attached to a thread which is
457 runnable or blocked. */
458 SCM_VM_BLOCKED, /* The thread attached to this VM is stopped
459 because of thread-yield! or thread-sleep!.
460 Note that if the thread is blocked by
461 system call, VM's state is still RUNNABLE.*/
462 SCM_VM_TERMINATED /* The thread attached to this VM is
463 terminated. */
464 };
465
466 /* Value of vm->evalSituation */
467 enum {
468 SCM_VM_EXECUTING, /* we're evaluating the form interactively. */
469 SCM_VM_LOADING, /* we're loading the forms */
470 SCM_VM_COMPILING /* we're batch-compiling the forms */
471 };
472
473
474 /*
475 * C stack rewinding
476 * (These macros interacts with VM internals, so must be used
477 * with care.)
478 *
479 * These macros should be used if you want to guarantee certain
480 * cleanup is called when the C-stack is "rewind". So it's like
481 * C-version of dynamic-wind. The typical usage will be like
482 * the following:
483 *
484 * SCM_UNWIND_PROTECT {
485 * preprocess
486 * main operation
487 * } SCM_WHEN_ERROR {
488 * clean up code on abnormal situation
489 * SCM_NEXT_HANDLER;
490 * } SCM_END_PROTECT;
491 * clean up code on normal situation
492 *
493 * Note that this construct does not install exception handler or
494 * error handler by itself. The handler installed by with-error-handler
495 * or with-exception-handler is invoked, and then the SCM_WHEN_ERROR
496 * part is called while the C stack is rewind.
497 * If you want to handle error as well, you should install error handler
498 * by yourself (and deinstall it in the cleanup code).
499 *
500 * If you don't call SCM_NEXT_HANDLER in the SCM_WHEN_ERROR clause,
501 * the control is transferred after SCM_END_PROTECT. It is not recommended
502 * unless you know what you're doing. The C stack is rewind not only
503 * at the error situation, but also a continuation is thrown in the main
504 * operation. Except certain special occasions, stopping C-stack rewinding
505 * may cause semantic inconsistency.
506 */
507
508 #define SCM_UNWIND_PROTECT \
509 do { \
510 ScmCStack cstack; \
511 cstack.prev = Scm_VM()->cstack; \
512 cstack.cont = NULL; \
513 Scm_VM()->cstack = &cstack; \
514 if (sigsetjmp(cstack.jbuf, FALSE) == 0) {
515
516 #define SCM_WHEN_ERROR \
517 } else {
518
519 #define SCM_NEXT_HANDLER \
520 do { \
521 if (Scm_VM()->cstack->prev) { \
522 Scm_VM()->cstack = Scm_VM()->cstack->prev; \
523 siglongjmp(Scm_VM()->cstack->jbuf, 1); \
524 } \
525 else Scm_Exit(1); \
526 } while (0)
527
528 #define SCM_END_PROTECT \
529 } \
530 Scm_VM()->cstack = Scm_VM()->cstack->prev; \
531 } while (0)
532
533 /*
534 * Runtime flags
535 */
536 enum {
537 SCM_ERROR_BEING_HANDLED = (1L<<0), /* we're in an error handler */
538 SCM_ERROR_BEING_REPORTED = (1L<<1), /* we're in an error reporter */
539 SCM_LOAD_VERBOSE = (1L<<2), /* report loading files */
540 SCM_CASE_FOLD = (1L<<3), /* symbols are case insensitive */
541 SCM_LIMIT_MODULE_MUTATION = (1L<<4),/* disable set! to modify the
542 global binding in the other
543 module */
544 SCM_COLLECT_VM_STATS = (1L<<5) /* enable statistics collection
545 (incurs runtime overhead) */
546 };
547
548 #define SCM_VM_RUNTIME_FLAG_IS_SET(vm, flag) ((vm)->runtimeFlags & (flag))
549 #define SCM_VM_RUNTIME_FLAG_SET(vm, flag) ((vm)->runtimeFlags |= (flag))
550 #define SCM_VM_RUNTIME_FLAG_CLEAR(vm, flag) ((vm)->runtimeFlags &= ~(flag))
551
552 /*
553 * C-continuation
554 */
555
556 #define SCM_CCONT_DATA_SIZE 6
557
558 typedef struct ScmCContinuation {
559 SCM_HEADER;
560 ScmObj (*func)(ScmObj value, void **data);
561 void *data[SCM_CCONT_DATA_SIZE];
562 } ScmCContinuation;
563
564 #define SCM_CCONT(obj) ((ScmCContinuation*)(obj))
565 #define SCM_CCONTP(obj) SCM_XTYPEP(obj, SCM_CLASS_CCONT)
566
567 SCM_CLASS_DECL(Scm_CContClass);
568 #define SCM_CLASS_CCONT (&Scm_CContClass)
569
570 SCM_EXTERN void Scm_VMPushCC(ScmObj (*func)(ScmObj value, void **data),
571 void **data,
572 int datasize);
573
574 /*
575 * Compiler flags
576 */
577
578 enum {
579 SCM_COMPILE_NOINLINE_GLOBALS = (1L<<0),/* Do not inline global procs */
580 SCM_COMPILE_NOINLINE_LOCALS = (1L<<1), /* Do not inline local procs */
581 SCM_COMPILE_NOINLINE_CONSTS = (1L<<2), /* Do not inline constants */
582 SCM_COMPILE_NOSOURCE = (1L<<3), /* Do not insert source info */
583 SCM_COMPILE_SHOWRESULT = (1L<<4), /* Display each result of
584 compilation */
585 SCM_COMPILE_NOCOMBINE = (1L<<5) /* Do not combine instructions */
586 };
587
588 #define SCM_VM_COMPILER_FLAG_IS_SET(vm, flag) ((vm)->compilerFlags & (flag))
589 #define SCM_VM_COMPILER_FLAG_SET(vm, flag) ((vm)->compilerFlags |= (flag))
590 #define SCM_VM_COMPILER_FLAG_CLEAR(vm, flag) ((vm)->compilerFlags &= ~(flag))
591
592 /*
593 * Compiler internal APIs
594 */
595
596 SCM_EXTERN ScmObj Scm_Compile(ScmObj program, ScmObj mod);
597
598 SCM_EXTERN ScmObj Scm_CallSyntaxCompiler(ScmObj syn, ScmObj from, ScmObj env);
599 SCM_EXTERN ScmObj Scm_CallMacroExpander(ScmMacro *mac, ScmObj expr, ScmObj env);
600 SCM_EXTERN ScmObj Scm_CallMacroExpanderOld(ScmMacro *mac, ScmObj expr, ScmObj env);
601 SCM_EXTERN int Scm_HasInlinerP(ScmObj obj);
602 SCM_EXTERN ScmObj Scm_CallProcedureInliner(ScmObj obj, ScmObj form, ScmObj env);
603
604 /* This is in module.c, but it's not for public, so declaration is here. */
605 SCM_EXTERN ScmModule* Scm_GaucheInternalModule(void);
606
607 #endif /* GAUCHE_VM_H */