Logo Search packages:      
Sourcecode: gambas version File versions  Download package

gbx_exec_loop.c

/***************************************************************************

  exec_loop.c

  The interpreter main loop

  (c) 2000-2004 Beno� Minisini <gambas@users.sourceforge.net>

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 1, or (at your option)
  any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

***************************************************************************/

#define __GBX_EXEC_LOOP_C

#include "gb_common.h"
#include "gb_error.h"
#include "gbx_type.h"
#include "gbx_debug.h"

#include "gbx_subr.h"
#include "gb_pcode.h"
#include "gbx_stack.h"
#include "gbx_trace.h"
#include "gbx_event.h"
#include "gbx_value.h"
#include "gbx_local.h"
#include "gbx_string.h"
#include "gbx_api.h"
#include "gbx_archive.h"

#include "gbx_exec.h"


#define SUBR_is EXEC_nop
#define SUBR_beep EXEC_nop


#define GET_XXX()   (((signed short)(code << 4)) >> 4)
#define GET_7XX()   (code & 0x7FF)
#define GET_XX()    ((signed char)(code & 0xFF))
#define GET_3X()    (code & 0x3F)


PRIVATE EXEC_FUNC SubrTable[] =
{
  /* 28 */  SUBR_eq,            SUBR_ne,            SUBR_gt,            SUBR_le,
  /* 2C */  SUBR_lt,            SUBR_ge,            SUBR_is,            SUBR_case,
  /* 30 */  SUBR_add,           SUBR_sub,           SUBR_mul,           SUBR_div,
  /* 34 */  SUBR_neg,           SUBR_quo,           SUBR_rem,           SUBR_pow,
  /* 38 */  SUBR_and,           SUBR_or,            SUBR_not,           SUBR_xor,
  /* 3C */  SUBR_cat,           SUBR_like,          SUBR_file,          EXEC_ILLEGAL,

  SUBR_left,       /* 00 */
  SUBR_mid,        /* 01 */
  SUBR_right,      /* 02 */
  SUBR_len,        /* 03 */
  SUBR_space,      /* 04 */
  SUBR_string,     /* 05 */
  SUBR_trim,       /* 06 */
  SUBR_upper,      /* 07 */
  SUBR_lower,      /* 08 */
  SUBR_chr,        /* 09 */
  SUBR_asc,        /* 10 */
  SUBR_instr,      /* 11 */
  SUBR_instr,      /* 12 */
  SUBR_subst,      /* 13 */
  SUBR_replace,    /* 14 */
  SUBR_split,      /* 15 */
  SUBR_sconv,      /* 16 */

  SUBR_abs,        /* 17 */
  SUBR_int,        /* 18 */

  SUBR_math,       /* 19 */

  SUBR_sgn,        /* 20 */
  SUBR_fix,        /* 21 */

  SUBR_pi,         /* 22 */
  SUBR_round,      /* 23 */
  SUBR_randomize,  /* 24 */
  SUBR_rnd,        /* 25 */
  SUBR_min_max,    /* 26 */
  SUBR_min_max,    /* 27 */

  SUBR_if,         /* 28 */
  SUBR_choose,     /* 29 */

  SUBR_array,      /* 30 */

  EXEC_ILLEGAL,    /* 31 */
  EXEC_ILLEGAL,    /* 32 */
  EXEC_ILLEGAL,    /* 33 */
  EXEC_ILLEGAL,    /* 34 */

  SUBR_bit,        /* 35 */

  EXEC_ILLEGAL,    /* 36 */
  EXEC_ILLEGAL,    /* 37 */
  EXEC_ILLEGAL,    /* 38 */
  EXEC_ILLEGAL,    /* 39 */
  EXEC_ILLEGAL,    /* 40 */
  EXEC_ILLEGAL,    /* 41 */

  SUBR_is_type,    /* 42 */
  SUBR_type,       /* 43 */

  SUBR_conv,       /* 44 */

  SUBR_bin,        /* 45 */
  SUBR_hex,        /* 46 */
  SUBR_val,        /* 47 */
  SUBR_str,        /* 48 */
  SUBR_format,     /* 49 */

  SUBR_timer,      /* 50 */
  SUBR_now,        /* 51 */

  SUBR_year,       /* 52 */

  SUBR_date,       /* 53 */
  SUBR_time,       /* 54 */

  SUBR_error,      /* 55 */

  SUBR_eval,       /* 56 */

  SUBR_use,        /* 57 */

  SUBR_beep,       /* 58 */
  SUBR_wait,       /* 59 */

  SUBR_open,       /* 60 */
  SUBR_close,      /* 61 */
  SUBR_input,      /* 62 */
  SUBR_print,      /* 63 */
  SUBR_read,       /* 64 */
  SUBR_write,      /* 65 */
  SUBR_eof,        /* 66 */
  SUBR_lof,        /* 67 */
  SUBR_seek,       /* 68 */
  SUBR_kill,       /* 69 */
  SUBR_mkdir,      /* 70 */
  SUBR_rmdir,      /* 71 */
  SUBR_exist,      /* 72 */
  SUBR_rename,     /* 73 */
  SUBR_stat,       /* 74 */
  SUBR_linput,     /* 75 */
  SUBR_temp,       /* 76 */
  SUBR_isdir,      /* 77 */
  SUBR_dir,        /* 78 */
  SUBR_flush,      /* 79 */

  SUBR_exec,       /* 80 */

  SUBR_copy,       /* 81 */
  SUBR_access,     /* 82 */
  SUBR_link,       /* 83 */

  SUBR_lock,       /* 84 */
  EXEC_ILLEGAL,    /* 85 */
  EXEC_ILLEGAL,    /* 86 */
};


