root/src/gauche/vm.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. ScmEnvFrame
  2. ScmContFrame
  3. ScmSyntacticClosure
  4. ScmIdentifier
  5. ScmCStack
  6. ScmEscapePoint
  7. ScmVMParameterTable
  8. ScmSignalQueue
  9. ScmVMStat
  10. 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 */

/* [<][>][^][v][top][bottom][index][help] */