gambas-source-code/main/gbx/gbx_class_native.c
Benoît Minisini b3db598050 [DEVELOPMENT ENVIRONMENT]
* BUG: Breakpoints are correctly reset when opening a new project.

[INTERPRETER]
* BUG: The GB.NewString(), GB.NewZeroString() and GB.TempString() API 
  signature has changed. All components have been updated accordingly.
* OPT: Many optimizations to speed up the interpreter.

[GB.EVAL]
* NEW: During syntax highlighting, the first character of class names is
  automatically converted to uppercase.


git-svn-id: svn://localhost/gambas/trunk@2992 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2010-06-04 23:48:53 +00:00

314 lines
7.2 KiB
C
Raw Blame History

/***************************************************************************
gbx_class_native.c
(c) 2000-2009 Benoît 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 2, 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_CLASS_NATIVE_C
#include "gb_common.h"
#include "gb_common_buffer.h"
#include "gb_alloc.h"
#include "gb_error.h"
#include "gb_limit.h"
#include <ctype.h>
#include "gb_buffer.h"
#include "gb_file.h"
#include "gbx_type.h"
#include "gbx_exec.h"
#include "gbx_debug.h"
#include "gb_magic.h"
#include "gbx_stream.h"
#include "gbx_string.h"
#include "gbx_object.h"
#include "gbx_variant.h"
#include "gbx_number.h"
#include "gambas.h"
#include "gbx_api.h"
#include "gbx_class.h"
//extern long total;
BEGIN_PROPERTY(class_self_property)
GB_ReturnSelf(_object);
END_PROPERTY
CLASS *CLASS_register_class(GB_DESC *ptr, CLASS *class)
{
int i, n_desc;
CLASS_DESC *desc;
CLASS_DESC *start;
CLASS_DESC_GAMBAS *gambas = (CLASS_DESC_GAMBAS *)ptr;
CLASS_EVENT *event;
const char *ptype;
const char *type;
int first_event, nsign;
TYPE *sign;
int first;
int size_dynamic;
#if DEBUG_LOAD
printf("Registering native class %s (%p)...\n", class->name, class);
#endif
if (gambas->type != GB_VERSION)
return NULL;
if (class->error)
THROW(E_CLASS, class->name, "Loading has already failed", "");
class->error = TRUE;
class->is_native = TRUE;
class->load = NULL;
class->data = NULL;
class->component = COMPONENT_current;
#if DEBUG_COMP
if (class->component)
fprintf(stderr, "class %s -> component %s\n", class->name, class->component->name);
else
fprintf(stderr, "class %s -> no component\n", class->name);
#endif
class->is_virtual = *class->name == '.';
#ifdef OS_64BITS
size_dynamic = (gambas->val1 + 7) & ~7;
#else
size_dynamic = (gambas->val1 + 3) & ~3;
#endif
class->n_desc = 0;
class->n_event = 0;
nsign = 0;
/* Read the class global information at the beginning of the description */
desc = (CLASS_DESC *)&gambas[1];
for (start = NULL; start == NULL; desc++)
{
if (desc->gambas.name == NULL)
{
start = desc;
break;
}
switch ((intptr_t)desc->gambas.name)
{
case (intptr_t)GB_INHERITS_ID:
CLASS_inheritance(class, CLASS_find((const char *)desc->gambas.type));
break;
case (intptr_t)GB_AUTO_CREATABLE_ID:
class->auto_create = TRUE;
break;
case (intptr_t)GB_NOT_CREATABLE_ID:
case (intptr_t)GB_VIRTUAL_CLASS_ID:
class->no_create = TRUE;
break;
case (intptr_t)GB_HOOK_CHECK_ID:
class->check = (int (*)())(desc->hook.func);
class->must_check = TRUE;
break;
default:
start = desc;
break;
}
}
/* If there is a parent class, and if the size is zero, then inherits the size */
if (class->parent && size_dynamic == 0)
size_dynamic = class->parent->size;
/* Compute the number of symbol description */
for(desc = start, n_desc = 0; desc->gambas.name != NULL; desc++, n_desc++);
CLASS_make_description(class, start, n_desc, &first);
/* Analyse de la description :
- Calcul du nombre de signatures
- Calcul du nombre d'<27><>ements
*/
for (i = first; i < class->n_desc; i++)
{
desc = class->table[i].desc;
ptype = (char *)desc->gambas.type;
type = ptype;
desc->gambas.type = TYPE_from_string(&ptype);
switch (CLASS_DESC_get_type(desc))
{
case CD_CONSTANT:
if (desc->constant.type == T_STRING)
desc->constant.type = T_CSTRING;
break;
case CD_PROPERTY:
case CD_STATIC_PROPERTY:
case CD_PROPERTY_READ:
case CD_STATIC_PROPERTY_READ:
if ((intptr_t)desc->property.read == CLASS_DESC_SELF)
desc->property.read = (void (*)())class_self_property;
desc->property.write = desc->property.read;
desc->property.native = TRUE;
//desc->property.help = (char *)type;
break;
case CD_METHOD:
case CD_STATIC_METHOD:
//desc->method.help = (char *)desc->method.signature;
desc->method.native = TRUE;
if (desc->method.signature)
{
TYPE_signature_length((char *)desc->method.signature, &desc->method.npmin, &desc->method.npmax, &desc->method.npvar);
nsign += desc->method.npmax;
}
break;
case CD_EVENT:
class->n_event++;
//desc->event.help = (char *)desc->event.signature;
if (desc->event.signature)
{
TYPE_signature_length((char *)desc->event.signature, &desc->event.npmin, &desc->event.npmax, &desc->method.npvar);
desc->event.npmin = desc->event.npmax;
nsign += desc->event.npmax;
}
break;
}
desc->method.class = class;
}
CLASS_calc_info(class, class->n_event, size_dynamic, TRUE, 0);
CLASS_make_event(class, &first_event);
/* Transfert des évènements et signatures */
if (nsign)
{
ALLOC(&class->signature, sizeof(TYPE) * nsign, "CLASS_register");
sign = class->signature;
}
for (i = first; i < class->n_desc; i++)
{
desc = class->table[i].desc;
switch (CLASS_DESC_get_type(desc))
{
case CD_METHOD:
case CD_STATIC_METHOD:
if (desc->method.npmax)
{
desc->method.signature =
TYPE_transform_signature(&sign, (char *)desc->method.signature, desc->method.npmax);
}
break;
case CD_EVENT:
if (desc->event.npmax)
{
desc->event.signature =
TYPE_transform_signature(&sign, (char *)desc->event.signature, desc->event.npmax);
}
event = &class->event[first_event];
event->name = class->table[i].name;
if (desc->event.index)
*desc->event.index = first_event;
event->type = desc->event.type;
event->param = (CLASS_PARAM *)desc->event.signature;
event->n_param = desc->event.npmax;
first_event++;
break;
}
}
/* Sort the class description */
CLASS_sort(class);
/* Search for special methods */
CLASS_search_special(class);
/* Class is loaded */
class->state = CS_LOADED;
class->error = FALSE;
/* Run the static initializer */
EXEC_public(class, NULL, "_init", 0);
/* Class is ready */
class->state = CS_READY;
class->ready = TRUE;
//total += MEMORY_size - alloc;
//printf("%s: %d TOTAL = %d\n", class->name, MEMORY_size - alloc, total);
return class;
}
CLASS *CLASS_register(GB_DESC *ptr)
{
return CLASS_register_class(ptr, CLASS_check_global(((CLASS_DESC_GAMBAS *)ptr)->name));
}