PUBLIC void EXEC_loop(void)
{
  static void *jump_table[256] =
  {
    /* 00 NOP             */  &&_NEXT,
    /* 01 PUSH LOCAL      */  &&_PUSH_LOCAL,
    /* 02 PUSH ARRAY      */  &&_PUSH_ARRAY,
    /* 03 PUSH UNKNOWN    */  &&_PUSH_UNKNOWN,
    /* 04 illegal         */  &&_ILLEGAL,
    /* 05 illegal         */  &&_ILLEGAL,
    /* 06 PUSH SPECIAL    */  &&_PUSH_SPECIAL,
    /* 07 PUSH EVENT      */  &&_PUSH_EVENT,
    /* 08 QUIT            */  &&_QUIT,
    /* 09 POP LOCAL       */  &&_POP_LOCAL,
    /* 0A POP ARRAY       */  &&_POP_ARRAY,
    /* 0B POP UNKNOWN     */  &&_POP_UNKNOWN,
    /* 0C POP OPTIONAL    */  &&_POP_OPTIONAL,
    /* 0D POP CTRL        */  &&_POP_CTRL,
    /* 0E BREAK           */  &&_BREAK,
    /* 0F RETURN          */  &&_RETURN,
    /* 10 PUSH SHORT      */  &&_PUSH_SHORT,
    /* 11 PUSH INTEGER    */  &&_PUSH_INTEGER,
    /* 12 PUSH CHAR       */  &&_PUSH_CHAR,
    /* 13 PUSH ME         */  &&_PUSH_ME,
    /* 14 PUSH NULL       */  &&_PUSH_NULL,
    /* 15 PUSH VOID       */  &&_PUSH_VOID,
    /* 16 PUSH RETURN     */  &&_ILLEGAL,
    /* 17 PUSH BOOLEAN    */  &&_PUSH_BOOLEAN,
    /* 18 PUSH LAST       */  &&_PUSH_LAST,
    /* 19 EVENT           */  &&_EVENT,
    /* 1A TRY             */  &&_TRY,
    /* 1B END TRY         */  &&_END_TRY,
    /* 1C CATCH           */  &&_CATCH,
    /* 1D DUP             */  &&_DUP,
    /* 1E DROP            */  &&_DROP,
    /* 1F NEW             */  &&_NEW,
    /* 20 JUMP            */  &&_JUMP,
    /* 21 JUMP IF TRUE    */  &&_JUMP_IF_TRUE,
    /* 22 JUMP IF FALSE   */  &&_JUMP_IF_FALSE,
    /* 23 CALL            */  &&_CALL,
    /* 24 JUMP FIRST      */  &&_JUMP_FIRST,
    /* 25 JUMP NEXT       */  &&_JUMP_NEXT,
    /* 26 FIRST           */  &&_ENUM_FIRST,
    /* 27 NEXT            */  &&_ENUM_NEXT,
    /* 28                 */  &&_SUBR,
    /* 29                 */  &&_SUBR,
    /* 2A                 */  &&_SUBR,
    /* 2B                 */  &&_SUBR,
    /* 2C                 */  &&_SUBR,
    /* 2D                 */  &&_SUBR,
    /* 2E                 */  &&_SUBR,
    /* 2F                 */  &&_SUBR,
    /* 30                 */  &&_SUBR,
    /* 31                 */  &&_SUBR,
    /* 32                 */  &&_SUBR,
    /* 33                 */  &&_SUBR,
    /* 34                 */  &&_SUBR,
    /* 35                 */  &&_SUBR,
    /* 36                 */  &&_SUBR,
    /* 37                 */  &&_SUBR,
    /* 38                 */  &&_SUBR,
    /* 39                 */  &&_SUBR,
    /* 3A                 */  &&_SUBR,
    /* 3B                 */  &&_SUBR,
    /* 3C                 */  &&_SUBR,
    /* 3D                 */  &&_SUBR,
    /* 3E                 */  &&_SUBR,
    /* 3F                 */  &&_SUBR,
    /* 40                 */  &&_SUBR,
    /* 41                 */  &&_SUBR,
    /* 42                 */  &&_SUBR,
    /* 43                 */  &&_SUBR,
    /* 44                 */  &&_SUBR,
    /* 45                 */  &&_SUBR,
    /* 46                 */  &&_SUBR,
    /* 47                 */  &&_SUBR,
    /* 48                 */  &&_SUBR,
    /* 49                 */  &&_SUBR,
    /* 4A                 */  &&_SUBR,
    /* 4B                 */  &&_SUBR,
    /* 4C                 */  &&_SUBR,
    /* 4D                 */  &&_SUBR,
    /* 4E                 */  &&_SUBR,
    /* 4F                 */  &&_SUBR,
    /* 50                 */  &&_SUBR,
    /* 51                 */  &&_SUBR,
    /* 52                 */  &&_SUBR,
    /* 53                 */  &&_SUBR,
    /* 54                 */  &&_SUBR,
    /* 55                 */  &&_SUBR,
    /* 56                 */  &&_SUBR,
    /* 57                 */  &&_SUBR,
    /* 58                 */  &&_SUBR,
    /* 59                 */  &&_SUBR,
    /* 5A                 */  &&_SUBR,
    /* 5B                 */  &&_SUBR,
    /* 5C                 */  &&_SUBR,
    /* 5D                 */  &&_SUBR,
    /* 5E                 */  &&_SUBR,
    /* 5F                 */  &&_SUBR,
    /* 60                 */  &&_SUBR,
    /* 61                 */  &&_SUBR,
    /* 62                 */  &&_SUBR,
    /* 63                 */  &&_SUBR,
    /* 64                 */  &&_SUBR,
    /* 65                 */  &&_SUBR,
    /* 66                 */  &&_SUBR,
    /* 67                 */  &&_SUBR,
    /* 68                 */  &&_SUBR,
    /* 69                 */  &&_SUBR,
    /* 6A                 */  &&_SUBR,
    /* 6B                 */  &&_SUBR,
    /* 6C                 */  &&_SUBR,
    /* 6D                 */  &&_SUBR,
    /* 6E                 */  &&_SUBR,
    /* 6F                 */  &&_SUBR,
    /* 70                 */  &&_SUBR,
    /* 71                 */  &&_SUBR,
    /* 72                 */  &&_SUBR,
    /* 73                 */  &&_SUBR,
    /* 74                 */  &&_SUBR,
    /* 75                 */  &&_SUBR,
    /* 76                 */  &&_SUBR,
    /* 77                 */  &&_SUBR,
    /* 78                 */  &&_SUBR,
    /* 79                 */  &&_SUBR,
    /* 7A                 */  &&_SUBR,
    /* 7B                 */  &&_SUBR,
    /* 7C                 */  &&_SUBR,
    /* 7D                 */  &&_SUBR,
    /* 7E                 */  &&_SUBR,
    /* 7F                 */  &&_SUBR,
    /* 80                 */  &&_SUBR,
    /* 81                 */  &&_SUBR,
    /* 82                 */  &&_SUBR,
    /* 83                 */  &&_SUBR,
    /* 84                 */  &&_SUBR,
    /* 85                 */  &&_SUBR,
    /* 86                 */  &&_SUBR,
    /* 87                 */  &&_SUBR,
    /* 88                 */  &&_SUBR,
    /* 89                 */  &&_SUBR,
    /* 8A                 */  &&_SUBR,
    /* 8B                 */  &&_SUBR,
    /* 8C                 */  &&_SUBR,
    /* 8D                 */  &&_SUBR,
    /* 8E                 */  &&_SUBR,
    /* 8F                 */  &&_SUBR,
    /* 90                 */  &&_SUBR,
    /* 91                 */  &&_SUBR,
    /* 92                 */  &&_SUBR,
    /* 93                 */  &&_SUBR,
    /* 94                 */  &&_SUBR,
    /* 95                 */  &&_SUBR,
    /* 96                 */  &&_SUBR,
    /* 97                 */  &&_SUBR,
    /* 98                 */  &&_SUBR,
    /* 99                 */  &&_SUBR,
    /* 9A                 */  &&_SUBR,
    /* 9B                 */  &&_SUBR,
    /* 9C                 */  &&_SUBR,
    /* 9D                 */  &&_ILLEGAL,
    /* 9E                 */  &&_ILLEGAL,
    /* 9F                 */  &&_ILLEGAL,
    /* A0 ADD QUICK       */  &&_TODO,
    /* A1 ADD QUICK       */  &&_TODO,
    /* A2 ADD QUICK       */  &&_TODO,
    /* A3 ADD QUICK       */  &&_TODO,
    /* A4 ADD QUICK       */  &&_TODO,
    /* A5 ADD QUICK       */  &&_TODO,
    /* A6 ADD QUICK       */  &&_TODO,
    /* A7 ADD QUICK       */  &&_TODO,
    /* A8 ADD QUICK       */  &&_TODO,
    /* A9 ADD QUICK       */  &&_TODO,
    /* AA ADD QUICK       */  &&_TODO,
    /* AB ADD QUICK       */  &&_TODO,
    /* AC ADD QUICK       */  &&_TODO,
    /* AD ADD QUICK       */  &&_TODO,
    /* AE ADD QUICK       */  &&_TODO,
    /* AF ADD QUICK       */  &&_TODO,
    /* B0 PUSH CLASS      */  &&_PUSH_CLASS,
    /* B1 PUSH CLASS      */  &&_PUSH_CLASS,
    /* B2 PUSH CLASS      */  &&_PUSH_CLASS,
    /* B3 PUSH CLASS      */  &&_PUSH_CLASS,
    /* B4 PUSH CLASS      */  &&_PUSH_CLASS,
    /* B5 PUSH CLASS      */  &&_PUSH_CLASS,
    /* B6 PUSH CLASS      */  &&_PUSH_CLASS,
    /* B7 PUSH CLASS      */  &&_PUSH_CLASS,
    /* B8 PUSH FUNCTION   */  &&_PUSH_FUNCTION,
    /* B9 PUSH FUNCTION   */  &&_PUSH_FUNCTION,
    /* BA PUSH FUNCTION   */  &&_PUSH_FUNCTION,
    /* BB PUSH FUNCTION   */  &&_PUSH_FUNCTION,
    /* BC PUSH FUNCTION   */  &&_PUSH_FUNCTION,
    /* BD PUSH FUNCTION   */  &&_PUSH_FUNCTION,
    /* BE PUSH FUNCTION   */  &&_PUSH_FUNCTION,
    /* BF PUSH FUNCTION   */  &&_PUSH_FUNCTION,
    /* C0 PUSH DYNAMIC    */  &&_PUSH_DYNAMIC,
    /* C1 PUSH DYNAMIC    */  &&_PUSH_DYNAMIC,
    /* C2 PUSH DYNAMIC    */  &&_PUSH_DYNAMIC,
    /* C3 PUSH DYNAMIC    */  &&_PUSH_DYNAMIC,
    /* C4 PUSH DYNAMIC    */  &&_PUSH_DYNAMIC,
    /* C5 PUSH DYNAMIC    */  &&_PUSH_DYNAMIC,
    /* C6 PUSH DYNAMIC    */  &&_PUSH_DYNAMIC,
    /* C7 PUSH DYNAMIC    */  &&_PUSH_DYNAMIC,
    /* C8 PUSH STATIC     */  &&_PUSH_STATIC,
    /* C9 PUSH STATIC     */  &&_PUSH_STATIC,
    /* CA PUSH STATIC     */  &&_PUSH_STATIC,
    /* CB PUSH STATIC     */  &&_PUSH_STATIC,
    /* CC PUSH STATIC     */  &&_PUSH_STATIC,
    /* CD PUSH STATIC     */  &&_PUSH_STATIC,
    /* CE PUSH STATIC     */  &&_PUSH_STATIC,
    /* CF PUSH STATIC     */  &&_PUSH_STATIC,
    /* D0 POP DYNAMIC     */  &&_POP_DYNAMIC,
    /* D1 POP DYNAMIC     */  &&_POP_DYNAMIC,
    /* D2 POP DYNAMIC     */  &&_POP_DYNAMIC,
    /* D3 POP DYNAMIC     */  &&_POP_DYNAMIC,
    /* D4 POP DYNAMIC     */  &&_POP_DYNAMIC,
    /* D5 POP DYNAMIC     */  &&_POP_DYNAMIC,
    /* D6 POP DYNAMIC     */  &&_POP_DYNAMIC,
    /* D7 POP DYNAMIC     */  &&_POP_DYNAMIC,
    /* D8 POP STATIC      */  &&_POP_STATIC,
    /* D9 POP STATIC      */  &&_POP_STATIC,
    /* DA POP STATIC      */  &&_POP_STATIC,
    /* DB POP STATIC      */  &&_POP_STATIC,
    /* DC POP STATIC      */  &&_POP_STATIC,
    /* DD POP STATIC      */  &&_POP_STATIC,
    /* DE POP STATIC      */  &&_POP_STATIC,
    /* DF POP STATIC      */  &&_POP_STATIC,
    /* E0 PUSH CONST      */  &&_PUSH_CONST,
    /* E1 PUSH CONST      */  &&_PUSH_CONST,
    /* E2 PUSH CONST      */  &&_PUSH_CONST,
    /* E3 PUSH CONST      */  &&_PUSH_CONST,
    /* E4 PUSH CONST      */  &&_PUSH_CONST,
    /* E5 PUSH CONST      */  &&_PUSH_CONST,
    /* E6 PUSH CONST      */  &&_PUSH_CONST,
    /* E7 PUSH CONST      */  &&_PUSH_CONST,
    /* E8 PUSH CONST      */  &&_PUSH_CONST,
    /* E9 PUSH CONST      */  &&_PUSH_CONST,
    /* EA PUSH CONST      */  &&_PUSH_CONST,
    /* EB PUSH CONST      */  &&_PUSH_CONST,
    /* EC PUSH CONST      */  &&_PUSH_CONST,
    /* ED PUSH CONST      */  &&_PUSH_CONST,
    /* EE PUSH CONST      */  &&_PUSH_CONST,
    /* EF PUSH CONST      */  &&_PUSH_CONST,
    /* F0 PUSH QUICK      */  &&_PUSH_QUICK,
    /* F1 PUSH QUICK      */  &&_PUSH_QUICK,
    /* F2 PUSH QUICK      */  &&_PUSH_QUICK,
    /* F3 PUSH QUICK      */  &&_PUSH_QUICK,
    /* F4 PUSH QUICK      */  &&_PUSH_QUICK,
    /* F5 PUSH QUICK      */  &&_PUSH_QUICK,
    /* F6 PUSH QUICK      */  &&_PUSH_QUICK,
    /* F7 PUSH QUICK      */  &&_PUSH_QUICK,
    /* F8 PUSH QUICK      */  &&_PUSH_QUICK,
    /* F9 PUSH QUICK      */  &&_PUSH_QUICK,
    /* FA PUSH QUICK      */  &&_PUSH_QUICK,
    /* FB PUSH QUICK      */  &&_PUSH_QUICK,
    /* FC PUSH QUICK      */  &&_PUSH_QUICK,
    /* FD PUSH QUICK      */  &&_PUSH_QUICK,
    /* FE PUSH QUICK      */  &&_PUSH_QUICK,
    /* FF PUSH QUICK      */  &&_PUSH_QUICK
  };

  register int ind;
  register ushort code;
  /*ushort uind;*/
  TYPE type;

  void _pop_ctrl(int ind)
  {
    register VALUE *val = &BP[ind];
    RELEASE(val);
    SP--;
    *val = *SP;
  }

  goto _MAIN;

/*-----------------------------------------------*/

_NEXT3:

  PC++;

_NEXT2:

  PC++;

_NEXT:

  PC++;

/*-----------------------------------------------*/

_MAIN:

  /*
  if (EXEC_stop_next)
  {
    EXEC_stop_next = FALSE;
    TRACE_next();
  }

  if (EXEC_stop_next_line)
  {
    if ((EXEC_stop_function == NULL || FP == EXEC_stop_function)
        && (PC < EXEC_begin_line || PC >= EXEC_end_line))
    {
      EXEC_stop_next_line = FALSE;
      TRACE_main();
    }
  }
  */

/*_MAIN_BREAK:*/

/*#define DEBUG_PCODE 1*/

#if DEBUG_PCODE
    TRACE_where();
#if DEBUG_STACK
      printf("[%d] ", SP - (VALUE *)STACK_base);
#endif
    if (*PC >> 8)
      PCODE_dump(PC - FP->code, PC);
#endif

    /*{
      char *addr; long len;

      if (SP > (VALUE *)STACK_base)
      {
        VALUE_to_string(SP - 1, &addr, &len);
        printf("SP -> %.*s\n", (int)len, addr);
      }
    }*/
#if 0
    /*printf("RET->type = %ld\n", RET.type);*/
    /*printf("EC = %p ", EC);*/
    TRACE_where();
    printf("[%d] ", SP - (VALUE *)STACK_base);
    if (*PC >> 8)
      PCODE_dump(PC - FP->code, PC);
     /*fflush(stdout); bug */
#endif

  /*TRACE_check_signal();*/

  code = *PC;
  goto *jump_table[code >> 8];

/*-----------------------------------------------*/

_TODO:

  printf("** Not yet implemented\n");
  goto _NEXT;

/*-----------------------------------------------*/

_ILLEGAL:

  THROW(E_ILLEGAL);

/*-----------------------------------------------*/

_BREAK:

  if (EXEC_debug && CP && CP->belong == ARCHIVE_main)
  {
    TRACE.ec = PC + 1;
    TRACE.ep = SP;

    ind = GET_XX();

    if (ind == 0)
    {
      if (!TRACE.stop)
        goto _NEXT;

      if (TRACE.fp != NULL)
      {
        if (BP > TRACE.bp)
          goto _NEXT;


        /*if (TRACE.fp != FP)
          goto _NEXT;*/


        /*printf("BP = %p  bp = %p\n", BP, TRACE.bp);*/
      }
    }

    TRACE_breakpoint(ind);
  }

  goto _NEXT;

/*-----------------------------------------------*/

_QUIT:

  if (GET_XX() == 0)
    EXEC_quit();

  if (EXEC_debug)
    TRACE_breakpoint(0);

  goto _NEXT;

/*-----------------------------------------------*/

_SUBR:

  EXEC_code = code;

  (*SubrTable[(code >> 8) - 0x28])();

  if (PCODE_is_void(EXEC_code))
    POP();

  goto _NEXT;

/*-----------------------------------------------*/

_PUSH_LOCAL:

  *SP = BP[GET_XX()];
  PUSH();

  goto _NEXT;

/*-----------------------------------------------*/

_PUSH_ARRAY:

  EXEC_push_array();
  goto _NEXT;

/*-----------------------------------------------*/

_PUSH_UNKNOWN:

  EXEC_push_unknown();
  goto _NEXT;

/*-----------------------------------------------*/

_PUSH_SPECIAL:

  EXEC_push_special();
  goto _NEXT;

/*-----------------------------------------------*/

_PUSH_EVENT:

  {
    OBJECT_EVENT *ev;
    OBJECT *parent;

    ind = GET_XX();
    ev = OBJECT_event(OP);

    if (CP->parent)
      ind += CP->parent->n_event;

    ind = ev->event[ind];
    parent = ev->parent;

    if (parent == NULL || ind == 0)
    {
      /* fonction ne faisant rien si ce n'est renvoyer une valeur par d�aut */
      SP->_function.object = NULL;
      SP->_function.class = NULL;
      SP->_function.kind = FUNCTION_NULL;
      /*SP->_function.function = (long)(CP->load->event[GET_XX()].type);*/
      /* ??? Pourquoi n'utilise-t-on pas desc ? */
    }
    else
    {
      ind--;

      SP->_function.kind = FUNCTION_PUBLIC;
      /*SP->_function.function = (long)parent->class->table[ind].desc;*/
      /*SP->_function.function = (long)((CLASS *)parent)->table[ind].desc;*/
      SP->_function.index = ind;
      SP->_function.defined = FALSE;

      if (parent->class == CLASS_Class)
      {
        SP->_function.object = NULL;
        SP->_function.class = (CLASS *)parent;
      }
      else
      {
        SP->_function.object = parent;
        SP->_function.class = parent->class;
      }

      EVENT_Last = OP;
    }

    SP->type = T_FUNCTION;
    OBJECT_REF(SP->_function.object, "exec_loop._PUSH_EVENT (FUNCTION)");
    SP++;
  }

  goto _NEXT;

/*-----------------------------------------------*/

_POP_LOCAL:

  {
    register VALUE *val = &BP[GET_XX()];

    VALUE_conv(&SP[-1], val->type);

    RELEASE(val);
    SP--;
    *val = *SP;
  }

  goto _NEXT;

/*-----------------------------------------------*/

_POP_CTRL:

  _pop_ctrl(GET_XX());

  goto _NEXT;

/*-----------------------------------------------*/

_POP_ARRAY:

  EXEC_pop_array();
  goto _NEXT;

/*-----------------------------------------------*/

_POP_UNKNOWN:

  EXEC_pop_unknown();
  goto _NEXT;

/*-----------------------------------------------*/

_POP_OPTIONAL:

  /*
  if (ind >= 0)
    val = &BP[ind];
  else
    val = &PP[ind];
  */

  {
    register VALUE *val = &BP[GET_XX()];

    if (val->type == T_VOID)
    {
      if (SP[-1].type == T_VOID)
        VALUE_default(&SP[-1], val->_void.ptype);
      else
        VALUE_conv(&SP[-1], val->_void.ptype);
      /* RELEASE(val); Pas n�essaire */
      SP--;
      *val = *SP;
    }
    else
      POP();
  }

  goto _NEXT;

/*-----------------------------------------------*/

_PUSH_SHORT:

  SP->type = T_INTEGER;
  PC++;
  SP->_integer.value = *((short *)PC);
  SP++;
  goto _NEXT;

/*-----------------------------------------------*/

_PUSH_INTEGER:

  SP->type = T_INTEGER;
  PC++;
  SP->_integer.value = *((long *)PC);
  SP++;
  goto _NEXT2;

/*-----------------------------------------------*/

_PUSH_CHAR:

  STRING_char_value(SP, (char)GET_XX());
  SP++;
  goto _NEXT;

/*-----------------------------------------------*/

_PUSH_ME:

  if (GET_XX())
  {
    if (TRACE.op)
    {
      SP->_object.class = TRACE.cp;
      SP->_object.object = TRACE.op;
    }
    else if (TRACE.cp)
    {
      SP->type = T_CLASS;
      SP->_class.class = TRACE.cp;
    }
    else
      SP->type = T_NULL;
  }
  else
  {
    if (OP == NULL)
    {
      SP->type = T_CLASS;
      SP->_class.class = CP;
    }
    else
    {
      SP->_object.class = CP;
      SP->_object.object = OP;
    }
  }

  PUSH();
  goto _NEXT;

/*-----------------------------------------------*/

_PUSH_NULL:

  SP->type = T_NULL;
  SP->_integer.value = 0;
  SP++;
  goto _NEXT;

/*-----------------------------------------------*/

_EVENT:

  switch(GET_XX())
  {
    case 1: GAMBAS_DoNotRaiseEvent = FALSE; break;
    case 2: GAMBAS_StopEvent = TRUE; break;
    default: GAMBAS_DoNotRaiseEvent = TRUE; break;
  }
  goto _NEXT;

/*-----------------------------------------------*/

/*
_PUSH_RETURN:

  *SP++ = *RP;
  goto _NEXT;
*/

/*-----------------------------------------------*/

_PUSH_BOOLEAN:

  SP->type = T_BOOLEAN;
  SP->_integer.value = (GET_XX() != 0) ? -1 : 0;
  SP++;
  goto _NEXT;

/*-----------------------------------------------*/

_PUSH_LAST:

  SP->type = T_OBJECT;
  SP->_object.object = EVENT_Last;
  PUSH();
  goto _NEXT;

/*-----------------------------------------------*/

_PUSH_VOID:

  SP->type = T_VOID;
  SP++;
  goto _NEXT;

/*-----------------------------------------------*/

_DUP:

  *SP = SP[-1];
  PUSH();
  goto _NEXT;

/*-----------------------------------------------*/

_DROP:

  ind = GET_3X();

  while (ind > 0)
  {
    POP();
    ind--;
  }

  goto _NEXT;

/*-----------------------------------------------*/

_NEW:

  EXEC_new();
  goto _NEXT;

/*-----------------------------------------------*/

_JUMP:

  PC += (signed short)PC[1] + 2;
  goto _MAIN;


/*-----------------------------------------------*/

_JUMP_IF_TRUE:

  VALUE_conv(&SP[-1], T_BOOLEAN);
  SP--;
  if (SP->_boolean.value)
  {
    PC += (signed short)PC[1] + 2;
    goto _MAIN;
  }

  goto _NEXT2;

/*-----------------------------------------------*/

_JUMP_IF_FALSE:

  VALUE_conv(&SP[-1], T_BOOLEAN);
  SP--;
  if (SP->_boolean.value == 0)
  {
    PC += (signed short)PC[1] + 2;
    goto _MAIN;
  }

  goto _NEXT2;

/*-----------------------------------------------*/

_RETURN:

  if (GET_XX())
  {
    VALUE_conv(&SP[-1], FP->type);
    SP--;
    *RP = *SP;

    EXEC_leave(FALSE);
  }
  else
  {
    VALUE_default(RP, FP->type);
    EXEC_leave(FALSE);
  }

  if (PC == NULL)
    return;

  goto _NEXT;

/*-----------------------------------------------*/

_CALL:

  {
    static void *call_jump[7] =
      { &&_CALL_NULL, &&_CALL_NATIVE, &&_CALL_PRIVATE, &&_CALL_PUBLIC,
        &&_CALL_SNATIVE, &&_CALL_SPUBLIC, &&_CALL_UNKNOWN };

    register VALUE *val;

    ind = GET_3X();
    val = &SP[-(ind + 1)];

    /*EXEC_FUNCTION exec_func;*/

    if (!TYPE_is_function(val->type))
    {
      bool defined;

      /* On devrait plut� cr�r une FUNCTION sur la pile */

      EXEC_object(val, &EXEC.class, (OBJECT **)&EXEC.object, &defined);
      EXEC.drop = PCODE_is_void(code);
      EXEC.nparam = ind;

      EXEC_class(); //class, object, ind, PCODE_is_void(code));
      goto _NEXT;
    }

    EXEC.class = val->_function.class;
    EXEC.object = val->_function.object;
    EXEC.drop = PCODE_is_void(code);
    EXEC.nparam = ind;

    if (!val->_function.defined)
      *PC |= CODE_CALL_VARIANT;

    goto *call_jump[(int)val->_function.kind];

  _CALL_NULL:

    while (ind > 0)
    {
      POP();
      ind--;
    }

    POP();

    if (!PCODE_is_void(code))
    {
      /*VALUE_default(SP, (TYPE)(val->_function.function));*/
      SP->type = T_NULL;
      SP++;
    }

    goto _NEXT;

  _CALL_NATIVE:

    EXEC.native = TRUE;
    EXEC.index = val->_function.index;
    EXEC.desc = &EXEC.class->table[EXEC.index].desc->method;
    EXEC.use_stack = TRUE;

    goto __EXEC_NATIVE;

  _CALL_PRIVATE:

    EXEC.native = FALSE;
    EXEC.index = val->_function.index;

    goto __EXEC_ENTER;

  _CALL_PUBLIC:

    EXEC.native = FALSE;
    EXEC.desc = &EXEC.class->table[val->_function.index].desc->method;
    EXEC.index = (int)(EXEC.desc->exec);
    EXEC.class = EXEC.desc->class;

    goto __EXEC_ENTER;

  _CALL_SNATIVE:

    EXEC.native = TRUE;
    EXEC.desc = &(EXEC.class)->special[val->_function.index]->method;
    EXEC.use_stack = TRUE;

    goto __EXEC_NATIVE;

  _CALL_SPUBLIC:

    EXEC.native = FALSE;
    EXEC.desc = &EXEC.class->special[val->_function.index]->method;
    EXEC.index = (int)(EXEC.desc->exec);
    EXEC.class = EXEC.desc->class;

  __EXEC_ENTER:

    EXEC_enter();
    goto _MAIN;

  _CALL_UNKNOWN:

    EXEC.native = TRUE;
    EXEC.desc = &EXEC.class->special[SPEC_UNKNOWN]->method;
    EXEC.use_stack = TRUE;
    EXEC.index = val->_function.index;
    EXEC.property = FALSE;

  __EXEC_NATIVE:

    //EXEC.class = EXEC.desc->class;
    EXEC_native();
    goto _NEXT;
  }

/*-----------------------------------------------*/

_JUMP_FIRST:

  PC[1] &= 0xFF00;
  goto _NEXT;

/*-----------------------------------------------*/

_JUMP_NEXT:

  {
    static void *jn_jump[5] = { &&_JN_START, &&_JN_NEXT_1, &&_JN_NEXT_2, &&_JN_NEXT_3, &&_JN_NEXT_4 };

    VALUE *end = &BP[PC[-1] & 0xFF];
    VALUE *inc = end + 1;
    register VALUE *val = &BP[PC[2] & 0xFF];

    goto *jn_jump[GET_XX()];

  _JN_START:

    type = val->type;

            // The step value must stay negative, even if the loop variable is a byte

    if (TYPE_is_integer(type))
    {
      VALUE_conv(&SP[-1], T_INTEGER);
      }
    else
    {
      VALUE_conv(&SP[-1], type);
            }

      VALUE_conv(&SP[-2], type);

    ind = PC[-1] & 0xFF;

    _pop_ctrl(ind + 1); /* modifie val ! */
    _pop_ctrl(ind);

    val = &BP[PC[2] & 0xFF];

    if (TYPE_is_integer(type))
    {
      if (inc->_integer.value > 0)
      {
        *PC |= 1;
        goto _JN_TEST_1;
      }
      else
      {
        *PC |= 2;
        goto _JN_TEST_2;
      }
    }
    else if (TYPE_is_float(type))
    {
      if (inc->_float.value > 0)
      {
        *PC |= 3;
        goto _JN_TEST_3;
      }
      else
      {
        *PC |= 4;
        goto _JN_TEST_4;
      }
    }
    else
      THROW(E_TYPE, "Number", TYPE_get_name(type));

  _JN_NEXT_1:

    val->_integer.value += inc->_integer.value;

  _JN_TEST_1:

    if (val->_integer.value <= end->_integer.value)
      goto _NEXT3;

    goto _JN_END;

  _JN_NEXT_2:

    val->_integer.value += inc->_integer.value;

  _JN_TEST_2:

    if (val->_integer.value >= end->_integer.value)
      goto _NEXT3;

    goto _JN_END;

  _JN_NEXT_3:

    val->_float.value += inc->_float.value;

  _JN_TEST_3:

    if (val->_float.value <= end->_float.value)
      goto _NEXT3;

    goto _JN_END;

  _JN_NEXT_4:

    val->_float.value += inc->_float.value;

  _JN_TEST_4:

    if (val->_float.value >= end->_float.value)
      goto _NEXT3;

    goto _JN_END;

  _JN_END:

    PC += (signed short)PC[1] + 2;
    goto _MAIN;
  }

/*-----------------------------------------------*/

_ENUM_FIRST:

  _pop_ctrl(GET_XX());
  EXEC_enum_first(code);
  goto _NEXT;

/*-----------------------------------------------*/

_ENUM_NEXT:

  if (EXEC_enum_next(code))
    goto _JUMP;
  else
    goto _NEXT2;

/*-----------------------------------------------*/

_PUSH_CLASS:

  SP->type = T_CLASS;
  SP->_class.class = CP->load->class_ref[GET_7XX()];
  SP++;

  goto _NEXT;

/*-----------------------------------------------*/

_PUSH_FUNCTION:

  /*ind = GET_7XX();*/

  SP->type = T_FUNCTION;
  SP->_function.class = CP;
  SP->_function.object = OP;
  SP->_function.kind = FUNCTION_PRIVATE;
  SP->_function.index = GET_7XX();
  SP->_function.defined = TRUE;

  OBJECT_REF(OP, "exec_loop._PUSH_FUNCTION (FUNCTION)");
  SP++;

  goto _NEXT;

/*-----------------------------------------------*/

  {
    CLASS_VAR *var;
    char *addr;

_PUSH_DYNAMIC:

    var = &CP->load->dyn[GET_7XX()];

    if (OP == NULL)
      THROW(E_ILLEGAL);

    addr = &OP[var->pos];
    goto __READ;

_PUSH_STATIC:

    var = &CP->load->stat[GET_7XX()];
    addr = (char *)CP->stat + var->pos;
    goto __READ;

__READ:

    VALUE_class_read(CP, SP, addr, var->type);

    PUSH();
    goto _NEXT;


_POP_DYNAMIC:

    var = &CP->load->dyn[GET_7XX()];

    if (OP == NULL)
      THROW(E_ILLEGAL);

    addr = &OP[var->pos];
    goto __WRITE;

_POP_STATIC:

    var = &CP->load->stat[GET_7XX()];
    addr = (char *)CP->stat + var->pos;
    goto __WRITE;

__WRITE:

    VALUE_class_write(CP, &SP[-1], addr, var->type);
    POP();

    goto _NEXT;

  }

/*-----------------------------------------------*/

_PUSH_CONST:

  ind = (short)GET_XXX();

  if (ind >= 0)
  {
    CLASS_CONST *cc = &CP->load->cst[ind];

    if (cc->type == T_FLOAT)
    {
      SP->type = cc->type;
      SP->_float.value = cc->_float.value;
    }
    else if (cc->type == T_STRING)
    {
      SP->type = T_CSTRING;
      SP->_string.addr = (char *)cc->_string.addr;
      SP->_string.start = 0;
      SP->_string.len = cc->_string.len;
    }
    else if (cc->type == T_CSTRING)
    {
      SP->type = T_CSTRING;
      SP->_string.addr = (char *)LOCAL_gettext(cc->_string.addr);
      SP->_string.start = 0;
      SP->_string.len = strlen(SP->_string.addr);
    }
    else
    {
      SP->type = cc->type;
      SP->_integer.value = cc->_integer.value;
    }
  }
  else
  {
    EXEC_ILLEGAL();
  }

  SP++;

  goto _NEXT;

/*-----------------------------------------------*/

_PUSH_QUICK:

  SP->type = T_INTEGER;
  SP->_integer.value = GET_XXX();
  SP++;
  goto _NEXT;

/*-----------------------------------------------*/

_TRY:

  ERROR_clear();
  EP = SP;
  ET = EC;
  EC = PC + (signed short)PC[1] + 2;

  #if DEBUG_ERROR
  printf("TRY %p\n", EC);
  #endif

  goto _NEXT2;

/*-----------------------------------------------*/

_END_TRY:

  #if DEBUG_ERROR
  printf("END TRY %p\n", PC);
  #endif

  EP = NULL;
  EC = ET;
  ET = NULL;
  goto _NEXT;

/*-----------------------------------------------*/

_CATCH:

  if (EC == NULL)
    goto _NEXT;
  else
    goto _RETURN;
}


Generated by  Doxygen 1.6.0   Back to index