📄 gbx_class_load.c
字号:
/*************************************************************************** class_load.c Gambas class loader (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_CLASS_LOAD_C#include "gb_common.h"#include "gb_common_case.h"#include "gb_common_buffer.h"#include "gb_common_swap.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_class.h"/*#define DEBUG#define DEBUG_LOAD 1*/PRIVATE const char *ClassName;PRIVATE bool _swap;/*PRIVATE void CLASS_new(void **ptr, CLASS *class, char *name, OBJECT *parent){ VALUE_FUNCTION exec; OBJECT_new(ptr, class, name, parent); exec.class = class; exec.object = *ptr; exec.function = FUNC_INIT_DYNAMIC; #if DEBUG_EVENT printf("CLASS_new (%s %p) parent (%s %p)\n", ((OBJECT *)*ptr)->class->name, *ptr, parent->class->name, parent); #endif EXEC_function(&exec, 0);}*/#ifdef DEBUGPRIVATE CLASS *Class;PRIVATE int NSection;#endif#define RELOCATE(_ptr) (_ptr = (char *)&class->string[(long)(_ptr)])static void SWAP_type(CTYPE *p){ SWAP_short(&p->value);}PRIVATE char *get_section(char *sec_name, char **section, long one, short *psize, char *swapcode){ char *current = *section + sizeof(long); long section_size = *((long *)(*section)); long i, n; char *p; char *ps; size_t ss; void (*func)(); short size; if (_swap) SWAP_long(§ion_size); #ifdef DEBUG NSection++; printf("Section #%d %s %08lX %ld %ld\n", NSection + 1, sec_name, (long)(current - (char *)Class->data), one, section_size); #endif /* if (section_size == 0) THROW(E_FORMAT); */ *section += section_size + sizeof(long); if (section_size % one) THROW(E_CLASS, ClassName, "Bad format in ", sec_name); size = section_size / one; if (psize) *psize = size; if (_swap && swapcode) { p = current; /*if (one == sizeof(short)) { for (i = 0; i < size; i++) { SWAP_short((short *)p); p += sizeof(short); } } else if (one == sizeof(long)) { for (i = 0; i < size; i++) { SWAP_long((long *)p); p += sizeof(long); } } else*/ { for (i = 0; i < size; i++) { p = current + i * one; ps = swapcode; while (*ps) { if (*ps == 's') { func = SWAP_short; ss = sizeof(short); } else if (*ps == 'l') { func = SWAP_long; ss = sizeof(long); } else { func = SWAP_type; ss = sizeof(long); } ps++; if (isdigit(*ps)) { n = *ps - '0'; ps++; } else if (*ps == '*') { n = one / ss; ps++; } else n = 1; while (n) { (*func)(p); p += ss; n--; } } } } } return current;}PRIVATE void conv_type(CLASS *class, void *ptype){ CTYPE ctype = *(CTYPE *)ptype; TYPE type; // = *((TYPE *)ptype); if (_swap) { SWAP_long((long *)&ctype); SWAP_type(&ctype); } if (ctype.id == T_OBJECT && ctype.value >= 0) type = (TYPE)(class->load->class_ref[ctype.value]); else if (ctype.id == T_ARRAY || ctype.id == T_STRUCT) ERROR_panic("conv_type: bad type"); else type = (TYPE)(ctype.id); *((TYPE *)ptype) = type;}PUBLIC void CLASS_load_without_init(CLASS *class){ char *section; CLASS_HEADER *header; CLASS_INFO *info; int i, j; CLASS_LOCAL *local; FUNCTION *func; CLASS_DESC *desc; CLASS_DESC *start; short n_class_ref; short n_unknown; CLASS_CONST *cc; CLASS_VAR *var; int len; CLASS_EVENT *event; short n_array; VALUE value; long len_data; long first; short n_desc; long offset; int first_event; FUNC_DEBUG *debug; if (class->state >= CS_LOADED) return; #if DEBUG_LOAD printf("Loading class %s (%p)...\n", class->name, class); #endif #ifdef DEBUG Class = class; NSection = 0; #endif ClassName = class->name; if (class->in_load) THROW(E_CLASS, ClassName, "Circular reference", ""); ARCHIVE_last = NULL; len = strlen(class->name); { char name[len + 9]; char *p; strcpy(name, ".gambas/"); p = &name[8]; for (i = 0; i < len; i++) *p++ = toupper(class->name[i]); *p = 0; TRY { STREAM_load(name, &class->data, &len_data); } CATCH { THROW(E_CLASS, class->name, "Unable to load class file", ""); } END_TRY /*if (BUFFER_load_file(&class->data, FILE_get(name))) THROW(E_CLASS, ClassName, "Unable to load class file", "");*/ } class->in_load = TRUE; class->belong = ARCHIVE_last; ALLOC_ZERO(&class->load, sizeof(CLASS_LOAD), "CLASS_load"); /* header */ section = class->data; header = (CLASS_HEADER *)section; section += sizeof(CLASS_HEADER); _swap = header->endian != OUTPUT_ENDIAN; if (_swap) fprintf(stderr, "gbx: swapping class %s\n", class->name); if (_swap) { SWAP_long((long *)&header->magic); SWAP_long((long *)&header->version); SWAP_long((long *)&header->flag); } if (header->magic != OUTPUT_MAGIC) THROW(E_CLASS, ClassName, "Bad header", ""); if (header->version != OUTPUT_VERSION) THROW(E_CLASS, ClassName, "Bad version", ""); class->debug = header->flag & CF_DEBUG; /* Chargement des sections */ #ifdef DEBUG Class = class; #endif info = (CLASS_INFO *)get_section("info section", §ion, sizeof(CLASS_INFO), NULL, "s2l2"); start = (CLASS_DESC *)get_section("description section", §ion, sizeof(CLASS_DESC), &n_desc, "l*"); class->load->cst = (CLASS_CONST *)get_section("constant section", §ion, sizeof(CLASS_CONST), &class->load->n_cst, "l*"); class->load->class_ref = (CLASS **)get_section("reference section", §ion, sizeof(long), &n_class_ref, "l*"); class->load->unknown = (char **)get_section("extern section", §ion, sizeof(long), &n_unknown, "l*"); class->load->stat = (CLASS_VAR *)get_section("static section", §ion, sizeof(CLASS_VAR), &class->load->n_stat, "tl"); class->load->dyn = (CLASS_VAR *)get_section("dynamic section", §ion, sizeof(CLASS_VAR), &class->load->n_dyn, "tl"); class->load->event = (CLASS_EVENT *)get_section("event section", §ion, sizeof(CLASS_EVENT), &class->n_event, "ls2l2"); class->load->func = (FUNCTION *)get_section("function section", §ion, sizeof(FUNCTION), &class->load->n_func, "ls6l4"); local = (CLASS_LOCAL *)get_section("local section", §ion, sizeof(CLASS_LOCAL), NULL, "l*"); class->load->array = (CLASS_ARRAY **)get_section("array section", §ion, sizeof(long), &n_array, "l"); /* Chargement du code */ for (i = 0; i < class->load->n_func; i++) { func = &class->load->func[i]; func->code = (ushort *)get_section("code section", §ion, sizeof(ushort), NULL, "s"); } /* Informations de d�ogage */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -