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

📄 gbx_exec.c

📁 Gambas is a graphical development environment based on a Basic interpreter, like Visual Basic. It us
💻 C
📖 第 1 页 / 共 2 页
字号:
            EC = NULL;            retry = TRUE;          }        }      }      END_TRY      #if DEBUG_ERROR      if (retry)        printf("retry %p\n", PC);      #endif    }    while (retry);  }  if (!keep_ret_value)    EXEC_release_return_value();  STACK_pop_frame(&EXEC_current);  /*PC = save;*/}PUBLIC bool EXEC_call_native(void (*exec)(), void *object, TYPE type, VALUE *param){  TYPE save = GAMBAS_ReturnType;  GAMBAS_Error = FALSE;  GAMBAS_ReturnType = type;  TEMP.type = T_NULL;  /*OBJECT_REF(object, "EXEC_call_native"); N'est plus n�essaire ! */  (*exec)(object, (void *)param);  /*OBJECT_UNREF(&object, "EXEC_call_native");*/  GAMBAS_ReturnType = save;  return GAMBAS_Error;}PUBLIC void EXEC_native(void){  CLASS_DESC_METHOD *desc = EXEC.desc;  bool drop = EXEC.drop;  int nparam = EXEC.nparam;  bool use_stack = EXEC.use_stack;  void *object = EXEC.object;  int i; /* ,j */  VALUE *value;  TYPE *sign;  bool error;  void *free;  int n;  VALUE ret;  /* v�ification des param�res */  #if DEBUG_STACK  printf("| >> EXEC_native: %s.%s (%p)\n", EXEC.class->name, desc->name, &desc);  #endif  if (nparam < desc->npmin)    THROW(E_NEPARAM);    if (!desc->npvar)  {    if (nparam > desc->npmax)      THROW(E_TMPARAM);      value = &SP[-nparam];    sign = desc->signature;      for (i = 0; i < desc->npmin; i++, value++, sign++)      VALUE_conv(value, *sign);      if (desc->npmin < desc->npmax)    {      for (; i < nparam; i++, value++, sign++)      {        if (value->type != T_VOID)          VALUE_conv(value, *sign);      }            n = desc->npmax - nparam;      STACK_check(n);      SP += n;      nparam = desc->npmax;      for (; i < nparam; i++, value++)        value->type = T_VOID;      }  }  else  {    value = &SP[-nparam];    sign = desc->signature;      for (i = 0; i < desc->npmin; i++, value++, sign++)      VALUE_conv(value, *sign);      if (desc->npmin < desc->npmax)    {      if (nparam < desc->npmax)      {        for (; i < nparam; i++, value++, sign++)        {          if (value->type != T_VOID)            VALUE_conv(value, *sign);        }          n = desc->npmax - nparam;          STACK_check(n);        SP += n;        nparam = desc->npmax;          for (; i < nparam; i++, value++)          value->type = T_VOID;        }      else      {        for (; i < desc->npmax; i++, value++, sign++)        {          if (value->type != T_VOID)            VALUE_conv(value, *sign);        }      }    }      if (desc->npmax < nparam)      EXEC.nparvar = nparam - desc->npmax;    else      EXEC.nparvar = 0;      for (; i < nparam; i++, value++)      VARIANT_undo(value);  }  error = EXEC_call_native(desc->exec, object, desc->type, &SP[-nparam]);  ret = TEMP;  /* Lib�ation des arguments */  while (nparam > 0)  {    nparam--;    POP();  }  /* Si la description de la fonction se trouve sur la pile */  if (use_stack)  {    SP--;    free = SP->_function.object;    SP->type = T_NULL;  }  /*  #if DEBUG_STACK  else    printf("** SP != func SP = %p func = %p **\n>", SP, func);  #endif  */  if (!error)  {    if (desc->type == T_VOID)    {      if (!drop)      {        SP->type = T_VOID;        SP->_void.ptype = T_NULL;        SP++;      }    }    else    {      BORROW(&ret);      if (drop)        RELEASE(&ret);      else      {        VALUE_conv(&ret, desc->type);        *SP = ret;        SP++;      }    }  }  if (use_stack)    OBJECT_UNREF(&free, "EXEC_native (FUNCTION)");  if (error)    PROPAGATE();  #if DEBUG_STACK  printf("| << EXEC_native: %s (%p)\n", desc->name, &desc);  #endif}PUBLIC void EXEC_object(VALUE *val, CLASS **class, OBJECT **object, boolean *defined){  if (val->type == T_FUNCTION && val->_function.kind == FUNCTION_UNKNOWN)  {    EXEC.class = val->_function.class;    EXEC.object = val->_function.object;    EXEC.drop = FALSE;    EXEC.nparam = 0;    EXEC.native = TRUE;    EXEC.desc = &EXEC.class->special[SPEC_UNKNOWN]->method;    EXEC.use_stack = FALSE;    EXEC.index = val->_function.index;    EXEC.property = TRUE;    /*SP--; on ne d�remente pas SP, car on ne sait pas sur quoi pointe val */    /* => il faut qu'il y ait une place vide dans la pile, sinon crash !*/    *object = EXEC.object;    EXEC_native();    OBJECT_UNREF(object, "EXEC_object (FUNCTION)");    SP--;    *val = *SP;  }  if (val->type == T_CLASS)  {    *class = val->_class.class;    *object = NULL;    *defined = TRUE;    CLASS_load(*class);    #if 0    if ((*class)->auto_create)    {      *object = CLASS_auto_create(*class); /* object is checked by CLASS_auto_create */      OBJECT_REF(*object, "EXEC_object");    }    #endif  }  else  {    if (val->type == T_OBJECT)    {      *object = val->_object.object;      *class = OBJECT_class(*object);      *defined = FALSE;    }    else if (TYPE_is_object(val->type))    {      *object = val->_object.object;      *class = val->_object.class;      *defined = TRUE;    }    else if (val->type == T_VARIANT)    {      if (val->_variant.vtype == T_OBJECT)      {        *object = *((void **)val->_variant.value);        *class = OBJECT_class(*object);        *defined = FALSE;      }      else if (TYPE_is_object(val->_variant.vtype))      {        *object = *((void **)val->_variant.value);        *class = (CLASS *)val->_variant.vtype;        *defined = FALSE;      }      else        THROW(E_NOBJECT);    }    else      THROW(E_NOBJECT);    if (*object == NULL)      THROW(E_NULL);    CLASS_load(*class);    if ((*class)->check(*object))      THROW(E_IOBJECT);  }}PUBLIC void EXEC_public(CLASS *class, void *object, const char *name, int nparam){  CLASS_DESC *desc;  desc = CLASS_get_symbol_desc_kind(class, name, (object != NULL) ? CD_METHOD : CD_STATIC_METHOD, 0);  if (desc == NULL)    return;  EXEC.class = desc->method.class;  EXEC.object = object;  EXEC.nparam = nparam;  EXEC.drop = TRUE;  if (FUNCTION_is_native(&desc->method))  {    EXEC.desc = &desc->method;    EXEC.use_stack = FALSE;    EXEC_native();  }  else  {    EXEC.index = (long)desc->method.exec;    //EXEC.func = &class->load->func[(long)desc->method.exec]    EXEC_function();  }}PUBLIC boolean EXEC_spec(int special, CLASS *class, void *object, int nparam, boolean drop){  CLASS_DESC *desc = class->special[special];  if (desc == NULL)    return TRUE;  if (CLASS_DESC_get_type(desc) == CD_STATIC_METHOD)  {    if (object != NULL)      return TRUE;  }  else  {    if (object == NULL)    {      if (class->auto_create)      {        object = EXEC_auto_create(class);        OBJECT_UNREF(&object, "EXEC_spec");      }      if (object == NULL)        THROW(E_NOBJECT);    }  }  EXEC.class = desc->method.class;  EXEC.object = object;  EXEC.nparam = nparam;  EXEC.drop = drop;  if (FUNCTION_is_native(&desc->method))  {    EXEC.desc = &desc->method;    EXEC.use_stack = FALSE;    EXEC.native = TRUE;    EXEC_native();  }  else  {    //EXEC.func = &class->load->func[(long)desc->method.exec]    EXEC.index = (long)desc->method.exec;    EXEC.native = FALSE;    EXEC_function_real(!drop);  }  return FALSE;}/* PRIVATE void dump(int np) *//* { *//*   int i; *//*  *//*   for (i = 1; i <= np; i++) *//*     printf("SP[%d] = %d  ", -i, SP[-i].type); *//*  *//*   printf("\n"); *//* } *//*  *//*  The highest parent method is called first, but get only the parameters  not consumed by the child methods.*/PUBLIC void EXEC_special_inheritance(int special, CLASS *class, OBJECT *object, int nparam, boolean drop){  CLASS *her[MAX_INHERITANCE];  int npher[MAX_INHERITANCE];  int nher;  int i, np;  CLASS_DESC *desc;  /*if (class->parent != NULL)    EXEC_special_inheritance(special, class->parent, object, 0, drop);*/  nher = CLASS_get_inheritance(class, her);  for(i = 0, np = 0; i < nher; i++)  {    class = her[i];    npher[i] = np;    desc = class->special[special];    if (!desc)      continue;    np += desc->method.npmax;  }  for(;;)  {    nher--;    if (nher < 0)      break;    class = her[nher];    if (special == SPEC_NEW)    {      if (!CLASS_is_native(class))      {        EXEC.class = class;        EXEC.object = object;        EXEC.index = FUNC_INIT_DYNAMIC;        //EXEC.func = &class->load->func[FUNC_INIT_DYNAMIC];        EXEC.native = FALSE;        EXEC.nparam = 0;        EXEC_function();      }    }    desc = class->special[special];    if (!desc)      continue;    /*np = Min(nparam, desc->method.npmax);*/    np = Max(0, nparam - npher[nher]);    /*    dup = ((np > 0) && nher > 0);    if (dup)    {      STACK_check(nparam);      for (i = 0; i < np; i++)      {        SP[i] = SP[i - np];        BORROW(&SP[i]);      }      SP += np;    }    */    EXEC_special(special, class, object, np, drop);    nparam -= np;  }}PUBLIC void EXEC_new(void){  CLASS *class;  int np;  boolean event;  void *object;  char *name = NULL;  char *cname = NULL;  np = *PC & 0xFF;  event = np & CODE_NEW_EVENT;  np &= 0x3F;  /* Instanciation */  SP -= np;  if (SP->type == T_CLASS)  {    class = SP->_class.class;  }  else if (TYPE_is_string(SP->type))  {    STRING_copy_from_value_temp(&cname, SP);    class = CLASS_find(cname);    RELEASE(SP);    SP->type = T_NULL;  }  else    THROW(E_TYPE, "String", TYPE_get_name(SP->type));  SP += np;  CLASS_load(class);  if (class->new == NULL)    THROW(E_CSTATIC, class->name);  if (event)  {    SP--;    if (!TYPE_is_string(SP->type))      THROW(E_TYPE, "String", TYPE_get_name(SP->type));    STRING_copy_from_value_temp(&name, SP);    STRING_ref(name);    (*class->new)(&object, class, name, ((OP == NULL) ? (OBJECT *)CP : (OBJECT *)OP));    STRING_unref(&name);    RELEASE(SP);    np -= 2;  }  else  {    (*class->new)(&object, class, name, ((OP == NULL) ? (OBJECT *)CP : (OBJECT *)OP));    np--;  }  /*OBJECT_REF(object, "EXEC_new");*/  /* On retourne l'objet cr� */  TRY  {      EXEC_special_inheritance(SPEC_NEW, class, object, np, TRUE);    SP--; /* class */    SP->_object.class = class;    SP->_object.object = object;    SP++;  }  CATCH  {    OBJECT_UNREF(&object, "EXEC_new");    SP--; /* class */    SP->type = T_NULL;    SP++;    PROPAGATE();  }  END_TRY  /*  PUSH(); */  /* L'objet a ��cr� avec un nombre de r��ence �al �1.     On remet ce nombre �0 maintenant que l'objet est pr�.     Mais on ne le d�ruit pas ! */  /* OBJECT_UNREF(&object, "EXEC_new"); */}PUBLIC void EXEC_class(void){  //fprintf(stderr, ">> EXEC_class: SP = %d  drop = %d\n", SP - (VALUE *)STACK_base, EXEC.drop);  if (EXEC_special(SPEC_CALL, EXEC.class, EXEC.object, EXEC.nparam, EXEC.drop))  {    if (EXEC.nparam < 1)      THROW(E_NEPARAM);    else if (EXEC.nparam > 1)      THROW(E_TMPARAM);    VALUE_conv(SP - 1, (TYPE)EXEC.class);  }  else  {    if (RP->type != T_VOID) /* Ceci est fait pour un EXEC_native, mais pas pour un EXEC_function */    {      BORROW(RP);      SP[-1] = *RP; /* On �rase la classe */      EXEC_release_return_value();    }    else      POP(); /* On enl�e la classe */  }    //fprintf(stderr, "<< EXEC_class: SP = %d\n\n", SP - (VALUE *)STACK_base);}PUBLIC void EXEC_nop(void){  printf("* NOP *\n");}PUBLIC void EXEC_ILLEGAL(void){  THROW(E_ILLEGAL);}PUBLIC void EXEC_quit(void){  GAMBAS_DoNotRaiseEvent = TRUE;  HOOK(quit)();  THROW(E_UNKNOWN);}PUBLIC void *EXEC_auto_create(CLASS *class){  void *object;  object = CLASS_auto_create(class, 0); /* object is checked by CLASS_auto_create */  OBJECT_REF(object, "EXEC_auto_create");  return object;}

⌨️ 快捷键说明

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