⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gbx_exec.c

📁 Gambas is a graphical development environment based on a Basic interpreter, like Visual Basic. It us
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************  exec.c  Subroutines for the interpreter : executing methods, native methods,  the NEW operator, the casting operator, etc.  (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_C#include "gb_common.h"#include "gb_error.h"#include "gbx_type.h"#include <unistd.h>#include <sys/time.h>#include "gb_limit.h"#include "gbx_subr.h"#include "gbx_stack.h"#include "gbx_trace.h"#include "gbx_string.h"#include "gbx_date.h"#include "gbx_array.h"#include "gbx_c_collection.h"#include "gbx_api.h"#include "gbx_exec.h"PUBLIC STACK_CONTEXT EXEC_current = { 0 }; /* Contexte �sauvegarder */PUBLIC PCODE EXEC_code; /* Opcode de l'instruction en cours */PUBLIC VALUE *SP = NULL; /* Pointeur de pile */PUBLIC VALUE TEMP; /* Stockage temporaire */PUBLIC VALUE RET; /* Valeur de retour de la fonction */PUBLIC bool EXEC_debug = FALSE; /* Mode d�ogage */PUBLIC boolean EXEC_enum_stop = FALSE; /* Indique la fin d'une �um�ation */PUBLIC void *EXEC_enum_data; /* Etat de l'�um�ation en cours */PUBLIC bool EXEC_arch = FALSE; /* Ex�ution d'une archive */PUBLIC bool EXEC_fifo = FALSE; /* D�ogage par fifo */PUBLIC EXEC_HOOK EXEC_Hook = { NULL };PUBLIC bool EXEC_big_endian;PUBLIC EXEC_FUNCTION EXEC;PUBLIC void EXEC_init(void){  char test[4];  PC = NULL;  BP = NULL;  OP = NULL;  CP = NULL;  RP->type = T_VOID;  test[0] = 0xAA;  test[1] = 0xBB;  test[2] = 0xCC;  test[3] = 0xDD;  EXEC_big_endian = *((ulong *)test) == 0xAABBCCDDL;  /*printf("%s endian\n", EXEC_big_endian ? "big" : "little");*/  DATE_init();}PUBLIC void BORROW(VALUE *value){  static void *jump[16] = {    &&__NONE, &&__NONE, &&__NONE, &&__NONE, &&__NONE, &&__NONE, &&__NONE, &&__NONE,    &&__STRING, &&__NONE, &&__VARIANT, &&__NONE, &&__NONE, &&__FUNCTION, &&__NONE, &&__NONE    };  TYPE type = value->type;  if (TYPE_is_object(type))    goto __OBJECT;  else    goto *jump[type];__STRING:  STRING_ref(value->_string.addr);  return;__OBJECT:  OBJECT_REF(value->_object.object, "BORROW");  return;__VARIANT:  if (value->_variant.vtype == T_STRING)    STRING_ref((*(char **)value->_variant.value));  else if (TYPE_is_object(value->_variant.vtype))    OBJECT_REF(*((void **)value->_variant.value), "BORROW");  return;__FUNCTION:  OBJECT_REF(value->_function.object, "BORROW");  return;__NONE:  return;}PUBLIC void UNBORROW(VALUE *value){  static void *jump[16] = {    &&__NONE, &&__NONE, &&__NONE, &&__NONE, &&__NONE, &&__NONE, &&__NONE, &&__NONE,    &&__STRING, &&__NONE, &&__VARIANT, &&__NONE, &&__NONE, &&__FUNCTION, &&__NONE, &&__NONE    };  TYPE type = value->type;  if (TYPE_is_object(type))    goto __OBJECT;  else    goto *jump[type];__STRING:  STRING_unref_keep(&value->_string.addr);  return;__OBJECT:  OBJECT_UNREF_KEEP(&value->_object.object, "UNBORROW");  return;__VARIANT:  if (value->_variant.vtype == T_STRING)    STRING_unref_keep((char **)value->_variant.value);  else if (TYPE_is_object(value->_variant.vtype))    OBJECT_UNREF_KEEP((void **)value->_variant.value, "UNBORROW");  return;__FUNCTION:  OBJECT_UNREF_KEEP(&value->_function.object, "UNBORROW");  return;__NONE:  return;}PUBLIC void RELEASE(VALUE *value){  static void *jump[16] = {    &&__NONE, &&__NONE, &&__NONE, &&__NONE, &&__NONE, &&__NONE, &&__NONE, &&__NONE,    &&__STRING, &&__NONE, &&__VARIANT, &&__ARRAY, &&__NONE, &&__FUNCTION, &&__NONE, &&__NONE    };  TYPE type = value->type;  if (TYPE_is_object(type))    goto __OBJECT;  else    goto *jump[type];__STRING:  STRING_unref(&value->_string.addr);  return;__OBJECT:  OBJECT_UNREF(&value->_object.object, "RELEASE");  return;__VARIANT:  if (value->_variant.vtype == T_STRING)    STRING_unref((char **)value->_variant.value);  else if (TYPE_is_object(value->_variant.vtype))    OBJECT_UNREF(value->_variant.value, "RELEASE");  return;__FUNCTION:  OBJECT_UNREF(&value->_function.object, "RELEASE");  return;__ARRAY:  if (!value->_array.keep)    ARRAY_free(&value->_array.addr, value->_array.desc);  return;__NONE:  return;}#if 0PUBLIC void DUMP(VALUE *value){  static void *jump[16] = {    &&__NONE, &&__NONE, &&__NONE, &&__NONE, &&__NONE, &&__NONE, &&__NONE, &&__NONE,    &&__STRING, &&__NONE, &&__VARIANT, &&__ARRAY, &&__NONE, &&__FUNCTION, &&__NONE, &&__NONE    };  TYPE type = value->type;  printf("type = %p / ", (void *)type);    if (TYPE_is_object(type))    goto __OBJECT;  else    goto *jump[type];__STRING:  printf("STRING %p\n", value->_string.addr);  return;__OBJECT:  if (value->_object.object)  {    printf("OBJECT (%p)\n", value->_object.object);    printf("-> %s\n", OBJECT_class(value->_object.object)->name);  }  else    printf("OBJECT (NULL)\n");  return;__VARIANT:  if (value->_variant.vtype == T_STRING)    printf("STRING %p\n", *((char **)value->_variant.value));  else if (TYPE_is_object(value->_variant.vtype))    printf("OBJECT (%s %p)\n", OBJECT_class(*((void **)value->_variant.value))->name, *((void **)value->_variant.value));  return;__FUNCTION:  printf("FUNCTION %s (%s %p)\n", value->_function.class->name, OBJECT_class(value->_function.object)->name, value->_function.object);  return;__ARRAY:  printf("ARRAY\n");  return;__NONE:  printf("\n");  return;}#endifPUBLIC void EXEC_release_return_value(void){  RELEASE(RP);  RP->type = T_VOID;}#define print_register() \  printf("| SP = %d  BP = %d  FP = %p  PC = %p  EC = %p\n", SP - (VALUE *)STACK_base, BP - (VALUE *)STACK_base, FP, PC, EC)PUBLIC void EXEC_enter(void){  int i;  FUNCTION *func; // = EXEC.func;  int nparam = EXEC.nparam;  void *object = EXEC.object;  CLASS *class = EXEC.class;  #if DEBUG_STACK  printf("\n| >> EXEC_enter(%s, %ld, %d)\n", EXEC.class->name, EXEC.index, nparam);  print_register();  #endif  /*  func_id = value->index;  if (value->kind & FUNCTION_PUBLIC)    func_id = (int)(class->table[func_id].desc.method->exec;  */  func = &class->load->func[EXEC.index];  #if DEBUG_STACK  if (func->debug)    printf(" | >> %s\n", func->debug->name);  #endif  /* v�ification des param�res */  if (nparam < func->npmin)    THROW(E_NEPARAM);  else if (nparam > func->n_param)    THROW(E_TMPARAM);  /* param�res obligatoires et r�ervation */  for (i = 0; i < func->npmin; i++)  {    VALUE_conv(SP - nparam + i, func->param[i].type);    /*BORROW(SP - nparam + i);*/  }  if (func->npmin < func->n_param)  {    /* param�res facultatifs, mais pass� �la fonction */    for (i = func->npmin; i < nparam; i++)    {      if (SP[- nparam + i].type == T_VOID)        SP[- nparam + i]._void.ptype = func->param[i].type;      else      {        VALUE_conv(SP - nparam + i, func->param[i].type);        /*BORROW(SP - nparam + i);*/      }    }    /* param�res facultatifs non pass� �la fonction */    if (nparam < func->n_param)    {      STACK_check(func->n_param - nparam);      for (i = nparam; i < func->n_param; i++)      {        SP->type = T_VOID;        SP->_void.ptype = func->param[i].type;        SP++;      }    }  }  /* sauvegarde du contexte */  STACK_push_frame(&EXEC_current);  /* V�ification de la pile */  STACK_check(func->stack_usage);  /* entr� de fonction */  BP = SP;  FP = func;  PC = func->code;  OP = object;  CP = class;  EP = NULL;  if (func->error)  {    #if DEBUG_ERROR      printf("EXEC_enter: EC = PC + %d\n", func->error);    #endif    EC = PC + func->error;  }  else    EC = NULL;  /* On r��ence l'objet pour qu'il ne soit pas d�ruit pendant l'ex�ution de la m�hode */  OBJECT_REF(OP, "EXEC_enter");  /*printf("PC = %p  nparam = %d\n", PC, FP->n_param);*/  /* Initialisation des variables locales */  if (func->n_local)  {    for (i = 0; i < func->n_local; i++)    {      VALUE_class_default(class, SP, func->local[i].type);      SP++;    }  }  /* Initialisation des variables de controles */  if (func->n_ctrl)  {    for (i = 0; i < func->n_ctrl; i++)    {      SP->type = T_VOID;      SP++;    }  }  /*printf("EXEC_enter: nparam = %d  nlocal = %d  nctrl = %d\n", func->n_param, func->n_local, func->n_ctrl);*/    RP->type = T_VOID;  #if DEBUG_STACK  printf("| << EXEC_enter()\n");  print_register();  #endif}PUBLIC void EXEC_leave(bool keep_ret_value){  int i, n;  boolean drop;  VALUE ret;#if DEBUG_STACK  printf("| >> EXEC_leave\n");  print_register();#endif  /* Je garde cette bourde en commentaires.     La honte...  for (i = 0; i < (SP - BP); i++)  {    SP--;    #if 1    printf("Release local %p (0x%08lX)\n", SP, (ulong)SP->type);    #endif    RELEASE(SP);  }  */  /* Sauvegarde de la valeur de retour.     Car elle peut �re �ras� par un _free() g���par un     OBJECT_UNREF  */  ret = *RP;  /* Lib�ation des variables locales et de controle */  n = FP->n_param + (SP - BP);  for (i = 0; i < n; i++)    POP();  /* On lib�e l'objet reserv�dans EXEC_enter() */  OBJECT_UNREF(&OP, "EXEC_leave");  /* restitution du contexte */  STACK_pop_frame(&EXEC_current);  /*printf("PC = %p  nparam = %d\n", PC, nparam);*/  if (PC)  {    drop = PCODE_is_void(*PC);    if (SP[-1].type != T_FUNCTION)    {      printf("EXEC_leave: type != T_FUNCTION\n");      POP(); /* description de la fonction ? */    }    else    {      SP--;      OBJECT_UNREF(&SP->_function.object, "EXEC_leave");    }    /*output = PCODE_is_output(*PC);*/  }  else  {    drop = TRUE;    keep_ret_value = TRUE;  }  /* lib�ation de la pile utilis� */  /*    Attention ! le RELEASE(RP) conjugu�au UNBORROW(RP)    peut faire descendre le compteur de r��ence d'un objet �-1 !  */  /*    NOTE: les param�res input-output ont le m�e probl�e que la    valeur de retour. Ils peuvent contenir des r��ences d�allou�s !    A CORRIGER ! En attendant, ils sont d�activ�.  */#if DEBUG_REF  printf("EXEC_leave: return\n");#endif  if (!drop)  {    *SP = ret;    RP->type = T_VOID;    if (PCODE_is_variant(*PC))      VALUE_conv(SP, T_VARIANT);    SP++;  }  else if (!keep_ret_value)    EXEC_release_return_value();/* output = TRUE      }      else      {        if (!drop)        {          UNBORROW(RP);          SP[-(nparam + 1)] = *RP;          RP->type = T_VOID;        }        else          RELEASE(RP);      }    }  }*/#if DEBUG_STACK  printf("| << EXEC_leave()\n");  print_register();  printf("\n");#endif}PUBLIC void EXEC_function_real(bool keep_ret_value){  /*PCODE *save = PC;*/  boolean retry;  /* n�essaire, car *PC est examin�par EXEC_leave pour savoir si on attend une valeur de retour */  STACK_push_frame(&EXEC_current);  PC = NULL;	TRY	{  	EXEC_enter();	}	CATCH	{	  STACK_pop_frame(&EXEC_current);		PROPAGATE();		}	END_TRY  if (PC != NULL)  {    do    {      TRY      {        EXEC_loop();        retry = FALSE;      }      CATCH      {        if (ERROR_info.code == E_UNKNOWN)        {          while (PC != NULL)            EXEC_leave(FALSE);                      PROPAGATE();        }        else if (EP != NULL)        {          #if DEBUG_ERROR          printf("#1 EP = %d  SP = %d\n", EP - STACK_base, SP - STACK_base);          #endif          while (SP > EP)            POP();          PC = EC;          retry = TRUE;          /* On va directement sur le END TRY */        }        else if (EC != NULL)        {          #if DEBUG_ERROR          printf("#2 EC = %p\n", EC);          #endif          PC = EC;          EC = NULL;          retry = TRUE;        }        else        {          #if DEBUG_ERROR          printf("#3\n");          #endif          if (EXEC_debug && !STACK_has_error_handler())          {            while (SP > TRACE.ep)              POP();            PC = TRACE.ec;            TRACE_main(TRUE);            retry = TRUE;          }          else          {            while (PC != NULL && EC == NULL)              EXEC_leave(FALSE);            if (PC == NULL)            {              /*printf("try to propagate\n");*/              STACK_pop_frame(&EXEC_current);              PROPAGATE();                            /*ERROR_print();              exit(1);*/              /*retry = FALSE;*/            }            PC = EC;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -