0f54fe9ccd
[INTERPRETER] * OPT: Optimize object creation when there is no special method to call ('_new', '_ready', global variable initialization) and no inheritance.
575 lines
15 KiB
C
575 lines
15 KiB
C
/***************************************************************************
|
|
|
|
gbx_class.h
|
|
|
|
(c) 2000-2017 Benoît Minisini <benoit.minisini@gambas-basic.org>
|
|
|
|
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., 51 Franklin Street, Fifth Floor, Boston,
|
|
MA 02110-1301, USA.
|
|
|
|
***************************************************************************/
|
|
|
|
#ifndef __GBX_CLASS_H
|
|
#define __GBX_CLASS_H
|
|
|
|
#include "gb_error.h"
|
|
#include "gbx_type.h"
|
|
#include "gb_table.h"
|
|
#include "gbx_class_desc.h"
|
|
#include "gbx_component.h"
|
|
|
|
#ifndef __GBX_CLASS_C
|
|
EXTERN bool CLASS_exiting;
|
|
#endif
|
|
|
|
typedef
|
|
int CLASS_ID;
|
|
|
|
typedef
|
|
struct {
|
|
CTYPE type;
|
|
int pos;
|
|
}
|
|
CLASS_VAR;
|
|
|
|
typedef
|
|
struct _CLASS *CLASS_REF;
|
|
|
|
typedef
|
|
char *CLASS_UNKNOWN;
|
|
|
|
typedef
|
|
union {
|
|
int type;
|
|
struct { int type; double value; } PACKED _float;
|
|
struct { int type; float value; } PACKED _single;
|
|
struct { int type; int value; } PACKED _integer;
|
|
struct { int type; int64_t value; } PACKED _long;
|
|
struct { int type; char *addr; int len; } PACKED _string;
|
|
struct { int type; int val[2]; } PACKED _swap;
|
|
}
|
|
PACKED
|
|
CLASS_CONST;
|
|
|
|
typedef
|
|
struct {
|
|
CTYPE type;
|
|
}
|
|
CLASS_LOCAL;
|
|
|
|
typedef
|
|
struct {
|
|
TYPE type;
|
|
}
|
|
CLASS_PARAM;
|
|
|
|
typedef
|
|
struct {
|
|
char *name;
|
|
int len;
|
|
}
|
|
PACKED
|
|
DEBUG_SYMBOL;
|
|
|
|
typedef
|
|
struct {
|
|
DEBUG_SYMBOL sym;
|
|
int value;
|
|
}
|
|
LOCAL_SYMBOL;
|
|
|
|
typedef
|
|
struct {
|
|
unsigned short line;
|
|
unsigned short nline;
|
|
unsigned short *pos;
|
|
char *name;
|
|
LOCAL_SYMBOL *local;
|
|
short n_local;
|
|
unsigned short index; // Function index in its class. Used by the profiler
|
|
}
|
|
PACKED
|
|
FUNC_DEBUG;
|
|
|
|
typedef
|
|
struct {
|
|
TYPE type;
|
|
uchar n_param;
|
|
uchar npmin;
|
|
uchar vararg;
|
|
unsigned fast : 1;
|
|
unsigned unsafe : 1;
|
|
unsigned fast_linked : 1;
|
|
unsigned optional : 1;
|
|
unsigned use_is_missing : 1;
|
|
unsigned is_static : 1;
|
|
unsigned _reserved : 2;
|
|
uchar n_local;
|
|
uchar n_ctrl;
|
|
uchar n_label; // Number of label for indirect jumps
|
|
uchar _reserved2;
|
|
short stack_usage;
|
|
short error;
|
|
unsigned short *code;
|
|
CLASS_PARAM *param;
|
|
CLASS_LOCAL *local;
|
|
FUNC_DEBUG *debug;
|
|
}
|
|
PACKED
|
|
FUNCTION;
|
|
|
|
typedef
|
|
struct {
|
|
TYPE type;
|
|
char n_param;
|
|
char npmin;
|
|
char vararg;
|
|
unsigned char flag;
|
|
short n_local;
|
|
short n_ctrl;
|
|
}
|
|
PACKED
|
|
FUNCTION_LOAD;
|
|
|
|
typedef
|
|
struct {
|
|
TYPE type;
|
|
short n_param;
|
|
short _reserved;
|
|
CLASS_PARAM *param;
|
|
char *name;
|
|
}
|
|
PACKED
|
|
CLASS_EVENT;
|
|
|
|
typedef
|
|
struct {
|
|
TYPE type;
|
|
short n_param;
|
|
bool vararg;
|
|
unsigned loaded : 1;
|
|
unsigned _reserved : 7;
|
|
CLASS_PARAM *param;
|
|
char *alias;
|
|
char *library;
|
|
}
|
|
PACKED
|
|
CLASS_EXTERN;
|
|
|
|
typedef
|
|
struct {
|
|
uint magic;
|
|
uint version;
|
|
uint endian;
|
|
uint flag;
|
|
}
|
|
PACKED
|
|
CLASS_HEADER;
|
|
|
|
typedef
|
|
struct {
|
|
short parent;
|
|
short flag;
|
|
int s_static;
|
|
int s_dynamic;
|
|
short nstruct;
|
|
short _reserved;
|
|
}
|
|
PACKED
|
|
CLASS_INFO;
|
|
|
|
typedef
|
|
struct {
|
|
CTYPE ctype;
|
|
int dim[0];
|
|
}
|
|
CLASS_ARRAY;
|
|
|
|
typedef
|
|
CLASS_ARRAY *CLASS_ARRAY_P;
|
|
|
|
struct _CLASS;
|
|
|
|
typedef
|
|
struct {
|
|
DEBUG_SYMBOL sym;
|
|
CTYPE ctype;
|
|
int value;
|
|
}
|
|
GLOBAL_SYMBOL;
|
|
|
|
typedef
|
|
struct {
|
|
int nfield;
|
|
int *desc;
|
|
}
|
|
CLASS_STRUCT;
|
|
|
|
typedef
|
|
struct {
|
|
short n_cst;
|
|
short n_stat;
|
|
short n_dyn;
|
|
short n_func;
|
|
|
|
CLASS_CONST *cst;
|
|
CLASS_VAR *stat;
|
|
CLASS_VAR *dyn;
|
|
FUNCTION *func;
|
|
CLASS_EVENT *event;
|
|
CLASS_EXTERN *ext;
|
|
CLASS_ARRAY **array;
|
|
|
|
CLASS_REF *class_ref;
|
|
char **unknown;
|
|
|
|
GLOBAL_SYMBOL *global;
|
|
ushort *sort;
|
|
short n_global;
|
|
short n_ext;
|
|
uint *prof; // Shortcut indexes attributed during profiling. The first one is for the class, the other ones for the functions
|
|
#ifdef OS_64BITS
|
|
CLASS_DESC *desc;
|
|
CLASS_PARAM *local;
|
|
FUNC_DEBUG *debug;
|
|
#endif
|
|
}
|
|
PACKED
|
|
CLASS_LOAD;
|
|
|
|
enum {
|
|
CO_EQUAL, CO_EQUALF, CO_EQUALO,
|
|
CO_COMP, CO_COMPF, CO_COMPO,
|
|
CO_ADD, CO_ADDF, CO_ADDO,
|
|
CO_SUB, CO_SUBF, CO_SUBO,
|
|
CO_MUL, CO_MULF, CO_MULO,
|
|
CO_DIV, CO_DIVF, CO_DIVO,
|
|
CO_POW, CO_POWF, CO_POWO,
|
|
CO_NEG, CO_ABS, CO_FABS, CO_SGN,
|
|
CO_STRENGTH
|
|
};
|
|
|
|
typedef
|
|
struct _CLASS { // 32b 64b
|
|
struct _CLASS *class; // 4 8 Points at the 'Class' class !
|
|
int ref; // 8 12 Reference count
|
|
int count; // 12 16 Number of instanciated objects
|
|
struct _CLASS *parent; // 16 24 Inherited class
|
|
char *name; // 20 32 Class name
|
|
|
|
unsigned loaded : 1; // Class is loaded
|
|
unsigned ready : 1; // Class is loaded and ready
|
|
unsigned debug : 1; // Debugging information ?
|
|
unsigned swap : 1; // Class endianness was swapped
|
|
unsigned free_event : 1; // Must free class->event
|
|
unsigned in_load : 1; // Class being loaded
|
|
unsigned exit : 1; // Marker used by CLASS_exit
|
|
unsigned auto_create : 1; // Automatically instanciated
|
|
|
|
unsigned quick_array : 2; // Array accessor optimization type
|
|
unsigned no_create : 1; // Cannot instanciate this class
|
|
unsigned is_virtual : 1; // Virtual class (name beginning with a dot)
|
|
unsigned enum_static : 1; // If class enumeration is static
|
|
unsigned is_stream : 1; // If the class inherits stream
|
|
unsigned global : 1; // If the class is in the global table
|
|
unsigned error : 1; // Loading or registering the class has failed
|
|
|
|
unsigned is_native : 1; // If the class is native (i.e. written in C/C++)
|
|
unsigned is_observer : 1; // This is the Observer class
|
|
unsigned is_struct : 1; // This class is a structure
|
|
unsigned is_array : 1; // This class is an array
|
|
unsigned is_array_of_struct : 1; // This class is an array of struct
|
|
unsigned init_dynamic : 1; // If there is a special function to call at instanciation
|
|
unsigned must_check : 1; // The class has a check function
|
|
unsigned has_child : 1; // The class has an inherited child class
|
|
|
|
unsigned unknown_static : 1; // If _unknown is static
|
|
unsigned property_static : 1; // If _property is static
|
|
unsigned has_convert : 1; // If the _convert interface is implemented
|
|
unsigned has_operators : 1; // If the _operators interface is implemented
|
|
unsigned is_simple : 1; // Class has no parent, no child, is not virtual, and has no 'check' function.
|
|
unsigned has_free : 1; // The class has a free function
|
|
unsigned is_test : 1; // The class is a test module
|
|
unsigned less_than_3_18 : 1; // 24 36 If bytecode version is strictly older than 3.18
|
|
|
|
short n_desc; // 26 38 number of descriptions
|
|
short n_event; // 28 40 number of events
|
|
|
|
CLASS_DESC_SYMBOL *table; // 32 48 class description
|
|
ushort *sort; // 36 56 table sort
|
|
|
|
CLASS_EVENT *event; // 40 64 event description
|
|
|
|
int (*check)(); // 44 72 method for checking that an object is valid
|
|
|
|
char *data; // 48 80 class file data for loaded class
|
|
// or generated description for native class
|
|
// or generated description for structures
|
|
|
|
CLASS_LOAD *load; // 52 88 information about loaded class
|
|
|
|
char *stat; // 56 96 static class data
|
|
TYPE *signature; // 60 104 signatures address
|
|
char *string; // 64 112 strings address
|
|
|
|
uint size_stat; // 68 116 static class size
|
|
uint size; // 72 120 dynamic class size
|
|
uint off_event; // 76 124 offset of OBJECT_EVENT structure in the object
|
|
|
|
unsigned new_method : 1; // if there is a special method to call when creating a new instance
|
|
unsigned ready_method : 1; // if there is a ready method to call
|
|
unsigned _reserved2 : 30; // 80 128
|
|
|
|
short special[16]; // 112 160 special functions index (_new, _free, ...)
|
|
|
|
TYPE array_type; // 116 168 datatype of the contents if this class is an array class of objects
|
|
struct _CLASS *array_class; // 120 176 array of class
|
|
struct _CLASS *astruct_class; // 124 184 array of struct class
|
|
|
|
void *instance; // 128 192 automatically created instance
|
|
void **operators; // 132 200 arithmetic interface
|
|
bool (*convert)(); // 136 208 convert method
|
|
|
|
COMPONENT *component; // 140 216 The component the class belongs to
|
|
|
|
struct _CLASS *next; // 148 224 next class
|
|
}
|
|
CLASS;
|
|
|
|
typedef
|
|
struct {
|
|
SYMBOL sym;
|
|
CLASS *class;
|
|
}
|
|
PACKED
|
|
CLASS_SYMBOL;
|
|
|
|
typedef
|
|
enum {
|
|
SPEC_NEW,
|
|
SPEC_FREE,
|
|
SPEC_GET,
|
|
SPEC_PUT,
|
|
SPEC_FIRST,
|
|
SPEC_NEXT,
|
|
SPEC_CALL,
|
|
SPEC_UNKNOWN,
|
|
SPEC_PROPERTY,
|
|
SPEC_COMPARE,
|
|
SPEC_ATTACH,
|
|
SPEC_READY,
|
|
SPEC_READ,
|
|
SPEC_WRITE,
|
|
SPEC_INVALID
|
|
}
|
|
CLASS_SPECIAL;
|
|
|
|
typedef
|
|
enum {
|
|
CQA_NONE = 0,
|
|
CQA_ARRAY = 1,
|
|
CQA_COLLECTION = 2,
|
|
CQA_STRING = 3
|
|
}
|
|
CLASS_QUICK_ARRAY;
|
|
|
|
typedef
|
|
enum
|
|
{
|
|
CF_DEBUG = 1
|
|
}
|
|
CLASS_FLAG;
|
|
|
|
typedef
|
|
enum
|
|
{
|
|
CI_EXPORTED = 1,
|
|
CI_AUTO_CREATE = 2,
|
|
CI_OPTIONAL = 4,
|
|
CI_NO_CREATE = 8,
|
|
CI_HAS_FAST = 16,
|
|
CI_TEST = 32
|
|
}
|
|
CLASS_INFO_FLAG;
|
|
|
|
#ifndef __GBX_CLASS_INIT_C
|
|
EXTERN CLASS *CLASS_Class;
|
|
EXTERN CLASS *CLASS_Enum;
|
|
EXTERN CLASS *CLASS_Symbol;
|
|
|
|
EXTERN CLASS *CLASS_Array;
|
|
EXTERN CLASS *CLASS_Collection;
|
|
EXTERN CLASS *CLASS_Stream;
|
|
EXTERN CLASS *CLASS_File;
|
|
EXTERN CLASS *CLASS_Stat;
|
|
EXTERN CLASS *CLASS_AppArgs;
|
|
EXTERN CLASS *CLASS_AppEnv;
|
|
EXTERN CLASS *CLASS_Application;
|
|
EXTERN CLASS *CLASS_Process;
|
|
EXTERN CLASS *CLASS_Component;
|
|
EXTERN CLASS *CLASS_Observer;
|
|
EXTERN CLASS *CLASS_Timer;
|
|
EXTERN CLASS *CLASS_BoxedString;
|
|
|
|
EXTERN CLASS *CLASS_BooleanArray;
|
|
EXTERN CLASS *CLASS_ByteArray;
|
|
EXTERN CLASS *CLASS_ShortArray;
|
|
EXTERN CLASS *CLASS_IntegerArray;
|
|
EXTERN CLASS *CLASS_SingleArray;
|
|
EXTERN CLASS *CLASS_FloatArray;
|
|
EXTERN CLASS *CLASS_DateArray;
|
|
EXTERN CLASS *CLASS_StringArray;
|
|
EXTERN CLASS *CLASS_ObjectArray;
|
|
EXTERN CLASS *CLASS_VariantArray;
|
|
EXTERN CLASS *CLASS_LongArray;
|
|
EXTERN CLASS *CLASS_PointerArray;
|
|
#endif
|
|
|
|
|
|
#define DO_ERROR ((void (*)()) -1)
|
|
|
|
#define CLASS_is_native(_class) ((_class)->is_native)
|
|
#define CLASS_is_struct(_class) ((_class)->is_struct)
|
|
#define CLASS_is_array(_class) ((_class)->is_array)
|
|
#define CLASS_is_array_of_struct(_class) ((_class)->is_array_of_struct)
|
|
|
|
#define FUNCTION_is_static(func) ((func)->type & TF_STATIC)
|
|
//#define FUNCTION_is_native(_desc) (((uintptr_t)(_desc)->exec >> 16) != 0)
|
|
#define FUNCTION_is_native(_desc) ((_desc)->native)
|
|
|
|
#define FUNC_INIT_STATIC 0
|
|
#define FUNC_INIT_DYNAMIC 1
|
|
|
|
|
|
/* class.c */
|
|
|
|
void CLASS_init(void);
|
|
void CLASS_clean_up(bool silent);
|
|
void CLASS_exit(void);
|
|
CLASS *CLASS_get_list(void);
|
|
|
|
CLASS *CLASS_get(const char *name);
|
|
int CLASS_count(void);
|
|
|
|
char *CLASS_get_name(CLASS *class);
|
|
|
|
CLASS_DESC_SYMBOL *CLASS_get_symbol(CLASS *class, const char *name);
|
|
CLASS_DESC *CLASS_get_symbol_desc(CLASS *class, const char *name);
|
|
|
|
//short CLASS_get_symbol_index_kind(CLASS *class, const char *name, int kind, int kind2);
|
|
CLASS_DESC *CLASS_get_symbol_desc_kind(CLASS *class, const char *name, int kind, int kind2, TYPE type);
|
|
CLASS_DESC_METHOD *CLASS_get_special_desc(CLASS *class, int spec);
|
|
|
|
#define CLASS_get_desc(_class, _index) (((_class)->table[_index].desc))
|
|
|
|
CLASS_DESC_EVENT *CLASS_get_event_desc(CLASS *class, const char *name);
|
|
|
|
#define CLASS_find_symbol(_class, _name) SYMBOL_find((_class)->table, (_class)->sort, (_class)->n_desc, sizeof(CLASS_DESC_SYMBOL), TF_IGNORE_CASE, (_name), strlen((_name)), NULL)
|
|
|
|
int CLASS_find_symbol_with_prefix(CLASS *class, const char *name, const char *prefix);
|
|
|
|
CLASS *CLASS_look_do(const char *name, int len, bool global);
|
|
CLASS *CLASS_find_do(const char *name, bool global);
|
|
|
|
#define CLASS_look(_name, _len) CLASS_look_do(_name, _len, FALSE)
|
|
#define CLASS_find(_name) CLASS_find_do(_name, FALSE)
|
|
|
|
#define CLASS_look_global(_name, _len) CLASS_look_do(_name, _len, TRUE)
|
|
#define CLASS_find_global(_name) CLASS_find_do(_name, TRUE)
|
|
|
|
TABLE *CLASS_get_table(void);
|
|
|
|
bool CLASS_inherits(CLASS *class, CLASS *parent);
|
|
|
|
CLASS *CLASS_replace_global(const char *name);
|
|
CLASS *CLASS_check_global(CLASS *class);
|
|
CLASS *CLASS_find_export(const char *name, const char *global);
|
|
|
|
void CLASS_ref(void *object);
|
|
bool CLASS_unref(void *object, bool can_free);
|
|
void CLASS_free(void *object);
|
|
|
|
int CLASS_get_inheritance(CLASS *class, CLASS **her);
|
|
|
|
void CLASS_do_nothing();
|
|
int CLASS_return_zero();
|
|
|
|
void CLASS_sort(CLASS *class);
|
|
|
|
void CLASS_inheritance(CLASS *class, CLASS *parent);
|
|
void CLASS_make_description(CLASS *class, const CLASS_DESC *desc, int n_desc, int *first);
|
|
void CLASS_make_event(CLASS *class, int *first);
|
|
void CLASS_calc_info(CLASS *class, int n_event, int size_dynamic, bool all, int size_static);
|
|
|
|
void *CLASS_auto_create(CLASS *class, int nparam);
|
|
|
|
void CLASS_search_special(CLASS *class);
|
|
|
|
CLASS_DESC_SYMBOL *CLASS_get_next_sorted_symbol(CLASS *class, int *index);
|
|
|
|
int CLASS_can_be_used_like_an_array(CLASS *class);
|
|
|
|
void CLASS_create_array_class(CLASS *class);
|
|
CLASS *CLASS_get_array_class(CLASS *class);
|
|
|
|
void CLASS_create_array_of_struct_class(CLASS *class);
|
|
CLASS *CLASS_get_array_of_struct_class(CLASS *class);
|
|
|
|
int CLASS_sizeof(CLASS *class);
|
|
|
|
CLASS *CLASS_find_load_from(const char *name, const char *from);
|
|
|
|
void CLASS_translation_must_be_reloaded(void);
|
|
|
|
/* class_init.c */
|
|
|
|
void CLASS_init_native(void);
|
|
void CLASS_update_global(CLASS *old_class, CLASS *new_class);
|
|
|
|
/* class_load.c */
|
|
|
|
TYPE CLASS_ctype_to_type(CLASS *class, CTYPE ctype);
|
|
int CLASS_sizeof_ctype(CLASS *class, CTYPE ctype);
|
|
|
|
void CLASS_load_real(CLASS *class);
|
|
#define CLASS_load(_class) \
|
|
({ \
|
|
if (!((_class)->ready)) \
|
|
CLASS_load_real(_class); \
|
|
})
|
|
void CLASS_run_inits(CLASS *class);
|
|
void CLASS_load_without_init(CLASS *class);
|
|
|
|
/* class_native.c */
|
|
|
|
CLASS *CLASS_register_class(GB_DESC *desc, CLASS *class);
|
|
CLASS *CLASS_register(GB_DESC *desc);
|
|
|
|
#define SET_IF_NULL(ptr, val) if ((ptr) == NULL) (ptr) = (val)
|
|
/*
|
|
#define DO_NOTHING(ptr) if ((ptr) == NULL) (ptr) = CLASS_do_nothing
|
|
#define RETURN_ZERO(ptr) if ((ptr) == NULL) (ptr) = CLASS_return_zero
|
|
*/
|
|
|
|
#define CLASS_is_virtual(class) (class->is_virtual)
|
|
|
|
#define CLASS_has_operator(_class, _op) (((void **)(_class)->operators)[_op] != NULL)
|
|
#define CLASS_get_operator_strength(_class) (((intptr_t *)(_class)->operators)[CO_STRENGTH])
|
|
#define CLASS_set_operator_strength(_class, _strength) (((intptr_t *)(_class)->operators)[CO_STRENGTH] = (_strength))
|
|
|
|
#define CLASS_is_loaded(_class) ((_class)->loaded)
|
|
#define CLASS_is_ready(_class) ((_class)->ready)
|
|
|
|
#endif /* _CLASS_H */
|