00001 #ifndef KITE_VM__KITEVM_H
00002 #define KITE_VM__KITEVM_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <setjmp.h>
00033
00034 #ifdef WIN32
00035 #undef __MINGW32__
00036 #else
00037 #include <pthread.h>
00038 #endif
00039
00040 #include <signal.h>
00041 #include <assert.h>
00042 #include "kite_opcodes.h"
00043
00044 struct kite_object_t;
00045 struct kite_symtab_t;
00046
00047
00048
00049
00050 struct kite_stack_entry_t;
00051 typedef struct kite_stack_t
00052 {
00053 size_t allocated ;
00054 int length ;
00055 struct kite_stack_entry_t *stack ;
00056 } kite_stack_t;
00057
00058 typedef struct kite_stack_entry_t
00059 {
00060 int reference ;
00061 void *obj ;
00062 } kite_stack_entry_t;
00063
00064
00065
00066
00067 typedef struct kite_funccall_info_t
00068 {
00069 char *file ;
00070 int line ;
00071 int sys_or_user ;
00072 struct kite_symtab_t *locals ;
00073 struct kite_object_t *this ;
00074 char *last_deref ;
00075 struct kite_symtab_t *last_deref_obj ;
00076 } kite_funccall_info_t;
00077
00078
00079
00080
00081
00082 typedef struct kite_thread_t
00083 {
00084 struct kite_thread_t **entry ;
00085 struct kite_vm_t *vm ;
00086 kite_stack_t *running_stack ;
00087 kite_stack_t *func_stack ;
00088 struct kite_object_t *exception ;
00089 void *start ;
00090 #ifdef WIN32
00091 HANDLE thread ;
00092 #else
00093 pthread_t thread ;
00094 #endif
00095 } kite_thread_t ;
00096
00097
00098
00099
00100 typedef struct kite_list_t
00101 {
00102 void *obj ;
00103 struct kite_list_t *prev ;
00104 struct kite_list_t *next ;
00105 } kite_list_t;
00106
00107
00108
00109
00110
00111 typedef struct kite_vm_t
00112 {
00113 struct kite_object_t *root_package ;
00114 struct kite_object_t *true_cached ;
00115 struct kite_object_t *false_cached ;
00116 struct kite_object_t *null_cached ;
00117 struct kite_object_t *int_cached ;
00118 struct kite_symtab_t *loader_refs ;
00119 struct kite_object_t *instruction_tracer;
00120 int numthreads ;
00121 kite_thread_t **thread_list ;
00122 #ifndef HAVE_GC_H
00123 kite_list_t *gc_begin , *gc_end ;
00124 #endif
00125 #ifdef WIN32
00126 HANDLE gc_mtx ;
00127 #else
00128 pthread_mutex_t gc_mtx ;
00129 #endif
00130 #ifdef HAVE_GC_H
00131 GC_warn_proc old_proc ;
00132 #endif
00133 char **args ;
00134 } kite_vm_t ;
00135
00136
00137
00138
00139 typedef struct kite_compiler_t
00140 {
00141 kite_thread_t *thd ;
00142 char *file ;
00143 int verMajor ;
00144 int verMinor ;
00145 int verPatch ;
00146 int currentLine ;
00147 int currentCol ;
00148 kite_stack_t *obj_created ;
00149 kite_stack_t *decide_exits ;
00150 char *curStr ;
00151 } kite_compiler_t;
00152
00153
00154
00155
00156
00161 KITE_EXPORT void kite_app_init();
00162
00168 KITE_EXPORT kite_vm_t *kite_new_vm(char **args);
00169
00174 KITE_EXPORT void kite_free_vm(kite_vm_t **vm);
00175
00176
00177
00178
00179
00185 KITE_EXPORT kite_thread_t *kite_new_thread_without_start(kite_vm_t *vm);
00186
00193 KITE_EXPORT kite_thread_t *kite_new_thread_bytecode(kite_vm_t *vm, void *ptr);
00194
00201 KITE_EXPORT kite_thread_t *kite_new_thread_compiled(kite_vm_t *vm, void *ptr);
00202
00207 #define kite_vm_creator_thread(vm) ((vm)->thread_list[0])
00208
00214 KITE_EXPORT void kite_start_bytecode(kite_thread_t *thd, void *ptr);
00215
00221 KITE_EXPORT void kite_start_compiled(kite_thread_t *thd, void *ptr);
00222
00228 KITE_EXPORT void kite_join_thread(kite_vm_t *vm, kite_thread_t *thd);
00229
00235 KITE_EXPORT void kite_exit_thread(kite_vm_t *vm, kite_thread_t *thd);
00236
00237
00238
00239
00240
00247 KITE_EXPORT void kite_push_stack(kite_stack_t **stack, int ref, void *obj);
00248
00253 KITE_EXPORT void kite_destroy_stack(kite_stack_t **stack);
00254
00260 KITE_EXPORT void *kite_pop_stack(kite_stack_t **stack);
00261
00262 #ifndef WIN32
00263
00264 #endif
00265 #ifndef INLINE_STACK
00266
00272 KITE_EXPORT void *kite_top_stack(kite_stack_t *stack);
00273
00274 #else
00275 #define kite_top_stack(st) \
00276 ((!st || st->length == 0) ? \
00277 NULL : \
00278 (((&st->stack[st->length - 1])->reference) ? \
00279 ((kite_symtab_t*)(&st->stack[st->length - 1])->obj)->value : \
00280 (&st->stack[st->length - 1])->obj))
00281 #endif
00282
00283
00284
00285
00286
00293 KITE_EXPORT void kite_list_remove(kite_list_t **begin, kite_list_t **end, kite_list_t *item);
00294
00301 KITE_EXPORT void kite_list_add_end(kite_list_t **begin, kite_list_t **end, kite_list_t *item);
00302
00309 KITE_EXPORT void kite_list_add_begin(kite_list_t **begin, kite_list_t **end, kite_list_t *item);
00310
00311
00312
00313
00314 #ifndef WIN32
00315
00319 void *kite_vm_execute(void *);
00320
00321 #else
00322
00326 KITE_EXPORT DWORD WINAPI kite_vm_execute(LPVOID);
00327
00328 #endif
00329
00333 KITE_EXPORT void kite_vm_execute_user_method(kite_thread_t *, void *);
00334
00338 KITE_EXPORT void kite_vm_execute_exception(kite_thread_t *, int);
00339
00349 KITE_EXPORT void kite_vm_call_method(kite_thread_t *thd, struct kite_object_t *this,
00350 char *name, struct kite_object_t *args, int err);
00351
00360 KITE_EXPORT void kite_vm_call_object(kite_thread_t *thd, struct kite_object_t *this,
00361 struct kite_object_t *method, struct kite_object_t *args);
00362
00369 KITE_EXPORT void kite_vm_call_constructor(kite_thread_t *thd, struct kite_object_t *this,
00370 struct kite_object_t *args);
00371
00381 KITE_EXPORT int kite_vm_call_operator(kite_thread_t *thd, struct kite_object_t *this,
00382 int op, struct kite_object_t *args, int err);
00383
00389 #define kite_vm_push(thd, obj) \
00390 kite_push_stack(&(thd)->running_stack, FALSE, kite_reference_object(obj))
00391
00397 #define kite_vm_pop(thd) (struct kite_object_t*)kite_pop_stack(&(thd)->running_stack)
00398
00404 #define kite_vm_return(thd, obj) \
00405 { \
00406 kite_object_t *tmp = (obj); \
00407 kite_vm_push((thd), tmp); \
00408 kite_dereference_object(tmp); \
00409 return; \
00410 }
00411
00413 #define STACK_MAX 1024
00414
00415 #ifndef HAVE_GC_H
00416
00419 #define PUSH_FUNC_STACK(t) \
00420 fc_entry = malloc(sizeof(kite_funccall_info_t)); \
00421 oldentry = ((kite_funccall_info_t*)kite_top_stack(thd->func_stack)); \
00422 old_sys = oldentry ? oldentry->sys_or_user : 0; \
00423 fc_entry->this = t; \
00424 fc_entry->locals = NULL; \
00425 fc_entry->file = ins->common.file; \
00426 fc_entry->line = ins->common.line; \
00427 fc_entry->last_deref = NULL; \
00428 fc_entry->last_deref_obj = NULL; \
00429 fc_entry->sys_or_user = 0; \
00430 kite_push_stack(&thd->func_stack, FALSE, fc_entry); \
00431 if (thd->func_stack->length >= STACK_MAX && !old_sys) { \
00432 kite_object_t *exc; \
00433 fc_entry->sys_or_user = 1; \
00434 exc = kite_new_exception(thd, "System.exceptions.StackOverflow", \
00435 "The function call stack has overflowed."); \
00436 kite_vm_call_method(thd, exc, "throw", kite_new_list(thd), TRUE); \
00437 fc_entry->sys_or_user = 0; \
00438 return; \
00439 }
00440
00444 #define PUSH_FUNC_STACK_WITH_RET_VALUE(t, nxt) \
00445 fc_entry = malloc(sizeof(kite_funccall_info_t)); \
00446 oldentry = ((kite_funccall_info_t*)kite_top_stack(thd->func_stack)); \
00447 old_sys = oldentry ? oldentry->sys_or_user : 0; \
00448 fc_entry->this = t; \
00449 fc_entry->locals = NULL; \
00450 fc_entry->file = ins->common.file; \
00451 fc_entry->line = ins->common.line; \
00452 fc_entry->last_deref = NULL; \
00453 fc_entry->last_deref_obj = NULL; \
00454 fc_entry->sys_or_user = 0; \
00455 kite_push_stack(&thd->func_stack, FALSE, fc_entry); \
00456 if (thd->func_stack->length >= STACK_MAX && !old_sys) { \
00457 kite_object_t *exc; \
00458 fc_entry->sys_or_user = 1; \
00459 exc = kite_new_exception(thd, "System.exceptions.StackOverflow", \
00460 "The function call stack has overflowed."); \
00461 kite_vm_call_method(thd, exc, "throw", kite_new_list(thd), TRUE); \
00462 fc_entry->sys_or_user = 0; \
00463 return nxt; \
00464 }
00465
00469 #define POP_FUNC_STACK \
00470 kite_pop_stack(&thd->func_stack); \
00471 if (fc_entry->locals) kite_destruct_symtab(thd, &fc_entry->locals, TRUE); \
00472 free(fc_entry);
00473
00474 #else
00475
00479 #define PUSH_FUNC_STACK(t) \
00480 fc_entry = (kite_funccall_info_t*)GC_malloc(sizeof(kite_funccall_info_t)); \
00481 oldentry = ((kite_funccall_info_t*)kite_top_stack(thd->func_stack)); \
00482 old_sys = oldentry ? oldentry->sys_or_user : 0; \
00483 fc_entry->this = t; \
00484 fc_entry->locals = NULL; \
00485 fc_entry->file = ins->common.file; \
00486 fc_entry->line = ins->common.line; \
00487 fc_entry->last_deref = NULL; \
00488 fc_entry->last_deref_obj = NULL; \
00489 fc_entry->sys_or_user = 0; \
00490 kite_push_stack(&thd->func_stack, FALSE, fc_entry); \
00491 if (thd->func_stack->length >= STACK_MAX && !old_sys) { \
00492 kite_object_t *exc; \
00493 fc_entry->sys_or_user = 1; \
00494 exc = kite_new_exception(thd, "System.exceptions.StackOverflow", \
00495 "The function call stack has overflowed."); \
00496 kite_vm_call_method(thd, exc, "throw", kite_new_list(thd), TRUE); \
00497 fc_entry->sys_or_user = 0; \
00498 return; \
00499 }
00500
00504 #define PUSH_FUNC_STACK_WITH_RET_VALUE(t, nxt) \
00505 fc_entry = (kite_funccall_info_t*)GC_malloc(sizeof(kite_funccall_info_t)); \
00506 oldentry = ((kite_funccall_info_t*)kite_top_stack(thd->func_stack)); \
00507 old_sys = oldentry ? oldentry->sys_or_user : 0; \
00508 fc_entry->this = t; \
00509 fc_entry->locals = NULL; \
00510 fc_entry->file = ins->common.file; \
00511 fc_entry->line = ins->common.line; \
00512 fc_entry->last_deref = NULL; \
00513 fc_entry->last_deref_obj = NULL; \
00514 fc_entry->sys_or_user = 0; \
00515 kite_push_stack(&thd->func_stack, FALSE, fc_entry); \
00516 if (thd->func_stack->length >= STACK_MAX && !old_sys) { \
00517 kite_object_t *exc; \
00518 fc_entry->sys_or_user = 1; \
00519 exc = kite_new_exception(thd, "System.exceptions.StackOverflow", \
00520 "The function call stack has overflowed."); \
00521 kite_vm_call_method(thd, exc, "throw", kite_new_list(thd), TRUE); \
00522 fc_entry->sys_or_user = 0; \
00523 return nxt; \
00524 }
00525
00529 #define POP_FUNC_STACK \
00530 kite_pop_stack(&thd->func_stack); \
00531 if (fc_entry->locals) kite_destruct_symtab(thd, &fc_entry->locals, TRUE);
00532
00533 #endif
00534
00535
00536
00537
00538
00546 KITE_EXPORT struct kite_object_t *kite_vm_compile_from_file(kite_thread_t *thd, char *file);
00547
00557 KITE_EXPORT struct kite_object_t *kite_vm_compile_from_fp
00558 (kite_thread_t *thd, FILE *fp, char *file, struct kite_object_t *created_obj);
00559
00568 KITE_EXPORT struct kite_object_t *kite_vm_compile_from_string(kite_thread_t *thd, char *code, int ln);
00569
00578 KITE_EXPORT struct kite_object_t *kite_vm_compile_from_file_without_create(
00579 kite_thread_t *thd, char *file, struct kite_object_t *created_obj);
00580
00581
00582
00583
00584 #ifndef WIN32
00585 #undef NSIG
00586
00590 #define NSIG 65
00591
00592 #endif
00593
00597 KITE_EXPORT extern struct kite_object_t *kite_signal_handlers[NSIG + 1];
00598
00602 void kite_handle_signal(int);
00603
00604
00605
00606
00607 #ifndef KITE_MODULE_INITIALIZER_C
00608
00611 extern void kite_module_initialize_now(kite_thread_t*);
00612 #endif
00613
00614 #ifdef INLINE_STACK
00615 inline void *kite_pop_stack(kite_stack_t **st)
00616 {
00617 kite_stack_t *entry;
00618 void *ret;
00619
00620 assert(st != NULL && (*st)->length > 0);
00621 entry = *st;
00622
00623 ret = kite_top_stack(entry);
00624 entry->length--;
00625
00626 return ret;
00627 }
00628
00629 inline void kite_push_stack(kite_stack_t **st, int ref, void *obj)
00630 {
00631 assert(st != NULL && obj != NULL);
00632
00633 kite_stack_t *cur = *st;
00634 if (cur == NULL)
00635 {
00636 #ifndef HAVE_GC_H
00637 cur = malloc(sizeof(kite_stack_t));
00638 #else
00639 cur = GC_malloc(sizeof(kite_stack_t));
00640 #endif
00641 assert(cur != NULL);
00642 cur->length = 0;
00643 cur->allocated = sizeof(kite_stack_entry_t);
00644 #ifndef HAVE_GC_H
00645 cur->stack = malloc(cur->allocated);
00646 #else
00647 cur->stack = GC_malloc(cur->allocated);
00648 #endif
00649 *st = cur;
00650 }
00651
00652 if (((cur->length + 1) * sizeof(kite_stack_entry_t)) > cur->allocated)
00653 {
00654 int newsize = cur->allocated << 1;
00655 #ifndef HAVE_GC_H
00656 cur->stack = realloc(cur->stack, newsize);
00657 #else
00658 cur->stack = GC_realloc(cur->stack, newsize);
00659 #endif
00660 assert(cur->stack != NULL);
00661 cur->allocated = newsize;
00662 }
00663
00664 kite_stack_entry_t *entry = &cur->stack[++cur->length - 1];
00665 entry->obj = obj;
00666 entry->reference = ref;
00667 }
00668 #endif
00669
00670 #endif