+THREADSPECIFIC void *_thread_nativestackframeinfo = NULL;
+
+
+/* include builtin tables *****************************************************/
+
+#include "vm/builtintable.inc"
+
+
+/* builtintable_init ***********************************************************
+
+ Parse the descriptors of builtin functions and create the parsed
+ descriptors.
+
+*******************************************************************************/
+
+static bool builtintable_init(void)
+{
+ descriptor_pool *descpool;
+ s4 dumpsize;
+ utf *descriptor;
+ s4 entries_internal;
+ s4 entries_automatic;
+ s4 i;
+
+ /* mark start of dump memory area */
+
+ dumpsize = dump_size();
+
+ /* create a new descriptor pool */
+
+ descpool = descriptor_pool_new(class_java_lang_Object);
+
+ /* add some entries we need */
+
+ if (!descriptor_pool_add_class(descpool, utf_java_lang_Object))
+ return false;
+
+ if (!descriptor_pool_add_class(descpool, utf_java_lang_Class))
+ return false;
+
+ /* calculate table entries statically */
+
+ entries_internal =
+ sizeof(builtintable_internal) / sizeof(builtintable_entry);
+
+ entries_automatic =
+ sizeof(builtintable_automatic) / sizeof(builtintable_entry)
+ - 1; /* last filler entry (comment see builtintable.inc) */
+
+ /* first add all descriptors to the pool */
+
+ for (i = 0; i < entries_internal; i++) {
+ /* create a utf8 string from descriptor */
+
+ descriptor = utf_new_char(builtintable_internal[i].descriptor);
+
+ if (!descriptor_pool_add(descpool, descriptor, NULL)) {
+ /* release dump area */
+
+ dump_release(dumpsize);
+
+ return false;
+ }
+ }
+
+ for (i = 0; i < entries_automatic; i++) {
+ /* create a utf8 string from descriptor */
+
+ descriptor = utf_new_char(builtintable_automatic[i].descriptor);
+
+ if (!descriptor_pool_add(descpool, descriptor, NULL)) {
+ /* release dump area */
+
+ dump_release(dumpsize);
+
+ return false;
+ }
+ }
+
+ /* create the class reference table */
+
+ (void) descriptor_pool_create_classrefs(descpool, NULL);
+
+ /* allocate space for the parsed descriptors */
+
+ descriptor_pool_alloc_parsed_descriptors(descpool);
+
+ /* now parse all descriptors */
+
+ for (i = 0; i < entries_internal; i++) {
+ /* create a utf8 string from descriptor */
+
+ descriptor = utf_new_char(builtintable_internal[i].descriptor);
+
+ /* parse the descriptor, builtin is always static (no `this' pointer) */
+
+ builtintable_internal[i].md =
+ descriptor_pool_parse_method_descriptor(descpool, descriptor,
+ ACC_STATIC, NULL);
+ }
+
+ for (i = 0; i < entries_automatic; i++) {
+ /* create a utf8 string from descriptor */
+
+ descriptor = utf_new_char(builtintable_automatic[i].descriptor);
+
+ /* parse the descriptor, builtin is always static (no `this' pointer) */
+
+ builtintable_automatic[i].md =
+ descriptor_pool_parse_method_descriptor(descpool, descriptor,
+ ACC_STATIC, NULL);
+ }
+
+ /* release dump area */
+
+ dump_release(dumpsize);
+
+ return true;
+}
+
+
+/* builtintable_comparator *****************************************************
+
+ qsort comparator for the automatic builtin table.
+
+*******************************************************************************/
+
+static int builtintable_comparator(const void *a, const void *b)
+{
+ builtintable_entry *bte1;
+ builtintable_entry *bte2;
+
+ bte1 = (builtintable_entry *) a;
+ bte2 = (builtintable_entry *) b;
+
+ return (bte1->opcode < bte2->opcode) ? -1 : (bte1->opcode > bte2->opcode);
+}
+
+
+/* builtintable_sort_automatic *************************************************
+
+ Sorts the automatic builtin table.
+
+*******************************************************************************/
+
+static void builtintable_sort_automatic(void)
+{
+ s4 entries;
+
+ /* calculate table size statically (`- 1' comment see builtintable.inc) */
+
+ entries = sizeof(builtintable_automatic) / sizeof(builtintable_entry) - 1;
+
+ qsort(builtintable_automatic, entries, sizeof(builtintable_entry),
+ builtintable_comparator);
+}
+
+
+/* builtin_init ****************************************************************
+
+ XXX
+
+*******************************************************************************/
+
+bool builtin_init(void)
+{
+ /* initialize the builtin tables */
+
+ if (!builtintable_init())
+ return false;
+
+ /* sort builtin tables */
+
+ builtintable_sort_automatic();
+
+ return true;
+}
+
+
+/* builtintable_get_internal ***************************************************
+
+ Finds an entry in the builtintable for internal functions and
+ returns the a pointer to the structure.
+
+*******************************************************************************/
+
+builtintable_entry *builtintable_get_internal(functionptr fp)
+{
+ s4 i;
+
+ for (i = 0; builtintable_internal[i].fp != NULL; i++) {
+ if (builtintable_internal[i].fp == fp)
+ return &builtintable_internal[i];
+ }
+
+ return NULL;
+}
+
+
+/* builtintable_get_automatic **************************************************
+
+ Finds an entry in the builtintable for functions which are replaced
+ automatically and returns the a pointer to the structure.
+
+*******************************************************************************/
+
+builtintable_entry *builtintable_get_automatic(s4 opcode)
+{
+ builtintable_entry *first;
+ builtintable_entry *last;
+ builtintable_entry *middle;
+ s4 half;
+ s4 entries;
+
+ /* calculate table size statically (`- 1' comment see builtintable.inc) */
+
+ entries = sizeof(builtintable_automatic) / sizeof(builtintable_entry) - 1;
+
+ first = builtintable_automatic;
+ last = builtintable_automatic + entries;
+
+ while (entries > 0) {
+ half = entries / 2;
+ middle = first + half;
+
+ if (middle->opcode < opcode) {
+ first = middle + 1;
+ entries -= half + 1;
+ } else
+ entries = half;
+ }
+
+ return (first != last ? first : NULL);
+}
+