DEADSOFTWARE

Patched for Linux
authorDeaDDooMER <deaddoomer@deadsoftware.ru>
Sat, 1 Nov 2014 14:18:19 +0000 (17:18 +0300)
committerDeaDDooMER <deaddoomer@deadsoftware.ru>
Sat, 1 Nov 2014 14:18:19 +0000 (17:18 +0300)
88 files changed:
LICENSE.txt [new file with mode: 0644]
MPC.3.5.LINUX/Linux/mp3CC [new file with mode: 0644]
MPC.3.5.LINUX/classgen/bytecode.c [new file with mode: 0644]
MPC.3.5.LINUX/classgen/bytecode.h [new file with mode: 0644]
MPC.3.5.LINUX/classgen/classgen.c [new file with mode: 0644]
MPC.3.5.LINUX/classgen/classgen.h [new file with mode: 0644]
MPC.3.5.LINUX/classgen/constant_pool.c [new file with mode: 0644]
MPC.3.5.LINUX/classgen/constant_pool.h [new file with mode: 0644]
MPC.3.5.LINUX/classgen/preverify.c [new file with mode: 0644]
MPC.3.5.LINUX/classgen/preverify.h [new file with mode: 0644]
MPC.3.5.LINUX/lex/lex.yy.c [new file with mode: 0644]
MPC.3.5.LINUX/lex/tokens.h [new file with mode: 0644]
MPC.3.5.LINUX/main/main.c [new file with mode: 0644]
MPC.3.5.LINUX/mp3CC.cbp [new file with mode: 0644]
MPC.3.5.LINUX/mp3CC.depend [new file with mode: 0644]
MPC.3.5.LINUX/mp3CC.layout [new file with mode: 0644]
MPC.3.5.LINUX/parser/parser.c [new file with mode: 0644]
MPC.3.5.LINUX/parser/parser.h [new file with mode: 0644]
MPC.3.5.LINUX/parser/stdpas.c [new file with mode: 0644]
MPC.3.5.LINUX/parser/stdpas.h [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/README.TXT [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/check_class.c [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/check_code.c [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/check_code.h [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/classloader.c [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/classresolver.c [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/convert_md.c [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/convert_md.h [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/file.c [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/inlinejsr.c [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/jar.c [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/jar.h [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/jar_support.c [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/jarint.h [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/jartables.h [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/locale_md.h [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/main.c [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/oobj.h [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/opcodes.h [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/opcodes.in_out [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/opcodes.init [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/opcodes.length [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/path.h [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/path_md.h [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/signature.h [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/stubs.c [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/sys_api.h [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/sys_support.c [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/sysmacros_md.h [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/tree.h [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/typecodes.h [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/typedefs.h [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/typedefs_md.h [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/utf.c [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/utf.h [new file with mode: 0644]
MPC.3.5.LINUX/preverifier/util.c [new file with mode: 0644]
MPC.3.5.LINUX/readme.txt [new file with mode: 0644]
MPC.3.5.LINUX/structures/block.c [new file with mode: 0644]
MPC.3.5.LINUX/structures/block.h [new file with mode: 0644]
MPC.3.5.LINUX/structures/identifier.c [new file with mode: 0644]
MPC.3.5.LINUX/structures/identifier.h [new file with mode: 0644]
MPC.3.5.LINUX/structures/name_table.c [new file with mode: 0644]
MPC.3.5.LINUX/structures/name_table.h [new file with mode: 0644]
MPC.3.5.LINUX/structures/string_list.c [new file with mode: 0644]
MPC.3.5.LINUX/structures/string_list.h [new file with mode: 0644]
MPC.3.5.LINUX/structures/type.c [new file with mode: 0644]
MPC.3.5.LINUX/structures/type.h [new file with mode: 0644]
MPC.3.5.LINUX/structures/type_list.c [new file with mode: 0644]
MPC.3.5.LINUX/structures/type_list.h [new file with mode: 0644]
MPC.3.5.LINUX/structures/unit.c [new file with mode: 0644]
MPC.3.5.LINUX/structures/unit.h [new file with mode: 0644]
MPC.3.5.LINUX/util/error.c [new file with mode: 0644]
MPC.3.5.LINUX/util/error.h [new file with mode: 0644]
MPC.3.5.LINUX/util/memory.c [new file with mode: 0644]
MPC.3.5.LINUX/util/memory.h [new file with mode: 0644]
MPC.3.5.LINUX/util/strings.c [new file with mode: 0644]
MPC.3.5.LINUX/util/strings.h [new file with mode: 0644]
MPS.3.1/F.java [new file with mode: 0644]
MPS.3.1/FS.java [new file with mode: 0644]
MPS.3.1/FW.java [new file with mode: 0644]
MPS.3.1/H.java [new file with mode: 0644]
MPS.3.1/P.java [new file with mode: 0644]
MPS.3.1/README.txt [new file with mode: 0644]
MPS.3.1/RS.java [new file with mode: 0644]
MPS.3.1/Real.java [new file with mode: 0644]
MPS.3.1/S.java [new file with mode: 0644]
MPS.3.1/SM.java [new file with mode: 0644]
README.txt [new file with mode: 0644]

diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644 (file)
index 0000000..e3133e8
--- /dev/null
@@ -0,0 +1,17 @@
+\r
+\r
+    MIDletPascal compiler\r
+    Copyright (C) 2009-2013 MIDletPascal project\r
+\r
+    This program is free software: you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation, either version 3 of the License, or\r
+    (at your option) any later version.\r
+\r
+    This program is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
diff --git a/MPC.3.5.LINUX/Linux/mp3CC b/MPC.3.5.LINUX/Linux/mp3CC
new file mode 100644 (file)
index 0000000..de8ba17
Binary files /dev/null and b/MPC.3.5.LINUX/Linux/mp3CC differ
diff --git a/MPC.3.5.LINUX/classgen/bytecode.c b/MPC.3.5.LINUX/classgen/bytecode.c
new file mode 100644 (file)
index 0000000..847d9c3
--- /dev/null
@@ -0,0 +1,145 @@
+/********************************************************************
+       
+       bytecode.c - funcions for creating the bytecode
+
+  Niksa Orlic, 2004-06-11
+
+********************************************************************/
+
+#include "bytecode.h"
+#include "../util/error.h"
+//#include "../util/message.h"
+#include "../util/memory.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+//#include "../main/static_entry.h"
+
+extern int linenum;
+
+//extern FILE* yyin;
+//extern int fileSize;
+
+/*
+       Allocate a new bytecode
+*/
+bytecode *bytecode_create()
+{
+       bytecode *new_bytecode = (bytecode*) mem_alloc(sizeof(bytecode));
+
+       if (new_bytecode == NULL)
+               die(1);
+
+       new_bytecode->bytecode_allocated_size = 0;
+       new_bytecode->bytecode_pos = 0;
+
+       return new_bytecode;
+}
+
+/*
+       Destroy the bytecode
+*/
+void bytecode_destroy(bytecode *code)
+{
+       if (code->bytecode_allocated_size > 0)
+               mem_free(code->bytecode);
+
+       mem_free(code);
+}
+
+bytecode *bytecode_duplicate(bytecode *code)
+{
+       bytecode *new_bytecode = bytecode_create();
+       bytecode_append_bytecode(new_bytecode, code);
+
+       return new_bytecode;
+}
+
+
+/*
+       Appends a single byte to the bytecode
+*/
+void bytecode_append(bytecode *code, char c)
+{
+       //if (c == swap$)
+       //{
+       //      int a = 1;
+       //}
+       if (code->bytecode_pos == code->bytecode_allocated_size)
+       {
+               if (code->bytecode_allocated_size == 0)
+                       code->bytecode = (char*) mem_alloc(128);
+               else
+                       code->bytecode = (char*) mem_realloc(code->bytecode, 
+                                                        code->bytecode_allocated_size + 128);
+               
+               if (code->bytecode == NULL)
+                       die(1);
+
+               code->bytecode_allocated_size += 128;
+       }
+
+       code->bytecode[code->bytecode_pos] = c;
+       code->bytecode_pos ++;
+}
+
+/*
+       Append one bytecode to another.
+*/
+void bytecode_append_bytecode(bytecode *dest, bytecode *src)
+{
+       if (src->bytecode_pos == 0)
+               return;
+
+       if (dest->bytecode_allocated_size == 0)
+       {
+               dest->bytecode_allocated_size += src->bytecode_pos;
+               dest->bytecode = (char*) mem_alloc(dest->bytecode_allocated_size);
+       }
+       else
+       {
+               dest->bytecode_allocated_size += src->bytecode_pos;
+               dest->bytecode = (char*) mem_realloc(dest->bytecode, dest->bytecode_allocated_size);
+       }
+
+       if (dest->bytecode == NULL)
+               die(1);
+
+       memcpy(dest->bytecode + dest->bytecode_pos, src->bytecode, src->bytecode_pos);
+       dest->bytecode_pos += src->bytecode_pos;
+}
+
+/*
+       Appends a short int to the bytecode
+*/
+void bytecode_append_short_int(bytecode *code, short int s)
+{
+       char ch;
+
+       ch = (char) (s >> 8);
+       bytecode_append(code, ch);
+       
+       ch = (char) s;
+       bytecode_append(code, ch);
+}
+
+/*
+       Appends a long int to the bytecode
+*/
+void bytecode_append_long_int(bytecode *code, long int l)
+{
+       char ch;
+
+       ch = (char) (l >> 24);
+       bytecode_append(code, ch);
+
+       ch = (char) (l >> 16);
+       bytecode_append(code, ch);
+
+       ch = (char) (l >> 8);
+       bytecode_append(code, ch);
+       
+       ch = (char) l;
+       bytecode_append(code, ch);
+}
diff --git a/MPC.3.5.LINUX/classgen/bytecode.h b/MPC.3.5.LINUX/classgen/bytecode.h
new file mode 100644 (file)
index 0000000..587f091
--- /dev/null
@@ -0,0 +1,235 @@
+/********************************************************************
+       
+       bytecode.h - methods for handling the bytecode
+
+  Niksa Orlic, 2004-05-22
+
+********************************************************************/
+
+struct bytecode_struct
+{
+       int bytecode_pos;
+       int bytecode_allocated_size;
+       char *bytecode;
+};
+
+typedef struct bytecode_struct bytecode;
+
+bytecode *bytecode_create();
+void bytecode_destroy(bytecode *code);
+bytecode *bytecode_duplicate(bytecode*);
+
+void bytecode_append(bytecode *code, char c);
+void bytecode_append_short_int(bytecode *code, short int s);
+void bytecode_append_long_int(bytecode *code, long int l);
+void bytecode_append_bytecode(bytecode *dest, bytecode *src);
+
+/* Java bytecode mnemonics defines */
+enum Java_mnemonics
+{
+       nop$                            = 0x00,
+       aconst_null$,
+       iconst_m1$,
+       iconst_0$,
+       iconst_1$,
+       iconst_2$,
+       iconst_3$,
+       iconst_4$,
+       iconst_5$,
+       lconst_0$,
+       lconst_1$,
+       fconst_0$,
+       fconst_1$,
+       fconst_2$,
+       dconst_0$,
+       dconst_1$,
+       bipush$,
+       sipush$,
+       ldc$,
+       ldc_w$,
+       ldc2_w$,
+       iload$,
+       lload$,
+       fload$,
+       dload$,
+       aload$,
+       iload_0$,
+       iload_1$,
+       iload_2$,
+       iload_3$,
+       lload_0$,
+       lload_1$,
+       lload_2$,
+       lload_3$,
+       fload_0$,
+       fload_1$,
+       fload_2$,
+       fload_3$,
+       dload_0$,
+       dload_1$,
+       dload_2$,
+       dload_3$,
+       aload_0$,
+       aload_1$,
+       aload_2$,
+       aload_3$,
+       iaload$,
+       laload$,
+       faload$,
+       daload$,
+       aaload$,
+       baload$,
+       caload$,
+       saload$,
+       istore$,
+       lstore$,
+       fstore$,
+       dstore$,
+       astore$,
+       istore_0$,
+       istore_1$,
+       istore_2$,
+       istore_3$,
+       lstore_0$,
+       lstore_1$,
+       lstore_2$,
+       lstore_3$,
+       fstore_0$,
+       fstore_1$,
+       fstore_2$,
+       fstore_3$,
+       dstore_0$,
+       dstore_1$,
+       dstore_2$,
+       dstore_3$,
+       astore_0$,
+       astore_1$,
+       astore_2$,
+       astore_3$,
+       iastore$,
+       lastore$,
+       fastore$,
+       dastore$,
+       aastore$,
+       bastore$,
+       castore$,
+       sastore$,
+       pop$,
+       pop2$,
+       dup$,
+       dup_x1$,
+       dup_x2$,
+       dup2$,
+       dup2_x1$,
+       dup2_x2$,
+       swap$,
+       iadd$,
+       ladd$,
+       fadd$,
+       dadd$,
+       isub$,
+       lsub$,
+       fsub$,
+       dsub$,
+       imul$,
+       lmul$,
+       fmul$,
+       dmul$,
+       idiv$,
+       ldiv$,
+       fdiv$,
+       ddiv$,
+       irem$,
+       lrem$,
+       frem$,
+       drem$,
+       ineg$,
+       lneg$,
+       fneg$,
+       dneg$,
+       ishl$,
+       lshl$,
+       ishr$,
+       lshr$,
+       iushr$,
+       lushr$,
+       iand$,
+       land$,
+       ior$,
+       lor$,
+       ixor$,
+       lxor$,
+       iinc$,
+       i2l$,
+       i2f$,
+       i2d$,
+       l2i$,
+       l2f$,
+       l2d$,
+       f2i$,
+       f2l$,
+       f2d$,
+       d2i$,
+       d2l$,
+       d2f$,
+       i2b$,
+       i2c$,
+       i2s$,
+       lcmp$,
+       fcmpl$,
+       fcmpg$,
+       dcmpl$,
+       dcmpg$,
+       ifeq$,
+       ifne$,
+       iflt$,
+       ifge$,
+       ifgt$,
+       ifle$,
+       if_icmpeq$,
+       if_icmpne$,
+       if_icmplt$,
+       if_icmpge$,
+       if_icmpgt$,
+       if_icmple$,
+       if_acmpeq$,
+       if_acmpne$,
+       goto$,
+       jsr$,
+       ret$,
+       tableswitch$,
+       lookupswitch$,
+       ireturn$,
+       lreturn$,
+       freturn$,
+       dreturn$,
+       areturn$,
+       return$,
+       getstatic$,
+       putstatic$,
+       getfield$,
+       putfield$,
+       invokevirtual$,
+       invokespecial$,
+       invokestatic$,
+       invokeinterface$,
+       xxxunusedxxx1$,
+       new$,
+       newarray$,
+       anewarray$,
+       arraylength$,
+       athrow$,
+       checkcast$,
+       instanceof$,
+       monitorenter$,
+       monitorexit$,
+       wide$,
+       multianewarray$,
+       ifnull$,
+       ifnonnull$,
+       goto_w$,
+       jsr_w$,
+
+       break_stmt$ = 250 /* used internally by the parser to mark break statment positions */
+};
+
diff --git a/MPC.3.5.LINUX/classgen/classgen.c b/MPC.3.5.LINUX/classgen/classgen.c
new file mode 100644 (file)
index 0000000..32cf178
--- /dev/null
@@ -0,0 +1,645 @@
+/********************************************************************
+
+       classgen.c - methods for creating the .class binary file
+
+  Niksa Orlic, 2004-05-16
+
+********************************************************************/
+
+//#include "../util/message.h"
+#include "../util/error.h"
+#include "../util/strings.h"
+#include "../structures/type_list.h"
+#include "../structures/string_list.h"
+#include "../structures/type.h"
+#include "../structures/identifier.h"
+#include "../structures/name_table.h"
+#include "../classgen/bytecode.h"
+#include "../structures/block.h"
+#include "../classgen/constant_pool.h"
+#include "../classgen/preverify.h"
+#include "../util/memory.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "classgen.h"
+
+extern char* output_path;
+extern int linenum;
+
+extern int detect_units_only;
+
+extern constant_pool *constants;
+extern int constant_pool_size;
+
+//extern int usesFloat;
+extern int mathType;
+
+char class_name[16];
+
+/*
+       Creates a class file for pascal record.
+*/
+void create_record_class(type *record)
+{
+       char class_file_name[16];
+       char *output_file_name;
+       char copy_sig[64];
+
+       FILE *record_file;
+
+       bytecode *init_method;
+       bytecode *copy_method;
+
+       /* save the previous constant pool state */
+       constant_pool *global_cp;
+       int global_cp_count;
+
+       global_cp = constants;
+       global_cp_count = constant_pool_size;
+
+       constants = NULL;
+       constant_pool_size = 0;
+
+       /* check for consistency */
+       if (record->type_class != record_type)
+               die(12);
+
+       sprintf(class_name, "R_%d", record->unique_record_ID);
+       sprintf(class_file_name, "%s.class", class_name);
+
+    if (!detect_units_only)
+        requires(3, class_file_name);
+
+       output_file_name = (char*) mem_alloc(strlen(output_path) +
+                                                                         strlen(class_file_name) + 5);
+       if (output_file_name == NULL)
+               die (1);
+
+    #ifdef WIN32
+       sprintf(output_file_name, "%s\\%s", output_path, class_file_name);
+       #endif
+       #ifdef UNIX
+       sprintf(output_file_name, "%s/%s", output_path, class_file_name);
+       #endif
+       record_file = fopen(output_file_name, "wb");
+       mem_free(output_file_name);
+
+       if (record_file == NULL)
+               die(3);
+
+       /* write the class file header */
+       create_class_file_header(record_file);
+
+       /* add some stuff into the constant pool */
+       cp_add_class(class_name);
+       cp_add_class("java/lang/Object");
+       cp_add_utf8("<init>");
+       cp_add_utf8("()V");
+       cp_add_utf8("Code");
+       cp_add_utf8("Copy");
+       sprintf(copy_sig, "(LR_%d;)LR_%d;", record->unique_record_ID, record->unique_record_ID);
+       cp_add_utf8(copy_sig);
+
+       create_record_fields(record);
+
+       /* create the bytecode for the init method */
+       init_method = bytecode_create();
+       create_init_method(record, init_method);
+
+       /* create the bytecode for the copy method */
+       copy_method = bytecode_create();
+       create_copy_method(record, copy_method);
+
+       /* write the constant pool into the file */
+       write_constant_pool(record_file);
+
+       /* write the access flags, set to ACC_PUBLIC and ACC_SUPER */
+       write_short_int(record_file, 0x0021);
+
+       /* write the index to constat pool with this class description */
+       write_short_int(record_file, cp_add_class(class_name));
+
+       /* write the index to constant pool with the super class description */
+       write_short_int(record_file, cp_add_class("java/lang/Object"));
+
+       /* we have no interfaces */
+       write_short_int(record_file, 0);
+
+       /* write the fields */
+       write_short_int(record_file, (short) type_list_length(record->elements_type_list));
+       write_record_fields(record_file, record);
+
+       /* we have <init> and Copy method */
+       write_short_int(record_file, 2);
+
+       /* write the init method */
+       write_init_method(record_file, init_method);
+
+       /* write the copy method */
+       write_copy_method(record, record_file, copy_method);
+
+       /* we have no attributes */
+       write_short_int(record_file, 0);
+
+       fclose(record_file);
+
+
+       /* restore the constant pool */
+       constants = global_cp;
+       constant_pool_size = global_cp_count;
+}
+
+
+/*
+       Writes a class file header into the output file
+*/
+void create_class_file_header(FILE *class_file)
+{
+       char magic[4] = { (char)0xCA, (char)0xFE, (char)0xBA, (char)0xBE };
+
+       fwrite(magic, 1, 4, class_file);
+
+       /* Write the minor version number 3 */
+       write_short_int(class_file, 0x0003);
+
+       /* Wrte the major version number 45 */
+       write_short_int(class_file, 0x002d);
+}
+
+
+/*
+       Creates entries into constant pool with names and types of
+       the elements of the structure.
+*/
+void create_record_fields(type *record)
+{
+       string_list *names;
+       type_list *types;
+       char descriptor[128];
+
+       names = record->elements_name_list;
+       types = record->elements_type_list;
+
+       while (names != NULL)
+       {
+               if (names->data != NULL)
+               {
+                       lowercase(names->data->cstr);
+                       get_field_descriptor(types->data, descriptor);
+                       cp_add_nameandtype(names->data->cstr, descriptor);
+               }
+
+               names = names->next;
+               types = types->next;
+       }
+}
+
+
+/*
+       Writes the fields from the record into the
+       class file.
+*/
+void write_record_fields(FILE *class_file, type *record)
+{
+       string_list *names;
+       type_list *types;
+       char descriptor[128];
+       int field_num = 0;
+
+       names = record->elements_name_list;
+       types = record->elements_type_list;
+
+       while (names != NULL)
+       {
+               if (names->data != NULL)
+               {
+                       /* write the access flags: ACC_PUBLIC */
+                       write_short_int(class_file, 0x0001);
+
+                       /* write the name index */
+                       lowercase(names->data->cstr);
+                       write_short_int(class_file, cp_add_utf8(names->data->cstr));
+
+                       /* write the descriptor index */
+                       get_field_descriptor(types->data, descriptor);
+                       write_short_int(class_file, cp_add_utf8(descriptor));
+
+                       /* we have no attributes */
+                       write_short_int(class_file, 0);
+               }
+
+               names = names->next;
+               types = types->next;
+               field_num ++;
+       }
+}
+
+
+/*
+       Writes a short int in bigendian format. If
+       class_file is NULL, does nothing.
+*/
+void write_short_int(FILE *class_file, short int num)
+{
+       char ch;
+
+       if (class_file == NULL)
+               return;
+
+       ch = (char) (num >> 8);
+       fwrite(&ch, 1, 1, class_file);
+
+       ch = (char) num;
+       fwrite(&ch, 1, 1, class_file);
+}
+
+void write_long_int(FILE *class_file, long int num)
+{
+       char ch;
+
+       if (class_file == NULL)
+               return;
+
+       ch = (char) (num >> 24);
+       fwrite(&ch, 1, 1, class_file);
+
+       ch = (char) (num >> 16);
+       fwrite(&ch, 1, 1, class_file);
+
+       ch = (char) (num >> 8);
+       fwrite(&ch, 1, 1, class_file);
+
+       ch = (char) num;
+       fwrite(&ch, 1, 1, class_file);
+
+}
+
+short int read_short_int(FILE *class_file)
+{
+       short int return_value = 0;
+
+       return_value = fgetc(class_file) << 8;
+       return_value |= (fgetc(class_file) & 0x00FF);
+
+       return return_value;
+}
+
+long int read_long_int(FILE *class_file)
+{
+       long int return_value = 0;
+
+       return_value = fgetc(class_file) << 24;
+       return_value |= (fgetc(class_file) & 0x00FF) << 16;
+       return_value |= (fgetc(class_file) & 0x00FF) << 8;
+       return_value |= (fgetc(class_file) & 0x00FF);
+
+       return return_value;
+}
+
+/*
+       Construct a valid Java field descriptor for a given type.
+*/
+void get_field_descriptor(type *field_type, char *descriptor)
+{
+       switch (field_type->type_class)
+       {
+       case void_type:
+               sprintf(descriptor, "V");
+               break;
+
+       case integer_type:
+       case char_type:
+       case boolean_type:
+               sprintf(descriptor, "I");
+               break;
+
+       case real_type:
+               if (mathType == 1)
+                       sprintf(descriptor, "I");
+               else
+                       sprintf(descriptor, "LReal;");
+               break;
+
+       case string_type:
+               sprintf(descriptor, "Ljava/lang/String;");
+               break;
+
+       case command_type:
+               sprintf(descriptor, "Ljavax/microedition/lcdui/Command;");
+               break;
+
+       case stream_type:
+               sprintf(descriptor, "Ljava/io/InputStream;");
+               break;
+
+       case record_store_type:
+               sprintf(descriptor, "Ljavax/microedition/rms/RecordStore;");
+               break;
+
+       case http_type:
+               sprintf(descriptor, "LH;");
+               break;
+
+       case alert_type:
+               sprintf(descriptor, "Ljavax/microedition/lcdui/AlertType;");
+               break;
+
+       case image_type:
+               sprintf(descriptor, "Ljavax/microedition/lcdui/Image;");
+               break;
+
+       case array_type:
+               {
+                       char element_type[128];
+                       int i, len;
+
+                       get_field_descriptor(field_type->element_type, element_type);
+
+                       len = type_list_length(field_type->dimensions_list);
+                       for(i=0; i < len; i++)
+                       {
+                               descriptor[i] = '[';
+                       }
+
+                       descriptor[len] = '\0';
+
+                       sprintf(descriptor + len, "%s", element_type);
+               }
+               break;
+
+       case record_type:
+               sprintf(descriptor, "LR_%d;", field_type->unique_record_ID);
+
+               break;
+
+       case error_type:
+               break;
+
+       default:
+               die(13);
+       }
+}
+
+/*
+       Creates the <init> method for records.
+*/
+void create_init_method(type *record, bytecode *code)
+{
+       type_list *type_it;
+       string_list *name_it;
+       int counter = 0;
+
+       if (code == NULL)
+               die(1);
+
+       /* create the code */
+       type_it = record->elements_type_list;
+       name_it = record->elements_name_list;
+
+       bytecode_append(code, aload_0$);
+       bytecode_append(code, invokespecial$);
+       bytecode_append_short_int(code, cp_add_methodref("java/lang/Object", "<init>", "()V"));
+
+
+       while (type_it != NULL)
+       {
+               if ((type_it->data != NULL) && (name_it->data != NULL))
+               {
+                       block *code_wrapper;
+                       identifier *type_wrapper;
+
+                       code_wrapper = block_create(NULL, string_create());
+                       code_wrapper->code = code;
+
+                       type_wrapper = identifier_create();
+                       type_wrapper->identifier_class = variable_name;
+                       type_wrapper->variable_type = type_it->data;
+                       type_wrapper->belongs_to_program_block = 1;
+
+                       /* put 'this' to the stack */
+                       bytecode_append(code, aload_0$);
+
+                       /* create the code to initialize the variable */
+                       initialize_variable(code_wrapper, type_wrapper, name_it->data->cstr, 0, class_name);
+
+                       if (type_it->data->type_class == array_type)
+                               add_error_message(446, name_it->data->cstr, "");
+
+                       code_wrapper->code = bytecode_create();
+                       block_destroy(code_wrapper);
+
+                       type_wrapper->variable_type = type_create();
+                       identifier_destroy(type_wrapper);
+               }
+
+               type_it = type_it->next;
+               if (name_it != NULL)
+                       name_it = name_it->next;
+
+               counter ++;
+       }
+
+       bytecode_append(code, return$);
+}
+
+/*
+       Creates the Copy method for records.
+*/
+void create_copy_method(type *record, bytecode *code)
+{
+       char type_name[64];
+
+       type_list *type_it;
+       string_list *name_it;
+       int counter = 0;
+
+       if (code == NULL)
+               die(1);
+
+       sprintf(type_name, "R_%d", record->unique_record_ID);
+
+       /* create the code */
+       type_it = record->elements_type_list;
+       name_it = record->elements_name_list;
+
+       while (type_it != NULL)
+       {
+               if ((type_it->data != NULL) && (name_it->data != NULL))
+               {
+                       lowercase(name_it->data->cstr);
+
+                       if (type_it->data->type_class == record_type)
+                       {
+                               char copy_sig[64];
+                               char type_descriptor[128];
+                               get_field_descriptor(type_it->data, type_descriptor);
+
+                               sprintf(copy_sig, "(LR_%d;)LR_%d;", record->unique_record_ID, record->unique_record_ID);
+
+                               bytecode_append(code, aload_0$);
+                               bytecode_append(code, getfield$);
+                               bytecode_append_short_int(code, cp_add_fieldref(type_name, name_it->data->cstr, type_descriptor));
+
+                               bytecode_append(code, aload_1$);
+                               bytecode_append(code, getfield$);
+                               bytecode_append_short_int(code, cp_add_fieldref(type_name, name_it->data->cstr, type_descriptor));
+
+                               bytecode_append(code, invokevirtual$);
+                               bytecode_append_short_int(code, cp_add_methodref(type_name, "Copy", copy_sig));
+
+                       }
+                       else if (type_it->data->type_class == string_type)
+                       {
+                               bytecode_append(code, aload_0$);
+
+                               bytecode_append(code, aload_1$);
+                               bytecode_append(code, getfield$);
+                               bytecode_append_short_int(code, cp_add_fieldref(type_name, name_it->data->cstr, "Ljava/lang/String;"));
+
+                               bytecode_append(code, new$);
+                               bytecode_append_short_int(code, cp_add_class("java/lang/String"));
+                               bytecode_append(code, dup_x1$);
+                               bytecode_append(code, swap$);
+                               bytecode_append(code, invokespecial$);
+                               bytecode_append_short_int(code, cp_add_methodref("java/lang/String", "<init>", "(Ljava/lang/String;)V"));
+
+                               bytecode_append(code, putfield$);
+                               bytecode_append_short_int(code, cp_add_fieldref(type_name, name_it->data->cstr, "Ljava/lang/String;"));
+                       }
+                       else if ((type_it->data->type_class == real_type) && (mathType != 1))
+                       {
+                               bytecode_append(code, aload_0$);
+
+                               bytecode_append(code, aload_1$);
+                               bytecode_append(code, getfield$);
+                               bytecode_append_short_int(code, cp_add_fieldref(type_name, name_it->data->cstr, "LReal;"));
+
+                               bytecode_append(code, new$);
+                               bytecode_append_short_int(code, cp_add_class("Real"));
+                               bytecode_append(code, dup_x1$);
+                               bytecode_append(code, swap$);
+                               bytecode_append(code, invokespecial$);
+                               bytecode_append_short_int(code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+
+                               bytecode_append(code, putfield$);
+                               bytecode_append_short_int(code, cp_add_fieldref(type_name, name_it->data->cstr, "LReal;"));
+
+                       }
+                       else
+                       {
+                               char type_descriptor[128];
+                               get_field_descriptor(type_it->data, type_descriptor);
+
+                               bytecode_append(code, aload_0$);
+                               bytecode_append(code, aload_1$);
+
+                               bytecode_append(code, getfield$);
+                               bytecode_append_short_int(code, cp_add_fieldref(type_name, name_it->data->cstr, type_descriptor));
+
+                               bytecode_append(code, putfield$);
+                               bytecode_append_short_int(code, cp_add_fieldref(type_name, name_it->data->cstr, type_descriptor));
+                       }
+               }
+
+               type_it = type_it->next;
+               if (name_it != NULL)
+                       name_it = name_it->next;
+
+               counter ++;
+       }
+
+       // return this
+       bytecode_append(code, aload_0$);
+       bytecode_append(code, areturn$);
+}
+
+
+/*
+       Writes the <init> method to the file.
+*/
+void write_init_method(FILE *fp, bytecode *code)
+{
+       /* write the method headers */
+
+       /* write access flags, ACC_PUBLIC  */
+       write_short_int(fp, 0x0001);
+
+       /* write method name '<init>' */
+       write_short_int(fp, cp_add_utf8("<init>"));
+
+       /* write method descriptor '()V' */
+       write_short_int(fp, cp_add_utf8("()V"));
+
+       /* write 1 attribute */
+       write_short_int(fp, 1);
+
+       /* write the Code attribute 'Code' */
+       write_short_int(fp, cp_add_utf8("Code"));
+       write_long_int(fp, code->bytecode_pos + 12);
+
+       /* write the max stack */
+       write_short_int(fp, 10);
+
+       /* max locals for program block */
+       write_short_int(fp, 2);
+
+       /* code length */
+       write_long_int(fp, code->bytecode_pos);
+
+       /* write the code itself */
+       if (fp != NULL)
+               fwrite(code->bytecode, 1, code->bytecode_pos, fp);
+
+       bytecode_destroy(code);
+
+       write_short_int(fp, 0);
+       write_short_int(fp, 0);
+}
+
+/*
+       Writes the Copy method to the file.
+*/
+void write_copy_method(type* record, FILE *fp, bytecode *code)
+{
+       char method_sig[64];
+
+       /* write the method headers */
+
+       /* write access flags, ACC_PUBLIC  */
+       write_short_int(fp, 0x0001);
+
+       /* write method name '<init>' */
+       write_short_int(fp, cp_add_utf8("Copy"));
+
+       /* write method descriptor (record)record */
+       sprintf(method_sig, "(LR_%d;)LR_%d;", record->unique_record_ID, record->unique_record_ID);
+       write_short_int(fp, cp_add_utf8(method_sig));
+
+       /* write 1 attribute */
+       write_short_int(fp, 1);
+
+       /* write the Code attribute 'Code' */
+       write_short_int(fp, cp_add_utf8("Code"));
+       write_long_int(fp, code->bytecode_pos + 12);
+
+       /* write the max stack */
+       write_short_int(fp, 10);
+
+       /* max locals for program block */
+       write_short_int(fp, 2);
+
+       /* code length */
+       write_long_int(fp, code->bytecode_pos);
+
+       /* write the code itself */
+       if (fp != NULL)
+               fwrite(code->bytecode, 1, code->bytecode_pos, fp);
+
+       bytecode_destroy(code);
+
+       write_short_int(fp, 0);
+       write_short_int(fp, 0);
+}
diff --git a/MPC.3.5.LINUX/classgen/classgen.h b/MPC.3.5.LINUX/classgen/classgen.h
new file mode 100644 (file)
index 0000000..f858abb
--- /dev/null
@@ -0,0 +1,31 @@
+/********************************************************************
+       
+       classgen.h - methods for creating the .class binary file
+
+  Niksa Orlic, 2004-05-16
+
+********************************************************************/
+
+
+void create_record_class(type *record_type);
+
+void create_class_file_header(FILE *class_file);
+void write_record_constant_pool(FILE *class_file, type *record);
+void create_record_fields(type *record);
+void write_record_fields(FILE *class_file, type *record);
+void write_constant_pool_class(FILE *class_file, char *class_name);
+void write_constant_pool_utf8(FILE *class_file, char *string);
+void write_constant_pool_fieldref(FILE *class_file, int type_index, int name_index);
+void write_constant_pool_methodref(FILE *class_file, int, int, int);
+void get_field_descriptor(type *field_type, char *descriptor);
+void write_short_int(FILE *class_file, short int num);
+void write_long_int(FILE *class_file, long int num);
+
+short int read_short_int(FILE *class_file);
+long int read_long_int(FILE *class_file);
+
+void create_init_method(type *record, bytecode*);
+void write_init_method(FILE *class_file, bytecode*);
+void create_copy_method(type *record, bytecode*);
+void write_copy_method(type* record, FILE *class_file, bytecode*);
+void initialize_record_variable(bytecode *code, type *variable_type, int fieldref_index, int index);
diff --git a/MPC.3.5.LINUX/classgen/constant_pool.c b/MPC.3.5.LINUX/classgen/constant_pool.c
new file mode 100644 (file)
index 0000000..ee12f04
--- /dev/null
@@ -0,0 +1,449 @@
+/********************************************************************
+
+       constant_pool.c - methods for handling constant pool
+
+  Niksa Orlic, 2004-06-11
+
+********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "constant_pool.h"
+//#include "../util/message.h"
+#include "../util/error.h"
+#include "../util/strings.h"
+#include "../structures/type_list.h"
+#include "../structures/string_list.h"
+#include "../structures/type.h"
+#include "../structures/identifier.h"
+#include "../structures/name_table.h"
+#include "../classgen/bytecode.h"
+#include "../structures/block.h"
+#include "../util/memory.h"
+
+#include "classgen.h"
+
+constant_pool *constants;
+int constant_pool_size = 0;
+
+/*
+       Insert a utf8 string into the constant pool table and return its index in the table.
+*/
+int cp_add_utf8(char *str)
+{
+       int i, j, len;
+       int size = 0;
+       constant_pool *entry;
+
+       /* check if the string already exists in the table */
+       for (i=0; i<constant_pool_size; i++)
+       {
+               if ((constants[i].tag == 1)
+                       && (strcmp(constants[i].data, str) == 0))
+               {
+                       return i+1; /* the indexes for the constant pool are in range 1..N (not zero based) */
+               }
+       }
+
+       /* create a new entry */
+       entry = cp_create_new_entry();
+       entry->tag = 1;
+
+       /* calculate the needeed size for the string */
+       len = strlen(str);
+       for (i=0; i<len; i++)
+       {
+       /*      if ((unsigned char)str[i] > 127)
+                       size += 2;
+               else*/
+                       size ++;
+       }
+
+       entry->data = (char*) mem_alloc(size + 1);
+       entry->data_len = size;
+
+       if (entry->data == NULL)
+               die(1);
+
+       for(i=0, j=0; i<len; i++)
+       {
+       /*      if ((unsigned char)str[i] <= 127)
+               {*/
+                       entry->data[j] = str[i];
+                       j++;
+       /*      }
+               else
+               {
+                       entry->data[j] = (char)0xC2 | (str[i]>>7)&0x01;
+                       j++;
+                       entry->data[j] = (str[i] & 0x3F) | 0x80;
+                       j++;
+               }*/
+       }
+
+       entry->data[j] = '\0';
+
+       return constant_pool_size;
+}
+
+/*
+       Add a string entry into the constant pool.
+*/
+int cp_add_string(char *str)
+{
+       int i;
+       constant_pool *entry;
+
+       /* first add the utf8 constant */
+       int utf8_const = cp_add_utf8(str);
+
+       /* search if the same string already exists */
+       for(i=0; i<constant_pool_size; i++)
+       {
+               if ((constants[i].tag == 8)
+                       && (constants[i].param1 == utf8_const))
+               {
+                       return i+1;
+               }
+       }
+
+       /* create the new entry */
+       entry = cp_create_new_entry();
+       entry->tag = 8;
+       entry->param1 = utf8_const;
+
+       return constant_pool_size;
+}
+
+/*
+       Add an integer into the constant pool.
+*/
+int cp_add_integer(int data)
+{
+       int i;
+       constant_pool *entry;
+
+       /* check if the string already exists in the table */
+       for (i=0; i<constant_pool_size; i++)
+       {
+               if (constants[i].tag == 3)
+               {
+                       int *p_value;
+                       p_value = (int*)(constants[i].data);
+                       if(*p_value == data)
+                               return i+1; /* the indexes for the constant pool are in range 1..N (not zero based) */
+               }
+       }
+
+       /* create a new entry */
+       entry = cp_create_new_entry();
+       entry->tag = 3;
+       entry->data = (char*) mem_alloc(sizeof(int));
+
+       if (entry->data == NULL)
+               die(1);
+
+       *((int*)(entry->data)) = data;
+
+       return constant_pool_size;
+}
+
+/*
+       Add a long constant into the constant pool
+*/
+int cp_add_long(long data)
+{
+       die(18);
+
+       return constant_pool_size;
+}
+
+/*
+       Add a float constant into the constant pool
+*/
+int cp_add_double(double data)
+{
+       die(18);
+
+       return constant_pool_size;
+}
+
+/*
+       Add a double constant into the constant pool
+*/
+int cp_add_float(float data)
+{
+       int i;
+       constant_pool *entry;
+
+       /* check if the string already exists in the table */
+       for (i=0; i<constant_pool_size; i++)
+       {
+               if (constants[i].tag == 6)
+               {
+                       float *p_value;
+                       p_value = (float*)(constants[i].data);
+                       if(*p_value == data)
+                               return i+1; /* the indexes for the constant pool are in range 1..N (not zero based) */
+               }
+       }
+
+       /* create a new entry */
+       entry = cp_create_new_entry();
+       entry->tag = 6;
+       entry->data = (char*) mem_alloc(sizeof(float));
+
+       if (entry->data == NULL)
+               die(1);
+
+       *((float*)(entry->data)) = data;
+
+       return constant_pool_size;
+}
+
+
+/*
+       Adds a class information into the constants pool
+*/
+int cp_add_class(char *class_name)
+{
+       int i;
+       constant_pool *entry;
+
+       /* first add the utf8 constant */
+       int utf8_const = cp_add_utf8(class_name);
+
+       /* search if the same string already exists */
+       for(i=0; i<constant_pool_size; i++)
+       {
+               if ((constants[i].tag == 7)
+                       && (constants[i].param1 == utf8_const))
+               {
+                       return i+1;
+               }
+       }
+
+       /* create the new entry */
+       entry = cp_create_new_entry();
+       entry->tag = 7;
+       entry->param1 = utf8_const;
+
+       return constant_pool_size;
+}
+
+/*
+       Add name and type entry into the constant pool
+*/
+int cp_add_nameandtype(char *name, char *type)
+{
+       int i;
+       int name_index;
+       int type_index;
+       constant_pool *entry;
+
+       /* first add the utf8 constant */
+       name_index = cp_add_utf8(name);
+       type_index = cp_add_utf8(type);
+
+       /* search if the same string already exists */
+       for(i=0; i<constant_pool_size; i++)
+       {
+               if ((constants[i].tag == 12)
+                       && (constants[i].param1 == name_index)
+                       && (constants[i].param2 == type_index))
+               {
+                       return i+1;
+               }
+       }
+
+       /* create the new entry */
+       entry = cp_create_new_entry();
+       entry->tag = 12;
+       entry->param1 = name_index;
+       entry->param2 = type_index;
+
+       return constant_pool_size;
+}
+
+/*
+       Adds the fieldref entry into the constant pool
+*/
+int cp_add_fieldref(char *class_name, char *name, char *type)
+{
+       int i;
+       int class_index;
+       int nameandtype_index;
+       constant_pool *entry;
+
+       /* first add the utf8 constant */
+       class_index = cp_add_class(class_name);
+       nameandtype_index = cp_add_nameandtype(name, type);
+
+       /* search if the same string already exists */
+       for(i=0; i<constant_pool_size; i++)
+       {
+               if ((constants[i].tag == 9)
+                       && (constants[i].param1 == class_index)
+                       && (constants[i].param2 == nameandtype_index))
+               {
+                       return i+1;
+               }
+       }
+
+       /* create the new entry */
+       entry = cp_create_new_entry();
+       entry->tag = 9;
+       entry->param1 = class_index;
+       entry->param2 = nameandtype_index;
+
+       return constant_pool_size;
+}
+
+/*
+       Add the fieldref entry into the constant pool
+*/
+int cp_add_methodref(char *class_name, char *name, char *type)
+{
+       int i;
+       int class_index;
+       int nameandtype_index;
+       constant_pool *entry;
+
+       /* first add the utf8 constant */
+       class_index = cp_add_class(class_name);
+       nameandtype_index = cp_add_nameandtype(name, type);
+
+       /* search if the same string already exists */
+       for(i=0; i<constant_pool_size; i++)
+       {
+               if ((constants[i].tag == 10)
+                       && (constants[i].param1 == class_index)
+                       && (constants[i].param2 == nameandtype_index))
+               {
+                       return i+1;
+               }
+       }
+
+       /* create the new entry */
+       entry = cp_create_new_entry();
+       entry->tag = 10;
+       entry->param1 = class_index;
+       entry->param2 = nameandtype_index;
+
+       return constant_pool_size;
+}
+
+/*
+       Add the interface entry into the constant pool
+*/
+int cp_add_interface(char *class_name, char *name, char *type)
+{
+       int i;
+       int class_index;
+       int nameandtype_index;
+       constant_pool *entry;
+       /* first add the utf8 constant */
+       class_index = cp_add_class(class_name);
+       nameandtype_index = cp_add_nameandtype(name, type);
+       /* search if the same string already exists */
+       for(i=0; i<constant_pool_size; i++)
+       {
+               if ((constants[i].tag == 10) && (constants[i].param1 == class_index) && (constants[i].param2 == nameandtype_index))
+                       return i+1;
+       }
+       /* create the new entry */
+       entry = cp_create_new_entry();
+       entry->tag = 11;
+       entry->param1 = class_index;
+       entry->param2 = nameandtype_index;
+       return constant_pool_size;
+}
+
+/*
+       Creates a new entry in the constant pool.
+*/
+constant_pool *cp_create_new_entry()
+{
+       constant_pool_size ++;
+
+       if (constant_pool_size == 1)
+               constants = (constant_pool*) mem_alloc(sizeof(constant_pool));
+       else
+               constants = (constant_pool*) mem_realloc(constants,
+                                                    sizeof(constant_pool) * constant_pool_size);
+
+       if (constants == NULL)
+               die(1);
+
+       return &constants[constant_pool_size-1];
+}
+
+/*
+       Writes the constant pool to the disk
+*/
+void write_constant_pool(FILE *fp)
+{
+       int i;
+
+       /* write the constant pool count */
+       write_short_int(fp, (short)(constant_pool_size + 1));
+
+       /* write the constant pool entries */
+       for(i=0; i<constant_pool_size; i++)
+       {
+               /* write the tag */
+               char tag = constants[i].tag;
+
+               fwrite(&tag, 1, 1, fp);
+
+               switch (tag)
+               {
+               case 7: /* constant_class */
+                       {
+                               write_short_int(fp, constants[i].param1);
+                       }
+               break;
+
+               case 9:  /* fieldref */
+               case 10: /* methodref */
+               case 12: /* name and type */
+                       {
+                               write_short_int(fp, constants[i].param1);
+                               write_short_int(fp, constants[i].param2);
+                       }
+               break;
+
+               case 8: /* string */
+                       {
+                               write_short_int(fp, constants[i].param1);
+                       }
+               break;
+
+               case 3:  /* integer */
+                       {
+                               write_long_int(fp, *((int*)constants[i].data));
+                       }
+               break;
+
+               case 4: /* float */
+                       {
+                               int *data;
+                               data = (int*) constants[i].data;
+                               write_long_int(fp, *data);
+                       }
+               break;
+
+               case 1: /* Utf-8 */
+                       {
+                               write_short_int(fp, (short) constants[i].data_len);
+                               fwrite(constants[i].data, 1, constants[i].data_len, fp);
+                       }
+               break;
+
+               default:
+                       die(16);
+               }
+       }
+}
diff --git a/MPC.3.5.LINUX/classgen/constant_pool.h b/MPC.3.5.LINUX/classgen/constant_pool.h
new file mode 100644 (file)
index 0000000..4ee9ea5
--- /dev/null
@@ -0,0 +1,33 @@
+/********************************************************************
+
+       constant_pool.h - methods for handling constant pool
+
+  Niksa Orlic, 2004-06-11
+
+********************************************************************/
+
+struct constant_pool_struct
+{
+       unsigned char tag;
+       unsigned short param1;
+       unsigned short param2;
+       char *data;
+       int data_len;
+};
+
+typedef struct constant_pool_struct constant_pool;
+
+int cp_add_string(char *str);
+int cp_add_utf8(char *str);
+int cp_add_class(char *class_name);
+int cp_add_integer(int data);
+int cp_add_long(long data);
+int cp_add_float(float data);
+int cp_add_double(double data);
+int cp_add_fieldref(char *class_name, char *name, char *type);
+int cp_add_methodref(char *class_name, char *name, char *type);
+int cp_add_interface(char *class_name, char *name, char *type);
+int cp_add_nameandtype(char *name, char *type);
+constant_pool *cp_create_new_entry();
+
+void write_constant_pool(FILE *fp);
diff --git a/MPC.3.5.LINUX/classgen/preverify.c b/MPC.3.5.LINUX/classgen/preverify.c
new file mode 100644 (file)
index 0000000..e05337f
--- /dev/null
@@ -0,0 +1,1119 @@
+/********************************************************************
+       
+       preverify.c - methods for preverifing class files
+
+  Niksa Orlic, 2004-05-16
+
+********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+
+//#include "../util/message.h"
+#include "../util/error.h"
+#include "../util/strings.h"
+#include "../structures/type_list.h"
+#include "../structures/string_list.h"
+#include "../structures/type.h"
+#include "../structures/identifier.h"
+#include "../structures/name_table.h"
+#include "constant_pool.h"
+#include "bytecode.h"
+#include "preverify.h"
+#include "../util/error.h"
+//#include "../util/message.h"
+#include "../util/memory.h"
+
+extern constant_pool *constants;
+extern int constant_pool_size;
+
+stack_map_list *pending_list;
+stack_map_list *output_list;
+
+
+stack_map_list *preverify_bytecode(bytecode *code, identifier *block_identifier)
+{
+       stack_map *map;
+       pending_list = NULL;
+       output_list = NULL;
+
+       /* go through the bytecode */
+       map = stack_map_create();
+       map->bytecode_offset = 0;
+       preverify_bytecode_from(map, code, block_identifier);
+       stack_map_destroy(map);
+
+       /* revisit the offsets in the pending list */
+       while (pending_list != NULL)
+       {
+               map = stack_map_list_get(&pending_list);
+               if (map == NULL)
+                       break;
+
+               stack_map_list_append(&output_list, stack_map_duplicate(map));
+               preverify_bytecode_from(map, code, block_identifier);
+               stack_map_destroy(map);
+       }
+
+       output_list = sort_map_list(output_list);
+
+       return output_list;
+}
+
+
+/*
+       Sorts the list according to offsets
+*/
+stack_map_list* sort_map_list(stack_map_list *list)
+{
+       int range = 0;
+
+       stack_map_list *it;
+       stack_map_list *sorted_list = NULL;
+
+       /* repeat until the list is empty */
+       while (list != NULL)
+       {
+               /* find the next smallest number */
+               int smallest = 0x0fffffff;
+
+               it = list;
+               while (it != NULL)
+               {
+                       if ((it->data->bytecode_offset < smallest)
+                               && (it->data->bytecode_offset >= range))
+                               smallest = it->data->bytecode_offset;
+                       it = it->next;
+               }
+
+               if (smallest == 0x0fffffff)
+                       break;
+
+               range = smallest + 1;
+
+               /* extract the smallest number into the output list */
+               it = list;
+               while (it != NULL)
+               {
+                       if (it->data->bytecode_offset == smallest)
+                       {
+                               stack_map_list_append(&sorted_list, it->data);
+
+                               break;
+                       }                       
+                       it = it->next;
+               }
+
+       }
+
+       return sorted_list;
+}
+
+
+/*
+       Preverifies the bytecode starting with the given stackmap
+*/
+void preverify_bytecode_from(stack_map *map, bytecode *code, identifier *block_identifier)
+{
+       int offset;
+       offset = map->bytecode_offset;
+
+       while (preverify_consume_bytecode(code, map, &offset, block_identifier))
+       {
+               /* do nothing */
+       }
+}
+
+
+/*
+       Reads one bytecode and updates stack map. Returns 0 if
+       'return' bytocode is found, or 1 otherwise.
+
+       It seems that most of the jumps have nothing on the stack. The few 
+       jumps that have something on the stack will only have integers.
+*/
+int preverify_consume_bytecode(bytecode *code, stack_map *map, int *offset, identifier *block_identifier)
+{
+       unsigned char opcode = code->bytecode[*offset];
+       switch ((unsigned char)(code->bytecode[*offset]))
+       {
+       case nop$: 
+               (*offset) ++; 
+               break;
+
+       case aconst_null$: 
+               (*offset) ++;
+               stack_map_push_entry(map, ITEM_Null, 0);
+               break;
+
+       case iconst_m1$:
+       case iconst_0$:
+       case iconst_1$:
+       case iconst_2$:
+       case iconst_3$:
+       case iconst_4$:
+       case iconst_5$:
+               (*offset) ++;
+               stack_map_push_entry(map, ITEM_Integer, 0);
+               break;
+
+       case lconst_0$:
+       case lconst_1$:
+               (*offset) ++;
+               stack_map_push_entry(map, ITEM_Long, 0);
+               break;
+
+       case bipush$:
+               (*offset) += 2;
+               stack_map_push_entry(map, ITEM_Integer, 0);
+               break;
+
+       case sipush$:
+               (*offset) += 3;
+               stack_map_push_entry(map, ITEM_Integer, 0);
+               break;
+
+       case iload$:
+               (*offset) += 2;
+               stack_map_push_entry(map, ITEM_Integer, 0);
+               break;
+
+       case lload$:
+               (*offset) += 2;
+               stack_map_push_entry(map, ITEM_Long, 0);
+               break;
+
+       case iload_0$:
+       case iload_1$:
+       case iload_2$:
+       case iload_3$:
+               (*offset) ++;
+               stack_map_push_entry(map, ITEM_Integer, 0);
+               break;
+
+       case lload_0$:
+       case lload_1$:
+       case lload_2$:
+       case lload_3$:
+               (*offset) ++;
+               stack_map_push_entry(map, ITEM_Long, 0);
+               break;
+
+       case iaload$:
+       case baload$:
+       case caload$:
+       case saload$:
+               (*offset) ++;
+               stack_entry_destroy(stack_map_pop(map));
+               stack_entry_destroy(stack_map_pop(map));
+               stack_map_push_entry(map, ITEM_Integer, 0);
+               break;
+
+       case laload$:
+               (*offset) ++;
+               stack_entry_destroy(stack_map_pop(map));
+               stack_entry_destroy(stack_map_pop(map));
+               stack_map_push_entry(map, ITEM_Long, 0);
+               break;
+
+       case istore$:
+       case lstore$:
+       case astore$:
+               (*offset) += 2;
+               stack_entry_destroy(stack_map_pop(map));
+               break;
+
+       case istore_0$:
+       case istore_1$:
+       case istore_2$:
+       case istore_3$:
+       case lstore_0$:
+       case lstore_1$:
+       case lstore_2$:
+       case lstore_3$:
+       case astore_0$:
+       case astore_1$:
+       case astore_2$:
+       case astore_3$:
+               (*offset) ++;
+               stack_entry_destroy(stack_map_pop(map));
+               break;
+
+       case iastore$:
+       case lastore$:
+       case fastore$:
+       case dastore$:
+       case aastore$:
+       case bastore$:
+       case castore$:
+       case sastore$:
+               (*offset) ++;
+               stack_entry_destroy(stack_map_pop(map));
+               stack_entry_destroy(stack_map_pop(map));
+               stack_entry_destroy(stack_map_pop(map));
+               break;
+
+       case pop$:
+               (*offset) ++;
+               stack_entry_destroy(stack_map_pop(map));
+               break;
+
+       case pop2$:
+               (*offset) ++;
+               stack_entry_destroy(stack_map_pop(map));
+               stack_entry_destroy(stack_map_pop(map));
+               break;
+
+       case dup$:
+               {
+                       stack_entry *entry;
+                       (*offset) ++;
+                       entry = stack_map_pop(map);
+                       stack_map_push(map, entry);
+                       stack_map_push(map, entry);
+                       stack_entry_destroy(entry);
+               }
+               break;
+
+       case dup_x1$:
+       case dup_x2$:
+               {
+                       stack_entry *e1, *e2;
+                       (*offset) ++;
+                       e1 = stack_map_pop(map);
+                       e2 = stack_map_pop(map);
+                       stack_map_push(map, e1);
+                       stack_map_push(map, e2);
+                       stack_map_push(map, e1);
+                       stack_entry_destroy(e1);
+                       stack_entry_destroy(e2);
+               }
+               break;
+
+       case dup2_x1$:
+               {
+                       stack_entry *e1, *e2, *e3;
+                       (*offset) ++;
+                       e1 = stack_map_pop(map);
+                       e2 = stack_map_pop(map);
+                       e3 = stack_map_pop(map);
+                       stack_map_push(map, e2);
+                       stack_map_push(map, e1);
+                       stack_map_push(map, e3);
+                       stack_map_push(map, e2);
+                       stack_map_push(map, e1);                        
+                       stack_entry_destroy(e1);
+                       stack_entry_destroy(e2);
+                       stack_entry_destroy(e3);
+               }
+               break;
+
+       case swap$:
+               {
+                       stack_entry *e1, *e2;
+                       (*offset) ++;
+                       e1 = stack_map_pop(map);
+                       e2 = stack_map_pop(map);
+                       stack_map_push(map, e1);
+                       stack_map_push(map, e2);
+                       stack_entry_destroy(e1);
+                       stack_entry_destroy(e2);
+               }
+               break;
+
+       case iadd$:
+       case ladd$:
+       case fadd$:
+       case dadd$:
+       case isub$:
+       case lsub$:
+       case fsub$:
+       case dsub$:
+       case imul$:
+       case lmul$:
+       case fmul$:
+       case dmul$:
+       case idiv$:
+       case ldiv$:
+       case fdiv$:
+       case ddiv$:
+       case irem$:
+       case lrem$:
+       case frem$:
+       case drem$:
+       case iand$:
+       case land$:
+       case ior$:
+       case lor$:
+       case ixor$:
+       case lxor$:
+               (*offset) ++;
+               stack_entry_destroy(stack_map_pop(map));
+               break;
+
+       case ineg$:
+       case lneg$:
+       case fneg$:
+       case dneg$:
+       case i2b$:
+       case i2c$:
+       case i2s$:
+               (*offset) ++;
+               break;
+
+       case ishl$:
+       case lshl$:
+       case ishr$:
+       case lshr$:
+       case iushr$:
+       case lushr$:
+               (*offset) ++;
+               stack_entry_destroy(stack_map_pop(map));
+               break;
+
+       case iinc$:
+               (*offset) += 3;
+               break;
+
+       case i2l$:
+               (*offset) ++;
+               stack_entry_destroy(stack_map_pop(map));
+               stack_map_push_entry(map, ITEM_Long, 0);
+               break;
+
+       case l2i$:
+               (*offset) ++;
+               stack_entry_destroy(stack_map_pop(map));
+               stack_map_push_entry(map, ITEM_Integer, 0);
+               break;
+
+       case lcmp$:
+       case fcmpl$:
+       case fcmpg$:
+       case dcmpl$:
+       case dcmpg$:
+               (*offset) ++;
+               stack_entry_destroy(stack_map_pop(map));
+               stack_entry_destroy(stack_map_pop(map));
+               stack_map_push_entry(map, ITEM_Integer, 0);
+               break;
+
+       case ifeq$:
+       case ifne$:
+       case iflt$:
+       case ifge$:
+       case ifgt$:
+       case ifle$:
+               (*offset) ++;
+               stack_entry_destroy(stack_map_pop(map));
+               process_jump(map, *offset - 1 + (int)((code->bytecode[*offset] << 8) | (unsigned char)(code->bytecode[(*offset) + 1])));                
+               (*offset) ++;
+               (*offset) ++;
+               break;
+
+       case if_icmpeq$:
+       case if_icmpne$:
+       case if_icmplt$:
+       case if_icmpge$:
+       case if_icmpgt$:
+       case if_icmple$:
+       case if_acmpeq$:
+       case if_acmpne$:
+               (*offset) ++;
+               stack_entry_destroy(stack_map_pop(map));
+               stack_entry_destroy(stack_map_pop(map));
+               process_jump(map, *offset - 1 + (int)((code->bytecode[*offset] << 8) | (unsigned char)(code->bytecode[(*offset) + 1])));                
+               (*offset) ++;
+               (*offset) ++;
+               break;
+
+       case goto$:
+               {
+                       (*offset) ++;
+                       process_jump(map, *offset - 1 + (int)((code->bytecode[*offset] << 8) | (unsigned char)(code->bytecode[(*offset) + 1])));
+                       return 0;
+               }
+               break;
+
+       case ireturn$:
+       case lreturn$:
+       case freturn$:
+       case dreturn$:
+       case areturn$:
+               stack_entry_destroy(stack_map_pop(map));
+       case return$:
+               return 0;
+
+       case aload$:
+               (*offset) += 2;
+               stack_map_push_local(map, block_identifier, (unsigned char) code->bytecode[*offset-1]);
+               break;
+
+       case aload_0$:
+               (*offset) ++;
+               stack_map_push_local(map, block_identifier, 0);
+               break;
+
+       case aload_1$:
+               (*offset) ++;
+               stack_map_push_local(map, block_identifier, 1);
+               break;
+
+       case aload_2$:
+               (*offset) ++;
+               stack_map_push_local(map, block_identifier, 2);
+               break;
+
+       case aload_3$:
+               (*offset) ++;
+               stack_map_push_local(map, block_identifier, 3);
+               break;
+
+       case aaload$:
+               {
+                       char object_class[128];
+                       stack_entry* entry;
+                       int classname_index;
+                       int delta = 1;
+
+                       (*offset) ++;
+                       stack_entry_destroy(stack_map_pop(map));
+
+                       entry = stack_map_pop(map);
+                       classname_index = constants[entry->additional_data - 1].param1 - 1;
+                       strncpy(object_class, constants[classname_index].data, constants[classname_index].data_len);
+                       object_class[constants[classname_index].data_len] = '\0';
+                       
+                       if (object_class[1] == 'L')
+                       {
+                               delta = 2;
+                               object_class[strlen(object_class) - 1] = '\0';
+                       }
+                       stack_entry_destroy(entry);
+                       stack_map_push_entry(map, ITEM_Object, cp_add_class(object_class + delta));
+               }
+               break;
+
+       case tableswitch$:
+       case lookupswitch$:
+               // TODO::
+               break;
+
+       case instanceof$:
+               (*offset) += 3;
+               stack_entry_destroy(stack_map_pop(map));                
+               stack_map_push_entry(map, ITEM_Integer, 0);
+               break;
+
+       case ldc$:
+               (*offset) ++;
+               (*offset) ++;
+               stack_map_push_entry(map, ITEM_Bogus, 0);
+               break;
+
+       case ldc_w$:
+               (*offset) += 3;
+               stack_map_push_entry(map, ITEM_Bogus, 0);
+               break;
+
+       case getstatic$:
+               {
+                       int t;
+                       (*offset) ++;
+                       t = code->bytecode[*offset];
+                       t = t << 8 | (unsigned char)(code->bytecode[(*offset) + 1]);
+                       t = constants[t-1].param2;
+                       t = constants[t-1].param2;
+                       (*offset) += 2;
+                       switch(constants[t-1].data[0])
+                       {
+                       case  'L':
+                       case '[':
+                       {
+                               char *class_name = (char*) mem_alloc(sizeof(char) * strlen(constants[t-1].data));
+                               strcpy(class_name, constants[t-1].data + 1);
+                               class_name[strlen(constants[t-1].data) - 2] = '\0';
+                               stack_map_push_entry(map, ITEM_Object, cp_add_class(class_name));
+                               mem_free(class_name);
+                               break;
+                       }
+       //              case '[':
+       //                      stack_map_push_entry(map, ITEM_Object, t);
+       //                      break;
+                       case 'I':
+                               stack_map_push_entry(map, ITEM_Integer, 0);
+                               break;
+                       default:
+                               stack_map_push_entry(map, ITEM_Bogus, 0);
+                       
+                       }
+               }
+               break;
+
+       case new$:
+               (*offset) += 3;
+               stack_map_push_entry(map, ITEM_Bogus, 0);
+               break;
+
+       case getfield$:
+               (*offset) += 3;
+               break;
+
+       case putstatic$:
+               (*offset) += 3;
+               stack_entry_destroy(stack_map_pop(map));
+               break;
+
+       case putfield$:
+               (*offset) += 3;
+               stack_entry_destroy(stack_map_pop(map));
+               stack_entry_destroy(stack_map_pop(map));
+               break;
+
+       case invokevirtual$:
+       case invokespecial$:
+       case invokestatic$:
+               {
+                       unsigned short int num;
+                       int len, i = 0;
+                       int oldstate, state = 0;
+                       int count = 0;
+                       int isVoid = 0;
+                       char *descriptor;
+                       char *class_name;
+                       int state_machine_table[4][6] = 
+                       {   /*        (   )   L   ;   V   else       */
+                               /* 0 */ { 1, -1, -1, -1, -1, -1  },
+                               /* 1 */ {-1,  2,  3, -1,  1,  1  },
+                               /* 2 */ {-1, -1, -1, -1, -1, -1  },
+                               /* 3 */ { 3,  3,  3,  1,  3,  3  }
+                       };
+
+                       (*offset) ++;
+                       num = (code->bytecode[*offset] << 8) | (unsigned char)(code->bytecode[(*offset) + 1]);
+                       (*offset) += 2;
+
+                       num = constants[num-1].param2;
+                       num = constants[num-1].param2;
+                       len = constants[num-1].data_len;
+                       descriptor = constants[num-1].data;
+                       
+                       while (i < len)
+                       {
+                               oldstate = state;
+
+                               switch (descriptor[i])
+                               {
+                               case '(': state = state_machine_table[state][0]; break;
+                               case ')': state = state_machine_table[state][1]; break;
+                               case 'L': state = state_machine_table[state][2]; break;
+                               case ';': state = state_machine_table[state][3]; break;
+                               case 'V': state = state_machine_table[state][4]; break;
+                               default : state = state_machine_table[state][5]; break;
+                               }
+                               i ++;
+
+                               if ((state == 1) && (oldstate != 0))
+                                       count ++;
+
+                               if (state == 2)
+                               {
+                                       if (descriptor[i] == 'V')
+                                               isVoid = 1;
+
+                                       class_name = (char*) mem_alloc(len);
+
+                                       strcpy(class_name, descriptor + i);
+
+                                       break;
+                               }
+                       }
+
+                       if (opcode != invokestatic$)
+                               stack_entry_destroy(stack_map_pop(map));
+                       while (count > 0)
+                       {
+                               stack_entry_destroy(stack_map_pop(map));
+                               count --;
+                       }
+
+                       if (class_name[0] == 'L')
+                       {
+                               class_name[strlen(class_name) - 1] = '\0';
+                               if (!isVoid)
+                                       stack_map_push_entry(map, ITEM_Object, cp_add_class(class_name+1));
+                       }
+                       else if (class_name[0] == 'I')
+                       {
+                               if (!isVoid)
+                                       stack_map_push_entry(map, ITEM_Integer,0);
+                       }
+                       else
+                       {
+                               if (!isVoid)
+                                       stack_map_push_entry(map, ITEM_Bogus, 0);
+
+                       }
+
+                       mem_free(class_name);
+               }
+               break;
+
+       
+       /*case invokestatic$:
+                               {
+                       unsigned short int num;
+                       int len, i = 0;
+                       int oldstate, state = 0;
+                       int count = 0;
+                       int isVoid = 0;
+                       char *descriptor;
+                       int state_machine_table[4][6] = 
+                       {   /*        (   )   L   ;   V   else       
+                               /* 0  { 1, -1, -1, -1, -1, -1  },
+                               /* 1  {-1,  2,  3, -1,  1,  1  },
+                               /* 2  {-1, -1, -1, -1, -1, -1  },
+                               /* 3  { 3,  3,  3,  1,  3,  3  }
+                       };
+
+                       (*offset) ++;
+                       num = (code->bytecode[*offset] << 8) | (unsigned char)(code->bytecode[(*offset) + 1]);
+                       (*offset) += 2;
+
+                       num = constants[num-1].param2;
+                       num = constants[num-1].param2;
+                       len = constants[num-1].data_len;
+                       descriptor = constants[num-1].data;
+                       
+                       while (i < len)
+                       {
+                               oldstate = state;
+
+                               switch (descriptor[i])
+                               {
+                               case '(': state = state_machine_table[state][0]; break;
+                               case ')': state = state_machine_table[state][1]; break;
+                               case 'L': state = state_machine_table[state][2]; break;
+                               case ';': state = state_machine_table[state][3]; break;
+                               case 'V': state = state_machine_table[state][4]; break;
+                               default : state = state_machine_table[state][5]; break;
+                               }
+                               i ++;
+
+                               if ((state == 1) && (oldstate != 0))
+                                       count ++;
+
+                               if (state == 2)
+                               {
+                                       if (descriptor[i] == 'V')
+                                               isVoid = 1;
+
+                                       break;
+                               }
+                       }
+
+                       while (count > 0)
+                       {
+                               stack_entry_destroy(stack_map_pop(map));
+                               count --;
+                       }
+
+                       if (!isVoid)
+                               stack_map_push_entry(map, ITEM_Bogus, 0);
+               }
+               break;*/
+       
+       
+       case newarray$:
+               (*offset) += 2;
+               break;
+
+       case anewarray$:
+               (*offset) += 3;
+               break;
+
+       case arraylength$:
+               (*offset) ++;
+               stack_entry_destroy(stack_map_pop(map));
+               stack_map_push_entry(map, ITEM_Integer, 0);
+               break;
+       
+       case multianewarray$:
+               {
+                       unsigned int i, t, s;
+                       (*offset) ++;
+                       t = code->bytecode[*offset];
+                       t = t << 8 | (unsigned char)(code->bytecode[(*offset) + 1]);
+                       (*offset) += 2;
+                       i = code->bytecode[*offset];
+                       (*offset) ++;
+
+                       s = i;
+                       while (i>0)
+                       {
+                               stack_entry_destroy(stack_map_pop(map));
+                               i --;
+                       }
+
+                       stack_map_push_entry(map, ITEM_NewObject, *offset - 4);
+                       break;
+               }
+
+       case ifnull$:
+       case ifnonnull$:
+               stack_entry_destroy(stack_map_pop(map));
+               (*offset) ++;
+               process_jump(map, *offset - 1 + (int)((code->bytecode[*offset] << 8) | (unsigned char)(code->bytecode[(*offset) + 1])));
+               (*offset) ++;
+               (*offset) ++;
+               break;
+
+       default:
+               die(22);
+
+       }
+
+       return 1;
+}
+
+
+/*
+       When a branch instruction is found, adds the target offset into the list.
+*/
+void process_jump(stack_map *map, int position)
+{
+       stack_map *new_map;
+
+       /* check if the position is already in the pending or output list */
+       stack_map_list *it;
+       it = pending_list;
+
+       while (it != NULL)
+       {
+               if (it->data->bytecode_offset == position)
+                       return;
+               it = it->next;
+       }
+
+       it = output_list;
+
+       while (it != NULL)
+       {
+               if (it->data->bytecode_offset == position)
+                       return;
+               it = it->next;
+       }
+
+       /* if here, add the offset into the pendign list */
+       new_map = stack_map_duplicate(map);
+       new_map->bytecode_offset = position;
+       stack_map_list_append(&pending_list, new_map);
+}
+
+
+/*
+       Create anew stack_entry object.
+*/
+stack_entry* stack_entry_create()
+{
+       stack_entry *new_entry = (stack_entry*) mem_alloc(sizeof(stack_entry));
+
+       if (new_entry == NULL)
+               die(1);
+
+       return new_entry;
+}
+
+
+/*
+       Delete all data used by stack_entry
+*/
+void stack_entry_destroy(stack_entry *entry)
+{
+       mem_free(entry);
+}
+
+
+/*
+       Create a copy of the stack entry.
+*/
+stack_entry* stack_entry_duplicate(stack_entry *old_entry)
+{
+       stack_entry* new_entry = (stack_entry*) mem_alloc(sizeof(stack_entry));
+
+       if (new_entry == NULL)
+               die(1);
+
+       new_entry->item_type = old_entry->item_type;
+       new_entry->additional_data = old_entry->additional_data;
+
+       return new_entry;
+}
+
+
+/*
+       Create a stackmap object
+*/
+stack_map* stack_map_create()
+{
+       stack_map *new_map = (stack_map*) mem_alloc(sizeof(stack_map));
+
+       if (new_map == NULL)
+               die(1);
+
+       new_map->allocated_number_of_items = 0;
+       new_map->number_of_items = 0;
+
+       return new_map;
+}
+
+
+/*
+       Destroy the stack map
+*/
+void stack_map_destroy(stack_map *map)
+{
+       int i;
+       for (i=0; i<map->number_of_items; i++)
+       {
+               stack_entry_destroy(map->stack[i]);
+       }
+
+       if (map->allocated_number_of_items > 0)
+               mem_free(map->stack);
+       
+       mem_free(map);
+}
+
+
+/*
+       Create a copy of the map
+*/
+stack_map* stack_map_duplicate(stack_map *old_map)
+{
+       int i;
+
+       stack_map *new_map = (stack_map*) mem_alloc(sizeof(stack_map));
+
+       if (new_map == NULL)
+               die(1);
+
+       new_map->number_of_items = old_map->number_of_items;
+       new_map->allocated_number_of_items = old_map->allocated_number_of_items;
+       new_map->bytecode_offset = old_map->bytecode_offset;
+
+       if (old_map->allocated_number_of_items > 0)
+       {
+               new_map->stack = (stack_entry**) mem_alloc(sizeof(stack_entry) * old_map->allocated_number_of_items);
+
+               if (new_map->stack == NULL)
+                       die(1);
+       }
+
+       for (i=0; i<old_map->number_of_items; i++)
+               new_map->stack[i] = stack_entry_duplicate(old_map->stack[i]);
+
+       return new_map;
+}
+
+
+/*
+       Take the top element from the stack
+*/
+stack_entry* stack_map_pop(stack_map* map)
+{
+       stack_entry* top_element;
+
+       top_element = map->stack[map->number_of_items - 1];
+
+       map->number_of_items --;
+
+       return top_element;
+}
+
+
+/*
+       Add a new element to the top of the stack
+*/
+void stack_map_push(stack_map *map, stack_entry *entry)
+{
+       stack_map_push_entry(map, entry->item_type, entry->additional_data);
+}
+
+
+/*
+       Add a new element to the top of the stack.
+*/
+void stack_map_push_entry(stack_map *map, enum stack_item item_type, short int additional_data)
+{
+       stack_entry *new_entry = stack_entry_create();
+       new_entry->item_type = item_type;
+       new_entry->additional_data = additional_data;
+
+       /*
+               Do realloc or malloc if needeed
+       */
+       if (map->allocated_number_of_items <= map->number_of_items)
+       {
+               if (map->allocated_number_of_items == 0)
+               {
+                       map->stack = (stack_entry**) mem_alloc(sizeof(stack_entry*));
+
+                       if (map->stack == NULL)
+                               die(1);
+
+                       map->allocated_number_of_items = 1;
+               }
+               else
+               {
+                       map->stack = (stack_entry**) mem_realloc(map->stack, sizeof(stack_entry*) * (map->allocated_number_of_items + 1));
+
+                       if (map->stack == NULL)
+                               die(1);
+
+                       map->allocated_number_of_items ++;
+               }
+       }
+
+       map->number_of_items ++;
+       map->stack[map->number_of_items - 1] = new_entry;
+}
+
+void stack_map_list_destroy(stack_map_list*);
+
+/*
+       Push a local variable, determine its type
+*/
+void stack_map_push_local(stack_map *map, identifier *block_identifier, int localNum)
+{
+       type *variable_type = NULL;
+       char descriptor[256];
+       type_list *it;
+       int i = 0;
+       
+       if (block_identifier == NULL)
+       {
+               /* if block is the root block, this should never happen */
+               stack_map_push_entry(map, ITEM_Bogus, 0);
+               return;
+       }
+
+       it = block_identifier->parameters;      
+       while (it != NULL)
+       {
+               if (it->data == NULL)
+                       break;
+
+               if (i == localNum)
+               {
+                       variable_type = type_duplicate(it->data);
+                       break;
+               }
+               i ++;
+               it = it->next;
+       }
+
+
+       if ((block_identifier->identifier_class == function_name)
+               && (variable_type == NULL))
+       {
+               if (i == localNum)
+                       variable_type = type_duplicate(block_identifier->return_type);
+               i ++;
+       }
+
+       it = block_identifier->variables;
+       while ((it != NULL) && (variable_type == NULL))
+       {
+               if (it->data == NULL)
+                       break;
+
+               if (i == localNum)
+               {
+                       variable_type = type_duplicate(it->data);
+                       break;
+               }
+               i ++;
+               it = it->next;
+       }
+
+       switch (variable_type->type_class)
+       {
+       case integer_type:
+       case real_type:
+       case char_type:
+       case boolean_type:
+               stack_map_push_entry(map, ITEM_Integer, 0);
+               break;
+
+       case array_type:
+               get_field_descriptor(variable_type, descriptor);
+               stack_map_push_entry(map, ITEM_Object, cp_add_class(descriptor));
+               break;
+
+       default:
+               get_field_descriptor(variable_type, descriptor);
+               descriptor[strlen(descriptor)-1] = '\0';
+               stack_map_push_entry(map, ITEM_Object, cp_add_class(descriptor+1));
+               break;
+       }
+
+       type_destroy(variable_type);
+
+}
+
+/*
+       Append data to the end of the list
+*/
+void stack_map_list_append(stack_map_list **list, stack_map* data)
+{
+       stack_map_list *it;
+
+       if (*list == NULL)
+       {
+               *list = (stack_map_list*)mem_alloc(sizeof(stack_map_list));
+               if (*list == NULL)
+                       die(1);
+
+               (*list)->data = data;
+               (*list)->next = NULL;
+               return;
+       }
+
+       it = *list;
+
+       while (it->next != NULL)
+               it = it->next;
+
+       it->next = (stack_map_list*) mem_alloc(sizeof(stack_map_list));
+
+       if (it->next == NULL)
+               die(1);
+
+       it->next->data = data;
+       it->next->next = NULL;
+
+
+}
+
+
+/*
+       Get the first element from the list     
+*/
+stack_map* stack_map_list_get(stack_map_list **list)
+{
+       stack_map_list *next;
+       stack_map *data;
+
+       if (*list == NULL)
+               return NULL;
+
+       next = (*list)->next;
+       data = (*list)->data;
+
+       *list = next;
+
+       return data;
+}
\ No newline at end of file
diff --git a/MPC.3.5.LINUX/classgen/preverify.h b/MPC.3.5.LINUX/classgen/preverify.h
new file mode 100644 (file)
index 0000000..a92d9fb
--- /dev/null
@@ -0,0 +1,79 @@
+/********************************************************************
+       
+       preverify.h - methods and structures for bytecode preverification
+
+  Niksa Orlic, 2004-08-18
+
+********************************************************************/
+
+
+/*** Preverifier structures ***/
+enum stack_item
+{
+       ITEM_Bogus = 0,
+       ITEM_Integer,
+       ITEM_Float,
+       ITEM_Double,
+       ITEM_Long,
+       ITEM_Null,
+       ITEM_InitObject,
+       ITEM_Object,
+       ITEM_NewObject
+};
+
+struct stack_entry_struct
+{
+       enum stack_item item_type;
+       short int additional_data;
+};
+
+typedef struct stack_entry_struct stack_entry;
+
+struct stack_map_struct
+{
+       int number_of_items;
+       int allocated_number_of_items;
+       stack_entry **stack;
+       int bytecode_offset;
+};
+
+typedef struct stack_map_struct stack_map;
+
+
+
+stack_entry* stack_entry_create();
+void stack_entry_destroy(stack_entry*);
+stack_entry* stack_entry_duplicate(stack_entry*);
+
+stack_map* stack_map_create();
+void stack_map_destroy(stack_map*);
+stack_map* stack_map_duplicate(stack_map*);
+
+stack_entry* stack_map_pop(stack_map*);
+void stack_map_push(stack_map*, stack_entry*);
+void stack_map_push_entry(stack_map*, enum stack_item, short int);
+void stack_map_push_local(stack_map*, identifier*, int);
+
+
+struct stack_map_list_struct
+{
+       struct stack_map_list_struct *next;
+       stack_map *data;
+};
+
+typedef struct stack_map_list_struct stack_map_list;
+
+void stack_map_list_destroy(stack_map_list*);
+
+void stack_map_list_append(stack_map_list**, stack_map*);
+stack_map* stack_map_list_get(stack_map_list**);
+
+
+/*** Preverifier methods ***/
+stack_map_list *preverify_bytecode(bytecode*, identifier *);
+int preverify_consume_bytecode(bytecode*, stack_map*, int *offset, identifier*);
+void process_jump(stack_map *map, int position);
+void preverify_bytecode_from(stack_map*, bytecode*, identifier*);
+stack_map_list* sort_map_list(stack_map_list*);
+
+
diff --git a/MPC.3.5.LINUX/lex/lex.yy.c b/MPC.3.5.LINUX/lex/lex.yy.c
new file mode 100644 (file)
index 0000000..4845c34
--- /dev/null
@@ -0,0 +1,560 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "tokens.h"
+#include "../util/strings.h"
+#include "../util/error.h"
+
+extern int mathType;
+extern int goverify;
+char charbuf[10240];
+char textbuf[10240];
+char strconst[10240];
+int charcount;
+FILE *yyin; //, *yyout;  //source file
+char *yytext;  //current token string
+string *string_constant;
+char char_constant;
+char boolean_constant;
+float real_constant;
+long int integer_constant;
+int linenum;
+int fileSize;
+char c;
+
+void yyrestart(char *fname) {  //FILE *new_file){  //open source file
+       yyin = fopen(fname, "r");
+       if (yyin == NULL) die(5);
+       fseek(yyin, 0, SEEK_END);
+       fileSize = ftell(yyin);
+       fseek(yyin, 0, SEEK_SET);
+       charcount=0;
+    string_constant=&strconst;
+    yytext=&textbuf;
+       linenum=1;
+};
+
+char nextchar(){
+       int d;
+    if (charcount>0){
+               charcount--;
+               return charbuf[charcount];
+       }
+       d=fgetc(yyin);
+       if (d==10) linenum++;
+       if (d==EOF) return '\255';
+       return d;
+}
+
+void backchar(int c){ //put the char back to stream
+       charbuf[charcount]=c;
+       charcount++;
+};
+
+
+int yylex(){  //get token
+       int i,ncount,r;
+       char *p;
+       i = ftell(yyin);
+       compile_progress(i * 100 / fileSize);
+       do {
+               r=0;
+//lab:
+               //if (linenum==1059) {
+               //      linenum=1059;
+               //}
+               p=yytext;
+           *p='\0';
+               c=nextchar();
+               while ((c<=' ')&&(c!='\255')) c=nextchar();
+               if (((c>='A') && (c<='Z')) || ((c>='a') && (c<='z')) || (c=='_')) {
+                       while (((c>='A') && (c<='Z')) || ((c>='a') && (c<='z')) || ((c>='0') && (c<='9')) || (c=='_')) {
+                               *p=c;
+                               p=p+1;
+                               c=nextchar();
+                       }
+                   backchar(c);
+                       *p='\0';
+                       lowercase(yytext);
+                       if (strcmp(yytext, "begin") == 0) return KWD_BEGIN;
+                       if (strcmp(yytext, "end") == 0) return KWD_END;
+                       if (strcmp(yytext, "and") == 0) return OP_AND;
+                       if (strcmp(yytext, "program") == 0) return KWD_PROGRAM;
+                       if (strcmp(yytext, "procedure") == 0) return KWD_PROCEDURE;
+                       if (strcmp(yytext, "function") == 0) return KWD_FUNCTION;
+                       if (strcmp(yytext, "var") == 0) return KWD_VAR;
+                       if (strcmp(yytext, "for") == 0) return KWD_FOR;
+                       if (strcmp(yytext, "to") == 0) return KWD_TO;
+                       if (strcmp(yytext, "downto") == 0) return KWD_DOWNTO;
+                       if (strcmp(yytext, "do") == 0) return KWD_DO;
+                       if (strcmp(yytext, "const") == 0) return KWD_CONST;
+                       if (strcmp(yytext, "type") == 0) return KWD_TYPE;
+                       if (strcmp(yytext, "if") == 0) return KWD_IF;
+                       if (strcmp(yytext, "then") == 0) return KWD_THEN;
+                       if (strcmp(yytext, "else") == 0) return KWD_ELSE;
+                       if (strcmp(yytext, "case") == 0) return KWD_CASE;
+                       if (strcmp(yytext, "of") == 0) return KWD_OF;
+                       if (strcmp(yytext, "while") == 0) return KWD_WHILE;
+                       if (strcmp(yytext, "repeat") == 0) return KWD_REPEAT;
+                       if (strcmp(yytext, "until") == 0) return KWD_UNTIL;
+                       if (strcmp(yytext, "forever") == 0) return KWD_FOREVER;
+                       if (strcmp(yytext, "with") == 0) return KWD_WITH;
+                       if (strcmp(yytext, "packed") == 0) return KWD_PACKED;
+                       if (strcmp(yytext, "array") == 0) return KWD_ARRAY;
+                       if (strcmp(yytext, "or") == 0) return OP_OR;
+                       if (strcmp(yytext, "file") == 0) return KWD_FILE;
+                       if (strcmp(yytext, "set") == 0) return KWD_SET;
+                       if (strcmp(yytext, "record") == 0) return KWD_RECORD;
+                       if (strcmp(yytext, "in") == 0) return OP_IN;
+                       if (strcmp(yytext, "not") == 0) return OP_NOT;
+                       if (strcmp(yytext, "xor") == 0) return OP_XOR;
+                       if (strcmp(yytext, "forward") == 0) return KWD_FORWARD;
+                       if (strcmp(yytext, "break") == 0) return KWD_BREAK;
+                       if (strcmp(yytext, "uses") == 0) return KWD_USES;
+                       if (strcmp(yytext, "unit") == 0) return KWD_UNIT;
+                       if (strcmp(yytext, "interface") == 0) return KWD_INTERFACE;
+                       if (strcmp(yytext, "implementation") == 0) return KWD_IMPLEMENTATION;
+                       if (strcmp(yytext, "initialization") == 0) return KWD_INITIALIZATION;
+                       if (strcmp(yytext, "finalization") == 0) return KWD_FINALIZATION;
+                       if (strcmp(yytext, "mod") == 0) return OP_MOD;
+                       if (strcmp(yytext, "div") == 0) return OP_DIV;
+                       if (strcmp(yytext, "shr") == 0) return OP_SHR; //***
+                       if (strcmp(yytext, "shl") == 0) return OP_SHL; //***
+                       if (strcmp(yytext, "ushr") == 0) return OP_USHR; // j-a-s-d
+                       if (strcmp(yytext, "inline") == 0) return KWD_INLINE; //***?
+                       if (strcmp(yytext, "bytecode") == 0) return KWD_BYTECODE; // j-a-s-d
+                       if (strcmp(yytext, "exit") == 0) return KWD_EXIT; // j-a-s-d
+                       if (strcmp(yytext, "result") == 0) return KWD_RESULT; // j-a-s-d
+                       //////
+                       if (strcmp(yytext, "true") == 0) {boolean_constant=1; return CST_BOOLEAN;}
+                       if (strcmp(yytext, "false") == 0) {boolean_constant=0; return CST_BOOLEAN;}
+                       //////
+                       return IDENTIFIER;
+               } else if ((c>='0') && (c<='9')) {
+                       integer_constant=0;
+                       while ((c>='0') && (c<='9')) {
+                               integer_constant=integer_constant*10+c-48;
+                               c=nextchar();
+                       }
+                       if (c!='.') {backchar(c); return CST_INTEGER;}
+                       c=nextchar();
+                       if (c=='.') {backchar(c);backchar(c);return CST_INTEGER;}
+                       real_constant=(float)integer_constant;
+                       ncount=1;
+                       integer_constant=0;
+                       while ((c>='0') && (c<='9')) {
+                               integer_constant=integer_constant*10+c-48;
+                               ncount++;
+                               c=nextchar();
+                       }
+                       //real_constant=real_constant+(float)integer_constant/(10*ncount);
+                       // j-a-s-d: little but important bugfix, it was corrupting the decimal part
+                       real_constant+=(float)integer_constant/pow(10,--ncount);
+                       /*
+                       i=1;
+                       j=0;
+                       ncount=1;
+                       real_constant=(float)integer_constant;
+                       while (((c>='0') && (c<='9'))) {
+                               j=j*10+c-48;
+                               i++;
+                               c=nextchar();
+                       }
+                       real_constant=real_constant+(j/(10*i));
+                       */
+                       backchar(c);
+                       return CST_REAL;
+               } else if (c=='$') {
+                       int ok;
+                       integer_constant=0;
+                       do {
+                               c=nextchar();
+                               ok=0;
+                               if ((c>='0') && (c<='9')) {
+                                       integer_constant = integer_constant*16+c-48;
+                                       ok=1;
+                               }
+                               if ((c>='A') && (c<='Z')) {
+                                       integer_constant = integer_constant*16+10+c-65;
+                                       ok=1;
+                               }
+                               if ((c>='a') && (c<='z')) {
+                                       integer_constant = integer_constant*16+10+c-97;
+                                       ok=1;
+                               }
+                       } while (ok==1);
+                       backchar(c);
+                       return CST_INTEGER;
+               } else if (c=='/') {
+                       c=nextchar();
+                       if (c=='*') {   // j-a-s-d: C-style /* */ multiline comments support
+                char ch=c;
+                while (!((c=='/')&&(ch=='*'))) {ch=c; c=nextchar();}
+                r=1;
+               } else
+                       if (c=='/') {
+                               while (c!=10) c=nextchar();
+                               //goto lab;
+                               r=1;
+                       } else {
+                               backchar(c);
+                               return OP_SLASH;
+                       }
+               } else if ((c=='\'')||(c=='\"')||(c=='#'))  { // j-a-s-d: C-style double-quoted strings support
+                   char o_c = c;
+                       i=0;
+                       do {
+                               if (c=='#') {
+                                       c=nextchar();
+                                       integer_constant=0;
+                                       if (c=='$') {
+                                               int ok;
+                                               do {
+                                                       c=nextchar();
+                                                       ok=0;
+                                                       if ((c>='0') && (c<='9')) {
+                                                               integer_constant = integer_constant*16+c-48;
+                                                               ok=1;
+                                                       }
+                                                       if ((c>='A') && (c<='Z')) {
+                                                               integer_constant = integer_constant*16+10+c-65;
+                                                               ok=1;
+                                                       }
+                                                       if ((c>='a') && (c<='z')) {
+                                                               integer_constant = integer_constant*16+10+c-97;
+                                                               ok=1;
+                                                       }
+                                               } while (ok==1);
+                                       } else {
+                                               while (((c>='0') && (c<='9'))) {
+                                                       integer_constant=integer_constant*10+c-48;
+                                                       c=nextchar();
+                                               }
+                                       }
+                                       *p=(char)integer_constant;
+                                       p=p+1;
+                                       i=i+1;
+                               } else {
+                                       c=nextchar();
+                                       while (c!=o_c) {
+                                               if (c==10) {
+                                                       int current_token;
+                                                       add_error_message(101, "", "");
+                                                       do {
+                                                               current_token = yylex();
+                                                       } while ((current_token != END_OF_INPUT) && (current_token != SEMI_COLON));
+                                                       break;
+                                               }
+rep:                                   *p=c;
+                                               p=p+1;
+                                               i++;
+                                               c=nextchar();
+                                       }
+                                       c=nextchar();
+                                       if (c==o_c) goto rep;
+                               }
+                       } while ((c==o_c)||(c=='#'));
+                       *p='\0';
+                       backchar(c);
+                       if (i==1) {p=p-1; char_constant=*p; return CST_CHAR;}
+                       string_constant=string_from_cstr(yytext);
+                       return CST_STRING;
+               } else if (c=='+') {
+                   return OP_PLUS;
+               } else if (c=='-') {
+                       return OP_MINUS;
+               } else if (c=='*') {
+               return OP_MULT;
+               } else if (c=='=') {
+               return OP_EQUAL;
+               } else if (c==';') {
+                   return SEMI_COLON;
+               } else if (c==':') {
+                   c=nextchar();
+               if (c=='=') return OP_ASSIGN;
+                   backchar(c);
+                       return COLON;
+               } else if (c=='<') {
+                   c=nextchar();
+                       if (c=='=') return OP_LESS_EQUAL;
+               if (c=='>') return OP_NOT_EQUAL;
+               if (c=='<') return OP_SHL;
+                   backchar(c);
+                       return OP_LESS;
+               } else if (c=='>') {
+                   c=nextchar();
+                       if (c=='=') return OP_GREATER_EQUAL;
+                       if (c=='>') {
+                c=nextchar();
+                if (c=='>') return OP_USHR;
+                backchar(c);
+                           return OP_SHR;
+                       }
+               backchar(c);
+                   return OP_GREATER;
+               } else if (c=='.') {
+                   c=nextchar();
+                       if (c=='.') return DOTDOT;
+               backchar(c);
+                   return DOT;
+               } else if (c=='[') {
+                   return OPEN_SQ_BR;
+               } else if (c==']') {
+                   return CLOSE_SQ_BR;
+               } else if (c=='(') {
+                       char ch;
+                   c=nextchar();
+                       if (c!='*') {
+                               backchar(c);
+                               return OPEN_BR;
+               }
+            ch=c;
+               while (!((c==')')&&(ch=='*'))) {ch=c; c=nextchar();}
+                       //goto lab;
+                       r=1;
+               } else if (c==')') {
+                       return CLOSE_BR;
+               } else if (c==',') {
+               return COMMA;
+               } else if (c=='{') {  //skip comment
+                       c=nextchar();
+                       // j-a-s-d: removing $R and $V to avoid ambiguities
+                       /*
+                       if (c=='$') {
+                               c=nextchar();
+                               if (c=='R') { //real type switch
+                                       c=nextchar();
+                                       if (c=='-') mathType=1;
+                                       if (c=='+') mathType=2;
+                               }
+                               if (c=='V') { //preverify_bytecode switch
+                                       c=nextchar();
+                                       if (c=='-') goverify=0;
+                                       if (c=='+') goverify=1;
+                               }
+                       }
+                       */
+                       while (c!='}') c=nextchar();
+                       //goto lab;
+                       r=1;
+               }
+       } while (r==1);
+       return END_OF_INPUT;
+}
+
+//#define      CST_INTEGER             0
+//#define CST_REAL             1
+//#define CST_BOOLEAN          2
+//#define CST_CHAR             3
+//#define CST_STRING           4
+//
+//#define OP_MOD                       5
+//#define OP_DIV                       6
+//#define OP_PLUS                      7
+//#define OP_MINUS             8
+//#define OP_MULT                      9
+//#define OP_SLASH             10
+//#define OP_EQUAL             11
+//#define SEMI_COLON           18
+//#define COLON                        19
+//#define OP_ASSIGN            20
+//#define OP_LESS                      21
+//#define OP_GREATER           22
+//#define OP_LESS_EQUAL        23
+//#define OP_GREATER_EQUAL 24
+//#define OP_NOT_EQUAL 25
+//#define DOT                          26
+//#define OPEN_SQ_BR           27
+//#define CLOSE_SQ_BR          28
+//#define OPEN_BR                      34
+//#define CLOSE_BR             35
+//#define IDENTIFIER           57
+//#define COMMA                        58
+//#define DOTDOT                       59
+//#define END_OF_INPUT 100
+/*
+#define        CST_INTEGER             0
+#define CST_REAL               1
+#define CST_BOOLEAN            2
+#define CST_CHAR               3
+#define CST_STRING             4
+#define OP_MOD                 5
+#define OP_DIV                 6
+#define OP_PLUS                        7
+#define OP_MINUS               8
+#define OP_MULT                        9
+#define OP_SLASH               10
+#define OP_EQUAL               11
+#define KWD_BEGIN              12
+#define KWD_END                        13
+#define OP_AND                 14
+#define KWD_PROGRAM            15
+#define KWD_PROCEDURE  16
+#define KWD_FUNCTION   17
+#define SEMI_COLON             18
+#define COLON                  19
+#define OP_ASSIGN              20
+#define OP_LESS                        21
+#define OP_GREATER             22
+#define OP_LESS_EQUAL  23
+#define OP_GREATER_EQUAL 24
+#define OP_NOT_EQUAL   25
+#define DOT                            26
+#define OPEN_SQ_BR             27
+#define CLOSE_SQ_BR            28
+#define KWD_VAR                        29
+#define KWD_FOR                        30
+#define KWD_TO                 31
+#define KWD_DOWNTO             32
+#define KWD_DO                 33
+#define OPEN_BR                        34
+#define CLOSE_BR               35
+#define KWD_CONST              36
+#define KWD_TYPE               37
+#define KWD_IF                 38
+#define KWD_THEN               39
+#define KWD_ELSE               40
+#define KWD_CASE               41
+#define KWD_OF                 42
+#define KWD_WHILE              43
+#define KWD_REPEAT             44
+#define KWD_UNTIL              45
+#define KWD_WITH               46
+#define KWD_PACKED             47
+#define KWD_ARRAY              48
+#define OP_OR                  49
+#define KWD_FILE               50
+#define KWD_SET                        51
+#define KWD_RECORD             52
+#define OP_IN                  53
+#define OP_NOT                 54
+#define OP_XOR                 55
+#define KWD_FORWARD            56
+#define IDENTIFIER             57
+#define COMMA                  58
+#define DOTDOT                 59
+#define KWD_BREAK              60
+#define KWD_USES               61
+#define KWD_UNIT               62
+#define KWD_INTERFACE  63
+#define KWD_IMPLEMENTATION 64
+#define KWD_INITIALIZATION 65
+#define KWD_FINALIZATION 66
+#define END_OF_INPUT   100
+
+/*
+"mod" = (OP_MOD);
+"div" = (OP_DIV);
+"+" = (OP_PLUS);
+"-" = (OP_MINUS);
+"*" = (OP_MULT);
+"/" = (OP_SLASH);
+"=" = (OP_EQUAL);
+"begin" = (KWD_BEGIN);
+"end" = (KWD_END);
+"and" = (OP_AND);
+"program" = (KWD_PROGRAM);
+"procedure" = (KWD_PROCEDURE);
+"function" = (KWD_FUNCTION);
+";" = (SEMI_COLON);
+":" = (COLON);
+":=" = (OP_ASSIGN);
+"<" = (OP_LESS);
+">" = (OP_GREATER);
+"<=" = (OP_LESS_EQUAL);
+">=" = (OP_GREATER_EQUAL);
+"<>" = (OP_NOT_EQUAL);
+"." = (DOT);
+".." = (DOTDOT);
+"[" = (OPEN_SQ_BR);
+"]" = (CLOSE_SQ_BR);
+"var" = (KWD_VAR);
+"for" = (KWD_FOR);
+"to" = (KWD_TO);
+"downto" = (KWD_DOWNTO);
+"do" = (KWD_DO);
+"(" = (OPEN_BR);
+")" = (CLOSE_BR);
+"const" = (KWD_CONST);
+"type" = (KWD_TYPE);
+"if" = (KWD_IF);
+"then" = (KWD_THEN);
+"else" = (KWD_ELSE);
+"case" = (KWD_CASE);
+"of" = (KWD_OF);
+"while" = (KWD_WHILE);
+"repeat" = (KWD_REPEAT);
+"until" = (KWD_UNTIL);
+"with" = (KWD_WITH);
+"packed" = (KWD_PACKED);
+"array" = (KWD_ARRAY);
+"or" = (OP_OR);
+"file" = (KWD_FILE);
+"set" = (KWD_SET);
+"record" = (KWD_RECORD);
+"in" = (OP_IN);
+"not" = (OP_NOT);
+"xor" = (OP_XOR);
+"forward" = (KWD_FORWARD);
+"break" = (KWD_BREAK);
+"," = (COMMA);
+"uses" = (KWD_USES);
+"unit" = (KWD_UNIT);
+"interface" = (KWD_INTERFACE);
+"implementation" = (KWD_IMPLEMENTATION);
+"initialization" = (KWD_INITIALIZATION);
+"finalization" = (KWD_FINALIZATION);
+*/
+
+
+/*
+               c=nextchar();
+               i=0;
+rep:
+               while (c!='\'') {
+                       *p=c;
+                       p=p+1;
+                       i++;
+                       c=nextchar();
+               }
+               c=nextchar();
+               if (c=='\'') {*p=c; p=p+1; i=i+1; c=nextchar(); goto rep;}
+               if (c=='#') {
+                       j=0;
+                       c=nextchar();
+                       while (((c>='0') && (c<='9'))) {
+                               j=j*10+c-48;
+                               c=nextchar();
+                       }
+                       *p=(char)j;
+                       p=p+1;
+                       i=i+1;
+                       goto rep;
+               }
+*/
+
+/*
+int getnum() {  //get number
+       int sum;
+       sum=0;
+       ncount=1;
+       if (c=='$') {
+               c=nextchar();
+               do {
+                       if ((c >= 'A') && (c <= 'Z')) {sum = sum*16+10+c-65; ncount=ncount+1;}
+                       else if ((c >= 'a') && (c <= 'z')) {sum = sum*16+10+c-97; ncount=ncount+1;}
+                       else if (('0'>=c) && (c<='9')) {sum = sum*16+c-48; ncount=ncount+1;}
+                       else break;
+                       c=nextchar();
+               } while (1==1);
+       } else {
+               while (('0'>=c) && (c<='9')) {
+                       sum = sum*10+c-48;
+                       ncount=ncount+1;
+                       c=nextchar();
+               }
+       }
+       //if (numcount==1) backchar(255); //bad number
+       return sum;
+}
+*/
diff --git a/MPC.3.5.LINUX/lex/tokens.h b/MPC.3.5.LINUX/lex/tokens.h
new file mode 100644 (file)
index 0000000..be45532
--- /dev/null
@@ -0,0 +1,85 @@
+/********************************************************************
+
+       tokens.h - definitions of token constants used by lexical
+       scanner and the parser.
+
+  Niksa Orlic, 2004-04-19
+
+********************************************************************/
+
+#define        CST_INTEGER             0
+#define CST_REAL               1
+#define CST_BOOLEAN            2
+#define CST_CHAR               3
+#define CST_STRING             4
+#define OP_MOD                 5
+#define OP_DIV                 6
+#define OP_PLUS                        7
+#define OP_MINUS               8
+#define OP_MULT                        9
+#define OP_SLASH               10
+#define OP_SHR                 11
+#define OP_SHL                 12
+#define OP_EQUAL               13
+#define KWD_BEGIN              14
+#define KWD_END                        15
+#define OP_AND                 16
+#define KWD_PROGRAM            17
+#define KWD_PROCEDURE  18
+#define KWD_FUNCTION   19
+#define SEMI_COLON             20
+#define COLON                  21
+#define OP_ASSIGN              22
+#define OP_LESS                        23
+#define OP_GREATER             24
+#define OP_LESS_EQUAL  25
+#define OP_GREATER_EQUAL 26
+#define OP_NOT_EQUAL   27
+#define DOT                            28
+#define OPEN_SQ_BR             29
+#define CLOSE_SQ_BR            30
+#define KWD_VAR                        31
+#define KWD_FOR                        32
+#define KWD_TO                 33
+#define KWD_DOWNTO             34
+#define KWD_DO                 35
+#define OPEN_BR                        36
+#define CLOSE_BR               37
+#define KWD_CONST              38
+#define KWD_TYPE               39
+#define KWD_IF                 40
+#define KWD_THEN               41
+#define KWD_ELSE               42
+#define KWD_CASE               43
+#define KWD_OF                 44
+#define KWD_WHILE              45
+#define KWD_REPEAT             46
+#define KWD_UNTIL              47
+#define KWD_WITH               48
+#define KWD_PACKED             49
+#define KWD_ARRAY              50
+#define OP_OR                  51
+#define KWD_FILE               52
+#define KWD_SET                        53
+#define KWD_RECORD             54
+#define OP_IN                  55
+#define OP_NOT                 56
+#define OP_XOR                 57
+#define KWD_FORWARD            58
+#define IDENTIFIER             59
+#define COMMA                  60
+#define DOTDOT                 61
+#define KWD_BREAK              62
+#define KWD_USES               63
+#define KWD_UNIT               64
+#define KWD_INTERFACE  65
+#define KWD_IMPLEMENTATION 66
+#define KWD_INITIALIZATION 67
+#define KWD_FINALIZATION 68
+#define KWD_INLINE             69
+#define KWD_EXIT               70
+#define KWD_FOREVER            71
+#define KWD_RESULT             72
+#define KWD_BYTECODE   73
+#define OP_USHR                        74
+#define END_OF_INPUT   255
diff --git a/MPC.3.5.LINUX/main/main.c b/MPC.3.5.LINUX/main/main.c
new file mode 100644 (file)
index 0000000..156eaec
--- /dev/null
@@ -0,0 +1,402 @@
+/*
+
+        MIDletPascal-compiler 3.5.IDE (mp3CC.exe)
+        http://sourceforge.net/projects/midletpascal
+
+        MPC.2.0.2:
+            Niksa Orlic
+
+        MPC.3.0.003/009:
+            Artem (ironwoodcutter@bk.ru)
+                new lexer,
+                bytecode inline,
+                shl & shr operators,
+                smart string concatenation,
+                new max array size (up to 32767),
+                inclusion of {$R+/-} to enable/disable real numbers support,
+                and {$V+/-} to enable/disable internal bytecode preverification
+
+        MPC.3.0.IDE:
+            Javier Santo Domingo (j-a-s-d@users.sourceforge.net)
+                ported to GNUCC (with coditional defines),
+                pascal-like errors messages and warnings,
+                new command-line parsing (C way),
+                disabled $R and $V directives (confusing overlapped functionality with the IDE),
+                and several other adjustments (wow64 WM_COPYDATA workaround, etc)
+                and bugfixes (real numbers parsing, shl & shr swapped operators, etc)
+
+        MPC.3.1.IDE:
+            Javier Santo Domingo (j-a-s-d@users.sourceforge.net)
+                infinite-loop support (repeat/forever),
+                and bugfixes (complex-type bidimensional array initialization index out-of-bound, etc)
+
+        MPC.3.2.IDE:
+            Javier Santo Domingo (j-a-s-d@users.sourceforge.net)
+                exit keyword support,
+                C-style multiline comments support
+
+        MPC.3.3.IDE:
+            Javier Santo Domingo (j-a-s-d@users.sourceforge.net)
+                result keyword support,
+                C-style shift operators support (<< and >>),
+                and bugfixes (const assignment crash, etc)
+
+        MPC.3.4.IDE:
+            Javier Santo Domingo (j-a-s-d@users.sourceforge.net)
+                Project Library Directory support via -p switch,
+                imported the "ASM BLOCK" from the Artem's MPC.3.0.011.SIMPLE parser.c,
+                bytecode keyword support,
+                and ushr/>>> shift operator support
+
+        MPC.3.5.IDE:
+            Javier Santo Domingo (j-a-s-d@users.sourceforge.net)
+                C-like double quoted strings support,
+                negative integer constants support,
+                and bugfixes (consecutive same variable name declaration collision, etc)
+
+*/
+
+// j-a-s-d: workaround for Wow64 using WM_COPYDATA
+/*#ifndef LINUX
+    #define WOW64_WORKAROUND
+#endif*/
+
+#include "../util/strings.h"
+#include "../util/error.h"
+#include "../structures/type_list.h"
+#include "../structures/string_list.h"
+#include "../structures/type.h"
+#include "../structures/identifier.h"
+#include "../structures/name_table.h"
+#include "../classgen/bytecode.h"
+#include "../structures/block.h"
+#include "../parser/parser.h"
+#include "../util/memory.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+
+#ifdef WOW64_WORKAROUND
+    #include <windows.h>
+
+    int ParentNotifyHandle = INVALID_HANDLE_VALUE;
+    COPYDATASTRUCT COMPILERMESSAGE;
+#endif
+
+char msgstr[1024];
+int canvasType;
+int mathType;
+int next_record_ID;
+int detect_units_only;
+int goverify;
+
+extern FILE *yyin;
+extern string *string_constant;
+char *output_path;
+char *source_file_name;
+char *global_library_directory;
+char *project_library_directory;
+char *user_libraries = NULL;
+char **units;
+
+extern short int error_count;
+extern short int warning_count;
+
+extern int usesForms;
+extern int usesSupport;
+extern int usesFloat;
+extern int usesRecordStore;
+extern int usesHttp;
+extern int usesPlayer;
+extern int usesSMS;
+
+extern int constant_pool_size;
+extern long int last_error_linenum;
+extern int inside_loop;
+
+extern int linenum;
+extern string *string_constant;
+
+extern int next_record_ID;
+
+void compileMSG()
+{
+#ifdef WOW64_WORKAROUND
+    if (ParentNotifyHandle != INVALID_HANDLE_VALUE) {
+        COMPILERMESSAGE.dwData = 1;
+        COMPILERMESSAGE.cbData = sizeof( msgstr );
+        COMPILERMESSAGE.lpData = &msgstr;
+        SendMessage(ParentNotifyHandle, WM_COPYDATA,
+            (WPARAM) 0, (LPARAM)(LPVOID) &COMPILERMESSAGE);
+        return;
+    }
+#endif
+    printf(msgstr);
+    fflush(stdout);
+}
+
+void requires(int reqkind, char* req)
+{
+  switch (reqkind)
+  {
+    case 0: // unit
+        sprintf(msgstr,"^0%s\n", req);
+        break;
+    case 1: // lib
+        sprintf(msgstr,"^1%s\n", req);
+        break;
+    case 2: // stub
+        sprintf(msgstr,"^2%s\n", req);
+        break;
+    case 3: // record
+        sprintf(msgstr,"^3%s\n", req);
+        break;
+  }
+  compileMSG();
+}
+
+int last_progress;
+
+void compile_progress(int x)
+{
+    if (x != last_progress)
+    {
+        last_progress = x;
+        sprintf(msgstr,"@%d\n", last_progress);
+        compileMSG();
+    }
+}
+
+void compile_terminate(){
+       mem_close();
+       fclose(yyin);
+       exit(1);
+};
+
+//////////
+
+void initialize_compiler()
+{
+       constant_pool_size = 0;
+       string_constant = NULL;
+       error_count = 0;
+       warning_count = 0;
+       last_error_linenum = -1;
+       linenum = 1;
+       inside_loop = 0;
+       goverify = 1;
+       usesFloat = 0;
+       usesForms = 0;
+       usesSupport = 0;
+       usesRecordStore = 0;
+       usesHttp = 0;
+       usesPlayer = 0;
+       usesSMS = 0;
+       user_libraries = NULL;
+}
+
+void ShowHelp()
+{
+    sprintf(msgstr,
+    "-------------------------------------------------------------------------\n"
+    "MIDletPascal 3.5 Compiler\n"
+    "Version: MPC.3.5.IDE\n"
+    "Authors: Niksa Orlic (1.x-2.0), Artem (3.0), Javier Santo Domingo (3.x)\n"
+    "-------------------------------------------------------------------------\n"
+    "usage: mp3cc\n"
+    "\t-s\"<source_filename>\"\n"
+    "\t-o\"<output_path>\"\n"
+    "\t-l\"<global_library_path>\"\n"
+    "\t-p\"<project_library_path>\"\n"
+    "\t-m<math_type>\n"
+    "\t-c<canvas_type>\n"
+    "\t-r<next_record_ID>\n"
+    "\t[-d] // detect units only\n"
+#ifdef WOW64_WORKAROUND
+    "\t[-n]<parent_notify_handle> // outputs using WMCOPYDATA\n"
+#endif
+    "\n"
+    );
+    compileMSG();
+    exit(2);
+}
+
+void PrintFinalMessage ()
+{
+    if (usesForms) {
+        requires(2,"FS.class");
+    }
+    if (usesSupport) {
+        requires(2,"S.class");
+    }
+    if (usesFloat == 1) {
+        if (mathType == 2) {
+            requires(2,"Real.class");
+            requires(2,"Real$NumberFormat.class");
+        } else {
+            requires(2,"F.class");
+        }
+    }
+    if (usesRecordStore == 1) {
+        requires(2,"RS.class");
+    }
+    if (usesHttp == 1) {
+        requires(2,"H.class");
+    }
+    if (usesPlayer == 1) {
+        requires(2,"P.class");
+    }
+    if (usesSMS == 1) {
+        requires(2,"SM.class");
+    }
+    sprintf(msgstr,"Done - %d error(s), %d warning(s)\n", error_count, warning_count);
+}
+
+int main(int argc, char **argv)
+{
+    error_count = -1;
+    char *source_file = NULL;
+    char *output_directory = NULL;
+
+       int pos;
+
+       if (argc >= 2)
+       {
+        // -- parse command line arguments
+        detect_units_only = 0;
+        mathType = 1;
+        canvasType = NORMAL;
+
+        int c;
+        while ((c = getopt(argc, argv, "?:s:o:l:p:m:n:c:r:d")) != -1) {
+            switch(c) {
+                case 's':
+                    source_file = optarg;
+                    break;
+                case 'o':
+                    output_directory = optarg;
+                    break;
+                case 'l':
+                    global_library_directory = optarg;
+                    break;
+                case 'p':
+                    project_library_directory = optarg;
+                    break;
+                case 'm':
+                    if (strcmp("2", optarg) == 0) {
+                      mathType = 2; // REAL
+                    }
+                    break;
+                case 'n':
+#ifdef WOW64_WORKAROUND
+                    ParentNotifyHandle = atoi(optarg);
+#endif
+                    break;
+                case 'r':
+                    next_record_ID = atoi(optarg);
+                    break;
+                case 'c':
+                    if (strcmp("2", optarg) == 0) {
+                      canvasType = FULL_NOKIA; // FULL_NOKIA
+                    } else if (strcmp("1", optarg) == 0) {
+                      canvasType = FULL_MIDP20; // FULL_MIDP20
+                    }
+                    break;
+                case 'd':
+                    detect_units_only++;
+                    break;
+                case '?':
+                default:
+                    ShowHelp();
+            }
+        }
+
+        if (project_library_directory == NULL) {
+            sprintf(msgstr,"mp3cc: no project library directory\n");
+            compileMSG();
+            ShowHelp();
+        }
+        if (global_library_directory == NULL) {
+            sprintf(msgstr,"mp3cc: no global library directory\n");
+            compileMSG();
+            ShowHelp();
+        }
+        if (output_directory == NULL) {
+            sprintf(msgstr,"mp3cc: no output directory\n");
+            compileMSG();
+            ShowHelp();
+        }
+        if (source_file == NULL) {
+            sprintf(msgstr,"mp3cc: no source file\n");
+            compileMSG();
+            ShowHelp();
+        }
+
+    // --
+
+               mem_init();
+               initialize_compiler();
+               units=malloc(8);
+               *units=malloc(8);
+               *units=NULL;
+               pos=strlen(source_file)-1;
+               while ((source_file[pos] == '\r') || (source_file[pos] == '\n')) pos --;
+               source_file[pos + 1] = '\0';
+               source_file_name = (char*) mem_alloc(pos + 1);
+               if (source_file_name == NULL)  die(1);
+               //pos = len - 1;
+               #ifdef UNIX
+         while ((pos >= 0) && (source_file[pos] != '/'))  pos --;
+               #endif
+               #ifdef WIN32
+                while ((pos >= 0) && (source_file[pos] != '\\'))  pos --;
+         if (source_file[pos] != '\\')  die(21);
+               #endif
+               //pos ++;
+               strcpy(source_file_name, source_file + pos + 1);
+               ////////////////////
+               pos = strlen(output_directory) - 1;
+               while ((output_directory[pos] == '\r')|| (output_directory[pos] == '\n')) pos --;
+               output_directory[pos + 1] = '\0';
+               //len = strlen(output_directory);       output_path = (char*) mem_alloc(len + 1);
+               output_path = output_directory;
+               //library_directory=output_directory;
+               yyrestart(source_file);
+               if ((yyin != NULL) && (output_path != NULL))
+               {
+            if (detect_units_only) {
+                sprintf(msgstr,"Detecting units of \'%s\'...\n", source_file_name);
+            } else {
+                sprintf(msgstr,"Compiling \'%s\'...\n", source_file_name);
+            }
+                       compileMSG();
+                       strcpy(output_path, output_directory);
+                       parser_start();
+
+                       fclose(yyin);
+                       mem_free(output_path);
+                       mem_free(source_file_name);
+               }
+       }
+
+       if (string_constant != NULL)
+               string_destroy(string_constant);
+
+    if (!detect_units_only)
+    {
+        switch(error_count)
+        {
+            case -1:
+                ShowHelp();
+            case 0:
+                PrintFinalMessage();
+            default:
+                sprintf(msgstr,"");
+        }
+        compileMSG();
+    }
+
+       mem_close();
+    return error_count;
+}
diff --git a/MPC.3.5.LINUX/mp3CC.cbp b/MPC.3.5.LINUX/mp3CC.cbp
new file mode 100644 (file)
index 0000000..4961fda
--- /dev/null
@@ -0,0 +1,222 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_project_file>
+       <FileVersion major="1" minor="6" />
+       <Project>
+               <Option title="mp3CC" />
+               <Option pch_mode="2" />
+               <Option default_target="LINUX32" />
+               <Option compiler="gcc" />
+               <Build>
+                       <Target title="Debug Win32">
+                               <Option output="code/MP3IDE/bin/mp3CC" prefix_auto="1" extension_auto="1" />
+                               <Option object_output="Debug Win32" />
+                               <Option type="1" />
+                               <Option compiler="gcc" />
+                               <Option use_console_runner="0" />
+                               <Option parameters='-s&quot;C:\\NewProject\\src\\NewProject.mpsrc&quot; -o&quot;C:\\NewProject\\classes&quot;  -p&quot;C:\\NewProject\\libs&quot; -l&quot;C:\\code\\MP3IDE\\bin\\Libs&quot; -c0 -m2' />
+                               <Option host_application="C:/code/MP3IDE/bin/mp3IDE.exe" />
+                               <Option run_host_application_in_terminal="0" />
+                               <Compiler>
+                                       <Add option="-W" />
+                                       <Add option="-g" />
+                                       <Add option="-O0" />
+                                       <Add option="-DWIN32" />
+                                       <Add option="-D_DEBUG" />
+                                       <Add option="-D_CONSOLE" />
+                               </Compiler>
+                       </Target>
+                       <Target title="Release Win32">
+                               <Option output="code/MP3IDE/bin/mp3CC" prefix_auto="1" extension_auto="1" />
+                               <Option object_output="Release Win32" />
+                               <Option type="1" />
+                               <Option compiler="gcc" />
+                               <Option use_console_runner="0" />
+                               <Option host_application="C:/code/MP3IDE/bin/mp3IDE.exe" />
+                               <Option run_host_application_in_terminal="0" />
+                               <Compiler>
+                                       <Add option="-w" />
+                                       <Add option="-DWIN32" />
+                                       <Add option="-DNDEBUG" />
+                                       <Add option="-D_CONSOLE" />
+                               </Compiler>
+                               <Linker>
+                                       <Add option="-s" />
+                               </Linker>
+                       </Target>
+                       <Target title="LINUX32">
+                               <Option output="Linux/mp3CC" prefix_auto="1" extension_auto="1" />
+                               <Option type="1" />
+                               <Option compiler="gcc" />
+                               <Option use_console_runner="0" />
+                               <Option parameters="-sLinux/src/main.pas -oLinux/classes -pLinux/libs -lLinux/libs -c1 -m1" />
+                               <Compiler>
+                                       <Add option="-march=i386" />
+                                       <Add option="-w" />
+                                       <Add option="-m32" />
+                                       <Add option="-DLINUX" />
+                                       <Add option="-DUNIX" />
+                                       <Add option="-DNDEBUG" />
+                                       <Add option="-D_CONSOLE" />
+                               </Compiler>
+                               <Linker>
+                                       <Add option="-m32" />
+                               </Linker>
+                       </Target>
+                       <Target title="LINUX64">
+                               <Option output="Linux/mp3CC" prefix_auto="1" extension_auto="1" />
+                               <Option type="1" />
+                               <Option compiler="gcc" />
+                               <Option use_console_runner="0" />
+                               <Compiler>
+                                       <Add option="-march=k8" />
+                                       <Add option="-w" />
+                                       <Add option="-m64" />
+                                       <Add option="-DLINUX" />
+                                       <Add option="-DUNIX" />
+                                       <Add option="-DNDEBUG" />
+                                       <Add option="-D_CONSOLE" />
+                               </Compiler>
+                               <Linker>
+                                       <Add option="-m64" />
+                               </Linker>
+                       </Target>
+               </Build>
+               <Unit filename="classgen/bytecode.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="classgen/bytecode.h" />
+               <Unit filename="classgen/classgen.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="classgen/classgen.h" />
+               <Unit filename="classgen/constant_pool.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="classgen/constant_pool.h" />
+               <Unit filename="classgen/preverify.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="classgen/preverify.h" />
+               <Unit filename="lex/lex.yy.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="lex/tokens.h" />
+               <Unit filename="main/main.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="parser/parser.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="parser/parser.h" />
+               <Unit filename="parser/stdpas.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="parser/stdpas.h" />
+               <Unit filename="preverifier/check_class.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="preverifier/check_code.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="preverifier/check_code.h" />
+               <Unit filename="preverifier/classloader.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="preverifier/classresolver.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="preverifier/convert_md.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="preverifier/convert_md.h" />
+               <Unit filename="preverifier/file.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="preverifier/inlinejsr.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="preverifier/jar.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="preverifier/jar.h" />
+               <Unit filename="preverifier/jar_support.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="preverifier/jarint.h" />
+               <Unit filename="preverifier/jartables.h" />
+               <Unit filename="preverifier/locale_md.h" />
+               <Unit filename="preverifier/main.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="preverifier/oobj.h" />
+               <Unit filename="preverifier/opcodes.h" />
+               <Unit filename="preverifier/path.h" />
+               <Unit filename="preverifier/path_md.h" />
+               <Unit filename="preverifier/signature.h" />
+               <Unit filename="preverifier/stubs.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="preverifier/sys_api.h" />
+               <Unit filename="preverifier/sys_support.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="preverifier/sysmacros_md.h" />
+               <Unit filename="preverifier/tree.h" />
+               <Unit filename="preverifier/typecodes.h" />
+               <Unit filename="preverifier/typedefs.h" />
+               <Unit filename="preverifier/typedefs_md.h" />
+               <Unit filename="preverifier/utf.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="preverifier/utf.h" />
+               <Unit filename="preverifier/util.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="structures/block.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="structures/block.h" />
+               <Unit filename="structures/identifier.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="structures/identifier.h" />
+               <Unit filename="structures/name_table.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="structures/name_table.h" />
+               <Unit filename="structures/string_list.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="structures/string_list.h" />
+               <Unit filename="structures/type.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="structures/type.h" />
+               <Unit filename="structures/type_list.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="structures/type_list.h" />
+               <Unit filename="structures/unit.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="structures/unit.h" />
+               <Unit filename="util/error.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="util/error.h" />
+               <Unit filename="util/memory.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="util/memory.h" />
+               <Unit filename="util/strings.c">
+                       <Option compilerVar="CC" />
+               </Unit>
+               <Unit filename="util/strings.h" />
+               <Extensions>
+                       <code_completion />
+                       <envvars />
+                       <debugger />
+                       <lib_finder disable_auto="1" />
+               </Extensions>
+       </Project>
+</CodeBlocks_project_file>
diff --git a/MPC.3.5.LINUX/mp3CC.depend b/MPC.3.5.LINUX/mp3CC.depend
new file mode 100644 (file)
index 0000000..9d4715b
--- /dev/null
@@ -0,0 +1,3454 @@
+# depslib dependency file v1.0
+1260373732 source:c:\code\mp3cc\classgen\bytecode.c\r
+       "bytecode.h"\r
+       "../util/error.h"\r
+       "../util/memory.h"\r
+       <stdlib.h>\r
+       <string.h>\r
+       <stdio.h>\r
+
+1396209483 
+
+1260373732 c:\code\mp3cc\classgen\bytecode.h\r
+
+1260373734 c:\code\mp3cc\util\error.h\r
+
+1267714409 c:\code\mp3cc\util\memory.h\r
+
+1267726361 source:c:\code\mp3cc\classgen\classgen.c\r
+       "../util/error.h"\r
+       "../util/strings.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../classgen/constant_pool.h"\r
+       "../classgen/preverify.h"\r
+       "../util/memory.h"\r
+       <stdio.h>\r
+       <string.h>\r
+       <stdlib.h>\r
+       "classgen.h"\r
+
+1359821690 h"\r
+
+1260373734 c:\code\mp3cc\util\strings.h\r
+
+1260373734 c:\code\mp3cc\structures\type_list.h\r
+
+1260373734 c:\code\mp3cc\structures\string_list.h\r
+
+1260373734 c:\code\mp3cc\structures\type.h\r
+
+1260373734 c:\code\mp3cc\structures\identifier.h\r
+       <stdio.h>\r
+
+1260373734 c:\code\mp3cc\structures\name_table.h\r
+
+1260373734 c:\code\mp3cc\structures\block.h\r
+       <stdio.h>\r
+
+1306012600 c:\code\mp3cc\classgen\constant_pool.h\r
+
+1260373733 c:\code\mp3cc\classgen\preverify.h\r
+
+1260373732 c:\code\mp3cc\classgen\classgen.h\r
+
+1306012581 source:c:\code\mp3cc\classgen\constant_pool.c\r
+       <stdlib.h>\r
+       <string.h>\r
+       <stdio.h>\r
+       "constant_pool.h"\r
+       "../util/error.h"\r
+       "../util/strings.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../util/memory.h"\r
+       "classgen.h"\r
+
+1260373733 source:c:\code\mp3cc\classgen\preverify.c\r
+       <stdlib.h>\r
+       <string.h>\r
+       <stdio.h>\r
+       "../util/error.h"\r
+       "../util/strings.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "constant_pool.h"\r
+       "bytecode.h"\r
+       "preverify.h"\r
+       "../util/error.h"\r
+       "../util/memory.h"\r
+
+1359821690 emory.h"\r
+
+1307035065 source:c:\code\mp3cc\lex\lex.yy.c\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+       "tokens.h"\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+
+1396208800 rror.h"\r
+
+1307035316 c:\code\mp3cc\lex\tokens.h\r
+
+1307037385 source:c:\code\mp3cc\parser\parser.c\r
+       "../util/error.h"\r
+       "../util/strings.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../lex/tokens.h"\r
+       "../util/memory.h"\r
+       "../structures/unit.h"\r
+       "../classgen/constant_pool.h"\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+       "../classgen/classgen.h"\r
+       "parser.h"\r
+       "stdpas.h"\r
+
+1260373734 c:\code\mp3cc\structures\unit.h\r
+
+1260373733 c:\code\mp3cc\parser\parser.h\r
+
+1260373733 c:\code\mp3cc\parser\stdpas.h\r
+
+1270062370 source:c:\code\mp3cc\parser\stdpas.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../classgen/constant_pool.h"\r
+       "stdpas.h"\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+
+1260373733 source:c:\code\mp3cc\preverifier\check_class.c\r
+       <ctype.h>\r
+       "oobj.h"\r
+       "utf.h"\r
+       "tree.h"\r
+       "sys_api.h"\r
+
+1359821690 "\r
+
+1260373733 c:\code\mp3cc\preverifier\oobj.h\r
+       <stddef.h>\r
+       <stdarg.h>\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+       <limits.h>\r
+       "typedefs.h"\r
+       "signature.h"\r
+
+1359821690 .h"\r
+
+1260373734 c:\code\mp3cc\preverifier\typedefs.h\r
+       "typedefs_md.h"\r
+
+1359821690 md.h"\r
+
+1260373734 c:\code\mp3cc\preverifier\typedefs_md.h\r
+       <sys/types.h>\r
+       <sys/stat.h>\r
+       <sys/byteorder.h>\r
+       <asm/byteorder.h>\r
+       <windows.h>\r
+
+1396351241 >\r
+
+1260373734 c:\code\mp3cc\preverifier\signature.h\r
+
+1260373734 c:\code\mp3cc\preverifier\utf.h\r
+
+1260373734 c:\code\mp3cc\preverifier\tree.h\r
+       "oobj.h"\r
+       "typecodes.h"\r
+
+1260373734 c:\code\mp3cc\preverifier\typecodes.h\r
+
+1260373734 c:\code\mp3cc\preverifier\sys_api.h\r
+       "typedefs.h"\r
+       <time.h>\r
+       "sysmacros_md.h"\r
+
+1396350064 _md.h"\r
+
+1260373734 c:\code\mp3cc\preverifier\sysmacros_md.h\r
+       <io.h>\r
+
+1306020715 source:c:\code\mp3cc\preverifier\check_code.c\r
+       "check_code.h"\r
+       "opcodes.length"\r
+       "opcodes.in_out"\r
+
+1359821690 n_out"\r
+
+1260373733 c:\code\mp3cc\preverifier\check_code.h\r
+       <setjmp.h>\r
+       "oobj.h"\r
+       "opcodes.h"\r
+       "tree.h"\r
+       "sys_api.h"\r
+
+1260373733 c:\code\mp3cc\preverifier\opcodes.h\r
+
+1260373733 c:\code\mp3cc\preverifier\opcodes.length\r
+
+1260373733 c:\code\mp3cc\preverifier\opcodes.in_out\r
+
+1260373733 source:c:\code\mp3cc\preverifier\classloader.c\r
+       <string.h>\r
+       <stdio.h>\r
+       <sys/types.h>\r
+       <stddef.h>\r
+       <fcntl.h>\r
+       <sys/stat.h>\r
+       <stdlib.h>\r
+       <setjmp.h>\r
+       "jar.h"\r
+       "oobj.h"\r
+       "path.h"\r
+       "tree.h"\r
+       "signature.h"\r
+       "convert_md.h"\r
+       "sys_api.h"\r
+       <unistd.h>\r
+
+1260373733 c:\code\mp3cc\preverifier\jar.h\r
+       "typedefs.h"\r
+       "stdio.h"\r
+       "sys/types.h"\r
+       "stddef.h"\r
+
+1260373733 c:\code\mp3cc\preverifier\path.h\r
+       <sys/stat.h>\r
+       "path_md.h"\r
+
+1260373733 c:\code\mp3cc\preverifier\path_md.h\r
+       <dirent.h>\r
+       <direct.h>\r
+
+1260373733 c:\code\mp3cc\preverifier\convert_md.h\r
+
+1260373733 source:c:\code\mp3cc\preverifier\classresolver.c\r
+       <ctype.h>\r
+       <string.h>\r
+       <sys/types.h>\r
+       <fcntl.h>\r
+       <sys/stat.h>\r
+       <stdlib.h>\r
+       "oobj.h"\r
+       "tree.h"\r
+       "signature.h"\r
+       "path.h"\r
+       "sys_api.h"\r
+       "convert_md.h"\r
+
+1359821690 d.h"\r
+
+1260373733 source:c:\code\mp3cc\preverifier\convert_md.c\r
+       <stdio.h>\r
+       <string.h>\r
+       <langinfo.h>\r
+       <iconv.h>\r
+       <locale.h>\r
+       <WINDOWS.H>\r
+       "oobj.h"\r
+       "utf.h"\r
+
+1260373733 source:c:\code\mp3cc\preverifier\file.c\r
+       <sys/types.h>\r
+       <fcntl.h>\r
+       <sys/stat.h>\r
+       <stdio.h>\r
+       <string.h>\r
+       <stdlib.h>\r
+       <stddef.h>\r
+       <unistd.h>\r
+       "oobj.h"\r
+       "jar.h"\r
+       "tree.h"\r
+       "sys_api.h"\r
+       "convert_md.h"\r
+       <direct.h>\r
+       "opcodes.init"\r
+
+1359821690 nit"\r
+
+1260373733 c:\code\mp3cc\preverifier\opcodes.init\r
+
+1260373733 source:c:\code\mp3cc\preverifier\inlinejsr.c\r
+       "check_code.h"\r
+
+1359821690 e.h"\r
+
+1260373733 source:c:\code\mp3cc\preverifier\jar.c\r
+       <stdio.h>\r
+       <sys/types.h>\r
+       <stddef.h>\r
+       <assert.h>\r
+       "oobj.h"\r
+       "typedefs.h"\r
+       "jar.h"\r
+       "jarint.h"\r
+       "jartables.h"\r
+
+1260373733 c:\code\mp3cc\preverifier\jarint.h\r
+
+1260373733 c:\code\mp3cc\preverifier\jartables.h\r
+
+1260373733 source:c:\code\mp3cc\preverifier\jar_support.c\r
+       <ctype.h>\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <fcntl.h>\r
+       <sys/stat.h>\r
+       <sys/types.h>\r
+       <string.h>\r
+       "sys_api.h"\r
+       "path_md.h"\r
+       "path.h"\r
+       "oobj.h"\r
+       "jar.h"\r
+       "convert_md.h"\r
+       <string.h>\r
+       <process.h>\r
+
+1260373733 source:c:\code\mp3cc\preverifier\main.c\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <fcntl.h>\r
+       <sys/stat.h>\r
+       <sys/types.h>\r
+       <string.h>\r
+       "sys_api.h"\r
+       "path_md.h"\r
+       "path.h"\r
+       "oobj.h"\r
+       "locale_md.h"\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "../util/message.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../parser/parser.h"\r
+       "../util/memory.h"\r
+       "../main/static_entry.h"\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+
+1260373733 c:\code\mp3cc\preverifier\locale_md.h\r
+       <locale.h>\r
+
+1260373734 source:c:\code\mp3cc\preverifier\stubs.c\r
+       "oobj.h"\r
+       "sys_api.h"\r
+
+1260373734 source:c:\code\mp3cc\preverifier\sys_support.c\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+       "oobj.h"\r
+       "jar.h"\r
+       "typedefs.h"\r
+       "sys_api.h"\r
+       "path.h"\r
+
+1260373734 source:c:\code\mp3cc\preverifier\utf.c\r
+       <stdio.h>\r
+       <string.h>\r
+       <stdlib.h>\r
+       "oobj.h"\r
+       "utf.h"\r
+       "sys_api.h"\r
+
+1260373734 source:c:\code\mp3cc\preverifier\util.c\r
+       <stdio.h>\r
+       <string.h>\r
+       <ctype.h>\r
+       <stddef.h>\r
+       "oobj.h"\r
+       "utf.h"\r
+       "sys_api.h"\r
+       "path.h"\r
+
+1304655643 source:c:\code\mp3cc\structures\block.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "../classgen/bytecode.h"\r
+       "type_list.h"\r
+       "string_list.h"\r
+       "type.h"\r
+       "identifier.h"\r
+       "name_table.h"\r
+       "unit.h"\r
+       "block.h"\r
+       "../classgen/preverify.h"\r
+       "../util/memory.h"\r
+       <string.h>\r
+       <stdlib.h>\r
+       <stdio.h>\r
+       "../classgen/constant_pool.h"\r
+       "../classgen/classgen.h"\r
+
+1359818090 en/classgen.h"\r
+
+1267714288 source:c:\code\mp3cc\structures\identifier.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "type_list.h"\r
+       "string_list.h"\r
+       "type.h"\r
+       "identifier.h"\r
+       "name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "block.h"\r
+       "unit.h"\r
+       "../util/memory.h"\r
+       <string.h>\r
+       <stdlib.h>\r
+
+1260373734 source:c:\code\mp3cc\structures\name_table.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "type_list.h"\r
+       "string_list.h"\r
+       "type.h"\r
+       "identifier.h"\r
+       "name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "block.h"\r
+       "unit.h"\r
+       "../util/memory.h"\r
+       <string.h>\r
+       <stdlib.h>\r
+
+1260373734 source:c:\code\mp3cc\structures\string_list.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "string_list.h"\r
+       <string.h>\r
+       <stdlib.h>\r
+
+1260373734 source:c:\code\mp3cc\structures\type.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "type_list.h"\r
+       "string_list.h"\r
+       "type.h"\r
+       "identifier.h"\r
+       "name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "block.h"\r
+       "../util/memory.h"\r
+       <string.h>\r
+       <stdlib.h>\r
+
+1260373734 source:c:\code\mp3cc\structures\type_list.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "type_list.h"\r
+       "string_list.h"\r
+       "type.h"\r
+       "identifier.h"\r
+       "name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "block.h"\r
+       "../util/memory.h"\r
+       <stdlib.h>\r
+
+1260373734 source:c:\code\mp3cc\structures\unit.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "../classgen/bytecode.h"\r
+       "type_list.h"\r
+       "string_list.h"\r
+       "type.h"\r
+       "identifier.h"\r
+       "name_table.h"\r
+       "block.h"\r
+       "unit.h"\r
+       "../classgen/preverify.h"\r
+       "../util/memory.h"\r
+       <string.h>\r
+       <stdlib.h>\r
+       <stdio.h>\r
+       "../classgen/constant_pool.h"\r
+       "../classgen/classgen.h"\r
+
+1307037408 source:c:\code\mp3cc\util\error.c\r
+       <stdio.h>\r
+       <stdlib.h>\r
+
+1260373734 source:c:\code\mp3cc\util\memory.c\r
+       <stdlib.h>\r
+       <string.h>\r
+       "memory.h"\r
+       "error.h"\r
+
+1260373734 source:c:\code\mp3cc\util\strings.c\r
+       "error.h"\r
+       "strings.h"\r
+       "memory.h"\r
+       <stdlib.h>\r
+       <string.h>\r
+
+1307034609 source:c:\code\mp3cc\main\main.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../parser/parser.h"\r
+       "../util/memory.h"\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+       <getopt.h>\r
+       <windows.h>\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/classgen/bytecode.c\r
+       "bytecode.h"\r
+       "../util/error.h"\r
+       "../util/memory.h"\r
+       <stdlib.h>\r
+       <string.h>\r
+       <stdio.h>\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/classgen/bytecode.h\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/util/error.h\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/util/memory.h\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/classgen/classgen.c\r
+       "../util/error.h"\r
+       "../util/strings.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../classgen/constant_pool.h"\r
+       "../classgen/preverify.h"\r
+       "../util/memory.h"\r
+       <stdio.h>\r
+       <string.h>\r
+       <stdlib.h>\r
+       "classgen.h"\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/util/strings.h\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/structures/type_list.h\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/structures/string_list.h\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/structures/type.h\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/structures/identifier.h\r
+       <stdio.h>\r
+
+1396200141 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/structures/name_table.h\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/structures/block.h\r
+       <stdio.h>\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/classgen/constant_pool.h\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/classgen/preverify.h\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/classgen/classgen.h\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/classgen/constant_pool.c\r
+       <stdlib.h>\r
+       <string.h>\r
+       <stdio.h>\r
+       "constant_pool.h"\r
+       "../util/error.h"\r
+       "../util/strings.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../util/memory.h"\r
+       "classgen.h"\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/classgen/preverify.c\r
+       <stdlib.h>\r
+       <string.h>\r
+       <stdio.h>\r
+       "../util/error.h"\r
+       "../util/strings.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "constant_pool.h"\r
+       "bytecode.h"\r
+       "preverify.h"\r
+       "../util/error.h"\r
+       "../util/memory.h"\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/lex/lex.yy.c\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+       "tokens.h"\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/lex/tokens.h\r
+
+1396195894 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/main/main.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../parser/parser.h"\r
+       "../util/memory.h"\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+       <getopt.h>\r
+       <windows.h>\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/parser/parser.h\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/parser/parser.c\r
+       "../util/error.h"\r
+       "../util/strings.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../lex/tokens.h"\r
+       "../util/memory.h"\r
+       "../structures/unit.h"\r
+       "../classgen/constant_pool.h"\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+       "../classgen/classgen.h"\r
+       "parser.h"\r
+       "stdpas.h"\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/structures/unit.h\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/parser/stdpas.h\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/parser/stdpas.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../classgen/constant_pool.h"\r
+       "stdpas.h"\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/check_class.c\r
+       <ctype.h>\r
+       "oobj.h"\r
+       "utf.h"\r
+       "tree.h"\r
+       "sys_api.h"\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/oobj.h\r
+       <stddef.h>\r
+       <stdarg.h>\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+       <limits.h>\r
+       "typedefs.h"\r
+       "signature.h"\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/typedefs.h\r
+       "typedefs_md.h"\r
+
+1396195701 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/typedefs_md.h\r
+       <sys/types.h>\r
+       <sys/stat.h>\r
+       <sys/byteorder.h>\r
+       <asm/byteorder.h>\r
+       <windows.h>\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/signature.h\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/utf.h\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/tree.h\r
+       "oobj.h"\r
+       "typecodes.h"\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/typecodes.h\r
+
+1396195922 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/sys_api.h\r
+       "typedefs.h"\r
+       <time.h>\r
+       "sysmacros_md.h"\r
+
+1396195701 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/sysmacros_md.h\r
+       <io.h>\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/check_code.c\r
+       "check_code.h"\r
+       "opcodes.length"\r
+       "opcodes.in_out"\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/check_code.h\r
+       <setjmp.h>\r
+       "oobj.h"\r
+       "opcodes.h"\r
+       "tree.h"\r
+       "sys_api.h"\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/opcodes.h\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/opcodes.length\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/opcodes.in_out\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/classloader.c\r
+       <string.h>\r
+       <stdio.h>\r
+       <sys/types.h>\r
+       <stddef.h>\r
+       <fcntl.h>\r
+       <sys/stat.h>\r
+       <stdlib.h>\r
+       <setjmp.h>\r
+       "jar.h"\r
+       "oobj.h"\r
+       "path.h"\r
+       "tree.h"\r
+       "signature.h"\r
+       "convert_md.h"\r
+       "sys_api.h"\r
+       <unistd.h>\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/jar.h\r
+       "typedefs.h"\r
+       "stdio.h"\r
+       "sys/types.h"\r
+       "stddef.h"\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/path.h\r
+       <sys/stat.h>\r
+       "path_md.h"\r
+
+1396195701 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/path_md.h\r
+       <dirent.h>\r
+       <direct.h>\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/convert_md.h\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/classresolver.c\r
+       <ctype.h>\r
+       <string.h>\r
+       <sys/types.h>\r
+       <fcntl.h>\r
+       <sys/stat.h>\r
+       <stdlib.h>\r
+       "oobj.h"\r
+       "tree.h"\r
+       "signature.h"\r
+       "path.h"\r
+       "sys_api.h"\r
+       "convert_md.h"\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/file.c\r
+       <sys/types.h>\r
+       <fcntl.h>\r
+       <sys/stat.h>\r
+       <stdio.h>\r
+       <string.h>\r
+       <stdlib.h>\r
+       <stddef.h>\r
+       <unistd.h>\r
+       "oobj.h"\r
+       "jar.h"\r
+       "tree.h"\r
+       "sys_api.h"\r
+       "convert_md.h"\r
+       <direct.h>\r
+       "opcodes.init"\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/opcodes.init\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/inlinejsr.c\r
+       "check_code.h"\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/jar.c\r
+       <stdio.h>\r
+       <sys/types.h>\r
+       <stddef.h>\r
+       <assert.h>\r
+       "oobj.h"\r
+       "typedefs.h"\r
+       "jar.h"\r
+       "jarint.h"\r
+       "jartables.h"\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/jarint.h\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/jartables.h\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/jar_support.c\r
+       <ctype.h>\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <fcntl.h>\r
+       <sys/stat.h>\r
+       <sys/types.h>\r
+       <string.h>\r
+       "sys_api.h"\r
+       "path_md.h"\r
+       "path.h"\r
+       "oobj.h"\r
+       "jar.h"\r
+       "convert_md.h"\r
+       <string.h>\r
+       <process.h>\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/main.c\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <fcntl.h>\r
+       <sys/stat.h>\r
+       <sys/types.h>\r
+       <string.h>\r
+       "sys_api.h"\r
+       "path_md.h"\r
+       "path.h"\r
+       "oobj.h"\r
+       "locale_md.h"\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "../util/message.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../parser/parser.h"\r
+       "../util/memory.h"\r
+       "../main/static_entry.h"\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+
+1359818090 /media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/locale_md.h\r
+       <locale.h>\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/stubs.c\r
+       "oobj.h"\r
+       "sys_api.h"\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/sys_support.c\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+       "oobj.h"\r
+       "jar.h"\r
+       "typedefs.h"\r
+       "sys_api.h"\r
+       "path.h"\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/utf.c\r
+       <stdio.h>\r
+       <string.h>\r
+       <stdlib.h>\r
+       "oobj.h"\r
+       "utf.h"\r
+       "sys_api.h"\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/util.c\r
+       <stdio.h>\r
+       <string.h>\r
+       <ctype.h>\r
+       <stddef.h>\r
+       "oobj.h"\r
+       "utf.h"\r
+       "sys_api.h"\r
+       "path.h"\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/structures/block.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "../classgen/bytecode.h"\r
+       "type_list.h"\r
+       "string_list.h"\r
+       "type.h"\r
+       "identifier.h"\r
+       "name_table.h"\r
+       "unit.h"\r
+       "block.h"\r
+       "../classgen/preverify.h"\r
+       "../util/memory.h"\r
+       <string.h>\r
+       <stdlib.h>\r
+       <stdio.h>\r
+       "../classgen/constant_pool.h"\r
+       "../classgen/classgen.h"\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/structures/identifier.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "type_list.h"\r
+       "string_list.h"\r
+       "type.h"\r
+       "identifier.h"\r
+       "name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "block.h"\r
+       "unit.h"\r
+       "../util/memory.h"\r
+       <string.h>\r
+       <stdlib.h>\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/structures/name_table.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "type_list.h"\r
+       "string_list.h"\r
+       "type.h"\r
+       "identifier.h"\r
+       "name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "block.h"\r
+       "unit.h"\r
+       "../util/memory.h"\r
+       <string.h>\r
+       <stdlib.h>\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/structures/string_list.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "string_list.h"\r
+       <string.h>\r
+       <stdlib.h>\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/structures/type.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "type_list.h"\r
+       "string_list.h"\r
+       "type.h"\r
+       "identifier.h"\r
+       "name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "block.h"\r
+       "../util/memory.h"\r
+       <string.h>\r
+       <stdlib.h>\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/structures/type_list.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "type_list.h"\r
+       "string_list.h"\r
+       "type.h"\r
+       "identifier.h"\r
+       "name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "block.h"\r
+       "../util/memory.h"\r
+       <stdlib.h>\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/structures/unit.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "../classgen/bytecode.h"\r
+       "type_list.h"\r
+       "string_list.h"\r
+       "type.h"\r
+       "identifier.h"\r
+       "name_table.h"\r
+       "block.h"\r
+       "unit.h"\r
+       "../classgen/preverify.h"\r
+       "../util/memory.h"\r
+       <string.h>\r
+       <stdlib.h>\r
+       <stdio.h>\r
+       "../classgen/constant_pool.h"\r
+       "../classgen/classgen.h"\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/util/error.c\r
+       <stdio.h>\r
+       <stdlib.h>\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/util/memory.c\r
+       <stdlib.h>\r
+       <string.h>\r
+       "memory.h"\r
+       "error.h"\r
+
+1359818090 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/util/strings.c\r
+       "error.h"\r
+       "strings.h"\r
+       "memory.h"\r
+       <stdlib.h>\r
+       <string.h>\r
+
+1396196950 source:/media/second/Work/testmp/midletpascal-code-15/MPC.3.5.IDE/preverifier/convert_md.c\r
+       <stdio.h>\r
+       <string.h>\r
+       <langinfo.h>\r
+       <iconv.h>\r
+       <locale.h>\r
+       <stdlib.h>\r
+       <WINDOWS.H>\r
+       "oobj.h"\r
+       "utf.h"\r
+
+1359818090 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/classgen/bytecode.c\r
+       "bytecode.h"\r
+       "../util/error.h"\r
+       "../util/memory.h"\r
+       <stdlib.h>\r
+       <string.h>\r
+       <stdio.h>\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/classgen/bytecode.h\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/util/error.h\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/util/memory.h\r
+
+1396210518 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/classgen/classgen.c\r
+       "../util/error.h"\r
+       "../util/strings.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../classgen/constant_pool.h"\r
+       "../classgen/preverify.h"\r
+       "../util/memory.h"\r
+       <stdio.h>\r
+       <string.h>\r
+       <stdlib.h>\r
+       "classgen.h"\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/util/strings.h\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/structures/type_list.h\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/structures/string_list.h\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/structures/type.h\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/structures/identifier.h\r
+       <stdio.h>\r
+
+1396200141 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/structures/name_table.h\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/structures/block.h\r
+       <stdio.h>\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/classgen/constant_pool.h\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/classgen/preverify.h\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/classgen/classgen.h\r
+
+1359818090 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/classgen/constant_pool.c\r
+       <stdlib.h>\r
+       <string.h>\r
+       <stdio.h>\r
+       "constant_pool.h"\r
+       "../util/error.h"\r
+       "../util/strings.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../util/memory.h"\r
+       "classgen.h"\r
+
+1359818090 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/classgen/preverify.c\r
+       <stdlib.h>\r
+       <string.h>\r
+       <stdio.h>\r
+       "../util/error.h"\r
+       "../util/strings.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "constant_pool.h"\r
+       "bytecode.h"\r
+       "preverify.h"\r
+       "../util/error.h"\r
+       "../util/memory.h"\r
+
+1396208800 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/lex/lex.yy.c\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+       "tokens.h"\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/lex/tokens.h\r
+
+1396210518 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/parser/parser.c\r
+       "../util/error.h"\r
+       "../util/strings.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../lex/tokens.h"\r
+       "../util/memory.h"\r
+       "../structures/unit.h"\r
+       "../classgen/constant_pool.h"\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+       "../classgen/classgen.h"\r
+       "parser.h"\r
+       "stdpas.h"\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/structures/unit.h\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/parser/parser.h\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/parser/stdpas.h\r
+
+1359818090 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/parser/stdpas.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../classgen/constant_pool.h"\r
+       "stdpas.h"\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+
+1359818090 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/check_class.c\r
+       <ctype.h>\r
+       "oobj.h"\r
+       "utf.h"\r
+       "tree.h"\r
+       "sys_api.h"\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/oobj.h\r
+       <stddef.h>\r
+       <stdarg.h>\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+       <limits.h>\r
+       "typedefs.h"\r
+       "signature.h"\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/typedefs.h\r
+       "typedefs_md.h"\r
+
+1396195701 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/typedefs_md.h\r
+       <sys/types.h>\r
+       <sys/stat.h>\r
+       <sys/byteorder.h>\r
+       <asm/byteorder.h>\r
+       <windows.h>\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/signature.h\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/utf.h\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/tree.h\r
+       "oobj.h"\r
+       "typecodes.h"\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/typecodes.h\r
+
+1396195922 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/sys_api.h\r
+       "typedefs.h"\r
+       <time.h>\r
+       "sysmacros_md.h"\r
+
+1396195701 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/sysmacros_md.h\r
+       <io.h>\r
+
+1359818090 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/check_code.c\r
+       "check_code.h"\r
+       "opcodes.length"\r
+       "opcodes.in_out"\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/check_code.h\r
+       <setjmp.h>\r
+       "oobj.h"\r
+       "opcodes.h"\r
+       "tree.h"\r
+       "sys_api.h"\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/opcodes.h\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/opcodes.length\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/opcodes.in_out\r
+
+1396211517 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/classloader.c\r
+       <string.h>\r
+       <stdio.h>\r
+       <sys/types.h>\r
+       <stddef.h>\r
+       <fcntl.h>\r
+       <sys/stat.h>\r
+       <stdlib.h>\r
+       <setjmp.h>\r
+       "jar.h"\r
+       "oobj.h"\r
+       "path.h"\r
+       "tree.h"\r
+       "signature.h"\r
+       "convert_md.h"\r
+       "sys_api.h"\r
+       <unistd.h>\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/jar.h\r
+       "typedefs.h"\r
+       "stdio.h"\r
+       "sys/types.h"\r
+       "stddef.h"\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/path.h\r
+       <sys/stat.h>\r
+       "path_md.h"\r
+
+1396209483 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/path_md.h\r
+       <dirent.h>\r
+       <direct.h>\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/convert_md.h\r
+
+1359818090 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/classresolver.c\r
+       <ctype.h>\r
+       <string.h>\r
+       <sys/types.h>\r
+       <fcntl.h>\r
+       <sys/stat.h>\r
+       <stdlib.h>\r
+       "oobj.h"\r
+       "tree.h"\r
+       "signature.h"\r
+       "path.h"\r
+       "sys_api.h"\r
+       "convert_md.h"\r
+
+1396212576 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/convert_md.c\r
+       <stdio.h>\r
+       <string.h>\r
+       <langinfo.h>\r
+       <iconv.h>\r
+       <locale.h>\r
+       <stdlib.h>\r
+       <WINDOWS.H>\r
+       "oobj.h"\r
+       "utf.h"\r
+
+1359818090 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/file.c\r
+       <sys/types.h>\r
+       <fcntl.h>\r
+       <sys/stat.h>\r
+       <stdio.h>\r
+       <string.h>\r
+       <stdlib.h>\r
+       <stddef.h>\r
+       <unistd.h>\r
+       "oobj.h"\r
+       "jar.h"\r
+       "tree.h"\r
+       "sys_api.h"\r
+       "convert_md.h"\r
+       <direct.h>\r
+       "opcodes.init"\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/opcodes.init\r
+
+1359818090 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/inlinejsr.c\r
+       "check_code.h"\r
+
+1359818090 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/jar.c\r
+       <stdio.h>\r
+       <sys/types.h>\r
+       <stddef.h>\r
+       <assert.h>\r
+       "oobj.h"\r
+       "typedefs.h"\r
+       "jar.h"\r
+       "jarint.h"\r
+       "jartables.h"\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/jarint.h\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/jartables.h\r
+
+1359818090 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/jar_support.c\r
+       <ctype.h>\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <fcntl.h>\r
+       <sys/stat.h>\r
+       <sys/types.h>\r
+       <string.h>\r
+       "sys_api.h"\r
+       "path_md.h"\r
+       "path.h"\r
+       "oobj.h"\r
+       "jar.h"\r
+       "convert_md.h"\r
+       <string.h>\r
+       <process.h>\r
+
+1396211001 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/main.c\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <fcntl.h>\r
+       <sys/stat.h>\r
+       <sys/types.h>\r
+       <string.h>\r
+       "sys_api.h"\r
+       "path_md.h"\r
+       "path.h"\r
+       "oobj.h"\r
+       "locale_md.h"\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "../util/message.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../parser/parser.h"\r
+       "../util/memory.h"\r
+       "../main/static_entry.h"\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+
+1359818090 /media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/locale_md.h\r
+       <locale.h>\r
+
+1359818090 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/stubs.c\r
+       "oobj.h"\r
+       "sys_api.h"\r
+
+1359818090 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/sys_support.c\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+       "oobj.h"\r
+       "jar.h"\r
+       "typedefs.h"\r
+       "sys_api.h"\r
+       "path.h"\r
+
+1359818090 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/utf.c\r
+       <stdio.h>\r
+       <string.h>\r
+       <stdlib.h>\r
+       "oobj.h"\r
+       "utf.h"\r
+       "sys_api.h"\r
+
+1359818090 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/preverifier/util.c\r
+       <stdio.h>\r
+       <string.h>\r
+       <ctype.h>\r
+       <stddef.h>\r
+       "oobj.h"\r
+       "utf.h"\r
+       "sys_api.h"\r
+       "path.h"\r
+
+1396211001 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/structures/block.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "../classgen/bytecode.h"\r
+       "type_list.h"\r
+       "string_list.h"\r
+       "type.h"\r
+       "identifier.h"\r
+       "name_table.h"\r
+       "unit.h"\r
+       "block.h"\r
+       "../classgen/preverify.h"\r
+       "../util/memory.h"\r
+       <string.h>\r
+       <stdlib.h>\r
+       <stdio.h>\r
+       "../classgen/constant_pool.h"\r
+       "../classgen/classgen.h"\r
+
+1359818090 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/structures/identifier.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "type_list.h"\r
+       "string_list.h"\r
+       "type.h"\r
+       "identifier.h"\r
+       "name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "block.h"\r
+       "unit.h"\r
+       "../util/memory.h"\r
+       <string.h>\r
+       <stdlib.h>\r
+
+1359818090 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/structures/name_table.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "type_list.h"\r
+       "string_list.h"\r
+       "type.h"\r
+       "identifier.h"\r
+       "name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "block.h"\r
+       "unit.h"\r
+       "../util/memory.h"\r
+       <string.h>\r
+       <stdlib.h>\r
+
+1359818090 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/structures/string_list.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "string_list.h"\r
+       <string.h>\r
+       <stdlib.h>\r
+
+1359818090 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/structures/type.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "type_list.h"\r
+       "string_list.h"\r
+       "type.h"\r
+       "identifier.h"\r
+       "name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "block.h"\r
+       "../util/memory.h"\r
+       <string.h>\r
+       <stdlib.h>\r
+
+1359818090 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/structures/type_list.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "type_list.h"\r
+       "string_list.h"\r
+       "type.h"\r
+       "identifier.h"\r
+       "name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "block.h"\r
+       "../util/memory.h"\r
+       <stdlib.h>\r
+
+1359818090 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/structures/unit.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "../classgen/bytecode.h"\r
+       "type_list.h"\r
+       "string_list.h"\r
+       "type.h"\r
+       "identifier.h"\r
+       "name_table.h"\r
+       "block.h"\r
+       "unit.h"\r
+       "../classgen/preverify.h"\r
+       "../util/memory.h"\r
+       <string.h>\r
+       <stdlib.h>\r
+       <stdio.h>\r
+       "../classgen/constant_pool.h"\r
+       "../classgen/classgen.h"\r
+
+1359818090 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/util/error.c\r
+       <stdio.h>\r
+       <stdlib.h>\r
+
+1359818090 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/util/memory.c\r
+       <stdlib.h>\r
+       <string.h>\r
+       "memory.h"\r
+       "error.h"\r
+
+1359818090 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/util/strings.c\r
+       "error.h"\r
+       "strings.h"\r
+       "memory.h"\r
+       <stdlib.h>\r
+       <string.h>\r
+
+1396210022 source:/media/second/Work/testmp/mp3CC-source/MPC.3.5.LINUX/main/main.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../parser/parser.h"\r
+       "../util/memory.h"\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+       <getopt.h>\r
+       <windows.h>\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/classgen/bytecode.c\r
+       "bytecode.h"\r
+       "../util/error.h"\r
+       "../util/memory.h"\r
+       <stdlib.h>\r
+       <string.h>\r
+       <stdio.h>\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/classgen/bytecode.h\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/util/error.h\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/util/memory.h\r
+
+1396210518 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/classgen/classgen.c\r
+       "../util/error.h"\r
+       "../util/strings.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../classgen/constant_pool.h"\r
+       "../classgen/preverify.h"\r
+       "../util/memory.h"\r
+       <stdio.h>\r
+       <string.h>\r
+       <stdlib.h>\r
+       "classgen.h"\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/util/strings.h\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/type_list.h\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/string_list.h\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/type.h\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/identifier.h\r
+       <stdio.h>\r
+
+1396200141 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/name_table.h\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/block.h\r
+       <stdio.h>\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/classgen/constant_pool.h\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/classgen/preverify.h\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/classgen/classgen.h\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/classgen/constant_pool.c\r
+       <stdlib.h>\r
+       <string.h>\r
+       <stdio.h>\r
+       "constant_pool.h"\r
+       "../util/error.h"\r
+       "../util/strings.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../util/memory.h"\r
+       "classgen.h"\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/classgen/preverify.c\r
+       <stdlib.h>\r
+       <string.h>\r
+       <stdio.h>\r
+       "../util/error.h"\r
+       "../util/strings.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "constant_pool.h"\r
+       "bytecode.h"\r
+       "preverify.h"\r
+       "../util/error.h"\r
+       "../util/memory.h"\r
+
+1396208800 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/lex/lex.yy.c\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+       "tokens.h"\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/lex/tokens.h\r
+
+1396302610 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/main/main.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../parser/parser.h"\r
+       "../util/memory.h"\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+       <getopt.h>\r
+       <windows.h>\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/parser/parser.h\r
+
+1396210518 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/parser/parser.c\r
+       "../util/error.h"\r
+       "../util/strings.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../lex/tokens.h"\r
+       "../util/memory.h"\r
+       "../structures/unit.h"\r
+       "../classgen/constant_pool.h"\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+       "../classgen/classgen.h"\r
+       "parser.h"\r
+       "stdpas.h"\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/unit.h\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/parser/stdpas.h\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/parser/stdpas.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../classgen/constant_pool.h"\r
+       "stdpas.h"\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/check_class.c\r
+       <ctype.h>\r
+       "oobj.h"\r
+       "utf.h"\r
+       "tree.h"\r
+       "sys_api.h"\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/oobj.h\r
+       <stddef.h>\r
+       <stdarg.h>\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+       <limits.h>\r
+       "typedefs.h"\r
+       "signature.h"\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/typedefs.h\r
+       "typedefs_md.h"\r
+
+1396195701 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/typedefs_md.h\r
+       <sys/types.h>\r
+       <sys/stat.h>\r
+       <sys/byteorder.h>\r
+       <asm/byteorder.h>\r
+       <windows.h>\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/signature.h\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/utf.h\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/tree.h\r
+       "oobj.h"\r
+       "typecodes.h"\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/typecodes.h\r
+
+1396195922 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/sys_api.h\r
+       "typedefs.h"\r
+       <time.h>\r
+       "sysmacros_md.h"\r
+
+1396195701 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/sysmacros_md.h\r
+       <io.h>\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/check_code.c\r
+       "check_code.h"\r
+       "opcodes.length"\r
+       "opcodes.in_out"\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/check_code.h\r
+       <setjmp.h>\r
+       "oobj.h"\r
+       "opcodes.h"\r
+       "tree.h"\r
+       "sys_api.h"\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/opcodes.h\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/opcodes.length\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/opcodes.in_out\r
+
+1396211517 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/classloader.c\r
+       <string.h>\r
+       <stdio.h>\r
+       <sys/types.h>\r
+       <stddef.h>\r
+       <fcntl.h>\r
+       <sys/stat.h>\r
+       <stdlib.h>\r
+       <setjmp.h>\r
+       "jar.h"\r
+       "oobj.h"\r
+       "path.h"\r
+       "tree.h"\r
+       "signature.h"\r
+       "convert_md.h"\r
+       "sys_api.h"\r
+       <unistd.h>\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/jar.h\r
+       "typedefs.h"\r
+       "stdio.h"\r
+       "sys/types.h"\r
+       "stddef.h"\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/path.h\r
+       <sys/stat.h>\r
+       "path_md.h"\r
+
+1396209483 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/path_md.h\r
+       <dirent.h>\r
+       <direct.h>\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/convert_md.h\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/classresolver.c\r
+       <ctype.h>\r
+       <string.h>\r
+       <sys/types.h>\r
+       <fcntl.h>\r
+       <sys/stat.h>\r
+       <stdlib.h>\r
+       "oobj.h"\r
+       "tree.h"\r
+       "signature.h"\r
+       "path.h"\r
+       "sys_api.h"\r
+       "convert_md.h"\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/file.c\r
+       <sys/types.h>\r
+       <fcntl.h>\r
+       <sys/stat.h>\r
+       <stdio.h>\r
+       <string.h>\r
+       <stdlib.h>\r
+       <stddef.h>\r
+       <unistd.h>\r
+       "oobj.h"\r
+       "jar.h"\r
+       "tree.h"\r
+       "sys_api.h"\r
+       "convert_md.h"\r
+       <direct.h>\r
+       "opcodes.init"\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/opcodes.init\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/inlinejsr.c\r
+       "check_code.h"\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/jar.c\r
+       <stdio.h>\r
+       <sys/types.h>\r
+       <stddef.h>\r
+       <assert.h>\r
+       "oobj.h"\r
+       "typedefs.h"\r
+       "jar.h"\r
+       "jarint.h"\r
+       "jartables.h"\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/jarint.h\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/jartables.h\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/jar_support.c\r
+       <ctype.h>\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <fcntl.h>\r
+       <sys/stat.h>\r
+       <sys/types.h>\r
+       <string.h>\r
+       "sys_api.h"\r
+       "path_md.h"\r
+       "path.h"\r
+       "oobj.h"\r
+       "jar.h"\r
+       "convert_md.h"\r
+       <string.h>\r
+       <process.h>\r
+
+1396211001 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/main.c\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <fcntl.h>\r
+       <sys/stat.h>\r
+       <sys/types.h>\r
+       <string.h>\r
+       "sys_api.h"\r
+       "path_md.h"\r
+       "path.h"\r
+       "oobj.h"\r
+       "locale_md.h"\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "../util/message.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../parser/parser.h"\r
+       "../util/memory.h"\r
+       "../main/static_entry.h"\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/locale_md.h\r
+       <locale.h>\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/stubs.c\r
+       "oobj.h"\r
+       "sys_api.h"\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/sys_support.c\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+       "oobj.h"\r
+       "jar.h"\r
+       "typedefs.h"\r
+       "sys_api.h"\r
+       "path.h"\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/utf.c\r
+       <stdio.h>\r
+       <string.h>\r
+       <stdlib.h>\r
+       "oobj.h"\r
+       "utf.h"\r
+       "sys_api.h"\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/util.c\r
+       <stdio.h>\r
+       <string.h>\r
+       <ctype.h>\r
+       <stddef.h>\r
+       "oobj.h"\r
+       "utf.h"\r
+       "sys_api.h"\r
+       "path.h"\r
+
+1396211001 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/block.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "../classgen/bytecode.h"\r
+       "type_list.h"\r
+       "string_list.h"\r
+       "type.h"\r
+       "identifier.h"\r
+       "name_table.h"\r
+       "unit.h"\r
+       "block.h"\r
+       "../classgen/preverify.h"\r
+       "../util/memory.h"\r
+       <string.h>\r
+       <stdlib.h>\r
+       <stdio.h>\r
+       "../classgen/constant_pool.h"\r
+       "../classgen/classgen.h"\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/identifier.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "type_list.h"\r
+       "string_list.h"\r
+       "type.h"\r
+       "identifier.h"\r
+       "name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "block.h"\r
+       "unit.h"\r
+       "../util/memory.h"\r
+       <string.h>\r
+       <stdlib.h>\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/name_table.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "type_list.h"\r
+       "string_list.h"\r
+       "type.h"\r
+       "identifier.h"\r
+       "name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "block.h"\r
+       "unit.h"\r
+       "../util/memory.h"\r
+       <string.h>\r
+       <stdlib.h>\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/string_list.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "string_list.h"\r
+       <string.h>\r
+       <stdlib.h>\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/type.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "type_list.h"\r
+       "string_list.h"\r
+       "type.h"\r
+       "identifier.h"\r
+       "name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "block.h"\r
+       "../util/memory.h"\r
+       <string.h>\r
+       <stdlib.h>\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/type_list.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "type_list.h"\r
+       "string_list.h"\r
+       "type.h"\r
+       "identifier.h"\r
+       "name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "block.h"\r
+       "../util/memory.h"\r
+       <stdlib.h>\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/unit.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "../classgen/bytecode.h"\r
+       "type_list.h"\r
+       "string_list.h"\r
+       "type.h"\r
+       "identifier.h"\r
+       "name_table.h"\r
+       "block.h"\r
+       "unit.h"\r
+       "../classgen/preverify.h"\r
+       "../util/memory.h"\r
+       <string.h>\r
+       <stdlib.h>\r
+       <stdio.h>\r
+       "../classgen/constant_pool.h"\r
+       "../classgen/classgen.h"\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/util/error.c\r
+       <stdio.h>\r
+       <stdlib.h>\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/util/memory.c\r
+       <stdlib.h>\r
+       <string.h>\r
+       "memory.h"\r
+       "error.h"\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/util/strings.c\r
+       "error.h"\r
+       "strings.h"\r
+       "memory.h"\r
+       <stdlib.h>\r
+       <string.h>\r
+
+1396279194 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/convert_md.c\r
+       <stdio.h>\r
+       <string.h>\r
+       <langinfo.h>\r
+       <iconv.h>\r
+       <locale.h>\r
+       <stdlib.h>\r
+       <WINDOWS.H>\r
+       "oobj.h"\r
+       "utf.h"\r
+
+1359821690 source:d:\work\mp3cc-source\mpc.3.5.linux\classgen\bytecode.c\r
+       "bytecode.h"\r
+       "../util/error.h"\r
+       "../util/memory.h"\r
+       <stdlib.h>\r
+       <string.h>\r
+       <stdio.h>\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\classgen\bytecode.h\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\util\error.h\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\util\memory.h\r
+
+1396210518 source:d:\work\mp3cc-source\mpc.3.5.linux\classgen\classgen.c\r
+       "../util/error.h"\r
+       "../util/strings.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../classgen/constant_pool.h"\r
+       "../classgen/preverify.h"\r
+       "../util/memory.h"\r
+       <stdio.h>\r
+       <string.h>\r
+       <stdlib.h>\r
+       "classgen.h"\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\util\strings.h\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\structures\type_list.h\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\structures\string_list.h\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\structures\type.h\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\structures\identifier.h\r
+       <stdio.h>\r
+
+1396200141 d:\work\mp3cc-source\mpc.3.5.linux\structures\name_table.h\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\structures\block.h\r
+       <stdio.h>\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\classgen\constant_pool.h\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\classgen\preverify.h\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\classgen\classgen.h\r
+
+1359821690 source:d:\work\mp3cc-source\mpc.3.5.linux\classgen\constant_pool.c\r
+       <stdlib.h>\r
+       <string.h>\r
+       <stdio.h>\r
+       "constant_pool.h"\r
+       "../util/error.h"\r
+       "../util/strings.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../util/memory.h"\r
+       "classgen.h"\r
+
+1359821690 source:d:\work\mp3cc-source\mpc.3.5.linux\classgen\preverify.c\r
+       <stdlib.h>\r
+       <string.h>\r
+       <stdio.h>\r
+       "../util/error.h"\r
+       "../util/strings.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "constant_pool.h"\r
+       "bytecode.h"\r
+       "preverify.h"\r
+       "../util/error.h"\r
+       "../util/memory.h"\r
+
+1396208800 source:d:\work\mp3cc-source\mpc.3.5.linux\lex\lex.yy.c\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+       "tokens.h"\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\lex\tokens.h\r
+
+1396302610 source:d:\work\mp3cc-source\mpc.3.5.linux\main\main.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../parser/parser.h"\r
+       "../util/memory.h"\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+       <getopt.h>\r
+       <windows.h>\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\parser\parser.h\r
+
+1396210518 source:d:\work\mp3cc-source\mpc.3.5.linux\parser\parser.c\r
+       "../util/error.h"\r
+       "../util/strings.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../lex/tokens.h"\r
+       "../util/memory.h"\r
+       "../structures/unit.h"\r
+       "../classgen/constant_pool.h"\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+       "../classgen/classgen.h"\r
+       "parser.h"\r
+       "stdpas.h"\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\structures\unit.h\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\parser\stdpas.h\r
+
+1359821690 source:d:\work\mp3cc-source\mpc.3.5.linux\parser\stdpas.c\r
+       "../util/strings.h"\r
+       "../util/error.h"\r
+       "../structures/type_list.h"\r
+       "../structures/string_list.h"\r
+       "../structures/type.h"\r
+       "../structures/identifier.h"\r
+       "../structures/name_table.h"\r
+       "../classgen/bytecode.h"\r
+       "../structures/block.h"\r
+       "../classgen/constant_pool.h"\r
+       "stdpas.h"\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+
+1359821690 source:d:\work\mp3cc-source\mpc.3.5.linux\preverifier\check_class.c\r
+       <ctype.h>\r
+       "oobj.h"\r
+       "utf.h"\r
+       "tree.h"\r
+       "sys_api.h"\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\preverifier\oobj.h\r
+       <stddef.h>\r
+       <stdarg.h>\r
+       <stdio.h>\r
+       <stdlib.h>\r
+       <string.h>\r
+       <limits.h>\r
+       "typedefs.h"\r
+       "signature.h"\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\preverifier\typedefs.h\r
+       "typedefs_md.h"\r
+
+1396351241 d:\work\mp3cc-source\mpc.3.5.linux\preverifier\typedefs_md.h\r
+       <sys/types.h>\r
+       <sys/stat.h>\r
+       <sys/byteorder.h>\r
+       <asm/byteorder.h>\r
+       <windows.h>\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\preverifier\signature.h\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\preverifier\utf.h\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\preverifier\tree.h\r
+       "oobj.h"\r
+       "typecodes.h"\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\preverifier\typecodes.h\r
+
+1396350064 d:\work\mp3cc-source\mpc.3.5.linux\preverifier\sys_api.h\r
+       "typedefs.h"\r
+       <time.h>\r
+       "sysmacros_md.h"\r
+
+1396195701 d:\work\mp3cc-source\mpc.3.5.linux\preverifier\sysmacros_md.h\r
+       <io.h>\r
+
+1359821690 source:d:\work\mp3cc-source\mpc.3.5.linux\preverifier\check_code.c\r
+       "check_code.h"\r
+       "opcodes.length"\r
+       "opcodes.in_out"\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\preverifier\check_code.h\r
+       <setjmp.h>\r
+       "oobj.h"\r
+       "opcodes.h"\r
+       "tree.h"\r
+       "sys_api.h"\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\preverifier\opcodes.h\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\preverifier\opcodes.length\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\preverifier\opcodes.in_out\r
+
+1396211517 source:d:\work\mp3cc-source\mpc.3.5.linux\preverifier\classloader.c\r
+       <string.h>\r
+       <stdio.h>\r
+       <sys/types.h>\r
+       <stddef.h>\r
+       <fcntl.h>\r
+       <sys/stat.h>\r
+       <stdlib.h>\r
+       <setjmp.h>\r
+       "jar.h"\r
+       "oobj.h"\r
+       "path.h"\r
+       "tree.h"\r
+       "signature.h"\r
+       "convert_md.h"\r
+       "sys_api.h"\r
+       <unistd.h>\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\preverifier\jar.h\r
+       "typedefs.h"\r
+       "stdio.h"\r
+       "sys/types.h"\r
+       "stddef.h"\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\preverifier\path.h\r
+       <sys/stat.h>\r
+       "path_md.h"\r
+
+1396209483 d:\work\mp3cc-source\mpc.3.5.linux\preverifier\path_md.h\r
+       <dirent.h>\r
+       <direct.h>\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\preverifier\convert_md.h\r
+
+1359821690 source:d:\work\mp3cc-source\mpc.3.5.linux\preverifier\classresolver.c\r
+       <ctype.h>\r
+       <string.h>\r
+       <sys/types.h>\r
+       <fcntl.h>\r
+       <sys/stat.h>\r
+       <stdlib.h>\r
+       "oobj.h"\r
+       "tree.h"\r
+       "signature.h"\r
+       "path.h"\r
+       "sys_api.h"\r
+       "convert_md.h"\r
+
+1396279194 source:d:\work\mp3cc-source\mpc.3.5.linux\preverifier\convert_md.c\r
+       <stdio.h>\r
+       <string.h>\r
+       <langinfo.h>\r
+       <iconv.h>\r
+       <locale.h>\r
+       <stdlib.h>\r
+       <WINDOWS.H>\r
+       "oobj.h"\r
+       "utf.h"\r
+
+1359821690 source:d:\work\mp3cc-source\mpc.3.5.linux\preverifier\file.c\r
+       <sys/types.h>\r
+       <fcntl.h>\r
+       <sys/stat.h>\r
+       <stdio.h>\r
+       <string.h>\r
+       <stdlib.h>\r
+       <stddef.h>\r
+       <unistd.h>\r
+       "oobj.h"\r
+       "jar.h"\r
+       "tree.h"\r
+       "sys_api.h"\r
+       "convert_md.h"\r
+       <direct.h>\r
+       "opcodes.init"\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\preverifier\opcodes.init\r
+
+1359821690 source:d:\work\mp3cc-source\mpc.3.5.linux\preverifier\inlinejsr.c\r
+       "check_code.h"\r
+
+1359821690 source:d:\work\mp3cc-source\mpc.3.5.linux\preverifier\jar.c\r
+       <stdio.h>\r
+       <sys/types.h>\r
+       <stddef.h>\r
+       <assert.h>\r
+       "oobj.h"\r
+       "typedefs.h"\r
+       "jar.h"\r
+       "jarint.h"\r
+       "jartables.h"\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\preverifier\jarint.h\r
+
+1359821690 d:\work\mp3cc-source\mpc.3.5.linux\preverifier\jartables.h\r
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/classgen/bytecode.c
+       "bytecode.h"
+       "../util/error.h"
+       "../util/memory.h"
+       <stdlib.h>
+       <string.h>
+       <stdio.h>
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/classgen/bytecode.h
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/util/error.h
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/util/memory.h
+
+1396210518 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/classgen/classgen.c
+       "../util/error.h"
+       "../util/strings.h"
+       "../structures/type_list.h"
+       "../structures/string_list.h"
+       "../structures/type.h"
+       "../structures/identifier.h"
+       "../structures/name_table.h"
+       "../classgen/bytecode.h"
+       "../structures/block.h"
+       "../classgen/constant_pool.h"
+       "../classgen/preverify.h"
+       "../util/memory.h"
+       <stdio.h>
+       <string.h>
+       <stdlib.h>
+       "classgen.h"
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/util/strings.h
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/type_list.h
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/string_list.h
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/type.h
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/identifier.h
+       <stdio.h>
+
+1396200141 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/name_table.h
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/block.h
+       <stdio.h>
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/classgen/constant_pool.h
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/classgen/preverify.h
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/classgen/classgen.h
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/classgen/constant_pool.c
+       <stdlib.h>
+       <string.h>
+       <stdio.h>
+       "constant_pool.h"
+       "../util/error.h"
+       "../util/strings.h"
+       "../structures/type_list.h"
+       "../structures/string_list.h"
+       "../structures/type.h"
+       "../structures/identifier.h"
+       "../structures/name_table.h"
+       "../classgen/bytecode.h"
+       "../structures/block.h"
+       "../util/memory.h"
+       "classgen.h"
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/classgen/preverify.c
+       <stdlib.h>
+       <string.h>
+       <stdio.h>
+       "../util/error.h"
+       "../util/strings.h"
+       "../structures/type_list.h"
+       "../structures/string_list.h"
+       "../structures/type.h"
+       "../structures/identifier.h"
+       "../structures/name_table.h"
+       "constant_pool.h"
+       "bytecode.h"
+       "preverify.h"
+       "../util/error.h"
+       "../util/memory.h"
+
+1396208800 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/lex/lex.yy.c
+       <stdio.h>
+       <stdlib.h>
+       <string.h>
+       "tokens.h"
+       "../util/strings.h"
+       "../util/error.h"
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/lex/tokens.h
+
+1396302610 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/main/main.c
+       "../util/strings.h"
+       "../util/error.h"
+       "../structures/type_list.h"
+       "../structures/string_list.h"
+       "../structures/type.h"
+       "../structures/identifier.h"
+       "../structures/name_table.h"
+       "../classgen/bytecode.h"
+       "../structures/block.h"
+       "../parser/parser.h"
+       "../util/memory.h"
+       <stdio.h>
+       <stdlib.h>
+       <string.h>
+       <getopt.h>
+       <windows.h>
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/parser/parser.h
+
+1396210518 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/parser/parser.c
+       "../util/error.h"
+       "../util/strings.h"
+       "../structures/type_list.h"
+       "../structures/string_list.h"
+       "../structures/type.h"
+       "../structures/identifier.h"
+       "../structures/name_table.h"
+       "../classgen/bytecode.h"
+       "../structures/block.h"
+       "../lex/tokens.h"
+       "../util/memory.h"
+       "../structures/unit.h"
+       "../classgen/constant_pool.h"
+       <stdio.h>
+       <stdlib.h>
+       <string.h>
+       "../classgen/classgen.h"
+       "parser.h"
+       "stdpas.h"
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/unit.h
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/parser/stdpas.h
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/parser/stdpas.c
+       "../util/strings.h"
+       "../util/error.h"
+       "../structures/type_list.h"
+       "../structures/string_list.h"
+       "../structures/type.h"
+       "../structures/identifier.h"
+       "../structures/name_table.h"
+       "../classgen/bytecode.h"
+       "../structures/block.h"
+       "../classgen/constant_pool.h"
+       "stdpas.h"
+       <stdio.h>
+       <stdlib.h>
+       <string.h>
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/check_class.c
+       <ctype.h>
+       "oobj.h"
+       "utf.h"
+       "tree.h"
+       "sys_api.h"
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/oobj.h
+       <stddef.h>
+       <stdarg.h>
+       <stdio.h>
+       <stdlib.h>
+       <string.h>
+       <limits.h>
+       "typedefs.h"
+       "signature.h"
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/typedefs.h
+       "typedefs_md.h"
+
+1396351241 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/typedefs_md.h
+       <sys/types.h>
+       <sys/stat.h>
+       <sys/byteorder.h>
+       <asm/byteorder.h>
+       <windows.h>
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/signature.h
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/utf.h
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/tree.h
+       "oobj.h"
+       "typecodes.h"
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/typecodes.h
+
+1396368719 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/sys_api.h
+       "typedefs.h"
+       <time.h>
+       "sysmacros_md.h"
+
+1396195701 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/sysmacros_md.h
+       <io.h>
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/check_code.c
+       "check_code.h"
+       "opcodes.length"
+       "opcodes.in_out"
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/check_code.h
+       <setjmp.h>
+       "oobj.h"
+       "opcodes.h"
+       "tree.h"
+       "sys_api.h"
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/opcodes.h
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/opcodes.length
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/opcodes.in_out
+
+1396211517 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/classloader.c
+       <string.h>
+       <stdio.h>
+       <sys/types.h>
+       <stddef.h>
+       <fcntl.h>
+       <sys/stat.h>
+       <stdlib.h>
+       <setjmp.h>
+       "jar.h"
+       "oobj.h"
+       "path.h"
+       "tree.h"
+       "signature.h"
+       "convert_md.h"
+       "sys_api.h"
+       <unistd.h>
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/jar.h
+       "typedefs.h"
+       "stdio.h"
+       "sys/types.h"
+       "stddef.h"
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/path.h
+       <sys/stat.h>
+       "path_md.h"
+
+1396209483 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/path_md.h
+       <dirent.h>
+       <direct.h>
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/convert_md.h
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/classresolver.c
+       <ctype.h>
+       <string.h>
+       <sys/types.h>
+       <fcntl.h>
+       <sys/stat.h>
+       <stdlib.h>
+       "oobj.h"
+       "tree.h"
+       "signature.h"
+       "path.h"
+       "sys_api.h"
+       "convert_md.h"
+
+1396279194 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/convert_md.c
+       <stdio.h>
+       <string.h>
+       <langinfo.h>
+       <iconv.h>
+       <locale.h>
+       <stdlib.h>
+       <WINDOWS.H>
+       "oobj.h"
+       "utf.h"
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/file.c
+       <sys/types.h>
+       <fcntl.h>
+       <sys/stat.h>
+       <stdio.h>
+       <string.h>
+       <stdlib.h>
+       <stddef.h>
+       <unistd.h>
+       "oobj.h"
+       "jar.h"
+       "tree.h"
+       "sys_api.h"
+       "convert_md.h"
+       <direct.h>
+       "opcodes.init"
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/opcodes.init
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/inlinejsr.c
+       "check_code.h"
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/jar.c
+       <stdio.h>
+       <sys/types.h>
+       <stddef.h>
+       <assert.h>
+       "oobj.h"
+       "typedefs.h"
+       "jar.h"
+       "jarint.h"
+       "jartables.h"
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/jarint.h
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/jartables.h
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/jar_support.c
+       <ctype.h>
+       <stdio.h>
+       <stdlib.h>
+       <fcntl.h>
+       <sys/stat.h>
+       <sys/types.h>
+       <string.h>
+       "sys_api.h"
+       "path_md.h"
+       "path.h"
+       "oobj.h"
+       "jar.h"
+       "convert_md.h"
+       <string.h>
+       <process.h>
+
+1396211001 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/main.c
+       <stdio.h>
+       <stdlib.h>
+       <fcntl.h>
+       <sys/stat.h>
+       <sys/types.h>
+       <string.h>
+       "sys_api.h"
+       "path_md.h"
+       "path.h"
+       "oobj.h"
+       "locale_md.h"
+       "../util/strings.h"
+       "../util/error.h"
+       "../util/message.h"
+       "../structures/type_list.h"
+       "../structures/string_list.h"
+       "../structures/type.h"
+       "../structures/identifier.h"
+       "../structures/name_table.h"
+       "../classgen/bytecode.h"
+       "../structures/block.h"
+       "../parser/parser.h"
+       "../util/memory.h"
+       "../main/static_entry.h"
+       <stdio.h>
+       <stdlib.h>
+       <string.h>
+
+1359818090 /media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/locale_md.h
+       <locale.h>
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/stubs.c
+       "oobj.h"
+       "sys_api.h"
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/sys_support.c
+       <stdio.h>
+       <stdlib.h>
+       <string.h>
+       "oobj.h"
+       "jar.h"
+       "typedefs.h"
+       "sys_api.h"
+       "path.h"
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/utf.c
+       <stdio.h>
+       <string.h>
+       <stdlib.h>
+       "oobj.h"
+       "utf.h"
+       "sys_api.h"
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/util.c
+       <stdio.h>
+       <string.h>
+       <ctype.h>
+       <stddef.h>
+       "oobj.h"
+       "utf.h"
+       "sys_api.h"
+       "path.h"
+
+1396211001 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/block.c
+       "../util/strings.h"
+       "../util/error.h"
+       "../classgen/bytecode.h"
+       "type_list.h"
+       "string_list.h"
+       "type.h"
+       "identifier.h"
+       "name_table.h"
+       "unit.h"
+       "block.h"
+       "../classgen/preverify.h"
+       "../util/memory.h"
+       <string.h>
+       <stdlib.h>
+       <stdio.h>
+       "../classgen/constant_pool.h"
+       "../classgen/classgen.h"
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/identifier.c
+       "../util/strings.h"
+       "../util/error.h"
+       "type_list.h"
+       "string_list.h"
+       "type.h"
+       "identifier.h"
+       "name_table.h"
+       "../classgen/bytecode.h"
+       "block.h"
+       "unit.h"
+       "../util/memory.h"
+       <string.h>
+       <stdlib.h>
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/name_table.c
+       "../util/strings.h"
+       "../util/error.h"
+       "type_list.h"
+       "string_list.h"
+       "type.h"
+       "identifier.h"
+       "name_table.h"
+       "../classgen/bytecode.h"
+       "block.h"
+       "unit.h"
+       "../util/memory.h"
+       <string.h>
+       <stdlib.h>
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/string_list.c
+       "../util/strings.h"
+       "../util/error.h"
+       "string_list.h"
+       <string.h>
+       <stdlib.h>
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/type.c
+       "../util/strings.h"
+       "../util/error.h"
+       "type_list.h"
+       "string_list.h"
+       "type.h"
+       "identifier.h"
+       "name_table.h"
+       "../classgen/bytecode.h"
+       "block.h"
+       "../util/memory.h"
+       <string.h>
+       <stdlib.h>
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/type_list.c
+       "../util/strings.h"
+       "../util/error.h"
+       "type_list.h"
+       "string_list.h"
+       "type.h"
+       "identifier.h"
+       "name_table.h"
+       "../classgen/bytecode.h"
+       "block.h"
+       "../util/memory.h"
+       <stdlib.h>
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/structures/unit.c
+       "../util/strings.h"
+       "../util/error.h"
+       "../classgen/bytecode.h"
+       "type_list.h"
+       "string_list.h"
+       "type.h"
+       "identifier.h"
+       "name_table.h"
+       "block.h"
+       "unit.h"
+       "../classgen/preverify.h"
+       "../util/memory.h"
+       <string.h>
+       <stdlib.h>
+       <stdio.h>
+       "../classgen/constant_pool.h"
+       "../classgen/classgen.h"
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/util/error.c
+       <stdio.h>
+       <stdlib.h>
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/util/memory.c
+       <stdlib.h>
+       <string.h>
+       "memory.h"
+       "error.h"
+
+1359818090 source:/media/second/Work/mp3CC-source/MPC.3.5.LINUX/util/strings.c
+       "error.h"
+       "strings.h"
+       "memory.h"
+       <stdlib.h>
+       <string.h>
+
+1359818090 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/classgen/bytecode.c
+       "bytecode.h"
+       "../util/error.h"
+       "../util/memory.h"
+       <stdlib.h>
+       <string.h>
+       <stdio.h>
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/classgen/bytecode.h
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/util/error.h
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/util/memory.h
+
+1396210518 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/classgen/classgen.c
+       "../util/error.h"
+       "../util/strings.h"
+       "../structures/type_list.h"
+       "../structures/string_list.h"
+       "../structures/type.h"
+       "../structures/identifier.h"
+       "../structures/name_table.h"
+       "../classgen/bytecode.h"
+       "../structures/block.h"
+       "../classgen/constant_pool.h"
+       "../classgen/preverify.h"
+       "../util/memory.h"
+       <stdio.h>
+       <string.h>
+       <stdlib.h>
+       "classgen.h"
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/util/strings.h
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/structures/type_list.h
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/structures/string_list.h
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/structures/type.h
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/structures/identifier.h
+       <stdio.h>
+
+1396200141 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/structures/name_table.h
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/structures/block.h
+       <stdio.h>
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/classgen/constant_pool.h
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/classgen/preverify.h
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/classgen/classgen.h
+
+1359818090 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/classgen/constant_pool.c
+       <stdlib.h>
+       <string.h>
+       <stdio.h>
+       "constant_pool.h"
+       "../util/error.h"
+       "../util/strings.h"
+       "../structures/type_list.h"
+       "../structures/string_list.h"
+       "../structures/type.h"
+       "../structures/identifier.h"
+       "../structures/name_table.h"
+       "../classgen/bytecode.h"
+       "../structures/block.h"
+       "../util/memory.h"
+       "classgen.h"
+
+1359818090 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/classgen/preverify.c
+       <stdlib.h>
+       <string.h>
+       <stdio.h>
+       "../util/error.h"
+       "../util/strings.h"
+       "../structures/type_list.h"
+       "../structures/string_list.h"
+       "../structures/type.h"
+       "../structures/identifier.h"
+       "../structures/name_table.h"
+       "constant_pool.h"
+       "bytecode.h"
+       "preverify.h"
+       "../util/error.h"
+       "../util/memory.h"
+
+1407751994 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/lex/lex.yy.c
+       <stdio.h>
+       <stdlib.h>
+       <string.h>
+       "tokens.h"
+       "../util/strings.h"
+       "../util/error.h"
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/lex/tokens.h
+
+1407751870 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/main/main.c
+       "../util/strings.h"
+       "../util/error.h"
+       "../structures/type_list.h"
+       "../structures/string_list.h"
+       "../structures/type.h"
+       "../structures/identifier.h"
+       "../structures/name_table.h"
+       "../classgen/bytecode.h"
+       "../structures/block.h"
+       "../parser/parser.h"
+       "../util/memory.h"
+       <stdio.h>
+       <stdlib.h>
+       <string.h>
+       <getopt.h>
+       <windows.h>
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/parser/parser.h
+
+1396210518 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/parser/parser.c
+       "../util/error.h"
+       "../util/strings.h"
+       "../structures/type_list.h"
+       "../structures/string_list.h"
+       "../structures/type.h"
+       "../structures/identifier.h"
+       "../structures/name_table.h"
+       "../classgen/bytecode.h"
+       "../structures/block.h"
+       "../lex/tokens.h"
+       "../util/memory.h"
+       "../structures/unit.h"
+       "../classgen/constant_pool.h"
+       <stdio.h>
+       <stdlib.h>
+       <string.h>
+       "../classgen/classgen.h"
+       "parser.h"
+       "stdpas.h"
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/structures/unit.h
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/parser/stdpas.h
+
+1359818090 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/parser/stdpas.c
+       "../util/strings.h"
+       "../util/error.h"
+       "../structures/type_list.h"
+       "../structures/string_list.h"
+       "../structures/type.h"
+       "../structures/identifier.h"
+       "../structures/name_table.h"
+       "../classgen/bytecode.h"
+       "../structures/block.h"
+       "../classgen/constant_pool.h"
+       "stdpas.h"
+       <stdio.h>
+       <stdlib.h>
+       <string.h>
+
+1359818090 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/check_class.c
+       <ctype.h>
+       "oobj.h"
+       "utf.h"
+       "tree.h"
+       "sys_api.h"
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/oobj.h
+       <stddef.h>
+       <stdarg.h>
+       <stdio.h>
+       <stdlib.h>
+       <string.h>
+       <limits.h>
+       "typedefs.h"
+       "signature.h"
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/typedefs.h
+       "typedefs_md.h"
+
+1396351241 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/typedefs_md.h
+       <sys/types.h>
+       <sys/stat.h>
+       <sys/byteorder.h>
+       <asm/byteorder.h>
+       <windows.h>
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/signature.h
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/utf.h
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/tree.h
+       "oobj.h"
+       "typecodes.h"
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/typecodes.h
+
+1396368719 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/sys_api.h
+       "typedefs.h"
+       <time.h>
+       "sysmacros_md.h"
+
+1396195701 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/sysmacros_md.h
+       <io.h>
+
+1359818090 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/check_code.c
+       "check_code.h"
+       "opcodes.length"
+       "opcodes.in_out"
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/check_code.h
+       <setjmp.h>
+       "oobj.h"
+       "opcodes.h"
+       "tree.h"
+       "sys_api.h"
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/opcodes.h
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/opcodes.length
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/opcodes.in_out
+
+1396211517 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/classloader.c
+       <string.h>
+       <stdio.h>
+       <sys/types.h>
+       <stddef.h>
+       <fcntl.h>
+       <sys/stat.h>
+       <stdlib.h>
+       <setjmp.h>
+       "jar.h"
+       "oobj.h"
+       "path.h"
+       "tree.h"
+       "signature.h"
+       "convert_md.h"
+       "sys_api.h"
+       <unistd.h>
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/jar.h
+       "typedefs.h"
+       "stdio.h"
+       "sys/types.h"
+       "stddef.h"
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/path.h
+       <sys/stat.h>
+       "path_md.h"
+
+1396209483 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/path_md.h
+       <dirent.h>
+       <direct.h>
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/convert_md.h
+
+1359818090 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/classresolver.c
+       <ctype.h>
+       <string.h>
+       <sys/types.h>
+       <fcntl.h>
+       <sys/stat.h>
+       <stdlib.h>
+       "oobj.h"
+       "tree.h"
+       "signature.h"
+       "path.h"
+       "sys_api.h"
+       "convert_md.h"
+
+1396279194 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/convert_md.c
+       <stdio.h>
+       <string.h>
+       <langinfo.h>
+       <iconv.h>
+       <locale.h>
+       <stdlib.h>
+       <WINDOWS.H>
+       "oobj.h"
+       "utf.h"
+
+1359818090 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/file.c
+       <sys/types.h>
+       <fcntl.h>
+       <sys/stat.h>
+       <stdio.h>
+       <string.h>
+       <stdlib.h>
+       <stddef.h>
+       <unistd.h>
+       "oobj.h"
+       "jar.h"
+       "tree.h"
+       "sys_api.h"
+       "convert_md.h"
+       <direct.h>
+       "opcodes.init"
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/opcodes.init
+
+1359818090 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/inlinejsr.c
+       "check_code.h"
+
+1359818090 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/jar.c
+       <stdio.h>
+       <sys/types.h>
+       <stddef.h>
+       <assert.h>
+       "oobj.h"
+       "typedefs.h"
+       "jar.h"
+       "jarint.h"
+       "jartables.h"
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/jarint.h
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/jartables.h
+
+1359818090 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/jar_support.c
+       <ctype.h>
+       <stdio.h>
+       <stdlib.h>
+       <fcntl.h>
+       <sys/stat.h>
+       <sys/types.h>
+       <string.h>
+       "sys_api.h"
+       "path_md.h"
+       "path.h"
+       "oobj.h"
+       "jar.h"
+       "convert_md.h"
+       <string.h>
+       <process.h>
+
+1396211001 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/main.c
+       <stdio.h>
+       <stdlib.h>
+       <fcntl.h>
+       <sys/stat.h>
+       <sys/types.h>
+       <string.h>
+       "sys_api.h"
+       "path_md.h"
+       "path.h"
+       "oobj.h"
+       "locale_md.h"
+       "../util/strings.h"
+       "../util/error.h"
+       "../util/message.h"
+       "../structures/type_list.h"
+       "../structures/string_list.h"
+       "../structures/type.h"
+       "../structures/identifier.h"
+       "../structures/name_table.h"
+       "../classgen/bytecode.h"
+       "../structures/block.h"
+       "../parser/parser.h"
+       "../util/memory.h"
+       "../main/static_entry.h"
+       <stdio.h>
+       <stdlib.h>
+       <string.h>
+
+1359818090 /home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/locale_md.h
+       <locale.h>
+
+1359818090 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/stubs.c
+       "oobj.h"
+       "sys_api.h"
+
+1359818090 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/sys_support.c
+       <stdio.h>
+       <stdlib.h>
+       <string.h>
+       "oobj.h"
+       "jar.h"
+       "typedefs.h"
+       "sys_api.h"
+       "path.h"
+
+1359818090 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/utf.c
+       <stdio.h>
+       <string.h>
+       <stdlib.h>
+       "oobj.h"
+       "utf.h"
+       "sys_api.h"
+
+1359818090 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/preverifier/util.c
+       <stdio.h>
+       <string.h>
+       <ctype.h>
+       <stddef.h>
+       "oobj.h"
+       "utf.h"
+       "sys_api.h"
+       "path.h"
+
+1396211001 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/structures/block.c
+       "../util/strings.h"
+       "../util/error.h"
+       "../classgen/bytecode.h"
+       "type_list.h"
+       "string_list.h"
+       "type.h"
+       "identifier.h"
+       "name_table.h"
+       "unit.h"
+       "block.h"
+       "../classgen/preverify.h"
+       "../util/memory.h"
+       <string.h>
+       <stdlib.h>
+       <stdio.h>
+       "../classgen/constant_pool.h"
+       "../classgen/classgen.h"
+
+1359818090 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/structures/identifier.c
+       "../util/strings.h"
+       "../util/error.h"
+       "type_list.h"
+       "string_list.h"
+       "type.h"
+       "identifier.h"
+       "name_table.h"
+       "../classgen/bytecode.h"
+       "block.h"
+       "unit.h"
+       "../util/memory.h"
+       <string.h>
+       <stdlib.h>
+
+1359818090 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/structures/name_table.c
+       "../util/strings.h"
+       "../util/error.h"
+       "type_list.h"
+       "string_list.h"
+       "type.h"
+       "identifier.h"
+       "name_table.h"
+       "../classgen/bytecode.h"
+       "block.h"
+       "unit.h"
+       "../util/memory.h"
+       <string.h>
+       <stdlib.h>
+
+1359818090 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/structures/string_list.c
+       "../util/strings.h"
+       "../util/error.h"
+       "string_list.h"
+       <string.h>
+       <stdlib.h>
+
+1359818090 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/structures/type.c
+       "../util/strings.h"
+       "../util/error.h"
+       "type_list.h"
+       "string_list.h"
+       "type.h"
+       "identifier.h"
+       "name_table.h"
+       "../classgen/bytecode.h"
+       "block.h"
+       "../util/memory.h"
+       <string.h>
+       <stdlib.h>
+
+1359818090 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/structures/type_list.c
+       "../util/strings.h"
+       "../util/error.h"
+       "type_list.h"
+       "string_list.h"
+       "type.h"
+       "identifier.h"
+       "name_table.h"
+       "../classgen/bytecode.h"
+       "block.h"
+       "../util/memory.h"
+       <stdlib.h>
+
+1359818090 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/structures/unit.c
+       "../util/strings.h"
+       "../util/error.h"
+       "../classgen/bytecode.h"
+       "type_list.h"
+       "string_list.h"
+       "type.h"
+       "identifier.h"
+       "name_table.h"
+       "block.h"
+       "unit.h"
+       "../classgen/preverify.h"
+       "../util/memory.h"
+       <string.h>
+       <stdlib.h>
+       <stdio.h>
+       "../classgen/constant_pool.h"
+       "../classgen/classgen.h"
+
+1359818090 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/util/error.c
+       <stdio.h>
+       <stdlib.h>
+
+1359818090 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/util/memory.c
+       <stdlib.h>
+       <string.h>
+       "memory.h"
+       "error.h"
+
+1359818090 source:/home/deaddoomer/Work/mp3CC-source/MPC.3.5.LINUX/util/strings.c
+       "error.h"
+       "strings.h"
+       "memory.h"
+       <stdlib.h>
+       <string.h>
+
diff --git a/MPC.3.5.LINUX/mp3CC.layout b/MPC.3.5.LINUX/mp3CC.layout
new file mode 100644 (file)
index 0000000..62efb17
--- /dev/null
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_layout_file>
+       <ActiveTarget name="LINUX32" />
+       <File name="util/memory.c" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="1213" topLine="62" />
+               </Cursor>
+       </File>
+       <File name="structures/block.c" open="0" top="0" tabpos="6" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="11692" topLine="425" />
+               </Cursor>
+       </File>
+       <File name="parser/parser.c" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="227" topLine="441" />
+               </Cursor>
+       </File>
+       <File name="classgen/preverify.c" open="0" top="0" tabpos="10" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="20098" topLine="940" />
+               </Cursor>
+       </File>
+       <File name="preverifier/typedefs.h" open="0" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="911" topLine="37" />
+               </Cursor>
+       </File>
+       <File name="preverifier/sys_api.h" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="2470" topLine="81" />
+               </Cursor>
+       </File>
+       <File name="preverifier/classloader.c" open="0" top="0" tabpos="10" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="23674" topLine="703" />
+               </Cursor>
+       </File>
+       <File name="preverifier/jar.c" open="0" top="0" tabpos="14" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="4720" topLine="117" />
+               </Cursor>
+       </File>
+       <File name="preverifier/jartables.h" open="0" top="0" tabpos="7" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="15381" topLine="507" />
+               </Cursor>
+       </File>
+       <File name="util/strings.c" open="0" top="0" tabpos="9" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="3477" topLine="161" />
+               </Cursor>
+       </File>
+       <File name="classgen/bytecode.c" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="0" topLine="0" />
+               </Cursor>
+       </File>
+       <File name="preverifier/typedefs_md.h" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="1325" topLine="41" />
+               </Cursor>
+       </File>
+       <File name="classgen/classgen.c" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="1895" topLine="0" />
+               </Cursor>
+       </File>
+       <File name="main/main.c" open="1" top="1" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="7039" topLine="252" />
+               </Cursor>
+       </File>
+       <File name="structures/name_table.c" open="0" top="0" tabpos="7" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="1194" topLine="34" />
+               </Cursor>
+       </File>
+       <File name="preverifier/util.c" open="0" top="0" tabpos="8" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="9982" topLine="367" />
+               </Cursor>
+       </File>
+       <File name="preverifier/sys_support.c" open="0" top="0" tabpos="9" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="8747" topLine="249" />
+               </Cursor>
+       </File>
+       <File name="util/memory.h" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="395" topLine="0" />
+               </Cursor>
+       </File>
+       <File name="structures/string_list.c" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="0" topLine="88" />
+               </Cursor>
+       </File>
+       <File name="structures/identifier.c" open="0" top="0" tabpos="12" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="8404" topLine="361" />
+               </Cursor>
+       </File>
+       <File name="parser/stdpas.c" open="0" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="1815" topLine="3117" />
+               </Cursor>
+       </File>
+       <File name="preverifier/path_md.h" open="0" top="0" tabpos="6" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="698" topLine="3" />
+               </Cursor>
+       </File>
+       <File name="preverifier/convert_md.c" open="0" top="0" tabpos="18" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="1298" topLine="23" />
+               </Cursor>
+       </File>
+       <File name="lex/lex.yy.c" open="0" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="308" topLine="7" />
+               </Cursor>
+       </File>
+       <File name="parser/parser.h" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="0" topLine="23" />
+               </Cursor>
+       </File>
+       <File name="util/error.c" open="0" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="7944" topLine="127" />
+               </Cursor>
+       </File>
+       <File name="preverifier/oobj.h" open="0" top="0" tabpos="17" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="773" topLine="0" />
+               </Cursor>
+       </File>
+       <File name="preverifier/main.c" open="0" top="0" tabpos="15" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="15033" topLine="443" />
+               </Cursor>
+       </File>
+       <File name="preverifier/jar_support.c" open="0" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="41153" topLine="1220" />
+               </Cursor>
+       </File>
+       <File name="preverifier/check_code.c" open="0" top="0" tabpos="11" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+               <Cursor>
+                       <Cursor1 position="10928" topLine="249" />
+               </Cursor>
+       </File>
+</CodeBlocks_layout_file>
diff --git a/MPC.3.5.LINUX/parser/parser.c b/MPC.3.5.LINUX/parser/parser.c
new file mode 100644 (file)
index 0000000..a2acec5
--- /dev/null
@@ -0,0 +1,6835 @@
+/********************************************************************
+
+       parser.c - recursive-descent parser
+
+  Niksa Orlic, 2004-04-19
+
+********************************************************************/
+
+
+//#include "../util/message.h"
+#include "../util/error.h"
+#include "../util/strings.h"
+#include "../structures/type_list.h"
+#include "../structures/string_list.h"
+#include "../structures/type.h"
+#include "../structures/identifier.h"
+#include "../structures/name_table.h"
+#include "../classgen/bytecode.h"
+#include "../structures/block.h"
+#include "../lex/tokens.h"
+#include "../util/memory.h"
+#include "../structures/unit.h"
+
+#include "../classgen/constant_pool.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../classgen/classgen.h"
+
+#include "parser.h"
+#include "stdpas.h"
+
+#pragma warning (disable: 4305)
+#pragma warning (disable: 4761)
+
+extern int procedure_linenum;
+
+//extern void (*compile_terminate)();
+
+extern FILE* yyin;
+
+
+int current_token;
+block *root_block;
+
+int next_record_ID;
+
+/* Scanner variables and functions */
+extern long int linenum;
+extern int new_linenum;
+extern long int integer_constant;
+extern int error_count;
+extern float real_constant;
+extern char boolean_constant;
+extern char char_constant;
+extern string *string_constant;
+extern char *yytext;
+extern int yylex();
+extern FILE *yyin;
+extern void backchar(int c);
+extern int goverify;
+
+extern void VerifyFile(char*);
+
+extern int usesFloat;
+
+extern char *output_path;
+
+extern int detect_units_only;
+
+/* Small macro for outputting the yytext value */
+#define YYTEXT_STRING  (current_token == END_OF_INPUT ? "<EOF>" : yytext)
+
+
+/* A macro to explicitly declare we didn't forget break inside
+   the case statement */
+//#define no_break             /* do nothing */;
+
+
+int inside_loop = 0; /* the counter checks if 'break' is located inside a loop */
+
+int compiling_unit = 0; /* set to 1 if this is an unit */
+int inside_interface_part = 0; /* if the compiler is inside the interface part of the unit */
+int inside_implementation_part = 0; /* if the compiler is inside the implementation part of the unit */
+
+int inside_routine = 0;
+int routine_return_type = void_type;
+int routine_return_parameters_length = 0;
+
+string *str_program_name;
+string *str_currrent_routine_name;
+
+extern int mathType;
+
+FILE *symbols_file;
+
+//ASM - LABEL TABLE
+int nam[1024];
+int lab[1024];
+int len[1024];
+//int ofs[1024];
+int labcount;
+
+/*
+       Starts parsing the input file. The grammar rule
+       used is:
+
+       <parser_start> -> <RD_program_header> <RD_uses_list> <RD_block> . <<EOF>>
+                      -> <RD_program_header> <RD_unit_interface> <RD_unit_implementation> <RD_unit_initialization> <RD_unit_finalization> . <<EOF>>
+*/
+void parser_start()
+{
+       block *program_block;
+       int random_field_index;
+       int random_class_index;
+       int random_method_index;
+
+       root_block = initialize_root_block();
+
+       current_token = yylex();
+
+       compiling_unit = 0;
+
+       str_program_name = RD_program_header();
+
+       if (compiling_unit == 0)
+       {
+               RD_uses_list();
+
+               if (str_program_name == NULL)
+                       str_program_name = string_from_cstr("");
+
+               program_block = block_create(root_block, str_program_name);
+
+        // j-a-s-d
+        if (detect_units_only)
+            goto end_parsing;
+
+               /* initialize the random number generator */
+               random_field_index = cp_add_fieldref("M", "RNG", "Ljava/util/Random;");
+               random_class_index = cp_add_class("java/util/Random");
+               random_method_index = cp_add_methodref("java/util/Random", "<init>", "()V");
+
+               bytecode_append(program_block->code, new$);
+               bytecode_append_short_int(program_block->code, random_class_index);
+
+               bytecode_append(program_block->code, dup$);
+
+               bytecode_append(program_block->code, invokespecial$);
+               bytecode_append_short_int(program_block->code, random_method_index);
+
+               bytecode_append(program_block->code, putstatic$);
+               bytecode_append_short_int(program_block->code, random_field_index);
+               /* END initialize the random number generator */
+
+               /* initialize the index counter field */
+               bytecode_append(program_block->code, bipush$);
+               bytecode_append(program_block->code, 25);
+               bytecode_append(program_block->code, newarray$);
+               bytecode_append(program_block->code, 10);
+               bytecode_append(program_block->code, putstatic$);
+               bytecode_append_short_int(program_block->code, cp_add_fieldref("M", "IC", "[I"));
+               /* END initialize the IC field */
+
+               /* reset the keyboard buffers */
+               bytecode_append(program_block->code, iconst_0$);
+               bytecode_append(program_block->code, putstatic$);
+               bytecode_append_short_int(program_block->code, cp_add_fieldref("M", "KC", "I"));
+               bytecode_append(program_block->code, iconst_0$);
+               bytecode_append(program_block->code, putstatic$);
+               bytecode_append_short_int(program_block->code, cp_add_fieldref("M", "KP", "I"));
+               /* END reset the keyboard buffers */
+
+               RD_block(program_block);
+
+               /* do the 'halt' at the end of program execution */
+               bytecode_append(program_block->code, getstatic$);
+               bytecode_append_short_int(program_block->code, cp_add_fieldref("FW", "fw", "LFW;"));
+               bytecode_append(program_block->code, iconst_1$);
+               bytecode_append(program_block->code, invokevirtual$);
+               bytecode_append_short_int(program_block->code, cp_add_methodref("FW", "destroyApp", "(Z)V"));
+
+               /* bytecode verififer wants this unnecessary return */
+               bytecode_append(program_block->code, return$);
+       }
+       else
+       {
+               char *symbols_filename;
+               int filepos;
+
+               symbols_filename = (char*) mem_alloc(strlen(output_path) + string_length(str_program_name) + 10);
+               #ifdef WIN32
+               sprintf(symbols_filename, "%s\\%s.bsf", output_path, string_get_cstr(str_program_name));
+               #endif
+               #ifdef UNIX
+               sprintf(symbols_filename, "%s/%s.bsf", output_path, string_get_cstr(str_program_name));
+               #endif
+               symbols_file = fopen(symbols_filename, "wb");
+               mem_free(symbols_filename);
+
+               if (symbols_file == NULL)
+                       die(7);
+
+               program_block = block_create(root_block, str_program_name);
+
+               lowercase(string_get_cstr(str_program_name));
+
+               RD_unit_interface(program_block);
+               RD_unit_implementation(program_block);
+               RD_unit_initialization(program_block);
+               RD_unit_finalization(program_block);
+
+        // j-a-s-d
+        if (detect_units_only) {
+            fclose(symbols_file);
+            goto end_parsing;
+        }
+
+               if (current_token != KWD_END)
+                       add_error_message(203, "end", YYTEXT_STRING);
+               else
+               {
+                       current_token = yylex();
+               }
+
+               fclose(symbols_file);
+
+               bytecode_append(program_block->code, return$);
+       }
+
+       /* check if there are forward declarations without the body */
+       check_unmatched_forward_declarations(program_block, program_block->names);
+
+       if (current_token != DOT)
+       {
+               add_error_message(200, ".", YYTEXT_STRING);
+
+               /* Error-recovery: find the end of input */
+               while (current_token != END_OF_INPUT)
+                       current_token = yylex();
+       }
+       else
+               current_token = yylex();
+
+       if (current_token != END_OF_INPUT)
+       {
+               add_error_message(201, YYTEXT_STRING, "");
+       }
+
+       if (error_count == 0)
+       {
+               FILE *fp;
+               char *output_file_name;
+               char *short_file_name;
+
+               if (compiling_unit == 0)
+               {
+                       output_file_name = (char*) mem_alloc(strlen(output_path) + 10);
+                       short_file_name = (char*) mem_alloc(10);
+               }
+               else
+               {
+                       output_file_name = (char*) mem_alloc(strlen(output_path) + string_length(str_program_name) + 10);
+                       short_file_name = (char*) mem_alloc(string_length(str_program_name) + 10);
+               }
+
+               if (output_file_name == NULL)
+                       die (1);
+
+               if (compiling_unit == 0)
+               {
+                   #ifdef WIN32
+                       sprintf(output_file_name, "%s\\M.class", output_path);
+                       #endif
+                       #ifdef UNIX
+                       sprintf(output_file_name, "%s/M.class", output_path);
+                       #endif
+                       sprintf(short_file_name, "M");
+               }
+               else
+               {
+                   #ifdef WIN32
+                       sprintf(output_file_name, "%s\\%s.class", output_path, string_get_cstr(str_program_name));
+                       #endif
+                       #ifdef UNIX
+                       sprintf(output_file_name, "%s/%s.class", output_path, string_get_cstr(str_program_name));
+                       #endif
+                       sprintf(short_file_name, "%s", string_get_cstr(str_program_name));
+               }
+
+               fp = fopen(output_file_name, "wb");
+               mem_free(output_file_name);
+               if (fp == NULL)
+               {
+                       die (4);
+               }
+               create_class_file(program_block, fp);
+               fclose(fp);
+
+               if (goverify!=0) VerifyFile(short_file_name);
+       }
+// j-a-s-d
+end_parsing:
+       string_destroy(str_program_name);
+
+       block_destroy(program_block);
+       block_destroy(root_block);
+}
+
+
+/*
+       Program header, uses the grammar rule:
+
+       <RD_program_header> -> [program IDENTIFIER ;]
+*/
+string* RD_program_header()
+{
+       string *program_name = NULL;
+
+       if ((current_token == KWD_PROGRAM)
+               || (current_token == KWD_UNIT))
+       {
+               if (current_token == KWD_UNIT)
+                       compiling_unit = 1;
+
+               current_token = yylex();
+
+               if (current_token != IDENTIFIER)
+               {
+                       add_error_message(202, "", "");
+               }
+               else
+                       program_name = string_from_cstr(YYTEXT_STRING);
+
+               if ((compiling_unit) && (string_length(program_name) < 3))
+                       add_error_message(454, "", "");
+
+               current_token = yylex();
+
+               if (current_token != SEMI_COLON)
+               {
+
+                       add_error_message(200, ";", YYTEXT_STRING);
+
+                       /* Error-recovery: find any of the following:
+                          CONST, TYPE, VAR, PROCEDURE, FUNCTION, BEGIN, ., EOF
+                       */
+                       while ( (current_token != KWD_CONST)
+                               && (current_token != KWD_TYPE)
+                               && (current_token != KWD_VAR)
+                               && (current_token != KWD_PROCEDURE)
+                               && (current_token != KWD_FUNCTION)
+                               && (current_token != KWD_BEGIN)
+                               && (current_token != DOT)
+                               && (current_token != END_OF_INPUT))
+                       {
+                               current_token = yylex();
+                       }
+               }
+               else
+                       current_token = yylex();
+       }
+
+       return program_name;
+}
+
+/*
+       the interface part of the unit source
+
+    <RD_unit_interface> -> [interface [;] <RD_block> ]
+
+    special rules apply to declarations inside the interface; global variable inside_interface_part is used to denote the special cases
+*/
+void RD_unit_interface(block *current_block)
+{
+       if (current_token != KWD_INTERFACE)
+       {
+               if ((current_token == KWD_IMPLEMENTATION)
+                       || (current_token == KWD_INITIALIZATION))
+                       return;
+
+               add_error_message(203, "interface", YYTEXT_STRING);
+
+               do
+               {
+                       current_token = yylex();
+               }
+               while ((current_token != KWD_IMPLEMENTATION) && (current_token != END_OF_INPUT));
+
+               return;
+       }
+
+       current_token = yylex();
+
+       if (current_token == SEMI_COLON)
+               current_token = yylex();
+
+       inside_interface_part = 1;
+       RD_block(current_block);
+       inside_interface_part = 0;
+}
+
+/*
+  the implementation part of the unit source
+
+  <RD_unit_implementation> -> implementation [;] <RD_uses_list> <RD_block>
+*/
+void RD_unit_implementation(block *current_block)
+{
+       if (current_token == END_OF_INPUT)
+               return;
+
+       if (current_token != KWD_IMPLEMENTATION)
+       {
+               add_error_message(203, "implementation", YYTEXT_STRING);
+
+               do
+               {
+                       current_token = yylex();
+               }
+               while (current_token != END_OF_INPUT);
+
+               return;
+       }
+
+       current_token = yylex();
+
+       if (current_token == SEMI_COLON)
+               current_token = yylex();
+
+       RD_uses_list();
+
+    // j-a-s-d
+    if (detect_units_only)
+      return;
+
+       inside_implementation_part = 1;
+       RD_block(current_block);
+       inside_implementation_part = 0;
+}
+
+/*
+       the initialization part of the unit
+
+    <RD_unit_initialization> -> [initialization [;] <RD_block_body> ]
+*/
+void RD_unit_initialization(block* current_block)
+{
+       if (current_token == KWD_INITIALIZATION)
+       {
+               current_token = yylex();
+
+               if (current_token == SEMI_COLON)
+                       current_token = yylex();
+
+               RD_block_body(current_block);
+       }
+}
+
+/*
+       the finalization part of the unit is not supported by the compiler
+*/
+void RD_unit_finalization(block *current_block)
+{
+       if (current_token == KWD_FINALIZATION)
+       {
+               add_error_message(220, "", "");
+               current_token = yylex();
+               return;
+       }
+}
+
+/*
+       The list of 'uses' directives.
+       <RD_uses_list> -> ( uses NAME; )*
+*/
+void RD_uses_list()
+{
+       while (current_token == KWD_USES)
+       {
+following_unit:
+               current_token = yylex();
+
+               if (current_token != IDENTIFIER)
+               {
+                       add_error_message(202, "", "");
+
+                       /* do error recovery */
+                       while ((current_token != END_OF_INPUT)
+                               && (current_token != SEMI_COLON))
+                       {
+                               current_token = yylex();
+                               return;
+                       }
+               }
+
+               /* process the library */
+               load_extern_library(string_from_cstr(YYTEXT_STRING));
+
+               current_token = yylex();
+
+               if (current_token == COMMA)
+                       goto following_unit;
+
+               if (current_token != SEMI_COLON)
+               {
+                       add_error_message(200, ";", YYTEXT_STRING);
+
+                       /* do error recovery */
+                       while ((current_token != END_OF_INPUT)
+                               && (current_token != SEMI_COLON))
+                       {
+                               current_token = yylex();
+                               return;
+                       }
+               }
+               else
+                       current_token = yylex();
+       }
+
+       if (current_token == SEMI_COLON)
+               current_token = yylex();
+
+       if (detect_units_only)
+       {
+               mem_close();
+
+               fclose(yyin);
+
+        // j-a-s-d
+               //compile_terminate();
+        exit(0);
+       }
+}
+
+
+/*
+       Program block with declarations and code.
+       The grammar rule used:
+
+       <RD_block> -> const <RD_const_declaration>
+                   | type <RD_type_declaration>
+                               | var <RD_var_declaration>
+                               | procedure <RD_procedure_declaration>
+                               | function <RD_function_declaration>
+                               | begin <RD_block_body> end
+*/
+block* RD_block(block *current_block)
+{
+       switch (current_token)
+       {
+       case KWD_CONST:
+               {
+                       current_token = yylex();
+                       RD_const_declaration(current_block);
+                       break;
+               }
+
+       case KWD_TYPE:
+               {
+                       current_token = yylex();
+                       RD_type_declaration(current_block);
+                       break;
+               }
+
+       case KWD_VAR:
+               {
+                       current_token = yylex();
+                       RD_var_declaration(current_block);
+                       break;
+               }
+
+       case KWD_PROCEDURE:
+               {
+                       if (current_block->parent_block != root_block)
+                               add_error_message(431, "", "");
+
+                       current_token = yylex();
+                       RD_procedure_declaration(current_block);
+                       break;
+               }
+
+       case KWD_FUNCTION:
+               {
+                       if (current_block->parent_block != root_block)
+                               add_error_message(431, "", "");
+
+                       current_token = yylex();
+                       RD_function_declaration(current_block);
+                       break;
+               }
+
+       case KWD_BEGIN:
+               {
+                       if ((inside_interface_part) || (inside_implementation_part))
+                       {
+                               add_error_message(204, YYTEXT_STRING, "");
+
+                               do
+                               {
+                                       current_token = yylex();
+                               } while (current_token != END_OF_INPUT);
+
+                               break;
+                       }
+
+                       current_token = yylex();
+
+                       RD_block_body(current_block);
+
+                       if (current_token != KWD_END)
+                       {
+                               add_error_message(203, "end", YYTEXT_STRING);
+                       }
+                       else
+                               current_token = yylex();
+
+                       break;
+               }
+
+       default:
+               {
+                       if ((inside_interface_part)
+                               && (   (current_token == KWD_IMPLEMENTATION)
+                                   || (current_token == KWD_INITIALIZATION)
+                                   || (current_token == KWD_FINALIZATION)
+                                       || (current_token == KWD_END)
+                               ))
+                       {
+                               return current_block;
+                       }
+
+                       if ((inside_implementation_part)
+                               && (   (current_token == KWD_INITIALIZATION)
+                                   || (current_token == KWD_FINALIZATION)
+                                       || (current_token == KWD_END)
+                               ))
+                       {
+                               return current_block;
+                       }
+
+
+                       add_error_message(204, YYTEXT_STRING, "");
+
+                       /* Error-recovery: find any of the following:
+                          CONST, TYPE, VAR, PROCEDURE, FUNCTION, BEGIN, ., EOF
+                       */
+                       while ( (current_token != KWD_CONST)
+                               && (current_token != KWD_TYPE)
+                               && (current_token != KWD_VAR)
+                               && (current_token != KWD_PROCEDURE)
+                               && (current_token != KWD_FUNCTION)
+                               && (current_token != KWD_BEGIN)
+                               && (current_token != DOT)
+                               && (current_token != END_OF_INPUT))
+                       {
+                               current_token = yylex();
+                       }
+
+                       break;
+               }
+       }
+
+       return current_block;
+}
+
+
+/*
+       Constant declarations, the grammar rule used is:
+
+         <RD_constant_declaration> -> ( IDN = CONST ; )+ <RD_block>
+*/
+void RD_const_declaration(block *current_block)
+{
+       int first_pass = 1;
+       string *constant_name;
+
+       do
+       {
+               if (first_pass)
+                       first_pass = 0;
+               else
+                       current_token = yylex();
+
+               if (current_token != IDENTIFIER)
+               {
+                       break;
+               }
+
+               if (!block_check_name(current_block, YYTEXT_STRING))
+               {
+                       add_error_message(400, YYTEXT_STRING, "");
+               }
+
+               constant_name = string_from_cstr(YYTEXT_STRING);
+
+               current_token = yylex();
+
+               if (current_token != OP_EQUAL)
+               {
+                       add_error_message(200, "=", YYTEXT_STRING);
+
+                       /* Error-recovery: find the first SEMI_COLON */
+                       while ((current_token != SEMI_COLON)
+                               && (current_token != END_OF_INPUT))
+                       {
+                               current_token = yylex();
+                       }
+
+                       if (current_token == END_OF_INPUT)
+                       {
+                               add_error_message(207, "", "");
+                               string_destroy(constant_name);
+                               return;
+                       }
+
+                       continue;
+               }
+
+               current_token = yylex();
+
+        // j-a-s-d: quick fix to support negative integer constants
+        int sign_factor = 1;
+        if (current_token == OP_MINUS) {
+            sign_factor = -1;
+            current_token = yylex();
+            if (current_token != CST_INTEGER) {
+                add_error_message(206, "", "");
+                return;
+            }
+        }
+
+               switch (current_token)
+               {
+               case CST_INTEGER:
+                       {
+                               add_integer_constant(current_block,
+                                       integer_constant*sign_factor, string_get_cstr(constant_name));
+
+                               if (inside_interface_part)
+                                       bsf_write_integer_constant(integer_constant, string_get_cstr(constant_name));
+
+                               current_token = yylex();
+                               break;
+                       }
+
+               case CST_REAL:
+                       {
+                               add_real_constant(current_block,
+                                       real_constant, string_get_cstr(constant_name));
+
+                               if (inside_interface_part)
+                                       bsf_write_real_constant(real_constant, string_get_cstr(constant_name));
+
+                               current_token = yylex();
+                               break;
+                       }
+
+               case CST_BOOLEAN:
+                       {
+                               add_boolean_constant(current_block,
+                                       boolean_constant, string_get_cstr(constant_name));
+
+                               if (inside_interface_part)
+                                       bsf_write_boolean_constant(boolean_constant, string_get_cstr(constant_name));
+
+                               current_token = yylex();
+                               break;
+                       }
+
+               case CST_CHAR:
+                       {
+                               add_char_constant(current_block,
+                                       char_constant, string_get_cstr(constant_name));
+
+                               if (inside_interface_part)
+                                       bsf_write_char_constant(char_constant, string_get_cstr(constant_name));
+
+                               current_token = yylex();
+                               break;
+                       }
+
+               case CST_STRING:
+                       {
+                               add_string_constant(current_block,
+                                       string_constant, string_get_cstr(constant_name));
+
+                               if (inside_interface_part)
+                                       bsf_write_string_constant(string_constant, string_get_cstr(constant_name));
+
+                               current_token = yylex();
+                               break;
+                       }
+
+               default:
+                       {
+                               /* TODO:: ovo nije dobro, ovdje bi mogao pisati bilo kakav
+                                  konstantni izraz */
+                               add_error_message(206, "", "");
+
+                               /* Error-recovery: find the first semi-colon */
+                               while ( (current_token != SEMI_COLON)
+                                       && (current_token != END_OF_INPUT))
+                               {
+                                       current_token = yylex();
+                               }
+
+                               if (current_token == END_OF_INPUT)
+                               {
+                                       add_error_message(207, "", "");
+                                       return;
+                               }
+
+                               break;
+                       }
+               }
+
+               string_destroy(constant_name);
+
+       } while (current_token == SEMI_COLON);
+
+       RD_block(current_block);
+}
+
+
+/*
+       Handles variable declarations field. The grammar rule used is:
+
+       <RD_var_declaration> -> (<RD_identifier_list> : <RD_type> ;)+ <RD_block>
+*/
+void RD_var_declaration(block *current_block)
+{
+       string_list *identifier_list;
+       type *var_type;
+
+       do
+       {
+               identifier_list = RD_identifier_list(current_block, 1);
+
+               if (current_token != COLON)
+               {
+                       add_error_message(200, ":", YYTEXT_STRING);
+
+                       /* Error-recovery: find any of the following:
+                          CONST, TYPE, VAR, PROCEDURE, FUNCTION, BEGIN, ., EOF
+                       */
+                       while ( (current_token != KWD_CONST)
+                               && (current_token != KWD_TYPE)
+                               && (current_token != KWD_VAR)
+                               && (current_token != KWD_PROCEDURE)
+                               && (current_token != KWD_FUNCTION)
+                               && (current_token != KWD_BEGIN)
+                               && (current_token != DOT)
+                               && (current_token != END_OF_INPUT))
+                       {
+                               current_token = yylex();
+                       }
+
+                       if ((current_token == END_OF_INPUT)
+                               || (current_token == DOT))
+                       {
+                               add_error_message(207, "", "");
+                               return;
+                       }
+
+                       break;
+               }
+
+               current_token = yylex();
+
+               var_type = RD_type(current_block);
+
+               if (var_type->type_class == interval_type)
+               {
+                       add_error_message(440, "", "");
+                       var_type->type_class = integer_type;
+               }
+
+               add_variables(current_block, identifier_list, var_type);
+
+               if (inside_interface_part)
+                       bsf_write_variables(identifier_list, var_type);
+
+               type_destroy(var_type);
+               string_list_destroy(identifier_list);
+
+               if (current_token != SEMI_COLON)
+               {
+                       add_error_message(200, ";", YYTEXT_STRING);
+
+                       /* Error-recovery: find any of the following:
+                          CONST, TYPE, VAR, PROCEDURE, FUNCTION, BEGIN, ., EOF
+                       */
+                       while ( (current_token != KWD_CONST)
+                               && (current_token != KWD_TYPE)
+                               && (current_token != KWD_VAR)
+                               && (current_token != KWD_PROCEDURE)
+                               && (current_token != KWD_FUNCTION)
+                               && (current_token != KWD_BEGIN)
+                               && (current_token != DOT)
+                               && (current_token != END_OF_INPUT))
+                       {
+                               current_token = yylex();
+                       }
+
+                       if ((current_token == END_OF_INPUT)
+                               || (current_token == DOT))
+                       {
+                               add_error_message(207, "", "");
+                               return;
+                       }
+
+                       break;
+               }
+
+               current_token = yylex();
+
+               if (((inside_implementation_part) || (inside_interface_part))
+                               && (   (current_token == KWD_INITIALIZATION)
+                                   || (current_token == KWD_IMPLEMENTATION)
+                                       || (current_token == KWD_INTERFACE)
+                                       || (current_token == KWD_END)
+                               ))
+                       {
+                               break;
+                       }
+
+       } while ( (current_token != KWD_CONST)
+                       && (current_token != KWD_TYPE)
+                       && (current_token != KWD_VAR)
+                       && (current_token != KWD_PROCEDURE)
+                       && (current_token != KWD_FUNCTION)
+                       && (current_token != KWD_BEGIN)
+                       && (current_token != DOT)
+                       && (current_token != END_OF_INPUT));
+
+       if ((current_token == END_OF_INPUT)
+               || (current_token == DOT))
+       {
+               add_error_message(207, "", "");
+               return;
+       }
+
+       RD_block(current_block);
+}
+
+
+/*
+       The list of identifiers, the rule used is:
+
+       <RD_identifier_list> -> IDN (, IDN)*
+
+       param check_valid_names should be nonzero if the function
+       should call block_check_name() for each identifier
+*/
+string_list* RD_identifier_list(block *current_block,
+                                                               int check_valid_names)
+{
+       string_list *return_list;
+       string *identifier;
+
+       return_list = string_list_create();
+
+       if (current_token != IDENTIFIER)
+       {
+               add_error_message(444, "", "");
+
+               /* Error-recovery: find the first : or EOF */
+               while ((current_token != COLON)
+                       && (current_token != DOT)
+                       && (current_token != END_OF_INPUT))
+               {
+                       current_token = yylex();
+               }
+
+               return return_list;
+       }
+
+       if ((check_valid_names)
+               && (!block_check_name(current_block, YYTEXT_STRING)))
+       {
+               add_error_message(400, YYTEXT_STRING, "");
+       }
+
+       identifier = string_from_cstr(YYTEXT_STRING);
+       string_list_append(return_list, identifier);
+       string_destroy(identifier);
+
+       current_token = yylex();
+
+       while (current_token == COMMA)
+       {
+               current_token = yylex();
+
+               if (current_token != IDENTIFIER)
+               {
+                       add_error_message(202, "", "");
+
+                       /* Error-recovery: find the first : or EOF */
+                       while ((current_token != COLON)
+                               && (current_token != DOT)
+                               && (current_token != END_OF_INPUT))
+                       {
+                               current_token = yylex();
+                       }
+
+                       return return_list;
+               }
+
+               if ((check_valid_names)
+                       && (!block_check_name(current_block, YYTEXT_STRING)))
+               {
+                       add_error_message(400, YYTEXT_STRING, "");
+               }
+
+               identifier = string_from_cstr(YYTEXT_STRING);
+               string_list_append(return_list, identifier);
+               string_destroy(identifier);
+
+               current_token = yylex();
+       }
+
+       return return_list;
+}
+
+
+/*
+       Handles the declaration of a new type. The grammar
+       rule used is:
+
+       <RD_type_declaration> -> ( IDN = <RD_type> ; )+ <RD_block>
+*/
+void RD_type_declaration(block *current_block)
+{
+       string *type_name;
+       type *type_type;
+
+       do
+       {
+               if (current_token != IDENTIFIER)
+               {
+                       if (((inside_implementation_part) || (inside_interface_part))
+                               && (   (current_token == KWD_INITIALIZATION)
+                                   || (current_token == KWD_IMPLEMENTATION)
+                                       || (current_token == KWD_INTERFACE)
+                                       || (current_token == KWD_END)
+                               ))
+                       {
+                               return;
+                       }
+
+                       add_error_message(202, "", "");
+
+                       /* Error-recovery: find the first ; or EOF */
+                       while ((current_token != SEMI_COLON)
+                               && (current_token != DOT)
+                               && (current_token != END_OF_INPUT))
+                       {
+                               current_token = yylex();
+                       }
+
+                       if (current_token == SEMI_COLON)
+                               RD_block(current_block);
+
+                       return;
+               }
+
+               type_name = string_from_cstr(YYTEXT_STRING);
+               if (!block_check_name(current_block, YYTEXT_STRING))
+                       add_error_message(400, YYTEXT_STRING, "");
+
+               current_token = yylex();
+
+               if (current_token != OP_EQUAL)
+               {
+                       add_error_message(205, YYTEXT_STRING, "");
+
+                       /* Error-recovery: find the first ; or EOF */
+                       while ((current_token != SEMI_COLON)
+                               && (current_token != DOT)
+                               && (current_token != END_OF_INPUT))
+                       {
+                               current_token = yylex();
+                       }
+
+                       if (current_token == SEMI_COLON)
+                               RD_block(current_block);
+
+                       string_destroy(type_name);
+
+                       return;
+               }
+
+               current_token = yylex();
+
+               type_type = RD_type(current_block);
+
+               add_type(current_block, type_name, type_type);
+
+               if (inside_interface_part)
+                       bsf_write_type(type_name, type_type);
+
+               if (current_token != SEMI_COLON)
+               {
+                       add_error_message(200, ";", YYTEXT_STRING);
+
+                       /* Error-recovery: find the first ; or EOF */
+                       while ((current_token != SEMI_COLON)
+                               && (current_token != DOT)
+                               && (current_token != END_OF_INPUT))
+                       {
+                               current_token = yylex();
+                       }
+
+                       if (current_token == SEMI_COLON)
+                               RD_block(current_block);
+
+                       return;
+               }
+
+               current_token = yylex();
+       } while ( (current_token != KWD_CONST)
+                       && (current_token != KWD_TYPE)
+                       && (current_token != KWD_VAR)
+                       && (current_token != KWD_PROCEDURE)
+                       && (current_token != KWD_FUNCTION)
+                       && (current_token != KWD_BEGIN)
+                       && (current_token != DOT)
+                       && (current_token != END_OF_INPUT));
+
+       if ((current_token == END_OF_INPUT)
+               || (current_token == DOT))
+       {
+               add_error_message(207, "", "");
+               return;
+       }
+
+       RD_block(current_block);
+
+}
+
+
+/*
+       Handles the procedure declaration. The grammar
+       rule used is:
+
+       <RD_procedure_declaration> -> IDN <RD_param_list> ;
+                                      <RD_proc_block> ; <RD_block>
+*/
+void RD_procedure_declaration(block *current_block)
+{
+       string *procedure_name;
+       block *procedure_block;
+       type_list *parameters;
+       int forward_declaration;
+       type *void_return_type;
+       int procedure_linenum = linenum;
+
+       int old_inside_implementation = inside_implementation_part;
+
+       inside_implementation_part = 0;
+
+       if (!block_check_name(current_block, YYTEXT_STRING))
+       {
+               add_error_message(400, YYTEXT_STRING, "");
+       }
+
+       procedure_name = string_from_cstr(YYTEXT_STRING);
+    str_currrent_routine_name = string_from_cstr(YYTEXT_STRING);
+
+       if (current_token != IDENTIFIER)
+       {
+               add_error_message(202, "", "");
+
+               /* Error-recovery: find the first ; */
+               while ((current_token != SEMI_COLON)
+                       && (current_token != END_OF_INPUT))
+               {
+                       current_token = yylex();
+               }
+
+               if (current_token == END_OF_INPUT)
+                       return;
+       }
+       else
+       {
+               current_token = yylex();
+       }
+
+       if (STRING_COMPARE(procedure_name->cstr, "run") == 0)
+               add_error_message(433, "", "");
+
+       /* create a new block for the procedure */
+       procedure_block = block_create(current_block, string_duplicate(procedure_name));
+
+       parameters = RD_param_list(procedure_block);
+
+       if (current_token != SEMI_COLON)
+       {
+               add_error_message(200, ";", YYTEXT_STRING);
+
+               /* Error-recovery: do nothing */
+       }
+       else
+               current_token = yylex();
+
+       void_return_type = type_create();
+       void_return_type->type_class = void_type;
+
+       add_procedure(current_block, procedure_name, parameters, -1, procedure_linenum);
+
+       if (inside_interface_part)
+               bsf_write_procedure(procedure_name, parameters);
+
+       forward_declaration = RD_proc_block(procedure_block, void_return_type, parameters);
+
+       type_destroy(void_return_type);
+
+       add_procedure(current_block, procedure_name, parameters, forward_declaration, procedure_linenum);
+
+       if (current_token != SEMI_COLON)
+       {
+               if (inside_interface_part == 0)
+                       add_error_message(200, ";", YYTEXT_STRING);
+
+               /* Error-recovery: do nothing */
+       }
+       else
+               current_token = yylex();
+
+       inside_implementation_part = old_inside_implementation;
+
+       RD_block(current_block);
+}
+
+
+/*
+       Handles the function declaration. The grammar
+       rule used is:
+
+       <RD_function_declaration> -> IDN <RD_param_list> : IDN ;
+                                      <RD_proc_block> ; <RD_block>
+*/
+void RD_function_declaration(block *current_block)
+{
+       string *function_name;
+       block *function_block;
+       type_list *parameters;
+       int forward_declaration;
+       type *return_type;
+       identifier *return_value;
+       int function_linenum = linenum;
+
+       int old_inside_implementation = inside_implementation_part;
+
+       inside_implementation_part = 0;
+
+       if (!block_check_name(current_block, YYTEXT_STRING))
+       {
+               add_error_message(400, YYTEXT_STRING, "");
+       }
+
+       function_name = string_from_cstr(YYTEXT_STRING);
+       str_currrent_routine_name = string_from_cstr(YYTEXT_STRING);
+
+       if (current_token != IDENTIFIER)
+       {
+               add_error_message(202, "", "");
+
+               /* Error-recovery: find the first ; */
+               while ((current_token != SEMI_COLON)
+                       && (current_token != END_OF_INPUT))
+               {
+                       current_token = yylex();
+               }
+
+               if (current_token == END_OF_INPUT)
+                       return;
+       }
+       else
+               current_token = yylex();
+
+       if (STRING_COMPARE(function_name->cstr, "run") == 0)
+               add_error_message(433, "", "");
+
+       /* create a new block for the function */
+       function_block = block_create(current_block, string_duplicate(function_name));
+
+       /* parameters start at index 0, variables follow after the return value */
+       function_block->next_parameter_index = 0;
+       function_block->next_variable_index = 0;
+
+       parameters = RD_param_list(function_block);
+
+       function_block->next_variable_index ++;
+
+       if (current_token != COLON)
+       {
+               add_error_message(200, ":", YYTEXT_STRING);
+       }
+       else
+               current_token = yylex();
+
+       return_type = type_from_name(current_block, YYTEXT_STRING);
+
+       if (return_type->type_class == error_type)
+               add_error_message(406, YYTEXT_STRING, "");
+
+       if (return_type->type_class == interval_type)
+       {
+               add_error_message(440, "", "");
+               return_type->type_class = integer_type;
+       }
+
+       if (current_token != IDENTIFIER)
+       {
+               add_error_message(202, "", "");
+       }
+       else
+               current_token = yylex();
+
+       if (current_token != SEMI_COLON)
+       {
+               add_error_message(200, ";", YYTEXT_STRING);
+
+               /* Error-recovery: do nothing */
+       }
+       else
+               current_token = yylex();
+
+       /* initialize the return value */
+       return_value = identifier_create();
+       return_value->identifier_class = variable_name;
+       return_value->variable_index = type_list_length(parameters);
+       return_value->variable_type = type_duplicate(return_type);
+       return_value->belongs_to_program_block = 0;
+       if (compiling_unit == 0)
+               initialize_variable(function_block, return_value, NULL, 1, "M");
+       else
+               initialize_variable(function_block, return_value, NULL, 1, string_get_cstr(str_program_name));
+
+       identifier_destroy(return_value);
+
+       add_function(current_block, function_name, parameters,
+                       return_type, -1, function_linenum);
+
+       forward_declaration = RD_proc_block(function_block, return_type, parameters);
+
+       add_function(current_block, function_name, parameters,
+                       return_type, forward_declaration, function_linenum);
+
+       if (inside_interface_part)
+               bsf_write_function(function_name, parameters, return_type);
+
+       if (current_token != SEMI_COLON)
+       {
+               if (inside_interface_part == 0)
+                       add_error_message(200, ";", YYTEXT_STRING);
+
+               /* Error-recovery: do nothing */
+       }
+       else
+               current_token = yylex();
+
+       inside_implementation_part = old_inside_implementation;
+
+       RD_block(current_block);
+}
+
+
+/*
+       Allows forward declarations. The rule used is:
+
+       <RD_proc_block> -> forward | <RD_block>
+
+       Return nonzero value if the declaration is forward
+       declaration.
+*/
+int RD_proc_block(block *current_block, type *return_type, type_list *parameters)
+{
+routine_return_type = return_type->type_class;
+routine_return_parameters_length = type_list_length(parameters);
+inside_routine = 1;
+       int forward_declaration = 0;
+
+       if ((current_token == KWD_FORWARD)
+               || (inside_interface_part))
+       {
+               forward_declaration = 1;
+
+               if (inside_interface_part == 0)
+                       current_token = yylex();
+
+               block_destroy(current_block);
+       }
+       else
+       {
+               if (inside_interface_part)
+                       add_error_message(221, "", "");
+
+               RD_block(current_block);
+
+               /* insert current_block into it's parents block list */
+               if (current_block->parent_block->children_count == 0)
+               {
+                       current_block->parent_block->children = (block**) mem_alloc(sizeof(block*));
+               }
+               else
+               {
+                       current_block->parent_block->children = (block**) mem_realloc(current_block->parent_block->children,
+                               (current_block->parent_block->children_count + 1) * sizeof(block*));
+               }
+
+               current_block->parent_block->children_count ++;
+
+               if (current_block->parent_block->children == NULL)
+                       die(20);
+
+               switch(return_type->type_class)
+               {
+               case void_type:
+                       bytecode_append(current_block->code, return$);
+                       break;
+
+               case real_type:
+                       usesFloat=1;
+                       if (mathType == 1)
+                       {
+                               bytecode_append(current_block->code, iload$);
+                               bytecode_append(current_block->code, type_list_length(parameters));
+                               bytecode_append(current_block->code, ireturn$);
+                       }
+                       else
+                       {
+                               switch(type_list_length(parameters))
+                               {
+                               case 0:
+                                       bytecode_append(current_block->code, aload_0$);
+                                       break;
+                               case 1:
+                                       bytecode_append(current_block->code, aload_1$);
+                                       break;
+                               case 2:
+                                       bytecode_append(current_block->code, aload_2$);
+                                       break;
+                               case 3:
+                                       bytecode_append(current_block->code, aload_3$);
+                                       break;
+                               default:
+                                       bytecode_append(current_block->code, aload$);
+                                       bytecode_append(current_block->code, type_list_length(parameters));
+                               }
+
+                               bytecode_append(current_block->code, areturn$);
+                       }
+                       break;
+
+               case integer_type:
+               case boolean_type:
+               case char_type:
+                       bytecode_append(current_block->code, iload$);
+                       bytecode_append(current_block->code, type_list_length(parameters));
+                       bytecode_append(current_block->code, ireturn$);
+                       break;
+
+               case string_type:
+               case array_type:
+               case record_type:
+               case image_type:
+               case command_type:
+               case stream_type:
+               case record_store_type:
+               case http_type:
+                       switch(type_list_length(parameters))
+                       {
+                       case 0:
+                               bytecode_append(current_block->code, aload_0$);
+                               break;
+                       case 1:
+                               bytecode_append(current_block->code, aload_1$);
+                               break;
+                       case 2:
+                               bytecode_append(current_block->code, aload_2$);
+                               break;
+                       case 3:
+                               bytecode_append(current_block->code, aload_3$);
+                               break;
+                       default:
+                               bytecode_append(current_block->code, aload$);
+                               bytecode_append(current_block->code, type_list_length(parameters));
+                       }
+
+                       bytecode_append(current_block->code, areturn$);
+
+                       break;
+               }
+
+               current_block->parent_block->children[current_block->parent_block->children_count-1] = current_block;
+       }
+inside_routine = 0;
+       return forward_declaration;
+}
+
+
+/*
+       Handles the declarations of parameters to a
+       procedure/function. The grammar rule used is:
+
+       <RD_param_list> -> empty
+                          | "(" [var] <RD_identifier_list> : [IDN.]IDN (; [var] <RD_identifier_list> : [IDN.]IDN )+ ")"
+*/
+type_list* RD_param_list(block *current_block)
+{
+       type_list *parameter_list;
+       string_list *identifier_list;
+       type *parameters_type;
+       int is_parameter_variable;
+
+       int i, len;
+
+       parameter_list = type_list_create();
+
+       if (current_token == OPEN_BR)
+       {
+               do
+               {
+                       current_token = yylex();
+
+                       if (current_token == END_OF_INPUT)
+                       {
+                               add_error_message(207, "", "");
+                               return parameter_list;
+                       }
+
+                       if (current_token == CLOSE_BR)
+                               break;
+
+                       is_parameter_variable = 0;
+
+                       if (current_token == KWD_VAR)
+                       {
+                               is_parameter_variable = 1;
+                               current_token = yylex();
+                               add_warning_message(436, "", "");
+                       }
+
+                       identifier_list = RD_identifier_list(current_block, 0);
+
+                       if (current_token != COLON)
+                       {
+                               add_error_message(200, ":", YYTEXT_STRING);
+
+                               /* Error-recovery, find the ")" */
+                               while (current_token != CLOSE_BR)
+                               {
+                                       current_token = yylex();
+                               }
+
+                               if (current_token == END_OF_INPUT)
+                                       return parameter_list;
+
+                               break;
+
+                       }
+                       else
+                               current_token = yylex();
+
+                       parameters_type = type_from_name(current_block, YYTEXT_STRING);
+
+                       if (parameters_type->type_class == error_type)
+                       {
+                               /* check if the name is an unit name */
+                               identifier *unit;
+
+                               lowercase(YYTEXT_STRING);
+
+                               unit = get_identifier(current_block, YYTEXT_STRING);
+
+                               if (unit->identifier_class == unit_name)
+                               {
+                                       identifier *type_identifier;
+
+                                       current_token = yylex();
+
+                                       if (current_token != DOT)
+                                               add_error_message(200, ".", YYTEXT_STRING);
+                                       else
+                                               current_token = yylex();
+
+                                       type_identifier = name_table_find(unit->unit_block->names, string_from_cstr(YYTEXT_STRING));
+
+                                       if (type_identifier == NULL)
+                                               add_error_message(455, YYTEXT_STRING, "");
+                                       else
+                                               parameters_type = type_identifier->defined_type;
+                               }
+
+                               identifier_destroy(unit);
+                       }
+
+                       if (parameters_type->type_class == interval_type)
+                       {
+                               add_error_message(440, "", "");
+                               parameters_type->type_class = integer_type;
+                       }
+
+                       /* add the types into parameter_list */
+                       len = string_list_length(identifier_list);
+                       for(i=0; i<len; i++)
+                               type_list_append(parameter_list, type_duplicate(parameters_type));
+
+                       add_parameters(current_block, identifier_list, parameters_type,
+                                       is_parameter_variable);
+
+                       if (current_token != IDENTIFIER)
+                       {
+                               add_error_message(202, "", "");
+
+                               /* Error-recovery */
+                               if ((current_token != COMMA)
+                                       && (current_token != CLOSE_BR))
+                                       current_token = yylex();
+                       }
+                       else
+                               current_token = yylex();
+
+               } while (current_token == SEMI_COLON);
+
+               if (current_token != CLOSE_BR)
+               {
+                       add_error_message(208, YYTEXT_STRING, "");
+
+                       /* Error-recovery: find the first ; */
+                       while ((current_token != CLOSE_BR)
+                               && (current_token != END_OF_INPUT))
+                       {
+                               current_token = yylex();
+                       }
+               }
+
+               current_token = yylex();
+       }
+
+       return parameter_list;
+}
+
+/*
+       Handles the block of code. The grammar rule used is:
+
+       <RD_block_body> -> (<RD_statement> ; )+
+*/
+void RD_block_body(block *current_block)
+{
+       short int first_pass = 1;
+
+       do
+       {
+               if (first_pass)
+                       first_pass = 0;
+               else
+                       current_token = yylex();
+
+               RD_statement(current_block);
+
+       } while (current_token == SEMI_COLON);
+}
+
+
+/*
+       The statements rule:
+
+       <RD_statement> -> begin <RD_block_body> end
+                       | empty (if current_token == end || current_token == until)
+                                       | if <RD_if_statement>
+                                       | case <RD_case_statement>
+                                       | while <RD_while_statement>
+                                       | repeat <RD_repeat_statement>
+                                       | for <RD_for_statement>
+                                       | with <RD_with_statement>
+                                       | <RD_assignment_or_procedure_call>
+                                       | break
+*/
+void RD_statement(block *current_block)
+{
+       switch (current_token)
+       {
+       case KWD_BEGIN:
+               {
+                       current_token = yylex();
+                       RD_block_body(current_block);
+
+                       if (current_token != KWD_END)
+                       {
+                               add_error_message(203, "end", YYTEXT_STRING);
+                       }
+
+                       current_token = yylex();
+
+                       break;
+               }
+
+       case KWD_END: case KWD_UNTIL: case KWD_FOREVER:
+               {
+                       return;
+               }
+
+    case KWD_EXIT:
+        {
+            if (inside_routine == 0) { // j-a-s-d: in the main block treat it as a Halt()
+                    char *halt_text;
+                    halt_text = malloc(strlen("halt") + 1);
+                    strcpy(halt_text, "halt");
+                    create_std_function_code(current_block->code, halt_text);
+                    string_destroy(halt_text);
+            } else switch (routine_return_type) {
+                case void_type:
+                    bytecode_append(current_block->code, return$);
+                    break;
+
+                case real_type:
+                    if (mathType == 1)
+                    {
+                        bytecode_append(current_block->code, iload$);
+                        bytecode_append(current_block->code, routine_return_parameters_length);
+                        bytecode_append(current_block->code, ireturn$);
+                    }
+                    else
+                    {
+                        switch(routine_return_parameters_length)
+                        {
+                        case 0:
+                            bytecode_append(current_block->code, aload_0$);
+                            break;
+                        case 1:
+                            bytecode_append(current_block->code, aload_1$);
+                            break;
+                        case 2:
+                            bytecode_append(current_block->code, aload_2$);
+                            break;
+                        case 3:
+                            bytecode_append(current_block->code, aload_3$);
+                            break;
+                        default:
+                            bytecode_append(current_block->code, aload$);
+                            bytecode_append(current_block->code, routine_return_parameters_length);
+                        }
+
+                        bytecode_append(current_block->code, areturn$);
+                    }
+                    break;
+
+                case integer_type:
+                case boolean_type:
+                case char_type:
+                    bytecode_append(current_block->code, iload$);
+                    bytecode_append(current_block->code, routine_return_parameters_length);
+                    bytecode_append(current_block->code, ireturn$);
+                    break;
+
+                case string_type:
+                case array_type:
+                case record_type:
+                case image_type:
+                case command_type:
+                case stream_type:
+                case record_store_type:
+                case http_type:
+                    switch(routine_return_parameters_length)
+                    {
+                        case 0:
+                            bytecode_append(current_block->code, aload_0$);
+                            break;
+                        case 1:
+                            bytecode_append(current_block->code, aload_1$);
+                            break;
+                        case 2:
+                            bytecode_append(current_block->code, aload_2$);
+                            break;
+                        case 3:
+                            bytecode_append(current_block->code, aload_3$);
+                            break;
+                        default:
+                            bytecode_append(current_block->code, aload$);
+                            bytecode_append(current_block->code, routine_return_parameters_length);
+                    }
+                    bytecode_append(current_block->code, areturn$);
+                    break;
+            }
+                       current_token = yylex();
+            break;
+        }
+       case KWD_IF:
+               {
+                       current_token = yylex();
+                       RD_if_statement(current_block);
+                       break;
+               }
+
+       case KWD_CASE:
+               {
+                       current_token = yylex();
+                       RD_case_statement(current_block);
+                       break;
+               }
+
+       case KWD_WHILE:
+               {
+                       current_token = yylex();
+                       RD_while_statement(current_block);
+                       break;
+               }
+
+       case KWD_REPEAT:
+               {
+                       current_token = yylex();
+                       RD_repeat_statement(current_block);
+                       break;
+               }
+
+       case KWD_FOR:
+               {
+                       current_token = yylex();
+                       RD_for_statement(current_block);
+                       break;
+               }
+
+       case KWD_WITH:
+               {
+                       add_error_message(215, "", "");
+                       current_token = yylex();
+                       RD_with_statement(current_block);
+                       break;
+               }
+
+       case IDENTIFIER:
+       case KWD_RESULT: // j-a-s-d
+               {
+                       RD_assignment_or_procedure_call(current_block);
+                       break;
+               }
+
+       case KWD_BREAK:
+               {
+                       current_token = yylex();
+
+                       if (inside_loop <= 0)
+                               add_error_message(219, "", "");
+                       else
+                       {
+                               bytecode_append(current_block->code, break_stmt$);
+                               bytecode_append_short_int(current_block->code, 0);
+                       }
+                       break;
+               }
+
+    case KWD_BYTECODE:
+               {
+                       RD_inline_body(current_block);
+                       if (current_token != KWD_END) {
+                               add_error_message(200, "end ", YYTEXT_STRING);
+                               while ((current_token != SEMI_COLON) && (current_token != END_OF_INPUT))
+                                       current_token = yylex();
+                       } else current_token = yylex();
+                       break;
+               }
+
+       case KWD_INLINE:
+               {
+                   add_warning_message(464, "", "");
+                       current_token = yylex();
+                       if (current_token == OPEN_BR) {
+                               RD_inline_body(current_block);
+                               if (current_token != CLOSE_BR) {
+                                       add_error_message(200, "<inline>) ", YYTEXT_STRING);
+                                       while ((current_token != SEMI_COLON) && (current_token != END_OF_INPUT))
+                                               current_token = yylex();
+                               } else current_token = yylex();
+                       } else {
+                               add_error_message(200, "<inline>(", YYTEXT_STRING);
+                               while ((current_token != SEMI_COLON) && (current_token != END_OF_INPUT))
+                                       current_token = yylex();
+                       }
+                       break;
+               }
+
+       default:
+               {
+                       add_error_message(204, YYTEXT_STRING, "");
+                       break;
+               }
+       }
+}
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////// JAVA - ASM /////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/*
+       Handles the inline statement. The grammar rule
+       is:
+       <inline (byte)>
+       <inline (opcode)>
+       <inline (opcode int)>
+       <inline (opcode [[cp_type] 'param1', 'param2', 'param3'])>
+*/
+int RD_opcodes() {
+       if (strcmp(yytext, "nop") == 0)              return 0x00;       // íè÷åãî íå äåëàåò
+       if (strcmp(yytext, "aconst_null") == 0)      return 0x01;       // çàãðóçêà â ñòåê null ( ïóñòîé ññûëêè íà îáúåêò)
+       if (strcmp(yytext, "iconst_m1") == 0)        return 0x02;       // çàãðóçêà öåëî÷èñëåííîé êîíñòàíòû -1
+       if (strcmp(yytext, "iconst_0") == 0)         return 0x03;       // çàãðóçêà öåëî÷èñëåííîé êîíñòàíòû 0}
+       if (strcmp(yytext, "iconst_1") == 0)         return 0x04;       // çàãðóçêà öåëî÷èñëåííîé êîíñòàíòû 1}
+       if (strcmp(yytext, "iconst_2") == 0)         return 0x05;       // çàãðóçêà öåëî÷èñëåííîé êîíñòàíòû 2}
+       if (strcmp(yytext, "iconst_3") == 0)         return 0x06;       // çàãðóçêà öåëî÷èñëåííîé êîíñòàíòû 3}
+       if (strcmp(yytext, "iconst_4") == 0)         return 0x07;       // çàãðóçêà öåëî÷èñëåííîé êîíñòàíòû 4}
+       if (strcmp(yytext, "iconst_5") == 0)         return 0x08;       // çàãðóçêà öåëî÷èñëåííîé êîíñòàíòû 5}
+       if (strcmp(yytext, "lconst_0") == 0)         return 0x09;       // çàãðóçêà äëèííîé öåëî÷èñëåííîé êîíñòàíòû 0}
+       if (strcmp(yytext, "lconst_1") == 0)         return 0x0A;       // çàãðóçêà äëèííîé öåëî÷èñëåííîé êîíñòàíòû 1}
+       if (strcmp(yytext, "fconst_0") == 0)         return 0x0B;       // çàãðóçêà âåùåñòâåííîãî ÷èñëà îäèíàðíîé òî÷íîñòè 0}
+       if (strcmp(yytext, "fconst_1") == 0)         return 0x0C;       // çàãðóçêà âåùåñòâåííîãî ÷èñëà îäèíàðíîé òî÷íîñòè 1}
+       if (strcmp(yytext, "fconst_2") == 0)         return 0x0D;       // çàãðóçêà âåùåñòâåííîãî ÷èñëà îäèíàðíîé òî÷íîñòè 2}
+       if (strcmp(yytext, "dconst_0") == 0)         return 0x0E;       // çàãðóçêà âåùåñòâåííîãî ÷èñëà äâîéíîé òî÷íîñòè 0}
+       if (strcmp(yytext, "dconst_1") == 0)         return 0x0F;       // çàãðóçêà âåùåñòâåííîãî ÷èñëà äâîéíîé òî÷íîñòè 1}
+       if (strcmp(yytext, "bipush") == 0)           return 0x10;       // [1]çàãðóçêà â ñòåê îäíîáàéòîâîãî öåëîãî ñî çíàêîì}
+       if (strcmp(yytext, "sipush") == 0)           return 0x11;       // [2+-]çàãðóçêà â ñòåê äâóõáàéòîâîãî öåëîãî ñî çíàêîì}
+       if (strcmp(yytext, "ldc1") == 0)             return 0x12;       // [1]çàãðóçêà â ñòåê ýëåìåíòà èç êîíñòàíòíîãî ïóëà}
+       if (strcmp(yytext, "ldc2") == 0)             return 0x13;       // [2]çàãðóçêà â ñòåê ýëåìåíòà èç êîíñòàíòíîãî ïóëà}
+       if (strcmp(yytext, "ldc2w") == 0)            return 0x14;       // [2]çàãðóçêà â ñòåê äëèííîãî öåëîãî èëè äâîéíîãî âåùåñòâåííîãî çíà÷åíèÿ èç êîíñòàíòíîãî ïóëà}
+       if (strcmp(yytext, "iload") == 0)            return 0x15;       // [1]çàãðóçêà öåëîãî èç ëîêàëüíîé ïåðåìåííîé}
+       if (strcmp(yytext, "lload") == 0)            return 0x16;       // [1]çàãðóçêà äëèííîãî öåëîãî èç ëîêàëüíîé ïåðåìåííîé}
+       if (strcmp(yytext, "fload") == 0)            return 0x17;       // [1]çàãðóçêà âåùåñòâåííîãî îäèíàðíîé òî÷íîñòè èç ëîêàëüíîé ïåðåìåííîé}
+       if (strcmp(yytext, "dload") == 0)            return 0x18;       // [1]çàãðóçêà âåùåñòâåííîãî äâîéíîé òî÷íîñòè èç ëîêàëüíîé ïåðåìåííîé}
+       if (strcmp(yytext, "aload") == 0)            return 0x19;       // [1]çàãðóçêà îáúåêòíîé ññûëêè èç ëîêàëüíîé ïåðåìåííîé}
+       if (strcmp(yytext, "iload_0") == 0)          return 0x1A;       // çàãðóçêà öåëîãî èç ëîêàëüíîé ïåðåìåííîé 0}
+       if (strcmp(yytext, "iload_1") == 0)          return 0x1B;       // çàãðóçêà öåëîãî èç ëîêàëüíîé ïåðåìåííîé 1}
+       if (strcmp(yytext, "iload_2") == 0)          return 0x1C;       // çàãðóçêà öåëîãî èç ëîêàëüíîé ïåðåìåííîé 2}
+       if (strcmp(yytext, "iload_3") == 0)          return 0x1D;       // çàãðóçêà öåëîãî èç ëîêàëüíîé ïåðåìåííîé 3}
+       if (strcmp(yytext, "lload_0") == 0)          return 0x1E;       // çàãðóçêà äëèííîãî öåëîãî èç ëîêàëüíîé ïåðåìåííîé 0}
+       if (strcmp(yytext, "lload_1") == 0)          return 0x1F;       // çàãðóçêà äëèííîãî öåëîãî èç ëîêàëüíîé ïåðåìåííîé 1}
+       if (strcmp(yytext, "lload_2") == 0)          return 0x20;       // çàãðóçêà äëèííîãî öåëîãî èç ëîêàëüíîé ïåðåìåííîé 2}
+       if (strcmp(yytext, "lload_3") == 0)          return 0x21;       // çàãðóçêà äëèííîãî öåëîãî èç ëîêàëüíîé ïåðåìåííîé 3}
+       if (strcmp(yytext, "fload_0") == 0)          return 0x22;       // çàãðóçêà âåùåñòâåííîãî îäèíàðíîé òî÷íîñòè èç ëîêàëüíîé ïåðåìåííîé 0}
+       if (strcmp(yytext, "fload_1") == 0)          return 0x23;       // çàãðóçêà âåùåñòâåííîãî îäèíàðíîé òî÷íîñòè èç ëîêàëüíîé ïåðåìåííîé 1}
+       if (strcmp(yytext, "fload_2") == 0)          return 0x24;       // çàãðóçêà âåùåñòâåííîãî îäèíàðíîé òî÷íîñòè èç ëîêàëüíîé ïåðåìåííîé 2}
+       if (strcmp(yytext, "fload_3") == 0)          return 0x25;       // çàãðóçêà âåùåñòâåííîãî îäèíàðíîé òî÷íîñòè èç ëîêàëüíîé ïåðåìåííîé 3}
+       if (strcmp(yytext, "dload_0") == 0)          return 0x26;       // çàãðóçêà âåùåñòâåííîãî äâîéíîé òî÷íîñòè èç ëîêàëüíîé ïåðåìåííîé 0}
+       if (strcmp(yytext, "dload_1") == 0)          return 0x27;       // çàãðóçêà âåùåñòâåííîãî äâîéíîé òî÷íîñòè èç ëîêàëüíîé ïåðåìåííîé 1}
+       if (strcmp(yytext, "dload_2") == 0)          return 0x28;       // çàãðóçêà âåùåñòâåííîãî äâîéíîé òî÷íîñòè èç ëîêàëüíîé ïåðåìåííîé 2}
+       if (strcmp(yytext, "dload_3") == 0)          return 0x29;       // çàãðóçêà âåùåñòâåííîãî äâîéíîé òî÷íîñòè èç ëîêàëüíîé ïåðåìåííîé 3}
+       if (strcmp(yytext, "aload_0") == 0)          return 0x2A;       // çàãðóçêà îáúåêòíîé ññûëêè èç ëîêàëüíîé ïåðåìåííîé 0}
+       if (strcmp(yytext, "aload_1") == 0)          return 0x2B;       // çàãðóçêà îáúåêòíîé ññûëêè èç ëîêàëüíîé ïåðåìåííîé 1}
+       if (strcmp(yytext, "aload_2") == 0)          return 0x2C;       // çàãðóçêà îáúåêòíîé ññûëêè èç ëîêàëüíîé ïåðåìåííîé 2}
+       if (strcmp(yytext, "aload_3") == 0)          return 0x2D;       // çàãðóçêà îáúåêòíîé ññûëêè èç ëîêàëüíîé ïåðåìåííîé 3}
+       if (strcmp(yytext, "iaload") == 0)           return 0x2E;       // çàãðóçêà öåëîãî èç ìàññèâà}
+       if (strcmp(yytext, "laload") == 0)           return 0x2F;       // çàãðóçêà äëèííîãî öåëîãî èç ìàññèâà}
+       if (strcmp(yytext, "faload") == 0)           return 0x30;       // çàãðóçêà âåùåñòâåííîãî èç ìàññèâà}
+       if (strcmp(yytext, "daload") == 0)           return 0x31;       // çàãðóçêà äâîéíîãî âåùåñòâåííîãî èç ìàññèâà}
+       if (strcmp(yytext, "aaload") == 0)           return 0x32;       // çàãðóçêà îáúåêòíîé ññûëêè èç ìàññèâà}
+       if (strcmp(yytext, "baload") == 0)           return 0x33;       // çàãðóçêà áàéòà ñî çíàêîì èç ìàññèâà}
+       if (strcmp(yytext, "caload") == 0)           return 0x34;       // çàãðóçêà ñèìâîëà èç ìàññèâà}
+       if (strcmp(yytext, "saload") == 0)           return 0x35;       // çàãðóçêà êîðîòêîãî èç ìàññèâà}
+       if (strcmp(yytext, "istore") == 0)           return 0x36;       // [1]ñîõðàíåíèå öåëîãî çíà÷åíèÿ â ëîêàëüíîé ïåðåìåííîé}
+       if (strcmp(yytext, "lstore") == 0)           return 0x37;       // [1]ñîõðàíåíèå äëèííîãî öåëîãî â ëîêàëüíîé ïåðåìåííîé}
+       if (strcmp(yytext, "fstore") == 0)           return 0x38;       // [1]ñîõðàíåíèå âåùåñòâåííîãî îäèíàðíîé òî÷íîñòè â ëîêàëüíîé ïåðåìåííîé}
+       if (strcmp(yytext, "dstore") == 0)           return 0x39;       // [1]ñîõðàíåíèå äâîéíîãî âåùåñòâåííîãî â ëîêàëüíîé ïåðåìåííîé}
+       if (strcmp(yytext, "astore") == 0)           return 0x3A;       // [1]ñîõðàíåíèå îáúåêòíîé ññûëêè â ëîêàëüíîé ïåðåìåííîé}
+       if (strcmp(yytext, "istore_0") == 0)         return 0x3B;       // ñîõðàíåíèå öåëîãî â ëîêàëüíîé ïåðåìåííîé 0}
+       if (strcmp(yytext, "istore_1") == 0)         return 0x3C;       // ñîõðàíåíèå öåëîãî â ëîêàëüíîé ïåðåìåííîé 1}
+       if (strcmp(yytext, "istore_2") == 0)         return 0x3D;       // ñîõðàíåíèå öåëîãî â ëîêàëüíîé ïåðåìåííîé 2}
+       if (strcmp(yytext, "istore_3") == 0)         return 0x3E;       // ñîõðàíåíèå öåëîãî â ëîêàëüíîé ïåðåìåííîé 3}
+       if (strcmp(yytext, "lstore_0") == 0)         return 0x3F;       // ñîõðàíåíèå äëèííîãî öåëîãî â ëîêàëüíîé ïåðåìåííîé 0}
+       if (strcmp(yytext, "lstore_1") == 0)         return 0x40;       // ñîõðàíåíèå äëèííîãî öåëîãî â ëîêàëüíîé ïåðåìåííîé 1}
+       if (strcmp(yytext, "lstore_2") == 0)         return 0x41;       // ñîõðàíåíèå äëèííîãî öåëîãî â ëîêàëüíîé ïåðåìåííîé 2}
+       if (strcmp(yytext, "lstore_3") == 0)         return 0x42;       // ñîõðàíåíèå äëèííîãî öåëîãî â ëîêàëüíîé ïåðåìåííîé 3}
+       if (strcmp(yytext, "fstore_0") == 0)         return 0x43;       // ñîõðàíåíèå âåùåñòâåííîãî îäèíàðíîé òî÷íîñòè â ëîêàëüíîé ïåðåìåííîé 0}
+       if (strcmp(yytext, "fstore_1") == 0)         return 0x44;       // ñîõðàíåíèå âåùåñòâåííîãî îäèíàðíîé òî÷íîñòè â ëîêàëüíîé ïåðåìåííîé 1}
+       if (strcmp(yytext, "fstore_2") == 0)         return 0x45;       // ñîõðàíåíèå âåùåñòâåííîãî îäèíàðíîé òî÷íîñòè â ëîêàëüíîé ïåðåìåííîé 2}
+       if (strcmp(yytext, "fstore_3") == 0)         return 0x46;       // ñîõðàíåíèå âåùåñòâåííîãî îäèíàðíîé òî÷íîñòè â ëîêàëüíîé ïåðåìåííîé 3}
+       if (strcmp(yytext, "dstore_0") == 0)         return 0x47;       // ñîõðàíåíèå äâîéíîãî âåùåñòâåííîãî â ëîêàëüíîé ïåðåìåííîé 0}
+       if (strcmp(yytext, "dstore_1") == 0)         return 0x48;       // ñîõðàíåíèå äâîéíîãî âåùåñòâåííîãî â ëîêàëüíîé ïåðåìåííîé 1}
+       if (strcmp(yytext, "dstore_2") == 0)         return 0x49;       // ñîõðàíåíèå äâîéíîãî âåùåñòâåííîãî â ëîêàëüíîé ïåðåìåííîé 2}
+       if (strcmp(yytext, "dstore_3") == 0)         return 0x4A;       // ñîõðàíåíèå äâîéíîãî âåùåñòâåííîãî â ëîêàëüíîé ïåðåìåííîé 3}
+       if (strcmp(yytext, "astore_0") == 0)         return 0x4B;       // ñîõðàíåíèå îáúåêòíîé ññûëêè â ëîêàëüíîé ïåðåìåííîé 0}
+       if (strcmp(yytext, "astore_1") == 0)         return 0x4C;       // ñîõðàíåíèå îáúåêòíîé ññûëêè â ëîêàëüíîé ïåðåìåííîé 1}
+       if (strcmp(yytext, "astore_2") == 0)         return 0x4D;       // ñîõðàíåíèå îáúåêòíîé ññûëêè â ëîêàëüíîé ïåðåìåííîé 2}
+       if (strcmp(yytext, "astore_3") == 0)         return 0x4E;       // ñîõðàíåíèå îáúåêòíîé ññûëêè â ëîêàëüíîé ïåðåìåííîé 3}
+       if (strcmp(yytext, "iastore") == 0)          return 0x4F;       // ñîõðàíåíèå â öåëî÷èñëåííîì ìàññèâå}
+       if (strcmp(yytext, "lastore") == 0)          return 0x50;       // ñîõðàíåíèå â ìàññèâå èç äëèííûõ öåëûõ}
+       if (strcmp(yytext, "fastore") == 0)          return 0x51;       // ñîõðàíåíèå â ìàññèâå èç îäèíàðíûõ âåùåñòâåííûõ}
+       if (strcmp(yytext, "dastore") == 0)          return 0x52;       // ñîõðàíåíèå â ìàññèâå èç äâîéíûõ âåùåñòâåííûõ}
+       if (strcmp(yytext, "aastore") == 0)          return 0x53;       // ñîõðàíåíèå â ìàññèâå èç îáúåêòíûõ ññûëîê}
+       if (strcmp(yytext, "bastore") == 0)          return 0x54;       // ñîõðàíåíèå â ìàññèâå áàéòîâ ñî çíàêîì}
+       if (strcmp(yytext, "castore") == 0)          return 0x55;       // ñîõðàíåíèå â ñèìâîëüíîì ìàññèâå}
+       if (strcmp(yytext, "sastore") == 0)          return 0x56;       // ñîõðàíåíèå â ìàññèâå èç êîðîòêèõ öåëûõ}
+       if (strcmp(yytext, "pop") == 0)              return 0x57;       // èçâëå÷åíèå ñëîâà ñ âåðøèíû ñòåêà}
+       if (strcmp(yytext, "pop2") == 0)             return 0x58;       // èçâëå÷åíèå äâóõ ñëîâ ñ âåðøèíû ñòåêà}
+       if (strcmp(yytext, "dup") == 0)              return 0x59;       // äóáëèðîâàíèå ñëîâà íà âåðøèíå ñòåêà}
+       if (strcmp(yytext, "dup_x1") == 0)           return 0x5A;       // äóáëèðîâàíèå ñëîâî íà âåðøèíå ñòåêà è ïîìåùåíèå êîïèè â ñòåê íà äâà ñëîâà íèæå}
+       if (strcmp(yytext, "dup_x2") == 0)           return 0x5B;       // äóáëèðîâàíèå âåðøèíû ñòåêà è ïîìåùåíèå êîïèè íà òðè ñëîâà íèæå}
+       if (strcmp(yytext, "dup2") == 0)             return 0x5C;       // äóáëèðîâàíèå äâóõ ñëîâ íà âåðøèíå ñòåêà}
+       if (strcmp(yytext, "dup2_x1") == 0)          return 0x5D;       // äóáëèðîâàíèå äâóõ ñëîâ íà âåðøèíå ñòåêà è ïîìåùåíèå êîïèé íà äâà ñëîâà íèæå}
+       if (strcmp(yytext, "dup2_x2") == 0)          return 0x5E;       // äóáëèðîâàíèå äâóõ ñëîâ íà âåðøèíå ñòåêà è ïîìåùåíèå êîïèé íà òðè ñëîâà íèæå}
+       if (strcmp(yytext, "swap") == 0)             return 0x5F;       // îáìåí äâóõ ñëîâ íà âåðøèíå ñòåêà}
+       if (strcmp(yytext, "iadd") == 0)             return 0x60;       // ñëîæåíèå öåëûõ}
+       if (strcmp(yytext, "ladd") == 0)             return 0x61;       // ñëîæåíèå äëèííûõ öåëûõ}
+       if (strcmp(yytext, "fadd") == 0)             return 0x62;       // ñëîæåíèå îäèíàðíûõ âåùåñòâåííûõ}
+       if (strcmp(yytext, "dadd") == 0)             return 0x63;       // ñëîæåíèå äâîéíûõ âåùåñòâåííûõ}
+       if (strcmp(yytext, "isub") == 0)             return 0x64;       // âû÷èòàíèå öåëûõ}
+       if (strcmp(yytext, "lsub") == 0)             return 0x65;       // âû÷èòàíèå äëèííûõ öåëûõ}
+       if (strcmp(yytext, "fsub") == 0)             return 0x66;       // âû÷èòàíèå îäèíàðíûõ âåùåñòâåííûõ}
+       if (strcmp(yytext, "dsub") == 0)             return 0x67;       // âû÷èòàíèå äâîéíûõ âåùåñòâåííûõ}
+       if (strcmp(yytext, "imul") == 0)             return 0x68;       // óìíîæåíèå öåëûõ}
+       if (strcmp(yytext, "lmul") == 0)             return 0x69;       // óìíîæåíèå äëèííûõ öåëûõ}
+       if (strcmp(yytext, "fmul") == 0)             return 0x6A;       // óìíîæåíèå îäèíàðíûõ âåùåñòâåííûõ}
+       if (strcmp(yytext, "dmul") == 0)             return 0x6B;       // óìíîæåíèå äâîéíûõ âåùåñòâåííûõ}
+       if (strcmp(yytext, "idiv") == 0)             return 0x6C;       // äåëåíèå öåëûõ}
+       if (strcmp(yytext, "ldiv") == 0)             return 0x6D;       // äåëåíèå äëèííûõ öåëûõ}
+       if (strcmp(yytext, "fdiv") == 0)             return 0x6E;       // äåëåíèå îäèíàðíûõ âåùåñòâåííûõ}
+       if (strcmp(yytext, "ddiv") == 0)             return 0x6F;       // äåëåíèå äâîéíûõ âåùåñòâåííûõ}
+       if (strcmp(yytext, "irem") == 0)             return 0x70;       // îñòàòîê îò äåëåíèÿ öåëûõ}
+       if (strcmp(yytext, "lrem") == 0)             return 0x71;       // îñòàòîê îò äåëåíèÿ äëèííûõ öåëûõ}
+       if (strcmp(yytext, "frem") == 0)             return 0x72;       // îñòàòîê îò äåëåíèÿ îäèíàðíûõ âåùåñòâåííûõ}
+       if (strcmp(yytext, "drem") == 0)             return 0x73;       // îñòàòîê îò äåëåíèÿ äâîéíûõ âåùåñòâåííûõ}
+       if (strcmp(yytext, "ineg") == 0)             return 0x74;       // îòðèöàíèå öåëîãî}
+       if (strcmp(yytext, "leg") == 0)              return 0x75;       // îòðèöàíèå äëèííîãî öåëîãî}
+       if (strcmp(yytext, "fneg") == 0)             return 0x76;       // îòðèöàíèå îäèíàðíîãî âåùåñòâåííîãî}
+       if (strcmp(yytext, "dneg") == 0)             return 0x77;       // îòðèöàíèå äâîéíîãî âåùåñòâåííîãî ÷èñëà}
+       if (strcmp(yytext, "ishl") == 0)             return 0x78;       // ñäâèã öåëîãî âëåâî}
+       if (strcmp(yytext, "lshl") == 0)             return 0x79;       // ñäâèã äëèííîãî öåëîãî âëåâî}
+       if (strcmp(yytext, "ishr") == 0)             return 0x7A;       // àðèôìåòè÷åñêèé ñäâèã öåëîãî âïðàâî}
+       if (strcmp(yytext, "lshr") == 0)             return 0x7B;       // àðèôìåòè÷åñêèé ñäâèã äëèííîãî öåëîãî âïðàâî}
+       if (strcmp(yytext, "iushr") == 0)            return 0x7C;       // ëîãè÷åñêèé ñäâèã öåëîãî âïðàâî}
+       if (strcmp(yytext, "lushr") == 0)            return 0x7D;       // ëîãè÷åñêèé ñäâèã äëèííîãî öåëîãî âïðàâî}
+       if (strcmp(yytext, "iand") == 0)             return 0x7E;       // ëîãè÷åñêîå È ñ îïåðàíäàìè öåëîãî òèïà}
+       if (strcmp(yytext, "land") == 0)             return 0x7F;       // ëîãè÷åñêîå È ñ îïåðàíäàìè äëèííîãî öåëîãî òèïà}
+       if (strcmp(yytext, "ior") == 0)              return 0x80;       // ëîãè÷åñêîå ÈËÈ ñ öåëî÷èñëåííûìè îïåðàíäàìè}
+       if (strcmp(yytext, "lor") == 0)              return 0x81;       // ëîãè÷åñêîå ÈËÈ ñ îïåðàíäàìè äëèííîãî öåëîãî òèïà}
+       if (strcmp(yytext, "ixor") == 0)             return 0x82;       // èñêëþ÷àþùåå ÈËÈ ñ öåëî÷èñëåííûìè îïåðàíäàìè}
+       if (strcmp(yytext, "lxor") == 0)             return 0x83;       // èñêëþ÷àþùåå ÈËÈ ñ îïåðàíäàìè äëèííîãî öåëîãî òèïà}
+       if (strcmp(yytext, "iinc") == 0)             return 0x84;       // [1,1+-]óâåëè÷åíèå ëîêàëüíîé ïåðåìåííîé íà êîíñòàíòó}
+       if (strcmp(yytext, "i2l") == 0)              return 0x85;       // ïðåîáðàçîâàíèå öåëîãî â äëèííîå öåëîå}
+       if (strcmp(yytext, "i2f") == 0)              return 0x86;       // öåëîå â âåùåñòâåííîå}
+       if (strcmp(yytext, "i2d") == 0)              return 0x87;       // öåëîå â äâîéíîå âåùåñòâåííîå}
+       if (strcmp(yytext, "l2i") == 0)              return 0x88;       // äëèííîå öåëîå â öåëîå}
+       if (strcmp(yytext, "l2f") == 0)              return 0x89;       // äëèííîå öåëîå â âåùåñòâåííîå}
+       if (strcmp(yytext, "l2d") == 0)              return 0x8A;       // äëèííîå öåëîå â äâîéíîå âåùåñòâåííîå}
+       if (strcmp(yytext, "f2i") == 0)              return 0x8B;       // âåùåñòâåííîå â öåëîå}
+       if (strcmp(yytext, "f2l") == 0)              return 0x8C;       // âåùåñòâåííîå â äëèííîå öåëîå}
+       if (strcmp(yytext, "f2d") == 0)              return 0x8D;       // âåùåñòâåííîå â äâîéíîå âåùåñòâåííîå}
+       if (strcmp(yytext, "d2i") == 0)              return 0x8E;       // äâîéíîå âåùåñòâåííîå â öåëîå}
+       if (strcmp(yytext, "d2l") == 0)              return 0x8F;       // äâîéíîå âåùåñòâåííîå â äëèííîå öåëîå}
+       if (strcmp(yytext, "d2f") == 0)              return 0x90;       // äâîéíîå âåùåñòâåííîå â âåùåñòâåííîå}
+       if (strcmp(yytext, "int2byte") == 0)         return 0x91;       // öåëîå â çíàêîâûé áàéò}
+       if (strcmp(yytext, "int2char") == 0)         return 0x92;       // öåëîå â ñèìâîë}
+       if (strcmp(yytext, "int2short") == 0)        return 0x93;       // öåëîå â êîðîòêîå}
+       if (strcmp(yytext, "lcmp") == 0)             return 0x94;       // ñðàâíåíèå äëèííûõ öåëûõ}
+       if (strcmp(yytext, "fcmpl") == 0)            return 0x95;       // ñðàâíåíèå âåùåñòâåííûõ îäèíàðíîé òî÷íîñòè (-1 ïðè NaN)}
+       if (strcmp(yytext, "fcmpg") == 0)            return 0x96;       // ñðàâíåíèå âåùåñòâåííûõ îäèíàðíîé òî÷íîñòè (1 ïðè NaN)}
+       if (strcmp(yytext, "dcmpl") == 0)            return 0x97;       // ñðàâíåíèå âåùåñòâåííûõ äâîéíîé òî÷íîñòè(-1 ïðè NaN)}
+       if (strcmp(yytext, "dcmpg") == 0)            return 0x98;       // ñðàâíåíèå âåùåñòâåííûõ äâîéíîé òî÷íîñòè(1 ïðè NaN)}
+       if (strcmp(yytext, "ifeq") == 0)             return 0x99;       // [2]ïåðåõîä, åñëè ðàâíî 0}
+       if (strcmp(yytext, "ifne") == 0)             return 0x9A;       // [2]ïåðåõîä, åñëè íå ðàâíî 0}
+       if (strcmp(yytext, "iflt") == 0)             return 0x9B;       // [2]ïåðåõîä, åñëè ìåíüøå 0}
+       if (strcmp(yytext, "ifge") == 0)             return 0x9C;       // [2]ïåðåõîä, åñëè áîëüøå èëè ðàâíî 0}
+       if (strcmp(yytext, "ifgt") == 0)             return 0x9D;       // [2]ïåðåõîä, åñëè áîëüøå 0}
+       if (strcmp(yytext, "ifle") == 0)             return 0x9E;       // [2]ïåðåõîä, åñëè ìåíüøå èëè ðàâíî 0}
+       if (strcmp(yytext, "if_icmpeq") == 0)        return 0x9F;       // [2]ïåðåõîä, åñëè öåëûå ðàâíû}
+       if (strcmp(yytext, "if_icmpne") == 0)        return 0xA0;       // [2]ïåðåõîä, åñëè öåëûå íå ðàâíû}
+       if (strcmp(yytext, "if_icmplt") == 0)        return 0xA1;       // [2]ïåðåõîä, åñëè öåëîå ìåíüøå 0}
+       if (strcmp(yytext, "if_icmpge") == 0)        return 0xA2;       // [2]ïåðåõîä, åñëè öåëîå áîëüøå èëè ðàâíî}
+       if (strcmp(yytext, "if_icmpgt") == 0)        return 0xA3;       // [2]ïåðåõîä, åñëè öåëîå áîëüøå 0}
+       if (strcmp(yytext, "if_icmple") == 0)        return 0xA4;       // [2]ïåðåõîä, åñëè öåëîå ìåíüøå èëè ðàâíî}
+       if (strcmp(yytext, "if_acmpeq") == 0)        return 0xA5;       // [2]ïåðåõîä, åñëè ññûëêè íà îáúåêò ðàâíû}
+       if (strcmp(yytext, "if_acmpne") == 0)        return 0xA6;       // [2]ïåðåõîä, åñëè ññûëêè íà îáúåêò íå ðàâíû}
+       if (strcmp(yytext, "goto") == 0)             return 0xA7;       // [2]ïåðåõîä íà}
+       if (strcmp(yytext, "jsr") == 0)              return 0xA8;       // [2]ïåðåõîä íà ïîäïðîãðàììó}
+       if (strcmp(yytext, "ret") == 0)              return 0xA9;       // [1]âîçâðàò èç ïîäïðîãðàììû}
+       if (strcmp(yytext, "tableswitch") == 0)      return 0xAA;       // [tbs] äîñòóï ê òàáëèöå ïåðåõîäà ïî èíäåêñó è ïåðåõîä}
+       if (strcmp(yytext, "lookupswitch") == 0)     return 0xAB;       // [lks] äîñòóï ê òàáëèöå ïåðåõîäà ïî ñðàâíåíèþ ñ êëþ÷îì è ïåðåõîä}
+       if (strcmp(yytext, "ireturn") == 0)          return 0xAC;       // âîçâðàò öåëîãî çíà÷åíèÿ ôóíêöèè}
+       if (strcmp(yytext, "lreturn") == 0)          return 0xAD;       // âîçâðàò äëèííîãî öåëîãî çíà÷åíèÿ ôóíêöèè}
+       if (strcmp(yytext, "freturn") == 0)          return 0xAE;       // âîçâðàò îäèíàðíîãî âåùåñòâåííîãî çíà÷åíèÿ ôóíêöèè}
+       if (strcmp(yytext, "dreturn") == 0)          return 0xAF;       // âîçâðàò äâîéíîãî âåùåñòâåííîãî çíà÷åíèÿ ôóíêöèè}
+       if (strcmp(yytext, "areturn") == 0)          return 0xB0;       // âîçâðàò îáúåêòíîé ññûëêè èç ôóíêöèè}
+       if (strcmp(yytext, "return") == 0)           return 0xB1;       // âîçâðàò(îïóñòîøàþùèé) èç ïðîöåäóðû}
+       if (strcmp(yytext, "getstatic") == 0)        return 0xB2;       // [2fld]ïîëó÷åíèå ñòàòè÷åñêîãî ïîëÿ êëàññà}
+       if (strcmp(yytext, "putstatic") == 0)        return 0xB3;       // [2fld]óñòàíîâêà ñòàòè÷åñêîãî ïîëÿ â êëàññå}
+       if (strcmp(yytext, "getfield") == 0)         return 0xB4;       // [2fld]ïåðåíîñ ïîëÿ èç îáúåêòà}
+       if (strcmp(yytext, "putfield") == 0)         return 0xB5;       // [2fld]óñòàíîâêà ïîëÿ â îáúåêòå}
+       if (strcmp(yytext, "invokevirtual") == 0)    return 0xB6;       // [2mtd],âûçûâàåò ìåòîä ýêçåìïëÿðà, îñíîâûâàÿñü íà òèïå âðåìåíè âûïîëíåíèÿ}
+       if (strcmp(yytext, "invokenonvirtual") == 0) return 0xB7;       // [2mtd],âûçûâàåò ìåòîä ýêçåìïëÿðà, îñíîâûâàÿñü íà íå âèðòóàëüíîì òèïå}
+       if (strcmp(yytext, "invokestatic") == 0)     return 0xB8;       // [2mtd]âûçîâ ìåòîäà êëàññà (ñòàòè÷åñêîãî ìåòîäà)}
+       if (strcmp(yytext, "invokeinterface") == 0)  return 0xB9;       // [2,1,1]âûçûâàåò ìåòîä èíòåðôåéñà}
+       if (strcmp(yytext, "new") == 0)              return 0xBB;       // [2]ñîçäàåò íîâûé îáúåêò}
+       if (strcmp(yytext, "newarray") == 0)         return 0xBC;       // [1]atype> T_BOOLEAN=4,T_CHAR=5,T_FLOAT=6,T_DOUBLE=7,T_BYTE=8, T_SHORT=9,T_INT=9,T_LONG=11}
+       if (strcmp(yytext, "anewarray") == 0)        return 0xBD;       // [2class]îáúÿâëåíèå íîâîãî ìàññèâà èç ññûëîê íà îáúåêòû}
+       if (strcmp(yytext, "arraylength") == 0)      return 0xBE;       // âîçâðàùàåò äëèíó ìàññèâà}
+       if (strcmp(yytext, "athrow") == 0)           return 0xBF;       // ãåíåðàöèÿ îáðàáîòêè èëè îøèáêè}
+       if (strcmp(yytext, "checkcast") == 0)        return 0xC0;       // cs 2,ïðîâåðÿåò, ÷òî îáúåêò èìååò äàííûé òèï}
+       if (strcmp(yytext, "instanceof") == 0)       return 0xC1;       // [2class]îïðåäåëÿåò, èìååò ëè îáúåêò äàííûé òèï}
+       if (strcmp(yytext, "monitorenter") == 0)     return 0xC2;       // âõîä â êîíòðîëèðóåìóþ îáëàñòü êîäà}
+       if (strcmp(yytext, "monitorexit") == 0)      return 0xC3;       // âûõîä èç êîíòðîëèðóåìîé îáëàñòè êîäà}
+       if (strcmp(yytext, "wide") == 0)             return 0xC4;       // ðàñøèðåííûé èíäåêñ äëÿ äîñòóïà ê ëîêàëüíûì ïåðåìåííûì äëÿ êîìàíä çàãðóçêè, ñîõðàíåíèÿ è ïðèðàùåíè}
+       if (strcmp(yytext, "multianewarray") == 0)   return 0xC5;       // [2cp-index,1b]ðàçìåùåíèå íîâîãî ìíîãîìåðíîãî ìàññèâà}
+       if (strcmp(yytext, "ifnull") == 0)           return 0xC6;       // [2ofs]ïåðåõîä, åñëè ïóñòîé óêàçàòåëü}
+       if (strcmp(yytext, "ifnonnull") == 0)        return 0xC7;       // [2ofs]ïåðåõîä, åñëè íå ïóñòîé óêàçàòåëü}
+       if (strcmp(yytext, "goto_w") == 0)           return 0xC8;       // [4ofs]ïåðåõîä íà (ðàñøèðåííûé èíäåêñ)}
+       if (strcmp(yytext, "jsr_w") == 0)            return 0xC9;       // [4ofs]ïåðåõîä íà ïîäïðîãðàììó (ðàñøèðåííûé èíäåêñ)}
+       if (strcmp(yytext, "breakpoint") == 0)       return 0xCA;       // îñòàíîâêà è ïåðåäà÷à êîíòðîëÿ îáðàáîò÷èêó ïðåðûâàíèé}
+       if (strcmp(yytext, "ret_w") == 0)            return 0xD1;       // [2]âîçâðàò èç ïîäïðîãðàììû (ðàñøèðåííûé èíäåêñ)}
+       return 0xFF;
+       //0x10,0xBC                                     1b;
+       //0x11                                          2b+-;
+       //0x12                                          1b constpool-index;
+       //0x13                                          2b constpool-index(2byte-const);
+       //0x14                                          2b constpool-index(4byte-const);
+       //0xB2,0xB3,0xB4,0xB5           2b constpool-field;
+       //0xB6,0xB7,0xB8                        2b constpool-method;
+       //0xB9                                          2b constpool-method; 1b; 1b;
+       //0xBB                                          2b constpool-index;
+       //0xC5                                          2b constpool-index; 1b;
+       //0xBD,0xC1                                     2b constpool-class;
+       //0xC0                                          2b constpool-string;
+       //0x15,0x16,0x17,0x18,0x19      1b locvar-index;
+       //0x36,0x37,0x38,0x39,0x3A      1b locvar-index;
+       //0x84                                          1b; 1b+-(locvar-add-const);
+       //0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xC6,0xC7  2b offs;
+       //0xC8                                          4b offs;
+       //0xC9                                          4b call;
+       //0xA8                                          2b call;
+       //0xA9                                          1b ret;
+       //0xD1                                          2b ret;
+       //0xC4                                          wide...;
+       //0xAA                                          tableswitch...;
+       //0xAB                                          loookupswitch...;
+       //îñòàëüíûå êîäû ïàðàìåòðîâ íå èìåþò...
+}
+
+int cp_index_body()
+{ //ðàçáîð ìîäèôèêàöèé ññûëîê íà ïàðàìåòðû êîíñòàíòíîãî ïóëà
+       char p1[512];
+       char p2[512];
+       if (current_token == IDENTIFIER)
+       {
+               if (strcmp(yytext, "int") == 0)
+               {
+                       current_token = yylex();
+                       if (current_token == CST_INTEGER) return cp_add_integer(integer_constant);
+               }
+               else if (strcmp(yytext, "utf8") == 0)
+               {
+                       current_token = yylex();
+                       if ((current_token == CST_STRING)||(current_token == CST_CHAR)) return cp_add_utf8(yytext);
+               }
+               else if (strcmp(yytext, "str") == 0)
+               {
+                       current_token = yylex();
+                       if ((current_token == CST_STRING)||(current_token == CST_CHAR)) return cp_add_string(yytext);
+               }
+               else if (strcmp(yytext, "class") == 0)
+               {
+                       current_token = yylex();
+                       if ((current_token == CST_STRING)||(current_token == CST_CHAR)) return cp_add_class(yytext);
+               }
+               else if (strcmp(yytext, "nametype") == 0)
+               {
+                       current_token = yylex();
+                       if ((current_token == CST_STRING)||(current_token == CST_CHAR))
+                       {
+                               strcpy(&p1,yytext);
+                               current_token = yylex();
+                               if (current_token == COMMA)
+                               {
+                                       current_token = yylex();
+                                       if ((current_token == CST_STRING)||(current_token == CST_CHAR)) return cp_add_nameandtype(p1, yytext);
+                               }
+                       }
+               } else if (strcmp(yytext, "field") == 0)
+               {
+                       current_token = yylex();
+                       if ((current_token == CST_STRING)||(current_token == CST_CHAR))
+                       {
+                               strcpy(&p1,yytext);
+                               current_token = yylex();
+                               if (current_token == COMMA)
+                               {
+                                       current_token = yylex();
+                                       if ((current_token == CST_STRING)||(current_token == CST_CHAR))
+                                       {
+                                               strcpy(&p2,yytext);
+                                               current_token = yylex();
+                                               if (current_token == COMMA)
+                                               {
+                                                       current_token = yylex();
+                                                       if ((current_token == CST_STRING)||(current_token == CST_CHAR)) return cp_add_fieldref(p1,p2,yytext);
+                                               }
+                                       }
+                               }
+                       }
+               }
+               else if (strcmp(yytext, "method") == 0)
+               {
+                       current_token = yylex();
+                       if ((current_token == CST_STRING)||(current_token == CST_CHAR))
+                       {
+                               strcpy(&p1,yytext);
+                               current_token = yylex();
+                               if (current_token == COMMA)
+                               {
+                                       current_token = yylex();
+                                       if ((current_token == CST_STRING)||(current_token == CST_CHAR))
+                                       {
+                                               strcpy(&p2,yytext);
+                                               current_token = yylex();
+                                               if (current_token == COMMA)
+                                               {
+                                                       current_token = yylex();
+                                                       if ((current_token == CST_STRING)||(current_token == CST_CHAR)) return cp_add_methodref(p1,p2,yytext);
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+       else if (current_token == KWD_INTERFACE)   //if (strcmp(yytext, "interface") == 0)
+       {
+               current_token = yylex();
+               if ((current_token == CST_STRING)||(current_token == CST_CHAR))
+               {
+                       strcpy(&p1,yytext);
+                       current_token = yylex();
+                       if (current_token == COMMA)
+                       {
+                               current_token = yylex();
+                               if ((current_token == CST_STRING)||(current_token == CST_CHAR))
+                               {
+                                       strcpy(&p2,yytext);
+                                       current_token = yylex();
+                                       if (current_token == COMMA)
+                                       {
+                                               current_token = yylex();
+                                               if ((current_token == CST_STRING)||(current_token == CST_CHAR)) return cp_add_interface(p1,p2,yytext);
+                                       }
+                               }
+                       }
+               }
+       }
+       return -1;  //îøèáêà ðàçáîðà ïàðàìåòðîâ
+}
+
+
+int RD_inline_offs(block *current_block, int n, int addr)
+{
+       current_token = yylex();
+       if (current_token == CST_INTEGER) return (short)integer_constant; //NUMBER
+       if (current_token == COLON) //FIND LABEL
+       {
+               current_token = yylex();
+               if (current_token == CST_INTEGER)
+               {
+                       int i = labcount;
+                       nam[0] = integer_constant;
+                       if (integer_constant==111)
+                               integer_constant=111;
+                       len[0] = 0;
+                       while ((nam[i] != integer_constant) || (len[i] != 0)) i--;
+                       if (i>0) return lab[i]-addr;
+                       //add find block
+                       labcount++;
+                       nam[labcount] = integer_constant;
+                       len[labcount] = n; //offs-type: 2bytes / 4bytes
+                       lab[labcount] = current_block->code->bytecode_pos;
+                       return addr;   //label no found
+               }
+       }
+       return 0; //error!
+}
+
+
+void RD_inline_body(block *current_block)
+{
+       int cp_index,opcode,err,addr,offs,i,j;
+       labcount=0;
+       err=0;
+       do {
+               current_token = yylex();
+               if (current_token == IDENTIFIER)
+               {
+                       opcode=RD_opcodes();
+                       bytecode_append(current_block->code, opcode);
+                       ///////
+                       switch (opcode)
+                       {
+                       case 0x10:  //1byte;
+                       case 0xBC:
+                       case 0x15:  //1b locvar-index;
+                       case 0x16:
+                       case 0x17:
+                       case 0x18:
+                       case 0x19:
+                       case 0x36:  //1b locvar-index;
+                       case 0x37:
+                       case 0x38:
+                       case 0x39:
+                       case 0x3A:
+                       case 0xA9:  //1b ret;
+                               err=1;
+                               current_token = yylex();
+                               if ((current_token == CST_INTEGER) && (integer_constant>=0) && (integer_constant<=255))
+                               {
+                                       bytecode_append(current_block->code, (char)integer_constant);
+                                       err=0;
+                               }
+                               break;
+                       case 0x84:  //1b; 1b+-(locvar-add-const);
+                               err=1;
+                               current_token = yylex();
+                               if ((current_token == CST_INTEGER) && (integer_constant>=0) && (integer_constant<=255))
+                               {
+                                       bytecode_append(current_block->code, (char)integer_constant);
+                                       current_token = yylex();
+                                       if (current_token == COMMA)
+                                       {
+                                               current_token = yylex();
+                                               if ((current_token == CST_INTEGER) && (integer_constant>=0)&&(integer_constant<=255))
+                                               {
+                                                       bytecode_append(current_block->code, (char)integer_constant);
+                                                       err=0;
+                                               }
+                                       }
+                               }
+                               break;
+                       case 0x11:  //2b+-;
+                               err=1;
+                               current_token = yylex();
+                               if ((current_token == CST_INTEGER) && (integer_constant>=0) && (integer_constant<=65535))
+                               {
+                                       bytecode_append_short_int(current_block->code, (short)integer_constant);
+                                       err=0;
+                               }
+                               break;
+                       case 0x99:  //2b offs;
+                       case 0x9A:
+                       case 0x9B:
+                       case 0x9C:
+                       case 0x9D:
+                       case 0x9E:
+                       case 0x9F:
+                       case 0xA0:
+                       case 0xA1:
+                       case 0xA2:
+                       case 0xA3:
+                       case 0xA4:
+                       case 0xA5:
+                       case 0xA6:
+                       case 0xA7:
+                       case 0xC6:
+                       case 0xC7:
+                       case 0xA8:  //2b call;
+                       case 0xD1:  //2b ret;
+                               err=1;
+                               addr = current_block->code->bytecode_pos-1;
+                               offs = RD_inline_offs(current_block, 2, addr);
+                               if (offs != 0)
+                               {
+                                       if ((offs>=-32768) && (offs<=32767))
+                                       {
+                                               bytecode_append_short_int(current_block->code, (short)offs);
+                                               err=0;
+                                       }
+                               }
+                               //current_token = yylex();
+                               //if ((current_token == CST_INTEGER) && (integer_constant>=0) && (integer_constant<=65535))
+                               //{
+                               //      bytecode_append_short_int(current_block->code, (short)integer_constant);
+                               //      err=0;
+                               //}
+                               break;
+                       case 0xC8:  //4b offs;
+                       case 0xC9:  //4b call;
+                               err=1;
+                               addr = current_block->code->bytecode_pos-1;
+                               offs = RD_inline_offs(current_block, 4, addr);
+                               if (offs != 0)
+                               {
+                                       bytecode_append_long_int(current_block->code, offs);
+                                       err=0;
+                               }
+                               //current_token = yylex();
+                               //if (current_token == CST_INTEGER)
+                               //{
+                               //      bytecode_append_long_int(current_block->code, integer_constant);
+                               //      err=0;
+                               //}
+                               break;
+                       case 0x12:  //1b constpool-index;
+                               err=1;
+                               current_token = yylex();
+                               cp_index=cp_index_body();
+                               if ((cp_index>=0) && (cp_index<=255))
+                               {
+                                       bytecode_append(current_block->code, cp_index);
+                                       err=0;
+                               }
+                               break;
+                       case 0xBB:  //2b constpool-index;
+                               err=1;
+                               current_token = yylex();
+                               cp_index=cp_index_body();
+                               if (cp_index>=0)
+                               {
+                                       bytecode_append_short_int(current_block->code, cp_index);
+                                       err=0;
+                               }
+                               break;
+                       case 0xC5:  //2b constpool-index; 1b;
+                               err=1;
+                               current_token = yylex();
+                               cp_index=cp_index_body();
+                               if (cp_index>=0)
+                               {
+                                       bytecode_append_short_int(current_block->code, cp_index);
+                                       current_token = yylex();
+                                       if (current_token == COMMA)
+                                       {
+                                               current_token = yylex();
+                                               if (current_token == CST_INTEGER)
+                                               {
+                                                       if ((integer_constant>=0) && (integer_constant<=255))
+                                                       {
+                                                               bytecode_append(current_block->code, (char)integer_constant);
+                                                               err=0;
+                                                       }
+                                               }
+                                       }
+                               }
+                               break;
+                       case 0xBD:  //2b constpool-class;
+                       case 0xC1:
+                               err=1;
+                               current_token = yylex();
+                               if ((current_token == IDENTIFIER) && (strcmp(yytext, "class") == 0))
+                               {
+                                       cp_index=cp_index_body();
+                                       if (cp_index>=0)
+                                       {
+                                               bytecode_append_short_int(current_block->code, cp_index);
+                                               err=0;
+                                       }
+                               }
+                               break;
+                       case 0xC0:  //2b constpool-string;
+                               err=1;
+                               current_token = yylex();
+                               if (current_token == IDENTIFIER) //&& (strcmp(yytext, "str") == 0))
+                               {
+                                       cp_index=cp_index_body();
+                                       if (cp_index>=0)
+                                       {
+                                               bytecode_append_short_int(current_block->code, cp_index);
+                                               err=0;
+                                       }
+                               }
+                               break;
+                       case 0x13:  //2b constpool-index(2byte-const);
+                       case 0x14:  //2b constpool-index(4byte-const);
+                               err=1;
+                               current_token = yylex();
+                               //if ((current_token == IDENTIFIER) && (strcmp(yytext, "int") == 0))
+                               //{
+                                       cp_index=cp_index_body();
+                                       if (cp_index>=0)
+                                       {
+                                               bytecode_append_short_int(current_block->code, cp_index);
+                                               err=0;
+                                       }
+                               //}
+                               break;
+                       case 0xB2:  //2b constpool-field;
+                       case 0xB3:
+                       case 0xB4:
+                       case 0xB5:
+                               err=1;
+                               current_token = yylex();
+                               if ((current_token == IDENTIFIER) && (strcmp(yytext, "field") == 0))
+                               {
+                                       cp_index=cp_index_body();
+                                       if (cp_index>=0)
+                                       {
+                                               bytecode_append_short_int(current_block->code, cp_index);
+                                               err=0;
+                                       }
+                               }
+                               break;
+                       case 0xB6:  //2b constpool-method;
+                       case 0xB7:
+                       case 0xB8:
+                               err=1;
+                               current_token = yylex();
+                               if ((current_token == IDENTIFIER) && (strcmp(yytext, "method") == 0))
+                               {
+                                       cp_index=cp_index_body();
+                                       if (cp_index>=0)
+                                       {
+                                               bytecode_append_short_int(current_block->code, cp_index);
+                                               err=0;
+                                       }
+                               }
+                               break;
+                       case 0xB9:  //2b constpool-method; 1b; 1b;
+                               err=1;
+                               current_token = yylex();
+                               if (current_token == KWD_INTERFACE) //&& (strcmp(yytext, "interface") != 0))
+                               {
+                                       cp_index=cp_index_body();
+                                       if (cp_index>=0)
+                                       {
+                                               bytecode_append_short_int(current_block->code, cp_index);
+                                               current_token = yylex();
+                                               if (current_token == COMMA)
+                                               {
+                                                       current_token = yylex();
+                                                       if (current_token == CST_INTEGER) {
+                                                               if ((integer_constant>=0) && (integer_constant<=255))
+                                                               {
+                                                                       bytecode_append(current_block->code, (char)integer_constant);
+                                                                       current_token = yylex();
+                                                                       if (current_token == COMMA)
+                                                                       {
+                                                                               current_token = yylex();
+                                                                               if (current_token == CST_INTEGER)
+                                                                               {
+                                                                                       if ((integer_constant>=0) && (integer_constant<=255))
+                                                                                       {
+                                                                                               bytecode_append(current_block->code, (char)integer_constant);
+                                                                                               err=0;
+                                                                                       }
+                                                                               }
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                               break;
+                       case 0xAA:  //tableswitch...;
+                               {
+                                       err=1;
+                                       addr = current_block->code->bytecode_pos-1;
+                                       while (current_block->code->bytecode_pos%4!=0)  //4byte-align
+                                               bytecode_append(current_block->code, 0);
+                                       offs = RD_inline_offs(current_block, 4, addr);
+                                       if (offs != 0)
+                                       {
+                                               bytecode_append_long_int(current_block->code, offs); //default-offs
+                                               current_token = yylex();
+                                               if (current_token == COMMA)
+                                               {
+                                                       current_token = yylex();
+                                                       if (current_token == CST_INTEGER)
+                                                       {
+                                                               bytecode_append_long_int(current_block->code, integer_constant); //low-index
+                                                               i=integer_constant;
+                                                               current_token = yylex();
+                                                               if (current_token == COMMA)
+                                                               {
+                                                                       current_token = yylex();
+                                                                       if (current_token == CST_INTEGER)
+                                                                       {
+                                                                               bytecode_append_long_int(current_block->code, integer_constant); //high-index    Length=high-low+1
+                                                                               j=integer_constant;
+                                                                               current_token = yylex();
+                                                                               if (current_token == COMMA)
+                                                                               {
+                                                                                       err=0;
+                                                                                       for (; i<=j; i++)
+                                                                                       {
+                                                                                               offs = RD_inline_offs(current_block, 4, addr);
+                                                                                               if (i<j)
+                                                                                               {
+                                                                                                       current_token = yylex();
+                                                                                                       if (current_token != COMMA) offs = 0;
+                                                                                               }
+                                                                                               if (offs == 0) //bad label
+                                                                                               {
+                                                                                                       add_error_message(462,  0, current_block->code->bytecode_pos);
+                                                                                                       err=1;
+                                                                                                       break;
+                                                                                               }
+                                                                                               bytecode_append_long_int(current_block->code, offs); //i-offs
+                                                                                       }
+                                                                               }
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                               break;
+
+                       case 0xAB:  //loookupswitch...;
+                               {
+                                       err=1;
+                                       addr = current_block->code->bytecode_pos-1;
+                                       while (current_block->code->bytecode_pos%4!=0)  //4byte-align
+                                               bytecode_append(current_block->code, 0);
+                                       offs = RD_inline_offs(current_block, 4, addr);
+                                       if (offs != 0)
+                                       {
+                                               bytecode_append_long_int(current_block->code, offs); //default-offs
+                                               current_token = yylex();
+                                               if (current_token == COMMA)
+                                               {
+                                                       current_token = yylex();
+                                                       if (current_token == CST_INTEGER)
+                                                       {
+                                                               bytecode_append_long_int(current_block->code, integer_constant); //length
+                                                               i=integer_constant;
+                                                               current_token = yylex();
+                                                               if (current_token == COMMA)
+                                                               {
+                                                                       err=0;
+                                                                       for (; i>0; i--)
+                                                                       {
+                                                                               offs = 0;
+                                                                               current_token = yylex();
+                                                                               if (current_token == CST_INTEGER)
+                                                                               {
+                                                                                       bytecode_append_long_int(current_block->code, integer_constant);
+                                                                                       offs = RD_inline_offs(current_block, 4, addr);
+                                                                                       if (i>1)
+                                                                                       {
+                                                                                               current_token = yylex();
+                                                                                               if (current_token != COMMA) offs = 0;
+                                                                                       }
+                                                                               }
+                                                                               if (offs == 0) //bad label
+                                                                               {
+                                                                                       add_error_message(462,  0, current_block->code->bytecode_pos);
+                                                                                       err=1;
+                                                                                       break;
+                                                                               }
+                                                                               bytecode_append_long_int(current_block->code, offs); //i-offs
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                               break;
+                       /*
+                       case 0xC4:  //wide;
+                               break;
+                       */
+                       case 0xFF:
+                               err=1;
+                               break;
+                       }
+               }
+               else if (current_token == CST_INTEGER)
+               {
+                       if (integer_constant<=255) bytecode_append(current_block->code, (char)integer_constant);
+                       else if (integer_constant<=65535) bytecode_append_short_int(current_block->code, (short)integer_constant);
+                       else bytecode_append_long_int(current_block->code, integer_constant);
+                       err=0;
+               }
+               else if (current_token == COLON) //SET LABEL
+               {
+                       err=1;
+                       current_token = yylex();
+                       if (current_token == CST_INTEGER)
+                       {
+                               nam[0]=integer_constant;
+                               len[0]=0;
+                               i=labcount;
+                               while ((nam[i]!=integer_constant) || (len[i]!=0)) i--;
+                               if (i==0)
+                               {
+                                       labcount++;
+                                       nam[labcount] = integer_constant;
+                                       len[labcount] = 0;
+                                       lab[labcount] = current_block->code->bytecode_pos;
+                                       err=0;
+                               }
+                               else
+                               {
+                                       add_error_message(461,  nam[i], current_block->code->bytecode_pos);
+                                       labcount=0;
+                               }
+
+                       }
+               }
+               else err=1;
+               /////////
+               if (err==0)
+               {
+                       current_token = yylex();
+                       if (current_token != SEMI_COLON) err=1;
+               }
+       } while (err==0);
+       //modify old label
+       for (i=labcount; i>0; i--) if (len[i]>0)
+       {
+               for (j=labcount; j>i; j--) if (len[j]==0) if (nam[i]==nam[j]) break;
+               if (j>i)
+               {
+                       int k;
+                       offs = 0;
+                       for (k = lab[i];  k<lab[i]+len[i];  k++)
+                               offs = (offs << 8) + (current_block->code->bytecode[k] & 0xff);
+                       offs = lab[j]-offs;
+                       for (k--;  k>=lab[i];  k--)
+                       {
+                               current_block->code->bytecode[k] = (char)offs;
+                               offs = offs>>8;
+                       }
+               }
+               else add_error_message(460, nam[i], lab[i]);
+       }
+}
+///////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////// END JAVA - ASM ///////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+
+/*
+       Handles the if-then-[else] statement. The grammar rule
+       is:
+
+       <RD_if_statement> -> <RD_expression> then <RD_statement>
+                             [ else <RD_statement> ]
+
+*/
+void RD_if_statement(block *current_block)
+{
+       type *expression_type;
+       long int jump_offset_position;
+       signed short int offset;
+
+       expression_type = RD_expression(current_block);
+
+       if ((expression_type->type_class != error_type) /* a simple error-recovery */
+               && (expression_type->type_class != boolean_type))
+       {
+               add_error_message(407, "boolean", "");
+       }
+
+       type_destroy(expression_type);
+
+       if (current_token != KWD_THEN)
+       {
+               add_error_message(216, YYTEXT_STRING, "");
+       }
+
+       current_token = yylex();
+
+       /* generate the code */
+       bytecode_append(current_block->code, ifeq$); /* branch if comparison with zero succedd */
+       jump_offset_position = current_block->code->bytecode_pos;
+       bytecode_append(current_block->code, 0); /* the place for offset of where to jump */
+       bytecode_append(current_block->code, 0);
+
+       RD_statement(current_block);
+
+       while (current_token == SEMI_COLON)
+               current_token = yylex();
+
+       if (current_token == KWD_ELSE)
+       {
+               /* set the address of the next instruction */
+               offset = (short) (current_block->code->bytecode_pos + 4 - jump_offset_position);
+               current_block->code->bytecode[jump_offset_position] = (char) (offset>>8);
+               current_block->code->bytecode[jump_offset_position+1] = (char) offset;
+
+               bytecode_append(current_block->code, goto$);
+               jump_offset_position = current_block->code->bytecode_pos;
+               bytecode_append(current_block->code, 0);
+               bytecode_append(current_block->code, 0);
+
+               current_token = yylex();
+
+               RD_statement(current_block);
+
+               /* set the adress of the next instruction */
+               offset = (short) (current_block->code->bytecode_pos - jump_offset_position + 1);
+               current_block->code->bytecode[jump_offset_position] = (char) (offset>>8);
+               current_block->code->bytecode[jump_offset_position+1] = (char) offset;
+       }
+       else
+       {
+               char *yycopy;
+               int i;
+
+               /* set the address of the next instruction */
+               offset = (short) (current_block->code->bytecode_pos - jump_offset_position + 1);
+               current_block->code->bytecode[jump_offset_position] = (char) (offset>>8);
+               current_block->code->bytecode[jump_offset_position+1] = (char) offset;
+
+               /* put the current token back to stream and preceed it with ';' */
+               yycopy = strdup(yytext);
+
+               for(i = strlen(yytext) - 1; i >= 0; i--)
+                       backchar(yycopy[i]);
+               backchar(';');
+               free(yycopy);
+
+               current_token = yylex();
+       }
+}
+
+/*
+       The case-of statement. The rule used is:
+
+       <RD_case_statement> -> <RD_expression> OF
+                                <RD_case_list> end
+*/
+void RD_case_statement(block *current_block)
+{
+       type *expression_type;
+       expression_type = RD_expression(current_block);
+
+       add_error_message(442, "", "");
+
+       if ((expression_type->type_class != error_type) /* a simple error-recovery */
+               && (expression_type->type_class != integer_type)
+               && (expression_type->type_class != char_type)
+               && (expression_type->type_class != string_type))
+       {
+               add_error_message(408, "", "");
+       }
+
+       if (current_token != KWD_OF)
+       {
+               add_error_message(203, "of", YYTEXT_STRING);
+       }
+
+       current_token = yylex();
+
+       RD_case_list(current_block, expression_type);
+
+       if (current_token != KWD_END)
+       {
+               add_error_message(203, "end", YYTEXT_STRING);
+       }
+
+       current_token = yylex();
+       type_destroy(expression_type);
+}
+
+
+/*
+       The case expression's list.
+
+       <RD_case_list> -> ( CONST (, CONST)* : <RD_statement> )+
+*/
+void RD_case_list(block *current_block, type *case_type)
+{
+       short int first_pass = 1;
+
+       do
+       {
+               if (first_pass)
+                       first_pass = 0;
+               else
+                       current_token = yylex();
+
+               switch(current_token)
+               {
+               case CST_INTEGER:
+                       {
+                               if (case_type->type_class != integer_type)
+                               {
+                                       string *expected_type_name;
+                                       expected_type_name = type_get_name(case_type);
+                                       add_error_message(409, string_get_cstr(expected_type_name), "integer");
+                                       string_destroy(expected_type_name);
+                               }
+                               current_token = yylex();
+                               break;
+                       }
+
+               case CST_REAL:
+                       {
+                               string *expected_type_name;
+                               expected_type_name = type_get_name(case_type);
+                               add_error_message(409, string_get_cstr(expected_type_name), "real");
+                               string_destroy(expected_type_name);
+
+                               current_token = yylex();
+                               break;
+                       }
+
+               case CST_BOOLEAN:
+                       {
+
+                               string *expected_type_name;
+                               expected_type_name = type_get_name(case_type);
+                               add_error_message(409, string_get_cstr(expected_type_name), "boolean");
+                               string_destroy(expected_type_name);
+
+                               current_token = yylex();
+                               break;
+                       }
+
+               case CST_CHAR:
+                       {
+                               if (case_type->type_class != char_type)
+                               {
+                                       string *expected_type_name;
+                                       expected_type_name = type_get_name(case_type);
+                                       add_error_message(409, string_get_cstr(expected_type_name), "char");
+                                       string_destroy(expected_type_name);
+                               }
+                               current_token = yylex();
+                               break;
+                       }
+
+               case CST_STRING:
+                       {
+                               if (case_type->type_class != string_type)
+                               {
+                                       string *expected_type_name;
+                                       expected_type_name = type_get_name(case_type);
+                                       add_error_message(409, string_get_cstr(expected_type_name), "string");
+                                       string_destroy(expected_type_name);
+                               }
+                               current_token = yylex();
+                               break;
+                       }
+
+               case IDENTIFIER:
+                       {
+                               /* find the constant type for the given identifier */
+                               type *constant_type;
+
+                               constant_type = get_constant_type(current_block, YYTEXT_STRING);
+
+                               if (constant_type->type_class == error_type)
+                                       add_error_message(410, YYTEXT_STRING, "");
+                               else
+                                       if (!type_equal(constant_type, case_type))
+                                       {
+                                               string *expected_type_name;
+                                               string *constant_type_name;
+
+                                               expected_type_name = type_get_name(case_type);
+                                               constant_type_name = type_get_name(constant_type);
+
+                                               add_error_message(409, string_get_cstr(expected_type_name), string_get_cstr(constant_type_name));
+
+                                               string_destroy(expected_type_name);
+                                               string_destroy(constant_type_name);
+                                       }
+
+                                       type_destroy(constant_type);
+
+                               current_token = yylex();
+                               break;
+                       }
+
+               default:
+                       {
+                               add_error_message(206, "", "");
+
+                               /* Error-recovery: find the first : */
+                               while ((current_token != COLON)
+                                       && (current_token != END_OF_INPUT))
+                               {
+                                       current_token = yylex();
+                               }
+
+                               if (current_token == END_OF_INPUT)
+                                       return;
+
+                               break;
+                       }
+               }
+
+
+       } while (current_token == COMMA);
+
+       current_token = yylex();
+
+       if (current_token != COLON)
+       {
+               add_error_message(200, ":", YYTEXT_STRING);
+
+               /* Error-recovery: find the first : */
+               while ((current_token != COLON)
+                       && (current_token != END_OF_INPUT))
+               {
+                       current_token = yylex();
+               }
+
+               if (current_token == END_OF_INPUT)
+                       return;
+       }
+
+       current_token = yylex();
+
+       RD_statement(current_block);
+}
+
+
+/*
+       The while-do statement.
+
+       <RD_while_statement> -> <RD_expression> do <RD_statement>
+*/
+void RD_while_statement(block *current_block)
+{
+       type *expression_type;
+       int pos1, pos2;
+       int jump_offset_position;
+       int jump_offset;
+       int break_pos1, break_pos2;
+
+       pos1 = current_block->code->bytecode_pos;
+
+       expression_type = RD_expression(current_block);
+
+       pos2 = current_block->code->bytecode_pos;
+       bytecode_append(current_block->code, ifeq$);
+       jump_offset_position = current_block->code->bytecode_pos;
+       bytecode_append_short_int(current_block->code, 0); /* make place for offset value */
+
+       if ((expression_type->type_class != error_type) /* a simple error-recovery */
+               && (expression_type->type_class != boolean_type))
+       {
+               add_error_message(407, "boolean", "");
+       }
+
+       type_destroy(expression_type);
+
+       if (current_token != KWD_DO)
+       {
+               add_error_message(203, "do", YYTEXT_STRING);
+       }
+       else
+               current_token = yylex();
+
+       inside_loop++;
+       break_pos1 = current_block->code->bytecode_pos;
+       RD_statement(current_block);
+       break_pos2 = current_block->code->bytecode_pos;
+       inside_loop --;
+
+       bytecode_append(current_block->code, goto$);
+       bytecode_append_short_int(current_block->code, pos1 - current_block->code->bytecode_pos + 1);
+
+       jump_offset = current_block->code->bytecode_pos - pos2;
+       current_block->code->bytecode[jump_offset_position] = (char)(jump_offset >> 8);
+       current_block->code->bytecode[jump_offset_position + 1] = (char) jump_offset;
+
+       transform_break_stmts(current_block->code, break_pos1, break_pos2, current_block->code->bytecode_pos);
+}
+
+
+// j-a-s-d: besides
+//
+//     current_token = yylex();
+//
+//     bytecode_append(current_block->code, goto$);
+//     bytecode_append_short_int(current_block->code, pos1 - current_block->code->bytecode_pos + 1);
+//
+//     transform_break_stmts(current_block->code, break_pos1, break_pos2, current_block->code->bytecode_pos);
+//
+// is the exact implementation of forever,
+// the lesser impact implementation of repeat/forever to this MP compiler seems to be an "until false"
+
+type* RD_forever(block *current_block)
+{
+    type *return_type;
+       return_type = type_create();
+       bytecode_append(current_block->code, iconst_0$);
+       current_token = yylex();
+       return_type->type_class = boolean_type;
+       return return_type;
+}
+
+/*
+       The repeat-until statement.
+
+       <RD_repeat_statement> -> <RD_block_body> until <RD_expression>
+*/
+
+void RD_repeat_statement(block *current_block)
+{
+       type *expression_type;
+
+       int pos1;
+       int break_pos1, break_pos2;
+
+       pos1 = current_block->code->bytecode_pos;
+       inside_loop ++;
+       break_pos1 = current_block->code->bytecode_pos;
+       RD_block_body(current_block);
+       break_pos2 = current_block->code->bytecode_pos;
+       inside_loop --;
+
+       if (current_token == KWD_FOREVER)
+       {
+               expression_type = RD_forever(current_block);
+       } else {
+               if (current_token != KWD_UNTIL)
+               {
+                       add_error_message(203, "until", YYTEXT_STRING);
+               }
+
+               current_token = yylex();
+
+               expression_type = RD_expression(current_block);
+       }
+       /* generate the code */
+       bytecode_append(current_block->code, ifeq$);
+       bytecode_append_short_int(current_block->code, pos1 - current_block->code->bytecode_pos + 1);
+
+       if ((expression_type->type_class != error_type) /* a simple error-recovery */
+               && (expression_type->type_class != boolean_type))
+       {
+               add_error_message(407, "boolean", "");
+       }
+
+       transform_break_stmts(current_block->code, break_pos1, break_pos2, current_block->code->bytecode_pos);
+
+       type_destroy(expression_type);
+}
+
+
+
+/*
+       The for statement.
+
+       <RD_for_statement> -> IDN := <RD_expression> (to | downto)
+                               <RD_expression> do <RD_statement>
+*/
+void RD_for_statement(block *current_block)
+{
+       type *iterator_type;
+       type *expression1_type;
+       type *expression2_type;
+       identifier *iterator;
+       string *iterator_name;
+       int is_field;
+       int check_bytecode_pos;
+       int direction;
+       int evaluate_pos;
+       int break_pos1, break_pos2;
+
+       iterator_type = get_variable_type(current_block, YYTEXT_STRING);
+       iterator = get_identifier(current_block, YYTEXT_STRING);
+       iterator_name = string_from_cstr(YYTEXT_STRING);
+
+       if (iterator->identifier_class == unit_name)
+       {
+               add_error_message(456, "", "");
+               current_token = yylex();
+               current_token = yylex();
+       }
+
+       if ((iterator_type->type_class != integer_type)
+               && (iterator_type->type_class != char_type))
+       {
+               add_error_message(411, "", "");
+       }
+
+       if (current_token != IDENTIFIER)
+       {
+               add_error_message(202, "", "");
+
+               /* Error-recovery: find the first := */
+               while ((current_token != OP_ASSIGN)
+                       && (current_token != END_OF_INPUT))
+               {
+                       current_token = yylex();
+               }
+
+               if (current_token == END_OF_INPUT)
+               {
+                       type_destroy(iterator_type);
+                       string_destroy(iterator_name);
+                       return;
+               }
+       }
+       else
+               current_token = yylex();
+
+       if (current_token != OP_ASSIGN)
+       {
+               add_error_message(209, YYTEXT_STRING, "");
+       }
+       else
+               current_token = yylex();
+
+       expression1_type = RD_expression(current_block);
+
+       is_field = iterator->belongs_to_program_block;
+       create_put_variable_bytecode(iterator, current_block->code, iterator_name->cstr, is_field);
+
+       if (!type_equal(iterator_type, expression1_type))
+       {
+               string *name1, *name2;
+               name1 = type_get_name(iterator_type);
+               name2 = type_get_name(expression1_type);
+
+               add_error_message(412, string_get_cstr(name1), string_get_cstr(name2));
+
+               string_destroy(name1);
+               string_destroy(name2);
+       }
+
+       switch (current_token)
+       {
+       case KWD_TO:
+               {
+                       direction = 1;
+                       current_token = yylex();
+                       break;
+               }
+
+       case KWD_DOWNTO:
+               {
+                       direction = -1;
+                       current_token = yylex();
+                       break;
+               }
+
+       default:
+               {
+                       add_error_message(204, YYTEXT_STRING, "");
+                       break;
+               }
+       }
+
+       evaluate_pos = current_block->code->bytecode_pos;
+       expression2_type = RD_expression(current_block);
+
+       create_variable_bytecode(iterator, current_block->code, iterator_name->cstr, iterator->belongs_to_program_block);
+
+       check_bytecode_pos = current_block->code->bytecode_pos;
+       if (direction == 1)
+               bytecode_append(current_block->code, if_icmplt$);
+       else
+               bytecode_append(current_block->code, if_icmpgt$);
+
+       bytecode_append_short_int(current_block->code, 0);
+
+       if (!type_equal(iterator_type, expression2_type))
+       {
+               string *name1, *name2;
+               name1 = type_get_name(iterator_type);
+               name2 = type_get_name(expression2_type);
+
+               add_error_message(412, string_get_cstr(name1), string_get_cstr(name2));
+
+               string_destroy(name1);
+               string_destroy(name2);
+       }
+
+       if (current_token != KWD_DO)
+       {
+               add_error_message(203, "do", YYTEXT_STRING);
+       }
+       else
+               current_token = yylex();
+
+       inside_loop ++;
+       break_pos1 = current_block->code->bytecode_pos;
+       RD_statement(current_block);
+       break_pos2 = current_block->code->bytecode_pos;
+       inside_loop --;
+
+
+       // TODO:: moguca optimizacija za neke slucajeve sa iinc$ naredbom
+       create_variable_bytecode(iterator, current_block->code, iterator_name->cstr, iterator->belongs_to_program_block);
+
+       if (direction == 1)
+               bytecode_append(current_block->code, iconst_1$);
+       else
+               bytecode_append(current_block->code, iconst_m1$);
+
+       bytecode_append(current_block->code, iadd$);
+
+       create_put_variable_bytecode(iterator, current_block->code, iterator_name->cstr, iterator->belongs_to_program_block);
+
+       bytecode_append(current_block->code, goto$);
+       bytecode_append_short_int(current_block->code, evaluate_pos - current_block->code->bytecode_pos + 1);
+
+       current_block->code->bytecode[check_bytecode_pos + 1] = (char) ((current_block->code->bytecode_pos - check_bytecode_pos)>>8);
+       current_block->code->bytecode[check_bytecode_pos + 2] = (char) (current_block->code->bytecode_pos - check_bytecode_pos);
+
+
+       transform_break_stmts(current_block->code, break_pos1, break_pos2, current_block->code->bytecode_pos);
+
+       type_destroy(iterator_type);
+       type_destroy(expression1_type);
+       type_destroy(expression2_type);
+       string_destroy(iterator_name);
+}
+
+
+/*
+       Type declaration:
+
+       <RD_type> -> <RD_basic_type>
+                  | [packed] array <RD_array_declaration>
+                          | record <RD_record_declaration>
+                          | file <RD_file_declaration>
+                          | set <RD_set_declaration>  currently unsupported !!!
+*/
+type* RD_type(block *current_block)
+{
+       switch (current_token)
+       {
+       case KWD_PACKED:
+               {
+                       add_warning_message(210, "", "");
+                       current_token = yylex();
+                       if (current_token != KWD_ARRAY)
+                               add_error_message(203, "array", YYTEXT_STRING);
+                       //no_break;
+               }
+
+       case KWD_ARRAY:
+               {
+                       current_token = yylex();
+                       return RD_array_declaration(current_block);
+               }
+
+       case KWD_RECORD:
+               {
+                       current_token = yylex();
+                       return RD_record_declaration(current_block);
+               }
+
+       case KWD_FILE:
+               {
+                       current_token = yylex();
+                       return RD_file_declaration(current_block);
+               }
+
+       case KWD_SET:
+               {
+                       type *error;
+                       error = type_create();
+                       error->type_class = error_type;
+                       add_error_message(211, "", "");
+                       current_token = yylex();
+                       RD_set_declaration(current_block);
+                       return error;
+               }
+
+       default:
+               {
+                       return RD_basic_type(current_block);
+                       break;
+               }
+       }
+}
+
+
+/*
+       Basic type:
+
+       <RD_basic_type> -> [IDN .] IDN
+                        | CONST .. CONST
+                                        | "(" IDN (, IDN)* ")"    enumerated types are not supported
+*/
+type* RD_basic_type(block *current_block)
+{
+       type *return_type;
+       return_type = type_create();
+       return_type->type_class = error_type;
+
+       switch (current_token)
+       {
+       case IDENTIFIER:
+               {
+                       identifier* name;
+                       type *declared_type;
+                       declared_type = type_from_name(current_block, YYTEXT_STRING);
+
+                       lowercase(YYTEXT_STRING);
+
+                       name = get_identifier(current_block, YYTEXT_STRING);
+
+                       if (name->identifier_class == unit_name)
+                       {
+                               identifier* type_identifier;
+
+                               current_token = yylex();
+
+                               if (current_token != DOT)
+                                       add_error_message(200, ".", YYTEXT_STRING);
+                               else
+                                       current_token = yylex();
+
+                               type_identifier = name_table_find_cstr(name->unit_block->names, YYTEXT_STRING);
+
+                               if (type_identifier == NULL)
+                                       add_error_message(455, YYTEXT_STRING, "");
+                               else
+                                       declared_type = type_duplicate(type_identifier->defined_type);
+                       }
+
+                       identifier_destroy(name);
+
+                       if (declared_type->type_class != error_type)
+                       {
+                               type_destroy(return_type);
+                               return_type = type_duplicate(declared_type);
+                               current_token = yylex();
+                               type_destroy(declared_type);
+                       }
+                       else
+                       {
+                               identifier *constant_identifier;
+                               constant_identifier  = get_constant_identifier(current_block, YYTEXT_STRING);
+
+                               type_destroy(declared_type);
+
+                               if ((constant_identifier->identifier_class == constant_name)
+                                       && ((constant_identifier->constant_type->type_class == integer_type)
+                                           || (constant_identifier->constant_type->type_class == char_type)))
+                               {
+                                       return_type->type_class = interval_type;
+                                       return_type->interval_base_type = constant_identifier->constant_type->type_class;
+
+                                       if (constant_identifier->constant_type->type_class == integer_type)
+                                               return_type->first_element = constant_identifier->constant_int_value;
+                                       else
+                                               return_type->first_element = constant_identifier->constant_int_value;
+
+                                       return_type->last_element = return_type->first_element + 1;
+
+                                       identifier_destroy(constant_identifier);
+
+                                       current_token = yylex();
+
+                                       if (current_token != DOTDOT)
+                                       {
+                                               add_error_message(213, YYTEXT_STRING, "");
+
+                                               /* Error-recovery */
+                                               while ((current_token != CLOSE_SQ_BR)
+                                                       && (current_token != SEMI_COLON)
+                                                       && (current_token != KWD_END)
+                                                       && (current_token != END_OF_INPUT))
+                                               {
+                                                       current_token = yylex();
+                                               }
+
+                                               break;
+                                       }
+
+                                       current_token = yylex();
+
+                                       if (current_token == IDENTIFIER)
+                                       {
+                                               constant_identifier = get_constant_identifier(current_block, YYTEXT_STRING);
+
+                                               if ((constant_identifier->identifier_class != constant_name)
+                                                       || (constant_identifier->constant_type->type_class != return_type->interval_base_type))
+                                               {
+                                                       add_error_message(416, "", "");
+                                               }
+                                               else
+                                               {
+                                                       if (return_type->interval_base_type == integer_type)
+                                                               return_type->last_element = constant_identifier->constant_int_value;
+                                                       else
+                                                               return_type->last_element = constant_identifier->constant_int_value;
+                                               }
+
+                                               identifier_destroy(constant_identifier);
+                                       }
+                                       else if (current_token == CST_INTEGER)
+                                       {
+                                               if (return_type->interval_base_type != integer_type)
+                                                       add_error_message(416, "", "");
+
+                                               return_type->last_element = integer_constant;
+                                       }
+                                       else if (current_token == CST_CHAR)
+                                       {
+                                               if (return_type->interval_base_type != char_type)
+                                                       add_error_message(416, "", "");
+
+                                               return_type->last_element = char_constant;
+                                       }
+                                       else
+                                       {
+                                               add_error_message(416, "", "");
+                                       }
+
+                                       current_token = yylex();
+
+                               }
+                               else
+                               {
+                                       add_error_message(415, YYTEXT_STRING, "");
+                                       current_token = yylex();
+                                       identifier_destroy(constant_identifier);
+                               }
+                       }
+
+
+
+                       break;
+               }
+
+       case CST_INTEGER:
+       case CST_CHAR:
+               {
+                       return_type->type_class = interval_type;
+
+                       if (current_token == CST_INTEGER)
+                       {
+                               return_type->interval_base_type = integer_type;
+                               return_type->first_element = integer_constant;
+                       }
+                       else
+                       {
+                               return_type->interval_base_type = char_type;
+                               return_type->first_element = (long int) char_constant;
+                       }
+
+                       return_type->last_element = return_type->first_element + 1;
+
+                       current_token = yylex();
+
+                       if (current_token != DOTDOT)
+                       {
+                               add_error_message(213, YYTEXT_STRING, "");
+                       }
+
+                       current_token = yylex();
+
+                       if ((current_token != IDENTIFIER)
+                               && (current_token != CST_INTEGER)
+                               && (current_token != CST_CHAR))
+                       {
+                               add_error_message(217, "", "");
+                       }
+                       else
+                       {
+                               if (current_token == IDENTIFIER)
+                               {
+                                       type *constant_type;
+                                       identifier *constant_identifier;
+
+                                       constant_type = get_constant_type(current_block, YYTEXT_STRING);
+
+                                       if (constant_type->type_class != return_type->interval_base_type)
+                                       {
+                                               add_error_message(413, "", "");
+                                       }
+
+                                       type_destroy(constant_type);
+
+                                       constant_identifier = get_constant_identifier(current_block, YYTEXT_STRING);
+
+                                       if (constant_identifier->identifier_class != constant_name)
+                                       {
+                                               add_error_message(414, YYTEXT_STRING, "");
+                                       }
+                                       else
+                                       {
+                                               if (return_type->interval_base_type == integer_type)
+                                                       return_type->last_element = constant_identifier->constant_int_value;
+                                               else
+                                                       return_type->last_element = constant_identifier->constant_int_value;
+                                       }
+
+                                       identifier_destroy(constant_identifier);
+
+                               }
+                               else if (current_token == CST_INTEGER)
+                               {
+                                       return_type->last_element = integer_constant;
+                               }
+                               else
+                               {
+                                       return_type->last_element = (long int) char_constant;
+                               }
+                       }
+
+                       current_token = yylex();
+
+                       break;
+               }
+
+       case OPEN_BR:
+               {
+                       int brack_count = 1;
+                       add_error_message(212, "", "");
+
+                       while (brack_count > 0)
+                       {
+                               current_token = yylex();
+
+                               if (current_token == OPEN_BR)
+                                       brack_count ++;
+
+                               if (current_token == CLOSE_BR)
+                                       brack_count --;
+
+                               if (current_token == END_OF_INPUT)
+                                       return return_type;
+                       }
+
+                       current_token = yylex();
+
+                       break;
+               }
+
+       default:
+               {
+                       add_error_message(204, YYTEXT_STRING, "");
+                       while ((current_token != CLOSE_SQ_BR)
+                               && (current_token != SEMI_COLON)
+                               && (current_token != END_OF_INPUT)
+                               && (current_token != KWD_END))
+                       {
+                               current_token = yylex();
+                       }
+
+                       break;
+               }
+       }
+
+       return return_type;
+}
+
+
+/*
+       The declaration of an array.
+
+       <RD_array_declaration> -> "[" (<RD_basic_type> (, <RD_basic_type>)* )+ "]" of <RD_type>
+*/
+type* RD_array_declaration(block *current_block)
+{
+       type *new_type;
+       type *dimension;
+
+       new_type = type_create();
+       new_type->type_class = array_type;
+
+       new_type->dimensions_list = type_list_create();
+
+       if (current_token != OPEN_SQ_BR)
+       {
+               add_error_message(200, "[", YYTEXT_STRING);
+       }
+
+       do
+       {
+               current_token = yylex();
+
+               dimension = RD_basic_type(current_block);
+
+               if (dimension->type_class != interval_type)
+               {
+                       add_error_message(430, "", "");
+               }
+
+               type_list_append(new_type->dimensions_list, dimension);
+               type_destroy(dimension);
+
+               if ((current_token != CLOSE_SQ_BR)
+                       && (current_token != COMMA))
+               {
+                       add_error_message(200, ",", YYTEXT_STRING);
+               }
+
+               if (current_token == END_OF_INPUT)
+               {
+                       add_error_message(207, "", "");
+                       type_destroy(new_type);
+                       new_type = type_create();
+                       new_type->type_class = error_type;
+                       return new_type;
+               }
+
+       } while (current_token != CLOSE_SQ_BR);
+
+       current_token = yylex();
+
+       if (current_token != KWD_OF)
+       {
+               add_error_message(203, "of", YYTEXT_STRING);
+       }
+
+       current_token = yylex();
+
+       new_type->element_type = RD_type(current_block);
+
+       return new_type;
+}
+
+
+/*
+       The declaration of a record.
+
+       <RD_record_declaration> -> <RD_identifier_list> ":" <RD_type>
+                                    ( <RD_identifier_list> ":" <RD_type> )* end
+*/
+type* RD_record_declaration(block *current_block)
+{
+       type *new_type;
+       string_list *identifier_list;
+       type *element_type;
+       int old_linenum, tmp;
+
+       short int first_pass = 1;
+
+       new_type = type_create();
+       new_type->type_class = record_type;
+       new_type->elements_name_list = string_list_create();
+       new_type->elements_type_list = type_list_create();
+       new_type->unique_record_ID = next_record_ID;
+
+       next_record_ID ++;
+
+       do
+       {
+               if (first_pass)
+                       first_pass = 0;
+               else
+                       current_token = yylex();
+
+               if ((current_token == KWD_END)
+                       || (current_token == END_OF_INPUT))
+                       break;
+
+               identifier_list = RD_identifier_list(current_block, 0);
+
+               if (current_token != COLON)
+               {
+                       add_error_message(200, ":", YYTEXT_STRING);
+               }
+
+               old_linenum = linenum;
+               current_token = yylex();
+
+               element_type = RD_type(current_block);
+
+               if (element_type->type_class == interval_type)
+               {
+                       add_error_message(440, "", "");
+                       element_type->type_class = integer_type;
+               }
+
+               tmp = linenum;
+               linenum = old_linenum;
+
+               type_add_record(new_type, identifier_list, element_type);
+
+               linenum = tmp;
+
+               string_list_destroy(identifier_list);
+               type_destroy(element_type);
+
+       } while (current_token == SEMI_COLON);
+
+       if (current_token != KWD_END)
+       {
+               add_error_message(214, YYTEXT_STRING, "");
+       }
+
+       current_token = yylex();
+
+       create_record_class(new_type);
+
+       return new_type;
+}
+
+
+/*
+       The declaration of a file
+
+       <RD_file_declaration> -> of IDN
+*/
+type* RD_file_declaration(block *current_block)
+{
+       type *file_type;
+       file_type = type_create();
+       file_type->type_class = error_type;
+       if (current_token != KWD_OF)
+       {
+               add_error_message(203, "of", YYTEXT_STRING);
+       }
+
+       current_token = yylex();
+// !!!! TODO:: dodati podrsku za fajlove
+       current_token = yylex();
+       add_error_message(435, "", "");
+       return file_type;
+}
+
+
+/*
+       Sets are not supported yet, however, this rule is used
+       as an error-recovery rule if someone tries to use sets.
+
+       <RD_set_declaration> -> of <RD_basic_type>
+*/
+void RD_set_declaration(block *current_block)
+{
+       current_token = yylex();
+
+       RD_basic_type(current_block);
+}
+
+
+/*
+       Handle the expressions, the relational operators.
+
+       <RD_expression> -> <RD_sum> [<rel_operator> <RD_sum>]
+*/
+type* RD_expression(block *current_block)
+{
+       int old_linenum;
+       int old_token;
+       type *type1, *type2;
+
+       type1 = RD_sum(current_block);
+
+       if ((current_token == OP_LESS)
+               || (current_token == OP_LESS_EQUAL)
+               || (current_token == OP_GREATER_EQUAL)
+               || (current_token == OP_GREATER)
+               || (current_token == OP_EQUAL)
+               || (current_token == OP_NOT_EQUAL))
+       {
+               old_token = current_token;
+               current_token = yylex();
+
+               old_linenum = linenum;
+               type2 = RD_sum(current_block);
+
+               if ((type2->type_class != integer_type)
+                       && (type2->type_class != real_type)
+                       && (type2->type_class != char_type)
+                       && (type2->type_class != string_type)
+                       && (type2->type_class != boolean_type)
+                       && (type2->type_class != error_type)
+                       && (type2->type_class != command_type))
+               {
+                       new_linenum=old_linenum;
+                       add_error_message(417, "", "");
+               }
+               else
+               {
+                       int cast;
+                       cast = type_equal_cast(type1, type2);
+
+                       if (cast == 0){
+                               new_linenum=old_linenum;
+                               add_error_message(417, "", "");
+                       }
+
+                       /* if operands need to be casted */
+                       if ((type1->type_class == integer_type)
+                               || (type2->type_class == integer_type))
+                       {
+                               if (cast != 1)
+                               {
+                                       usesFloat=1;
+
+                                       if (cast == 3)
+                                               bytecode_append(current_block->code, swap$);
+
+                                       if (mathType == 1)
+                                       {
+                                               bytecode_append(current_block->code, invokestatic$);
+                                               bytecode_append_short_int(current_block->code, cp_add_methodref("F", "fI", "(I)I"));
+                                       }
+                                       else
+                                       {
+                                               bytecode_append(current_block->code, new$);
+                                               bytecode_append_short_int(current_block->code, cp_add_class("Real"));
+                                               bytecode_append(current_block->code, dup_x1$);
+                                               bytecode_append(current_block->code, swap$);
+                                               bytecode_append(current_block->code, invokespecial$);
+                                               bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "<init>", "(I)V"));
+                                       }
+
+                                       if (cast == 3)
+                                               bytecode_append(current_block->code, swap$);
+                               }
+
+                       }
+                       else
+                       {
+                               if ((cast == 2) || (cast == 3))
+                               {
+                                       int method_index = cp_add_methodref("java/lang/String", "valueOf", "(C)Ljava/lang/String;");
+
+                                       if (cast == 3)
+                                               bytecode_append(current_block->code, swap$);
+
+                                       /* string cast */
+                                       bytecode_append(current_block->code, invokestatic$);
+                                       bytecode_append_short_int(current_block->code, method_index);
+
+                                       if (cast == 3)
+                                               bytecode_append(current_block->code, swap$);
+                               }
+                       }
+
+                       if (cast == 3) /* return the real type if cast happened */
+                       {
+                               type *tmp;
+                               tmp = type2;
+                               type2 = type1;
+                               type1 = tmp;
+                       }
+
+                       /* create the code */
+                       if ((type1->type_class == integer_type)
+                               || (type1->type_class == boolean_type)
+                               || (type1->type_class == char_type)
+                               || ((type1->type_class == real_type) && (mathType == 1)))
+                       {
+                               if (type1->type_class == real_type)
+                                       usesFloat = 1;
+
+                               switch (old_token)
+                               {
+                               case OP_LESS:
+                                       bytecode_append(current_block->code, if_icmplt$);
+                                       break;
+                               case OP_LESS_EQUAL:
+                                       bytecode_append(current_block->code, if_icmple$);
+                                       break;
+                               case OP_GREATER_EQUAL:
+                                       bytecode_append(current_block->code, if_icmpge$);
+                                       break;
+                               case OP_GREATER:
+                                       bytecode_append(current_block->code, if_icmpgt$);
+                                       break;
+                               case OP_EQUAL:
+                                       bytecode_append(current_block->code, if_icmpeq$);
+                                       break;
+                               case OP_NOT_EQUAL:
+                                       bytecode_append(current_block->code, if_icmpne$);
+                                       break;
+                               }
+
+                               /* create the rest of the jumping and setting the whatever code */
+                               bytecode_append_short_int(current_block->code, 7);
+                               bytecode_append(current_block->code, iconst_0$);
+                               bytecode_append(current_block->code, goto$);
+                               bytecode_append_short_int(current_block->code, 4);
+                               bytecode_append(current_block->code, iconst_m1$);
+                       }
+
+                       if ((type1->type_class == real_type) && (mathType != 1))
+                       {
+                               usesFloat = 1;
+                               bytecode_append(current_block->code, invokevirtual$);
+
+                               switch (old_token)
+                               {
+                               case OP_LESS:
+                                       bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "lessThan", "(LReal;)Z"));
+                                       break;
+                               case OP_LESS_EQUAL:
+                                       bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "lessEqual", "(LReal;)Z"));
+                                       break;
+                               case OP_GREATER_EQUAL:
+                                       bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "greaterEqual", "(LReal;)Z"));
+                                       break;
+                               case OP_GREATER:
+                                       bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "greaterThan", "(LReal;)Z"));
+                                       break;
+                               case OP_EQUAL:
+                                       bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "equalTo", "(LReal;)Z"));
+                                       break;
+                               case OP_NOT_EQUAL:
+                                       bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "notEqualTo", "(LReal;)Z"));
+                                       break;
+                               }
+
+                               /* create the rest of the jumping and setting the whatever code */
+                               bytecode_append(current_block->code, ifne$);
+                               bytecode_append_short_int(current_block->code, 7);
+                               bytecode_append(current_block->code, iconst_0$);
+                               bytecode_append(current_block->code, goto$);
+                               bytecode_append_short_int(current_block->code, 4);
+                               bytecode_append(current_block->code, iconst_m1$);
+                       }
+
+                       if (type1->type_class == command_type)
+                       {
+                               if (old_token == OP_EQUAL)
+                               {
+                                       bytecode_append(current_block->code, if_acmpeq$);
+                               }
+                               else if (old_token == OP_NOT_EQUAL)
+                               {
+                                       bytecode_append(current_block->code, if_acmpne$);
+                               }
+                               else
+                               {
+                                       new_linenum=old_linenum;
+                                       add_error_message(417, "", "");
+                               }
+
+                               /* create the rest of the jumping and setting the whatever code */
+                               bytecode_append_short_int(current_block->code, 7);
+                               bytecode_append(current_block->code, iconst_0$);
+                               bytecode_append(current_block->code, goto$);
+                               bytecode_append_short_int(current_block->code, 4);
+                               bytecode_append(current_block->code, iconst_m1$);
+                       }
+
+               }
+
+               if (type1->type_class == string_type)
+               {
+                       int method_index = cp_add_methodref("java/lang/String", "compareTo", "(Ljava/lang/String;)I");
+                       bytecode_append(current_block->code, invokevirtual$);
+                       bytecode_append_short_int(current_block->code, method_index);
+
+                       switch (old_token)
+                       {
+                       case OP_LESS:
+                               bytecode_append(current_block->code, iflt$);
+                               break;
+                       case OP_LESS_EQUAL:
+                               bytecode_append(current_block->code, ifle$);
+                               break;
+                       case OP_GREATER_EQUAL:
+                               bytecode_append(current_block->code, ifge$);
+                               break;
+                       case OP_GREATER:
+                               bytecode_append(current_block->code, ifgt$);
+                               break;
+                       case OP_EQUAL:
+                               bytecode_append(current_block->code, ifeq$);
+                               break;
+                       case OP_NOT_EQUAL:
+                               bytecode_append(current_block->code, ifne$);
+                               break;
+                       }
+
+                       /* create the rest of the jumping and setting the whatever code */
+                       bytecode_append_short_int(current_block->code, 7);
+                       bytecode_append(current_block->code, iconst_0$);
+                       bytecode_append(current_block->code, goto$);
+                       bytecode_append_short_int(current_block->code, 4);
+                       bytecode_append(current_block->code, iconst_m1$);
+               }
+
+               type_destroy(type2);
+               type_destroy(type1);
+               /* the type of comparison is boolean */
+               type1 = type_create();
+               type1->type_class = boolean_type;
+       }
+
+       return type1;
+}
+
+
+/*
+       Handle +, -, or, xor operators.
+
+       <RD_sum> -> <RD_mult> (<sum_operator> <RD_mult>)*
+*/
+type* RD_sum(block *current_block)
+{
+       int old_linenum;
+       int old_token;
+
+       type *type1, *type2;
+
+       type1 = RD_mult(current_block);
+
+       while ((current_token == OP_PLUS)
+               || (current_token == OP_MINUS)
+               || (current_token == OP_OR)
+               || (current_token == OP_XOR))
+       {
+               old_token = current_token;
+
+               current_token = yylex();
+
+               old_linenum = linenum;
+
+               type2 = RD_mult(current_block);
+
+               if (((type2->type_class != integer_type)
+                       && (type2->type_class != real_type)
+                       && (type2->type_class != char_type)
+                       && (type2->type_class != string_type)
+                       && (type2->type_class != boolean_type)
+                       && (type2->type_class != error_type))
+               || ((type1->type_class == string_type)
+                   && (old_token != OP_PLUS)))
+               {
+                       new_linenum=old_linenum;
+                       add_error_message(417, "", "");
+               }
+               else
+               {
+                       int cast;
+
+                       /* if first type is char, cast it to string */
+                       if (type1->type_class == char_type)
+                       {
+                               int method_index = cp_add_methodref("java/lang/String", "valueOf", "(C)Ljava/lang/String;");
+
+                               bytecode_append(current_block->code, swap$);
+                               bytecode_append(current_block->code, invokestatic$);
+                               bytecode_append_short_int(current_block->code, method_index);
+                               bytecode_append(current_block->code, swap$);
+
+                               type1->type_class = string_type;
+                       }
+
+                       cast = type_equal_cast(type1, type2);
+
+                       if ((cast == 0) && (type1->type_class != string_type)){
+                               new_linenum=old_linenum;
+                               add_error_message(417, "", "");
+                       }
+
+                       /* if operands need to be casted */
+                       if ((type1->type_class != string_type)
+                               && (cast != 1))
+                       {
+                               usesFloat=1;
+
+                               if (cast == 3)
+                                       bytecode_append(current_block->code, swap$);
+
+                               if (mathType == 1)
+                               {
+                                       bytecode_append(current_block->code, invokestatic$);
+                                       bytecode_append_short_int(current_block->code, cp_add_methodref("F", "fI", "(I)I"));
+                               }
+                               else
+                               {
+                                       bytecode_append(current_block->code, new$);
+                                       bytecode_append_short_int(current_block->code, cp_add_class("Real"));
+                                       bytecode_append(current_block->code, dup_x1$);
+                                       bytecode_append(current_block->code, swap$);
+                                       bytecode_append(current_block->code, invokespecial$);
+                                       bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "<init>", "(I)V"));
+                               }
+
+
+                               if (cast == 3)
+                                       bytecode_append(current_block->code, swap$);
+
+                               if (cast == 3) /* return the real type if cast happened */
+                               {
+                                       type *tmp;
+                                       tmp = type2;
+                                       type2 = type1;
+                                       type1 = tmp;
+                               }
+
+                       }
+               }
+
+
+               if ((type1->type_class != integer_type)
+                       && (type1->type_class != boolean_type)
+                       && (type1->type_class != error_type)
+                       && ((old_token == OP_OR) || (old_token == OP_XOR)))
+               {
+                       new_linenum=old_linenum;
+                       add_error_message(417, "", "");
+               }
+
+               /* create the code */
+               if ((type1->type_class == integer_type)
+                       || (type1->type_class == boolean_type)
+                       || ((type1->type_class == real_type) && (mathType == 1)))
+               {
+                       if (type1->type_class == real_type)
+                               usesFloat = 1;
+
+                       switch (old_token)
+                       {
+                       case OP_PLUS:
+                               bytecode_append(current_block->code, iadd$);
+                               break;
+                       case OP_MINUS:
+                               bytecode_append(current_block->code, isub$);
+                               break;
+                       case OP_OR:
+                               bytecode_append(current_block->code, ior$);
+                               break;
+                       case OP_XOR:
+                               bytecode_append(current_block->code, ixor$);
+                               break;
+                       }
+               }
+
+               if ((type1->type_class == real_type) && (mathType != 1))
+               {
+                       usesFloat = 1;
+                       if (old_token == OP_PLUS)
+                       {
+                               bytecode_append(current_block->code, new$);
+                               bytecode_append_short_int(current_block->code, cp_add_class("Real"));
+                               bytecode_append(current_block->code, dup_x1$);
+                               bytecode_append(current_block->code, swap$);
+                               bytecode_append(current_block->code, invokespecial$);
+                               bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+
+                               bytecode_append(current_block->code, swap$);
+
+                               bytecode_append(current_block->code, new$);
+                               bytecode_append_short_int(current_block->code, cp_add_class("Real"));
+                               bytecode_append(current_block->code, dup_x1$);
+                               bytecode_append(current_block->code, swap$);
+                               bytecode_append(current_block->code, invokespecial$);
+                               bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+
+                               bytecode_append(current_block->code, dup_x1$);
+                               bytecode_append(current_block->code, swap$);
+
+                               bytecode_append(current_block->code, invokevirtual$);
+                               bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "add", "(LReal;)V"));
+
+                       }
+
+                       if (old_token == OP_MINUS)
+                       {
+                               bytecode_append(current_block->code, new$);
+                               bytecode_append_short_int(current_block->code, cp_add_class("Real"));
+                               bytecode_append(current_block->code, dup_x1$);
+                               bytecode_append(current_block->code, swap$);
+                               bytecode_append(current_block->code, invokespecial$);
+                               bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+
+                               bytecode_append(current_block->code, swap$);
+
+                               bytecode_append(current_block->code, new$);
+                               bytecode_append_short_int(current_block->code, cp_add_class("Real"));
+                               bytecode_append(current_block->code, dup_x1$);
+                               bytecode_append(current_block->code, swap$);
+                               bytecode_append(current_block->code, invokespecial$);
+                               bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+
+                               bytecode_append(current_block->code, dup_x1$);
+                               bytecode_append(current_block->code, swap$);
+
+                               bytecode_append(current_block->code, invokevirtual$);
+                               bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "sub", "(LReal;)V"));
+
+                       }
+               }
+
+               if ((type1->type_class == string_type)
+                       && (old_token == OP_PLUS))
+               {
+                       int class_index;
+                       int init_index;
+                       int append_index;
+                       int append2_index;
+                       int toString_index;
+
+                       if (type2->type_class == real_type)
+                       {
+                               usesFloat = 1;
+
+                               if (mathType == 1)
+                               {
+                                       bytecode_append(current_block->code, invokestatic$);
+                                       bytecode_append_short_int(current_block->code, cp_add_methodref("F", "tS", "(I)Ljava/lang/String;"));
+                               }
+                               else
+                               {
+                                       bytecode_append(current_block->code, invokevirtual$);
+                                       bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "toString", "()Ljava/lang/String;"));
+                               }
+                       }
+
+                       class_index = cp_add_class("java/lang/StringBuffer");
+                       init_index = cp_add_methodref("java/lang/StringBuffer", "<init>", "()V");
+                       append_index = cp_add_methodref("java/lang/StringBuffer", "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
+                       toString_index = cp_add_methodref("java/lang/StringBuffer", "toString", "()Ljava/lang/String;");
+
+                       switch(type2->type_class)
+                       {
+                       case string_type:
+                       case real_type:
+                               append2_index = cp_add_methodref("java/lang/StringBuffer", "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
+                               break;
+                       case integer_type:
+                               append2_index = cp_add_methodref("java/lang/StringBuffer", "append", "(I)Ljava/lang/StringBuffer;");
+                               break;
+                       case char_type:
+                               bytecode_append(current_block->code, i2c$);
+                               append2_index = cp_add_methodref("java/lang/StringBuffer", "append", "(C)Ljava/lang/StringBuffer;");
+                               break;
+                       case boolean_type:
+                               bytecode_append(current_block->code, i2b$);
+                               append2_index = cp_add_methodref("java/lang/StringBuffer", "append", "(Z)Ljava/lang/StringBuffer;");
+                               break;
+                       default:
+                               add_error_message(434, "", "");
+                       }
+
+                       bytecode_append(current_block->code, swap$);
+
+                       /* create new string buffer */
+                       bytecode_append(current_block->code, new$);
+                       bytecode_append_short_int(current_block->code, class_index);
+                       bytecode_append(current_block->code, dup$);
+                       bytecode_append(current_block->code, invokespecial$);
+                       bytecode_append_short_int(current_block->code, init_index);
+
+                       /* append the first argument */
+                       bytecode_append(current_block->code, swap$);
+                       bytecode_append(current_block->code, invokevirtual$);
+                       bytecode_append_short_int(current_block->code, append_index);
+
+                       /* append the second argument */
+                       bytecode_append(current_block->code, swap$);
+
+                       bytecode_append(current_block->code, invokevirtual$);
+                       bytecode_append_short_int(current_block->code, append2_index);
+
+                       /* convert StringBuffer into the String */
+                       bytecode_append(current_block->code, invokevirtual$);
+                       bytecode_append_short_int(current_block->code, toString_index);
+
+
+
+                       type_destroy(type2);
+               }
+
+       }
+
+       return type1;
+}
+
+
+/*
+       Handle * / div mod and operators.
+
+       <RD_mult> -> <RD_not> (<mult_operator> <RD_not>)*
+*/
+type* RD_mult(block *current_block)
+{
+       int old_linenum;
+       int old_token;
+       type *type1, *type2;
+
+       type1 = RD_not(current_block);
+
+       while ((current_token == OP_MULT)
+               || (current_token == OP_SLASH)
+               || (current_token == OP_DIV)
+               || (current_token == OP_MOD)
+               || (current_token == OP_AND)
+               || (current_token == OP_SHR)
+               || (current_token == OP_SHL)
+               || (current_token == OP_USHR))
+       {
+               old_token = current_token;
+
+               current_token = yylex();
+
+               old_linenum = linenum;
+
+               type2 = RD_not(current_block);
+
+               if ((type2->type_class != integer_type)
+                       && (type2->type_class != real_type)
+                       && (type2->type_class != boolean_type)
+                       && (type2->type_class != error_type))
+               {
+                       new_linenum=old_linenum;
+                       add_error_message(417, "", "");
+               }
+               else
+               {
+                       int cast;
+                       cast = type_equal_cast(type1, type2);
+
+                       if (cast == 0){
+                               new_linenum=old_linenum;
+                               add_error_message(417, "", "");
+                       }
+
+                       if (cast != 1)
+                       {
+                               /* if operands need to be casted */
+                               usesFloat=1;
+
+                               if (cast == 3)
+                                       bytecode_append(current_block->code, swap$);
+
+                               if (mathType == 1)
+                               {
+                                       bytecode_append(current_block->code, invokestatic$);
+                                       bytecode_append_short_int(current_block->code, cp_add_methodref("F", "fI", "(I)I"));
+                               }
+                               else
+                               {
+                                       bytecode_append(current_block->code, new$);
+                                       bytecode_append_short_int(current_block->code, cp_add_class("Real"));
+                                       bytecode_append(current_block->code, dup_x1$);
+                                       bytecode_append(current_block->code, swap$);
+                                       bytecode_append(current_block->code, invokespecial$);
+                                       bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "<init>", "(I)V"));
+                               }
+
+                               if (cast == 3)
+                                       bytecode_append(current_block->code, swap$);
+
+                               if (cast == 3) /* return the real type if cast happened */
+                               {
+                                       type *tmp;
+                                       tmp = type2;
+                                       type2 = type1;
+                                       type1 = tmp;
+                               }
+                       }
+               }
+
+               type_destroy(type2);
+
+               if ((type1->type_class == real_type)
+                       && (old_token != OP_MULT)
+                       && (old_token != OP_SLASH))
+               {
+                       new_linenum=old_linenum;
+                       add_error_message(417, "", "");
+               }
+
+               if ((type1->type_class == boolean_type)
+                       && (old_token != OP_AND))
+               {
+                       new_linenum=old_linenum;
+                       add_error_message(417, "", "");
+               }
+
+               /* generate the code */
+               if (type1->type_class == integer_type)
+               {
+                       switch(old_token)
+                       {
+                       case OP_MULT:
+                               bytecode_append(current_block->code, imul$);
+                               break;
+                       case OP_SLASH:
+                       case OP_DIV:
+                               bytecode_append(current_block->code, idiv$);
+                               break;
+                       case OP_MOD:
+                               bytecode_append(current_block->code, irem$);
+                               break;
+                       case OP_AND:
+                               bytecode_append(current_block->code, iand$);
+                               break;
+                       ///////////
+                       case OP_SHR:
+                               bytecode_append(current_block->code, ishr$);
+                               break;
+                       case OP_SHL:
+                               bytecode_append(current_block->code, ishl$);
+                               break;
+            // j-a-s-d
+                       case OP_USHR:
+                               bytecode_append(current_block->code, iushr$);
+                               break;
+                       }
+               }
+
+               if (type1->type_class == real_type)
+               {
+                       usesFloat = 1;
+                       switch(old_token)
+                       {
+                       case OP_MULT:
+                               {
+                                       if (mathType == 1)
+                                       {
+                                               bytecode_append(current_block->code, invokestatic$);
+                                               bytecode_append_short_int(current_block->code,
+                                                       cp_add_methodref("F", "M", "(II)I"));
+                                       }
+                                       else
+                                       {
+                                               bytecode_append(current_block->code, new$);
+                                               bytecode_append_short_int(current_block->code, cp_add_class("Real"));
+                                               bytecode_append(current_block->code, dup_x1$);
+                                               bytecode_append(current_block->code, swap$);
+                                               bytecode_append(current_block->code, invokespecial$);
+                                               bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+
+                                               bytecode_append(current_block->code, swap$);
+
+                                               bytecode_append(current_block->code, new$);
+                                               bytecode_append_short_int(current_block->code, cp_add_class("Real"));
+                                               bytecode_append(current_block->code, dup_x1$);
+                                               bytecode_append(current_block->code, swap$);
+                                               bytecode_append(current_block->code, invokespecial$); ///
+                                               bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+
+                                               bytecode_append(current_block->code, dup_x1$);
+                                               bytecode_append(current_block->code, swap$);
+
+                                               bytecode_append(current_block->code, invokevirtual$);
+                                               bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "mul", "(LReal;)V"));
+                                       }
+                               }
+                               break;
+                       case OP_SLASH:
+                               {
+                                       if (mathType == 1)
+                                       {
+                                               bytecode_append(current_block->code, invokestatic$);
+                                               bytecode_append_short_int(current_block->code,
+                                                       cp_add_methodref("F", "D", "(II)I"));
+                                       }
+                                       else
+                                       {
+                                               bytecode_append(current_block->code, new$);
+                                               bytecode_append_short_int(current_block->code, cp_add_class("Real"));
+                                               bytecode_append(current_block->code, dup_x1$);
+                                               bytecode_append(current_block->code, swap$);
+                                               bytecode_append(current_block->code, invokespecial$);
+                                               bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+
+                                               bytecode_append(current_block->code, swap$);
+
+                                               bytecode_append(current_block->code, new$);
+                                               bytecode_append_short_int(current_block->code, cp_add_class("Real"));
+                                               bytecode_append(current_block->code, dup_x1$);
+                                               bytecode_append(current_block->code, swap$);
+                                               bytecode_append(current_block->code, invokespecial$);
+                                               bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+
+                                               bytecode_append(current_block->code, dup_x1$);
+                                               bytecode_append(current_block->code, swap$);
+
+                                               bytecode_append(current_block->code, invokevirtual$);
+                                               bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "div", "(LReal;)V"));
+                                       }
+                               }
+                               break;
+                       }
+               }
+
+               if ((type1->type_class == boolean_type)
+                       && (old_token == OP_AND))
+               {
+                       bytecode_append(current_block->code, iand$);
+               }
+       }
+
+       return type1;
+}
+
+
+/*
+       The not operator.
+
+       <RD_not> -> [not] <RD_neg>
+*/
+type* RD_not(block *current_block)
+{
+       type *type1;
+       int is_not = 0;
+       int old_linenum;
+
+       if (current_token == OP_NOT)
+       {
+               current_token = yylex();
+               is_not = 1;
+       }
+
+       old_linenum = linenum;
+
+       type1 = RD_neg(current_block);
+
+       /* generate the code */
+       if (is_not)
+       {
+               bytecode_append(current_block->code, iconst_m1$);
+               bytecode_append(current_block->code, ixor$);
+       }
+
+       if ((is_not)
+               && (type1->type_class != integer_type)
+               && (type1->type_class != boolean_type)
+               && (type1->type_class != error_type))
+       {
+               new_linenum=old_linenum;
+               add_error_message(417, "", "");
+       }
+
+       return type1;
+}
+
+
+/*
+       The - sign operator.
+
+       <RD_neg> -> ["-"] <RD_value>
+*/
+type* RD_neg(block *current_block)
+{
+       type *type1;
+       int is_neg = 0;
+       int old_linenum;
+
+       if (current_token == OP_MINUS)
+       {
+               current_token = yylex();
+               is_neg = 1;
+       }
+
+       old_linenum = linenum;
+
+       type1 = RD_value(current_block);
+
+       /* generate the code */
+       if (is_neg)
+       {
+               if ((type1->type_class == integer_type)
+                       || ((type1->type_class == real_type) && (mathType == 1)))
+                       bytecode_append(current_block->code, ineg$);
+
+               if ((type1->type_class == real_type) && (mathType != 1))
+               {
+                       usesFloat = 1;
+
+                       bytecode_append(current_block->code, new$);
+                       bytecode_append_short_int(current_block->code, cp_add_class("Real"));
+                       bytecode_append(current_block->code, dup_x1$);
+                       bytecode_append(current_block->code, swap$);
+                       bytecode_append(current_block->code, invokespecial$);
+                       bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+                       bytecode_append(current_block->code, dup$);
+                       bytecode_append(current_block->code, invokevirtual$);
+                       bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "neg", "()V"));
+               }
+       }
+
+       if ((type1->type_class != real_type)
+               && (type1->type_class != integer_type)
+               && (type1->type_class != error_type)
+               && (is_neg))
+       {
+               new_linenum=old_linenum;
+               add_error_message(417, "", "");
+       }
+
+       return type1;
+}
+
+
+/*
+       The expression that calls a procedure or
+       assigns a value to a variable.
+
+       <RD_assignment_or_procedure_call>
+
+               -> IDN ["[" <RD_expression_list> "]" ] (. IDN ["[" <RD_expression_list> "]" ])* := <RD_expression>
+               -> IDN ["(" <RD_expression_list> ")"]
+
+*/
+void RD_assignment_or_procedure_call(block *current_block)
+{
+       identifier *name;
+       string *element_name;
+       char *identifier_text;
+
+    if (current_token == KWD_RESULT) { // j-a-s-d
+        if (inside_routine == 0) // result in main block
+        {
+                       add_error_message(463, "result", "");
+            current_token = yylex();
+                       return;
+        }
+        name = get_identifier(current_block, string_get_cstr(str_currrent_routine_name));
+               element_name = str_currrent_routine_name;
+        if (name->identifier_class == procedure_name) // result in procedure
+               {
+                       add_error_message(463, "result", "");
+            current_token = yylex();
+            identifier_destroy(name);
+            string_destroy(element_name);
+                       return;
+               }
+    } else {
+        name = get_identifier(current_block, YYTEXT_STRING);
+        element_name = string_from_cstr(YYTEXT_STRING);
+    }
+
+       procedure_linenum = linenum;
+
+       if ((current_token != IDENTIFIER) && (current_token != KWD_RESULT)) // j-a-s-d
+       {
+               add_error_message(202, "", "");
+
+               /* Error-recovery: find the first ";", end, "." or <<EOF>> */
+               while ((current_token != SEMI_COLON)
+                       && (current_token != DOT)
+                       && (current_token != KWD_END)
+                       && (current_token != END_OF_INPUT))
+               {
+                       current_token = yylex();
+               }
+
+               string_destroy(element_name);
+               return;
+       }
+
+
+       if ((name->identifier_class == none)
+               || (name->identifier_class == program_name)
+               || (name->identifier_class == constant_name)
+               || (name->identifier_class == type_name))
+       {
+
+               add_error_message(428, YYTEXT_STRING, "");
+               current_token = yylex();
+               identifier_destroy(name);
+               string_destroy(element_name);
+               return;
+       }
+
+       current_token = yylex();
+
+       if (name->identifier_class == unit_name)
+       {
+               identifier *unit_name;
+               type_list *params;
+               if (current_token != DOT)
+               {
+                       add_error_message(200, ".", YYTEXT_STRING);
+                       while (current_token != SEMI_COLON)
+                               current_token = yylex();
+                       return;
+               }
+
+               current_token = yylex();
+               unit_name = name_table_find(name->unit_block->names, string_from_cstr(YYTEXT_STRING));
+               identifier_text = malloc(strlen(YYTEXT_STRING) + 1);
+               strcpy(identifier_text, YYTEXT_STRING);
+               string_destroy(element_name);
+               element_name = string_from_cstr(YYTEXT_STRING);
+
+               if (unit_name == NULL)
+               {
+                       add_error_message(453, YYTEXT_STRING, "");
+                       add_error_message(200, ".", YYTEXT_STRING);
+                       while (current_token != SEMI_COLON)
+                               current_token = yylex();
+                       return;
+               }
+
+               name = identifier_duplicate(unit_name);
+               current_token = yylex();
+
+               if (name->identifier_class == procedure_name)
+                       goto procedure_call;
+               if (name->identifier_class == variable_name)
+                       goto variable_lvalue;
+
+               add_error_message(457, YYTEXT_STRING, "");
+       }
+
+
+       /* the name belongs to a procedure */
+       if (name->identifier_class == procedure_name)
+       {
+procedure_call:
+               if (name->standard_function)
+               {
+                       create_std_function_prefix(current_block->code, element_name->cstr);
+               }
+
+               if (type_list_length(name->parameters) == 0)
+               {
+                       int br_depth = 0;
+                       if (current_token == OPEN_BR)
+                       {
+                               add_error_message(419, "", "");
+                               br_depth = 1;
+                               while (br_depth > 0)
+                               {
+                                       if ((current_token == END_OF_INPUT)
+                                               || (current_token == KWD_END))
+                                       {
+                                               identifier_destroy(name);
+                                               string_destroy(element_name);
+                                               return;
+                                       }
+
+                                       current_token = yylex();
+
+                                       if (current_token == OPEN_BR)
+                                               br_depth ++;
+
+                                       if (current_token == CLOSE_BR)
+                                               br_depth --;
+                               }
+
+                               current_token = yylex();
+                       }
+               }
+               else
+               {
+                       if (current_token != OPEN_BR)
+                       {
+                               add_error_message(420, "", "");
+                       }
+                       else
+                       {
+                               int compare_result;
+                               int old_linenum;
+                               type_list *parameter_list;
+                               current_token = yylex();
+
+                               old_linenum = linenum;
+
+                               parameter_list = RD_expression_list_cast(current_block, name->parameters);
+
+                               compare_result = type_list_different_parameter_cast(parameter_list, name->parameters);
+
+                               if (compare_result == -1) {
+                                       new_linenum=old_linenum;
+                                       add_error_message(421, "", "");
+                               }
+
+                               if (compare_result > 0)
+                               {
+                                       char par_num[4];
+                                       sprintf(par_num, "%d", compare_result);
+                                       new_linenum=old_linenum;
+                                       add_error_message(422, par_num, "");
+                               }
+
+                               type_list_destroy(parameter_list);
+
+                               if (current_token != CLOSE_BR)
+                               {
+                                       add_error_message(200, ")", YYTEXT_STRING);
+                               }
+                               else
+                                       current_token = yylex();
+                       }
+               }
+
+               /* create the bytecode */
+               if (!name->standard_function)
+               {
+                       /* the procedure is user-defined */
+                       int methodref_index;
+                       identifier *block_identifier;
+                       type_list *it;
+                       int pos;
+
+                       char* descriptor = (char*) mem_alloc(5*1024);
+                       if (descriptor == NULL)
+                               die(1);
+                       descriptor[0] = '(';
+
+                       if (!name->unit_function)
+                       {
+                               block_identifier = name_table_find(current_block->names, element_name);
+
+                               if (block_identifier == NULL)
+                                       block_identifier = name_table_find(current_block->parent_block->names, element_name);
+                       }
+                       else
+                       {
+                               block_identifier = name;
+                       }
+
+                       it = block_identifier->parameters;
+                       pos = 1;
+
+                       while(it != NULL)
+                       {
+                               if (it->data == NULL)
+                                       break;
+
+                               get_field_descriptor(it->data, descriptor + pos);
+                               pos = strlen(descriptor);
+                               it = it->next;
+                       }
+
+                       descriptor[pos] = ')';
+                       pos ++;
+                       descriptor[pos] = '\0';
+
+                       if (block_identifier->identifier_class == procedure_name)
+                               strcat(descriptor, "V");
+                       else
+                               get_field_descriptor(block_identifier->return_type, descriptor + pos);
+
+
+                       lowercase(element_name->cstr);
+                       if (name->unit_function)
+                       {
+                               string *full_unit_name;
+
+                               if (name->container_unit->is_library)
+                                       full_unit_name = string_from_cstr("Lib_");
+                               else
+                                       full_unit_name = string_create();
+                               string_append(full_unit_name, name->container_unit->unit_name);
+                               methodref_index = cp_add_methodref(full_unit_name->cstr, element_name->cstr, descriptor);
+                               string_destroy(full_unit_name);
+                       }
+                       else
+                       {
+                               if (compiling_unit == 0)
+                                       methodref_index = cp_add_methodref("M", element_name->cstr, descriptor);
+                               else
+                                       methodref_index = cp_add_methodref(string_get_cstr(str_program_name), element_name->cstr, descriptor);
+                       }
+                       bytecode_append(current_block->code, invokestatic$); /* call */
+                       bytecode_append_short_int(current_block->code, methodref_index);
+
+                       mem_free(descriptor);
+               }
+               else
+               {
+                       /* handle standard functions and procedures */
+                       create_std_function_code(current_block->code, element_name->cstr);
+               }
+       }
+
+       /* if the identifier is the function name and that is not the name of the current
+       block, report an error */
+       if (name->identifier_class == function_name)
+       {
+               if (STRING_COMPARE(element_name->cstr, current_block->block_name->cstr) != 0)
+               {
+                       add_error_message(432, element_name->cstr, "");
+               }
+       }
+
+       /* if an identifier is a valid l-value */
+       if ((name->identifier_class == variable_name)
+               || (name->identifier_class == parameter_name)
+               || (name->identifier_class == function_name)) /* function names are treated as variables for return values */
+       {
+               type *current_type;
+               type *new_type;
+               type *expression_type;
+               int assign_linenum;
+               int is_field = 0;
+               bytecode *get_bytecode;
+               bytecode *put_bytecode;
+variable_lvalue:
+               is_field = 0;
+               get_bytecode = bytecode_create();
+               put_bytecode = bytecode_create();
+
+               if (name->identifier_class == variable_name)
+                       current_type = type_duplicate(name->variable_type);
+
+               if (name->identifier_class == parameter_name)
+                       current_type = type_duplicate(name->parameter_type);
+
+               if (name->identifier_class == function_name)
+                       current_type = type_duplicate(name->return_type);
+
+               /* create the get and put bytecodes */
+               is_field = name->belongs_to_program_block;
+
+               if (name->identifier_class == function_name)
+                       is_field = 0;
+
+               create_variable_bytecode(name, get_bytecode, element_name->cstr, is_field);
+               create_put_variable_bytecode(name, put_bytecode, element_name->cstr, is_field);
+
+               identifier_destroy(name);
+               name = NULL;
+               string_destroy(element_name);
+               element_name = NULL;
+
+               while (current_token != OP_ASSIGN)
+               {
+                       if ((current_token == SEMI_COLON)
+                               || (current_token == KWD_END)
+                               || (current_token == END_OF_INPUT))
+                       {
+                               add_error_message(218, "", "");
+                               type_destroy(current_type);
+                               bytecode_destroy(get_bytecode);
+                               bytecode_destroy(put_bytecode);
+                               return;
+                       }
+
+                       if (current_token == DOT)
+                       {
+                               int fieldref_index;
+                               char record_name[15];
+                               char field_descriptor[128];
+
+                               current_token = yylex();
+
+                               /* append the old get bytecode */
+                               bytecode_append_bytecode(current_block->code, get_bytecode);
+
+                               /* reset the bytecodes */
+                               put_bytecode->bytecode_pos = 0;
+                               get_bytecode->bytecode_pos = 0;
+
+                               if (current_type->type_class != record_type)
+                               {
+                                       add_error_message(424, "", "");
+
+                                       /* Error-recovery */
+                                       while ((current_token != SEMI_COLON)
+                                               && (current_token != KWD_END)
+                                               && (current_token != END_OF_INPUT))
+                                       {
+                                               current_token = yylex();
+                                       }
+
+                                       type_destroy(current_type);
+                                       bytecode_destroy(get_bytecode);
+                                       bytecode_destroy(put_bytecode);
+                                       return;
+                               }
+
+                               new_type = type_find_record_element(current_type, YYTEXT_STRING);
+
+                               if (new_type == NULL)
+                               {
+                                       add_error_message(447, YYTEXT_STRING, "");
+                               }
+                               else
+                               {
+                                       /* create the new put and get bytecodes */
+                                       sprintf(record_name, "R_%d", current_type->unique_record_ID);
+                                       get_field_descriptor(new_type, field_descriptor);
+                                       lowercase(YYTEXT_STRING);
+                                       fieldref_index = cp_add_fieldref(record_name, YYTEXT_STRING, field_descriptor);
+
+                                       bytecode_append(get_bytecode, getfield$);
+                                       bytecode_append_short_int(get_bytecode, fieldref_index);
+
+                                       bytecode_append(put_bytecode, putfield$);
+                                       bytecode_append_short_int(put_bytecode, fieldref_index);
+
+
+                                       type_destroy(current_type);
+                                       current_type = new_type;
+                               }
+
+
+                               if (current_type == NULL)
+                               {
+                                       add_error_message(425, YYTEXT_STRING, "");
+
+                                       /* Error-recovery */
+                                       while ((current_token != SEMI_COLON)
+                                               && (current_token != KWD_END)
+                                               && (current_token != END_OF_INPUT))
+                                       {
+                                               current_token = yylex();
+                                       }
+
+                                       type_destroy(current_type);
+                                       bytecode_destroy(get_bytecode);
+                                       bytecode_destroy(put_bytecode);
+                                       return;
+                               }
+
+                               current_token = yylex();
+                       }
+                       else if (current_token == OPEN_SQ_BR)
+                       {
+                               type_list *array_elements;
+                               bytecode *tmp_code;
+                               tmp_code = bytecode_create();
+
+                               // ako je [, a zadnji je array, procitaj listu, usporedi, vrati slijedeci, skoci gore
+                               if (current_type->type_class != array_type)
+                               {
+                                       add_error_message(426, "", "");
+
+                                       /* Error-recovery */
+                                       while ((current_token != SEMI_COLON)
+                                               && (current_token != KWD_END)
+                                               && (current_token != END_OF_INPUT))
+                                       {
+                                               current_token = yylex();
+                                       }
+
+                                       type_destroy(current_type);
+                                       bytecode_destroy(get_bytecode);
+                                       bytecode_destroy(put_bytecode);
+                                       return;
+                               }
+
+                               current_token = yylex();
+
+                               array_elements = RD_expression_list_array(current_block, tmp_code, current_type);
+
+                               bytecode_append_bytecode(get_bytecode, tmp_code);
+                               //bytecode_append_bytecode(put_bytecode, tmp_code);
+                               bytecode_destroy(put_bytecode);
+                               put_bytecode = bytecode_duplicate(get_bytecode);
+
+                               replace_aaload_instruction(get_bytecode, current_type->element_type);
+
+                               /* remove the last aaload from put bytecode, adjust the stack and create the
+                                put bytecode */
+                               put_bytecode->bytecode_pos --;
+                               bytecode_append(put_bytecode, dup2_x1$);
+                               bytecode_append(put_bytecode, pop2$);
+
+                               switch(current_type->element_type->type_class)
+                               {
+                               case integer_type:
+                               case boolean_type:
+                               case char_type:
+                                       bytecode_append(put_bytecode, iastore$);
+                                       break;
+
+                               case real_type:
+                                       if (mathType == 1)
+                                               bytecode_append(put_bytecode, iastore$);
+                                       else
+                                               bytecode_append(put_bytecode, aastore$);
+                                       break;
+
+
+                               case image_type:
+                               case string_type:
+                               case record_type:
+                               case command_type:
+                               case record_store_type:
+                               case http_type:
+                               case alert_type:
+                               case stream_type:
+                                       bytecode_append(put_bytecode, aastore$);
+                                       break;
+
+                               }
+
+                               bytecode_destroy(tmp_code);
+
+                               if (type_list_different_parameter_array(array_elements, current_type->dimensions_list) != 0)
+                               {
+                                       char num1[6], num2[6];
+
+                                       sprintf(num1, "%d", type_list_length(current_type->dimensions_list));
+                                       sprintf(num2, "%d", type_list_length(array_elements));
+                                       add_error_message(427, num1, num2);
+
+                                       /* Error-recovery */
+                                       while ((current_token != SEMI_COLON)
+                                               && (current_token != KWD_END)
+                                               && (current_token != END_OF_INPUT))
+                                       {
+                                               current_token = yylex();
+                                       }
+
+                                       type_destroy(current_type);
+                                       bytecode_destroy(get_bytecode);
+                                       bytecode_destroy(put_bytecode);
+                                       return;
+                               }
+
+                               if (current_token != CLOSE_SQ_BR)
+                               {
+                                       add_error_message(200, "]", YYTEXT_STRING);
+
+                                       /* Error-recovery */
+                                       while ((current_token != SEMI_COLON)
+                                               && (current_token != KWD_END)
+                                               && (current_token != END_OF_INPUT))
+                                       {
+                                               current_token = yylex();
+                                       }
+
+                                       type_destroy(current_type);
+                                       bytecode_destroy(get_bytecode);
+                                       bytecode_destroy(put_bytecode);
+                                       return;
+                               }
+
+                               current_token = yylex();
+
+                               new_type = type_duplicate(current_type->element_type);
+                               type_destroy(current_type);
+
+                               current_type = new_type;
+
+                               type_list_destroy(array_elements);
+                       }
+                       else
+                       {
+                               add_error_message(204, YYTEXT_STRING, "");
+
+                               /* Error-recovery */
+                               while ((current_token != SEMI_COLON)
+                                       && (current_token != KWD_END)
+                                       && (current_token != END_OF_INPUT))
+                               {
+                                       current_token = yylex();
+                               }
+                               bytecode_destroy(get_bytecode);
+                               bytecode_destroy(put_bytecode);
+                               return;
+                       }
+               }
+
+               assign_linenum = linenum;
+
+               current_token = yylex();
+
+               expression_type = RD_expression(current_block);
+
+               if ((type_equal_cast(current_type, expression_type) != 1)
+                       && (current_type->type_class == real_type))
+               {
+                       usesFloat = 1;
+
+                       if (mathType == 1)
+                       {
+                               bytecode_append(current_block->code, invokestatic$);
+                               bytecode_append_short_int(current_block->code, cp_add_methodref("F", "fI", "(I)I"));
+                       }
+                       else
+                       {
+                               bytecode_append(current_block->code, new$);
+                               bytecode_append_short_int(current_block->code, cp_add_class("Real"));
+                               bytecode_append(current_block->code, dup_x1$);
+                               bytecode_append(current_block->code, swap$);
+                               bytecode_append(current_block->code, invokespecial$);
+                               bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "<init>", "(I)V"));
+                       }
+               }
+
+               if ((type_equal_cast(current_type, expression_type) == 2)
+                       && (current_type->type_class == string_type))
+               {
+                       int method_index = cp_add_methodref("java/lang/String", "valueOf", "(C)Ljava/lang/String;");
+
+                       /* string cast */
+                       bytecode_append(current_block->code, invokestatic$);
+                       bytecode_append_short_int(current_block->code, method_index);
+               }
+
+               bytecode_append_bytecode(current_block->code, put_bytecode);
+
+               if ((type_equal_cast(current_type, expression_type) != 1)
+                       && (type_equal_cast(current_type, expression_type) != 2))
+               {
+                       new_linenum=assign_linenum;
+                       add_error_message(423, "", "");
+               }
+               else
+                       if (current_type->type_class == array_type)
+                       {
+                               new_linenum=assign_linenum;
+                               add_error_message(443, "", "");
+                       }
+
+
+
+               type_destroy(expression_type);
+               type_destroy(current_type);
+               bytecode_destroy(get_bytecode);
+               bytecode_destroy(put_bytecode);
+       }
+
+       if (name != NULL)
+               identifier_destroy(name);
+
+       if (element_name != NULL)
+               string_destroy(element_name);
+}
+
+
+/*
+       The list of expressions, used when calling the function
+       or procedure.
+
+       <RD_expression_list> -> <RD_expression> (, <RD_expression>)*
+*/
+type_list* RD_expression_list(block *current_block)
+{
+       type_list *return_list;
+       type *expression_type;
+
+       return_list = type_list_create();
+
+       expression_type = RD_expression(current_block);
+
+       type_list_append(return_list, expression_type);
+
+       type_destroy(expression_type);
+
+       while (current_token == COMMA)
+       {
+               current_token = yylex();
+
+               expression_type = RD_expression(current_block);
+
+               type_list_append(return_list, expression_type);
+
+               type_destroy(expression_type);
+       }
+
+       return return_list;
+}
+
+/*
+       Same as the above, only the types are casted according to the second parameter
+*/
+type_list* RD_expression_list_cast(block *current_block, type_list *formal_params)
+{
+       type_list *return_list;
+       type *expression_type;
+       type_list *it;
+
+       it = formal_params;
+
+       return_list = type_list_create();
+
+       expression_type = RD_expression(current_block);
+
+       if ((it != NULL) && (it->data != NULL))
+       {
+               int cast;
+
+               cast = type_equal_cast(it->data, expression_type);
+
+               if ((cast == 2) && (it->data->type_class == string_type))
+               {
+                       int method_index = cp_add_methodref("java/lang/String", "valueOf", "(C)Ljava/lang/String;");
+
+                       bytecode_append(current_block->code, invokestatic$);
+                       bytecode_append_short_int(current_block->code, method_index);
+               }
+
+               if ((cast == 2) && (it->data->type_class == real_type))
+               {
+                       usesFloat = 1;
+
+                       if (mathType == 1)
+                       {
+                               bytecode_append(current_block->code, invokestatic$);
+                               bytecode_append_short_int(current_block->code, cp_add_methodref("F", "fI", "(I)I"));
+                       }
+                       else
+                       {
+                               bytecode_append(current_block->code, new$);
+                               bytecode_append_short_int(current_block->code, cp_add_class("Real"));
+                               bytecode_append(current_block->code, dup_x1$);
+                               bytecode_append(current_block->code, swap$);
+                               bytecode_append(current_block->code, invokespecial$);
+                               bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "<init>", "(I)V"));
+                       }
+               }
+
+               it = it->next;
+       }
+
+       type_list_append(return_list, expression_type);
+
+       type_destroy(expression_type);
+
+       while (current_token == COMMA)
+       {
+               current_token = yylex();
+
+               expression_type = RD_expression(current_block);
+
+               if ((it != NULL) && (it->data != NULL))
+               {
+                       int cast;
+
+                       cast = type_equal_cast(it->data, expression_type);
+
+                       if ((cast == 2) && (it->data->type_class == string_type))
+                       {
+                               int method_index = cp_add_methodref("java/lang/String", "valueOf", "(C)Ljava/lang/String;");
+
+                               bytecode_append(current_block->code, invokestatic$);
+                               bytecode_append_short_int(current_block->code, method_index);
+                       }
+
+                       if ((cast == 2) && (it->data->type_class == real_type))
+                       {
+                               usesFloat = 1;
+
+                               if (mathType == 1)
+                               {
+                                       bytecode_append(current_block->code, invokestatic$);
+                                       bytecode_append_short_int(current_block->code, cp_add_methodref("F", "fI", "(I)I"));
+                               }
+                               else
+                               {
+                                       bytecode_append(current_block->code, new$);
+                                       bytecode_append_short_int(current_block->code, cp_add_class("Real"));
+                                       bytecode_append(current_block->code, dup_x1$);
+                                       bytecode_append(current_block->code, swap$);
+                                       bytecode_append(current_block->code, invokespecial$);
+                                       bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "<init>", "(I)V"));
+                               }
+                       }
+
+                       it = it->next;
+               }
+
+               type_list_append(return_list, expression_type);
+
+               type_destroy(expression_type);
+       }
+
+       return return_list;
+}
+
+/*
+       Same as RD_expression_list, only aaload is generated after each element and the indices
+       are adjusted.For example, if array is [a..b], the a value must be substracted from the index
+*/
+type_list* RD_expression_list_array(block *current_block, bytecode *code, type *array_type)
+{
+       type_list *return_list;
+       type *expression_type;
+       bytecode *oldBytecode;
+
+       type_list *it;
+       it = array_type->dimensions_list;
+
+       oldBytecode = current_block->code;
+       current_block->code = code;
+
+       return_list = type_list_create();
+
+       expression_type = RD_expression(current_block);
+       adjust_indices(code, it->data);
+
+       if(it != NULL)
+               it = it->next;
+
+       bytecode_append(code, aaload$);
+
+       type_list_append(return_list, expression_type);
+
+       type_destroy(expression_type);
+
+       while (current_token == COMMA)
+       {
+               current_token = yylex();
+
+               expression_type = RD_expression(current_block);
+               adjust_indices(code, it->data);
+
+               if(it != NULL)
+                       it = it->next;
+               bytecode_append(code, aaload$);
+
+               type_list_append(return_list, expression_type);
+
+               type_destroy(expression_type);
+       }
+
+       current_block->code = oldBytecode;
+
+       return return_list;
+}
+
+
+/*
+       The with statement, currently not supported. This
+       function is used as an error recovery function.
+
+       <RD_with_statement> -> IDN (. IDN)* do <RD_statement>
+*/
+void RD_with_statement(block *current_block)
+{
+       /* simplified parsing */
+       while (current_token != KWD_DO)
+       {
+               if (current_token == END_OF_INPUT)
+                       return;
+
+               current_token = yylex();
+       }
+
+       current_token = yylex();
+
+       RD_statement(current_block);
+}
+
+
+/*
+       Anything that has value: constant, identifier, identifier inside
+       a record or a function call.
+
+       <RD_value> -> CONST
+                   | IDN [ "[" <RD_expression_list> "]" ] ( . IDN [ "[" <RD_expression_list> "]" ])*
+                               | IDN [ "(" <RD_expression_list> ")"]
+                               | "(" <RD_expression> ")"
+*/
+type* RD_value(block *current_block)
+{
+       type *return_type;
+       return_type = type_create();
+
+       return_type->type_class = error_type;
+
+       if (current_token == CST_INTEGER)
+       {
+               switch(integer_constant)
+               {
+               case -1:
+                       bytecode_append(current_block->code, iconst_m1$);
+                       break;
+               case 0:
+                       bytecode_append(current_block->code, iconst_0$);
+                       break;
+               case 1:
+                       bytecode_append(current_block->code, iconst_1$);
+                       break;
+               case 2:
+                       bytecode_append(current_block->code, iconst_2$);
+                       break;
+               case 3:
+                       bytecode_append(current_block->code, iconst_3$);
+                       break;
+               case 4:
+                       bytecode_append(current_block->code, iconst_4$);
+                       break;
+               case 5:
+                       bytecode_append(current_block->code, iconst_5$);
+                       break;
+               default:
+                       {
+                               if (abs(integer_constant) < 127)
+                               {
+                                       bytecode_append(current_block->code, bipush$);
+                                       bytecode_append(current_block->code, (char)(integer_constant));
+                               }
+                               else if (abs(integer_constant) < 16000)
+                               {
+                                       bytecode_append(current_block->code, sipush$);
+                                       bytecode_append_short_int(current_block->code, (short)(integer_constant));
+                               }
+                               else
+                               {
+                                       int cp_index;
+                                       cp_index = cp_add_integer(integer_constant);
+                                       if (cp_index <= 255)
+                                       {
+                                               bytecode_append(current_block->code, ldc$);
+                                               bytecode_append(current_block->code, (char) cp_index);
+                                       }
+                                       else
+                                       {
+                                               bytecode_append(current_block->code, ldc_w$);
+                                               bytecode_append_short_int(current_block->code, (short) cp_index);
+                                       }
+                               }
+                               break;
+                       }
+               }
+
+               current_token = yylex();
+               return_type->type_class = integer_type;
+               return return_type;
+       }
+
+       if (current_token == CST_REAL)
+       {
+               float cst;
+               int csti; /* the integer part */
+               int cstf; /* the fraction part */
+
+               /* calculate the exponent and the integer part */
+               cst = real_constant;
+
+               csti = (int)cst;
+               cstf = (cst - (int)cst)*100000;
+
+               usesFloat = 1;
+
+               if (mathType == 1)
+               {
+                       /* put the integer part on the stack */
+                       if (abs(csti) < 127)
+                       {
+                               bytecode_append(current_block->code, bipush$);
+                               bytecode_append(current_block->code, csti);
+                       }
+                       else if (abs(csti) < 15000)
+                       {
+                               bytecode_append(current_block->code, sipush$);
+                               bytecode_append_short_int(current_block->code, csti);
+                       }
+                       else
+                       {
+                               bytecode_append(current_block->code, ldc_w$);
+                               bytecode_append_short_int(current_block->code, cp_add_integer(csti));
+                       }
+
+                       /* put the fraction part to the stack */
+                       if (abs(cstf) < 127)
+                       {
+                               bytecode_append(current_block->code, bipush$);
+                               bytecode_append(current_block->code, cstf);
+                       }
+                       else if (abs(cstf) < 15000)
+                       {
+                               bytecode_append(current_block->code, sipush$);
+                               bytecode_append_short_int(current_block->code, cstf);
+                       }
+                       else
+                       {
+                               bytecode_append(current_block->code, ldc_w$);
+                               bytecode_append_short_int(current_block->code, cp_add_integer(cstf));
+                       }
+
+                       bytecode_append(current_block->code, invokestatic$);
+                       bytecode_append_short_int(current_block->code, cp_add_methodref("F", "fI", "(II)I"));
+               }
+               else
+               {
+                       char number[64];
+
+                       bytecode_append(current_block->code, new$);
+                       bytecode_append_short_int(current_block->code, cp_add_class("Real"));
+                       bytecode_append(current_block->code, dup$);
+
+                       sprintf(number, "%f", real_constant);
+                       bytecode_append(current_block->code, ldc_w$);
+                       bytecode_append_short_int(current_block->code, cp_add_string(number));
+
+                       bytecode_append(current_block->code, invokespecial$);
+                       bytecode_append_short_int(current_block->code, cp_add_methodref("Real", "<init>", "(Ljava/lang/String;)V"));
+               }
+
+               current_token = yylex();
+               return_type->type_class = real_type;
+               return return_type;
+       }
+
+       if (current_token == CST_BOOLEAN)
+       {
+               if (boolean_constant)
+               {
+                       bytecode_append(current_block->code, iconst_m1$);
+               }
+               else
+               {
+                       bytecode_append(current_block->code, iconst_0$);
+               }
+
+               current_token = yylex();
+               return_type->type_class = boolean_type;
+               return return_type;
+       }
+
+       if (current_token == CST_CHAR)
+       {
+               bytecode_append(current_block->code, bipush$);
+               bytecode_append(current_block->code, char_constant);
+
+               current_token = yylex();
+               return_type->type_class = char_type;
+               return return_type;
+       }
+
+       if (current_token == CST_STRING)
+       {
+               int cp_index;
+               cp_index = cp_add_string(string_constant->cstr);
+               if (cp_index <= 255)
+               {
+                       bytecode_append(current_block->code, ldc$);
+                       bytecode_append(current_block->code, (char) cp_index);
+               }
+               else
+               {
+                       bytecode_append(current_block->code, ldc_w$);
+                       bytecode_append_short_int(current_block->code, (short) cp_index);
+               }
+
+               current_token = yylex();
+               return_type->type_class = string_type;
+               return return_type;
+       }
+
+       if (current_token == IDENTIFIER)
+       {
+               identifier *name;
+               char *identifier_text;
+               identifier_text = (char*) mem_alloc(strlen(YYTEXT_STRING) + 1);
+               strcpy(identifier_text, YYTEXT_STRING);
+               lowercase(identifier_text);
+
+               name = get_identifier(current_block, identifier_text);
+
+               if ((name->identifier_class == none)
+                       || (name->identifier_class == program_name)
+                       || (name->identifier_class == type_name)
+                       || (name->identifier_class == procedure_name))
+               {
+                       add_error_message(429, YYTEXT_STRING, "");
+                       current_token = yylex();
+                       identifier_destroy(name);
+                       mem_free(identifier_text);
+                       return return_type;
+               }
+
+
+               current_token = yylex();
+
+               if (name->identifier_class == constant_name)
+               {
+constant_value:
+                       create_constant_bytecode(name, current_block->code);
+                       type_destroy(return_type);
+                       return_type = type_duplicate(name->constant_type);
+                       identifier_destroy(name);
+                       mem_free(identifier_text);
+                       return return_type;
+               }
+
+               /*
+                       Parse the unit functions.
+               */
+               if (name->identifier_class == unit_name)
+               {
+                       identifier *unit_name;
+
+                       if (current_token != DOT)
+                       {
+                               add_error_message(200, ".", YYTEXT_STRING);
+                               while (current_token != SEMI_COLON)
+                                       current_token = yylex();
+                               return return_type;
+                       }
+
+                       current_token = yylex();
+                       unit_name = name_table_find(name->unit_block->names, string_from_cstr(YYTEXT_STRING));
+                       identifier_text = malloc(strlen(YYTEXT_STRING) + 1);
+                       strcpy(identifier_text, YYTEXT_STRING);
+
+                       if (unit_name == NULL)
+                       {
+                               add_error_message(453, YYTEXT_STRING, "");
+                               add_error_message(200, ".", YYTEXT_STRING);
+                               while (current_token != SEMI_COLON)
+                                       current_token = yylex();
+                               return return_type;
+                       }
+
+                       name = identifier_duplicate(unit_name);
+                       current_token = yylex();
+
+                       if (name->identifier_class == function_name)
+                               goto function_call;
+
+                       if (name->identifier_class == constant_name)
+                               goto constant_value;
+
+                       if (name->identifier_class == variable_name)
+                               goto variable_value;
+
+                       add_error_message(458, YYTEXT_STRING, "");
+               }
+
+               if ((name->identifier_class == variable_name)
+                       || (name->identifier_class == parameter_name))
+               {
+                       type *current_type;
+                       type *new_type;
+                       int is_field;
+variable_value:
+                       is_field = name->belongs_to_program_block;
+
+                       if (name->identifier_class == variable_name)
+                       {
+                               create_variable_bytecode(name, current_block->code, identifier_text, is_field);
+                               current_type = type_duplicate(name->variable_type);
+                       }
+
+
+                       if(name->identifier_class == parameter_name)
+                       {
+                               create_variable_bytecode(name, current_block->code, identifier_text, is_field);
+                               current_type = type_duplicate(name->parameter_type);
+                       }
+
+                       mem_free(identifier_text);
+
+                       identifier_destroy(name);
+
+                       name = NULL;
+
+                       while ((current_token == DOT)
+                               || (current_token == OPEN_SQ_BR))
+                       {
+                               /* get an element from the record */
+                               if (current_token == DOT)
+                               {
+                                       char record_name[5];
+                                       char field_descriptor[128];
+                                       int fieldref_index;
+
+                                       if (current_type->type_class != record_type)
+                                       {
+                                               add_error_message(424, "", "");
+
+                                               /* Error-recovery */
+                                               while ((current_token != SEMI_COLON)
+                                                       && (current_token != KWD_END)
+                                                       && (current_token != END_OF_INPUT))
+                                               {
+                                                       current_token = yylex();
+                                               }
+
+                                               type_destroy(current_type);
+                                               return return_type;
+                                       }
+
+                                       current_token = yylex();
+
+                                       new_type = type_find_record_element(current_type, YYTEXT_STRING);
+                                       sprintf(record_name, "R_%d", current_type->unique_record_ID);
+                                       type_destroy(current_type);
+                                       current_type = new_type;
+
+                                       if (current_type == NULL)
+                                       {
+                                               add_error_message(425, YYTEXT_STRING, "");
+
+                                               /* Error-recovery */
+                                               while ((current_token != SEMI_COLON)
+                                                       && (current_token != KWD_END)
+                                                       && (current_token != END_OF_INPUT))
+                                               {
+                                                       current_token = yylex();
+                                               }
+
+                                               type_destroy(current_type);
+                                               return return_type;
+                                       }
+
+                                       lowercase(YYTEXT_STRING);
+                                       get_field_descriptor(new_type, field_descriptor);
+                                       fieldref_index = cp_add_fieldref(record_name, YYTEXT_STRING, field_descriptor);
+
+                                       bytecode_append(current_block->code, getfield$);
+                                       bytecode_append_short_int(current_block->code, fieldref_index);
+
+                                       current_token = yylex();
+                               }
+                               /* get an element from an array */
+                               else if (current_token == OPEN_SQ_BR)
+                               {
+                                       type_list *array_elements;
+
+                                       if (current_type->type_class != array_type)
+                                       {
+                                               add_error_message(426, "", "");
+
+                                               /* Error-recovery */
+                                               while ((current_token != SEMI_COLON)
+                                                       && (current_token != KWD_END)
+                                                       && (current_token != END_OF_INPUT))
+                                               {
+                                                       current_token = yylex();
+                                               }
+
+                                               type_destroy(current_type);
+                                               return return_type;
+                                       }
+
+                                       current_token = yylex();
+
+                                       array_elements = RD_expression_list_array(current_block, current_block->code, current_type);
+
+                                       /* replace the last aaload in the bytecode with the proper loading instruction */
+                                       replace_aaload_instruction(current_block->code, current_type->element_type);
+
+                                       if (type_list_different_parameter_array(array_elements, current_type->dimensions_list) != 0)
+                                       {
+                                               char num1[6], num2[6];
+
+                                               sprintf(num1, "%d", type_list_length(current_type->dimensions_list));
+                                               sprintf(num2, "%d", type_list_length(array_elements));
+                                               add_error_message(427, num1, num2);
+
+                                               /* Error-recovery */
+                                               while ((current_token != SEMI_COLON)
+                                                       && (current_token != KWD_END)
+                                                       && (current_token != END_OF_INPUT))
+                                               {
+                                                       current_token = yylex();
+                                               }
+
+                                               type_destroy(current_type);
+                                               return return_type;
+                                       }
+
+                                       if (current_token != CLOSE_SQ_BR)
+                                       {
+                                               add_error_message(200, "]", YYTEXT_STRING);
+
+                                               /* Error-recovery */
+                                               while ((current_token != SEMI_COLON)
+                                                       && (current_token != KWD_END)
+                                                       && (current_token != END_OF_INPUT))
+                                               {
+                                                       current_token = yylex();
+                                               }
+
+                                               type_destroy(current_type);
+                                               return return_type;
+                                       }
+
+                                       current_token = yylex();
+
+                                       new_type = type_duplicate(current_type->element_type);
+                                       type_destroy(current_type);
+
+                                       current_type = new_type;
+
+                                       type_list_destroy(array_elements);
+                               }
+
+                       }
+
+                       type_destroy(return_type);
+
+                       return_type = current_type;
+
+                       return return_type;
+               }
+
+function_call:
+
+               /* a function call */
+               if (name->identifier_class == function_name)
+               {
+                       int methodref_index;
+                       char *method_type;
+                       int method_index;
+                       method_type = (char*) mem_alloc(1024*5);
+
+                       if (name->standard_function)
+                       {
+                               create_std_function_prefix(current_block->code, identifier_text);
+                       }
+
+                       if (type_list_length(name->parameters) == 0)
+                       {
+                               int br_depth = 0;
+                               if (current_token == OPEN_BR)
+                               {
+                                       add_error_message(419, "", "");
+                                       br_depth = 1;
+                                       while (br_depth > 0)
+                                       {
+                                               if ((current_token == END_OF_INPUT)
+                                                       || (current_token == KWD_END))
+                                               {
+                                                       identifier_destroy(name);
+                                                       return return_type;
+                                               }
+
+                                               current_token = yylex();
+
+                                               if (current_token == OPEN_BR)
+                                                       br_depth ++;
+
+                                               if (current_token == CLOSE_BR)
+                                                       br_depth --;
+                                       }
+
+                                       current_token = yylex();
+                               }
+
+                               /* create the bytecode */
+                               if (name->unit_function)
+                               {
+                                       string *full_unit_name;
+                                       if (name->container_unit->is_library == 1)
+                                               full_unit_name = string_from_cstr("Lib_");
+                                       else
+                                               full_unit_name = string_create();
+                                       string_append(full_unit_name, name->container_unit->unit_name);
+
+                                       lowercase(identifier_text);
+                                       strcpy(method_type, "()");
+                                       get_field_descriptor(name->return_type, method_type + 2);
+                                       method_index = cp_add_methodref(full_unit_name->cstr,
+                                               identifier_text, method_type);
+                                       bytecode_append(current_block->code, invokestatic$);
+                                       bytecode_append_short_int(current_block->code, method_index);
+                                       string_destroy(full_unit_name);
+                               }
+                               else if (!name->standard_function)
+                               {
+                                       /* the function is user-defined */
+                                       strcpy(method_type, "()");
+                                       get_field_descriptor(name->return_type, method_type + 2);
+                                       if (compiling_unit == 0)
+                                               methodref_index = cp_add_methodref("M", identifier_text, method_type);
+                                       else
+                                               methodref_index = cp_add_methodref(string_get_cstr(str_program_name), identifier_text, method_type);
+                                       bytecode_append(current_block->code, invokestatic$); /* call */
+                                       bytecode_append_short_int(current_block->code, methodref_index);
+                               }
+                               else
+                               {
+                                       /* handle standard functions and procedures */
+                                       create_std_function_code(current_block->code, identifier_text);
+                               }
+
+                               type_destroy(return_type);
+
+                               mem_free(identifier_text);
+                               mem_free(method_type);
+
+                               return_type = type_duplicate(name->return_type);
+
+                               identifier_destroy(name);
+
+                               return return_type;
+                       }
+                       else
+                       {
+                               int compare_result;
+                               int old_linenum;
+                               type_list *parameter_list;
+
+                               if (current_token != OPEN_BR)
+                               {
+                                       add_error_message(200, "(", YYTEXT_STRING);
+                               }
+
+                               current_token = yylex();
+
+                               old_linenum = linenum;
+
+                               parameter_list = RD_expression_list_cast(current_block, name->parameters);
+
+                               compare_result = type_list_different_parameter_cast(parameter_list, name->parameters);
+
+                               if (compare_result == -1){
+                                       new_linenum=old_linenum;
+                                       add_error_message(421, "", "");
+                               }
+
+                               if (compare_result > 0)
+                               {
+                                       char par_num[4];
+                                       sprintf(par_num, "%d", compare_result);
+                                       new_linenum=old_linenum;
+                                       add_error_message(422, par_num, "");
+                               }
+
+                               type_list_destroy(parameter_list);
+
+                               if (current_token != CLOSE_BR)
+                               {
+                                       add_error_message(200, ")", YYTEXT_STRING);
+                               }
+                               else
+                                       current_token = yylex();
+
+                               type_destroy(return_type);
+
+                               /* create the bytecode */
+                               if (!name->standard_function)
+                               {
+                                       {
+                                               int pos = 1;
+                                               type_list *it;
+
+                                               it = name->parameters;
+
+                                               method_type[0] = '(';
+
+                                               while (it != NULL)
+                                               {
+                                                       if (it->data == NULL)
+                                                               break;
+
+
+                                                       get_field_descriptor(it->data, method_type + pos);
+                                                       pos = strlen(method_type);
+
+                                                       it = it->next;
+                                               }
+
+                                               strcat(method_type, ")");
+                                       }
+
+
+                                       get_field_descriptor(name->return_type, method_type + strlen(method_type));
+
+                                       if (name->unit_function)
+                                       {
+                                               string *full_unit_name;
+                                               if (name->container_unit->is_library == 1)
+                                                       full_unit_name = string_from_cstr("Lib_");
+                                               else
+                                                       full_unit_name = string_create();
+                                               string_append(full_unit_name, name->container_unit->unit_name);
+                                               lowercase(identifier_text);
+                                               methodref_index = cp_add_methodref(full_unit_name->cstr, identifier_text, method_type);
+                                               string_destroy(full_unit_name);
+                                       }
+                                       else
+                                       {
+                                               if (compiling_unit == 0)
+                                                       methodref_index = cp_add_methodref("M", identifier_text, method_type);
+                                               else
+                                                       methodref_index = cp_add_methodref(string_get_cstr(str_program_name), identifier_text, method_type);
+                                       }
+
+                                       bytecode_append(current_block->code, invokestatic$); /* call */
+                                       bytecode_append_short_int(current_block->code, methodref_index);
+                               }
+                               else
+                               {
+                                       /* handle standard functions and procedures */
+                                       create_std_function_code(current_block->code, identifier_text);
+                               }
+                               /* END create the bytecode */
+
+                               return_type = type_duplicate(name->return_type);
+
+                               mem_free(identifier_text);
+                               mem_free(method_type);
+
+                               identifier_destroy(name);
+
+                               return return_type;
+                       }
+               }
+
+               mem_free(identifier_text);
+
+               return return_type;
+       }
+
+       /* brackets, priority change, no code generated in here */
+       if (current_token == OPEN_BR)
+       {
+               current_token = yylex();
+
+               type_destroy(return_type);
+               return_type =  RD_expression(current_block);
+
+               if (current_token != CLOSE_BR)
+               {
+                       add_error_message(200, ")", YYTEXT_STRING);
+               }
+
+               current_token = yylex();
+
+               return return_type;
+       }
+
+       add_error_message(204, YYTEXT_STRING, "");
+
+       return return_type;
+}
+
+
+/*
+       Create the bytecode that loads the given constant
+*/
+void create_constant_bytecode(identifier *item, bytecode *code)
+{
+       int cp_index;
+
+       switch(item->constant_type->type_class)
+       {
+       case integer_type:
+               cp_index = cp_add_integer(item->constant_int_value);
+               if (cp_index <= 255)
+               {
+                       bytecode_append(code, ldc$);
+                       bytecode_append(code, (char) cp_index);
+               }
+               else
+               {
+                       bytecode_append(code, ldc_w$);
+                       bytecode_append_short_int(code, (short) cp_index);
+               }
+               break;
+
+       case real_type:
+               {
+               float cst;
+               int csti; /* the integer part */
+               int cstf; /* the fraction part */
+
+               /* calculate the exponent and the integer part */
+               cst = item->constant_real_value;
+
+               csti = (int)cst;
+               cstf = (cst - (int)cst)*100000;
+
+               usesFloat = 1;
+
+               if (mathType == 1)
+               {
+                       /* put the integer part on the stack */
+                       if (abs(csti) < 127)
+                       {
+                               bytecode_append(code, bipush$);
+                               bytecode_append(code, csti);
+                       }
+                       else if (abs(csti) < 15000)
+                       {
+                               bytecode_append(code, sipush$);
+                               bytecode_append_short_int(code, csti);
+                       }
+                       else
+                       {
+                               bytecode_append(code, ldc_w$);
+                               bytecode_append_short_int(code, cp_add_integer(csti));
+                       }
+
+                       /* put the fraction part to the stack */
+                       if (abs(cstf) < 127)
+                       {
+                               bytecode_append(code, bipush$);
+                               bytecode_append(code, cstf);
+                       }
+                       else if (abs(cstf) < 15000)
+                       {
+                               bytecode_append(code, sipush$);
+                               bytecode_append_short_int(code, cstf);
+                       }
+                       else
+                       {
+                               bytecode_append(code, ldc_w$);
+                               bytecode_append_short_int(code, cp_add_integer(cstf));
+                       }
+
+                       bytecode_append(code, invokestatic$);
+                       bytecode_append_short_int(code, cp_add_methodref("F", "fI", "(II)I"));
+               }
+               else
+               {
+                       char number[64];
+
+                       bytecode_append(code, new$);
+                       bytecode_append_short_int(code, cp_add_class("Real"));
+                       bytecode_append(code, dup$);
+
+                       sprintf(number, "%f", real_constant);
+                       bytecode_append(code, ldc_w$);
+                       bytecode_append_short_int(code, cp_add_string(number));
+
+                       bytecode_append(code, invokespecial$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "<init>", "(Ljava/lang/String;)V"));
+
+               }
+
+
+
+               }
+               break;
+
+       case char_type:
+               cp_index = cp_add_integer(item->constant_int_value);
+               if (cp_index <= 255)
+               {
+                       bytecode_append(code, ldc$);
+                       bytecode_append(code, (char) cp_index);
+               }
+               else
+               {
+                       bytecode_append(code, ldc_w$);
+                       bytecode_append_short_int(code, (short) cp_index);
+               }
+               break;
+
+       case boolean_type:
+               if (item->constant_int_value)
+               {
+                       bytecode_append(code, iconst_m1$);
+               }
+               else
+               {
+                       bytecode_append(code, iconst_0$);
+               }
+               break;
+
+       case string_type:
+               cp_index = cp_add_string(item->constant_string_value->cstr);
+               if (cp_index <= 255)
+               {
+                       bytecode_append(code, ldc$);
+                       bytecode_append(code, (char) cp_index);
+               }
+               else
+               {
+                       bytecode_append(code, ldc_w$);
+                       bytecode_append_short_int(code, (short) cp_index);
+               }
+               break;
+       }
+}
+
+
+/*
+       Creates the code that loads the variable or parameter value to the stack
+*/
+void create_variable_bytecode(identifier *item, bytecode *code, char *name, int is_field)
+{
+       int index;
+       type *item_type;
+
+       /* if the block is program block, load field instead of variable */
+       if ((is_field) || (item->unit_function == 1))
+       {
+               if (item->identifier_class == variable_name)
+               {
+                       char type_descriptor[128];
+
+                       lowercase(name);
+                       bytecode_append(code, getstatic$);
+                       get_field_descriptor(item->variable_type, type_descriptor);
+
+                       if (item->unit_function == 0)
+                       {
+                               if (compiling_unit == 0)
+                                       bytecode_append_short_int(code, cp_add_fieldref("M", name, type_descriptor));
+                               else
+                                       bytecode_append_short_int(code, cp_add_fieldref(string_get_cstr(str_program_name), name, type_descriptor));
+                       }
+                       else
+                       {
+                               string *unit_name;
+
+                               if (item->container_unit->is_library == 0)
+                                       unit_name = string_create();
+                               else
+                                       unit_name = string_from_cstr("Lib_");
+
+                               lowercase(string_get_cstr(item->container_unit->unit_name));
+
+                               string_append(unit_name, item->container_unit->unit_name);
+
+                               bytecode_append_short_int(code, cp_add_fieldref(string_get_cstr(unit_name), name, type_descriptor));
+
+                               string_destroy(unit_name);
+                       }
+               }
+
+               return;
+       }
+
+       if (item->identifier_class == variable_name)
+       {
+               index = item->variable_index;
+               item_type = item->variable_type;
+       }
+       else if (item->identifier_class == function_name)
+       {
+               /* this is used for error recovery and returning values form functions */
+               index = type_list_length(item->parameters);
+               item_type = item->return_type;
+       }
+       else if (item->identifier_class == parameter_name)
+       {
+               index = item->parameter_index;
+               item_type = item->parameter_type;
+       }
+       else
+       {
+               add_error_message(444, "", "");
+               return 0;
+       }
+
+       switch (item_type->type_class)
+       {
+       case integer_type:
+       case char_type:
+       case boolean_type:
+               switch(index)
+               {
+               case 0:
+                       bytecode_append(code, iload_0$);
+                       break;
+               case 1:
+                       bytecode_append(code, iload_1$);
+                       break;
+               case 2:
+                       bytecode_append(code, iload_2$);
+                       break;
+               case 3:
+                       bytecode_append(code, iload_3$);
+                       break;
+               default:
+                       bytecode_append(code, iload$);
+                       bytecode_append(code, index);
+                       break;
+               }
+
+               break;
+
+       case real_type:
+               if (mathType == 1)
+               {
+                       switch(index)
+                       {
+                       case 0:
+                               bytecode_append(code, iload_0$);
+                               break;
+                       case 1:
+                               bytecode_append(code, iload_1$);
+                               break;
+                       case 2:
+                               bytecode_append(code, iload_2$);
+                               break;
+                       case 3:
+                               bytecode_append(code, iload_3$);
+                               break;
+                       default:
+                               bytecode_append(code, iload$);
+                               bytecode_append(code, index);
+                               break;
+                       }
+               }
+               else
+               {
+                       switch(index)
+                       {
+                       case 0:
+                               bytecode_append(code, aload_0$);
+                               break;
+                       case 1:
+                               bytecode_append(code, aload_1$);
+                               break;
+                       case 2:
+                               bytecode_append(code, aload_2$);
+                               break;
+                       case 3:
+                               bytecode_append(code, aload_3$);
+                               break;
+                       default:
+                               bytecode_append(code, aload$);
+                               bytecode_append(code, index);
+                               break;
+                       }
+               }
+               break;
+
+       case string_type:
+       case record_type:
+       case array_type:
+       case image_type:
+       case command_type:
+       case stream_type:
+       case record_store_type:
+       case http_type:
+       case alert_type:
+               switch(index)
+               {
+               case 0:
+                       bytecode_append(code, aload_0$);
+                       break;
+               case 1:
+                       bytecode_append(code, aload_1$);
+                       break;
+               case 2:
+                       bytecode_append(code, aload_2$);
+                       break;
+               case 3:
+                       bytecode_append(code, aload_3$);
+                       break;
+               default:
+                       bytecode_append(code, aload$);
+                       bytecode_append(code, index);
+                       break;
+               }
+
+               break;
+
+       default:
+               die(15);
+       }
+}
+
+/*
+       Creates the code that puts the variable or parameter value from the stack into memory
+*/
+void create_put_variable_bytecode(identifier *item, bytecode *code, char *name, int is_field)
+{
+       int index;
+       type *item_type;
+
+       if (item->identifier_class == variable_name)
+       {
+               index = item->variable_index;
+               item_type = item->variable_type;
+       }
+       else if (item->identifier_class == parameter_name)
+       {
+               index = item->parameter_index;
+               item_type = item->parameter_type;
+       }
+       else if (item->identifier_class == function_name)/* function name, it is return value variable */
+       {
+               index = type_list_length(item->parameters);
+               is_field = 0;
+               item_type = item->return_type;
+       }
+       else
+       {
+               add_error_message(444, "", "");
+               return;
+       }
+
+       /* if the value on the top of the stack is string, copy it */
+       if (item_type->type_class == string_type)
+       {
+               int class_index;
+               int method_index;
+
+               class_index = cp_add_class("java/lang/String");
+               method_index = cp_add_methodref("java/lang/String", "<init>", "(Ljava/lang/String;)V");
+
+               bytecode_append(code, new$);
+               bytecode_append_short_int(code, class_index);
+               bytecode_append(code, dup_x1$);
+               bytecode_append(code, swap$);
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, method_index);
+       }
+
+       if ((item_type->type_class == real_type) && (mathType != 1))
+       {
+               int class_index;
+               int method_index;
+
+               usesFloat = 1;
+
+               class_index = cp_add_class("Real");
+               method_index = cp_add_methodref("Real", "<init>", "(LReal;)V");
+
+               bytecode_append(code, new$);
+               bytecode_append_short_int(code, class_index);
+               bytecode_append(code, dup_x1$);
+               bytecode_append(code, swap$);
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, method_index);
+       }
+
+       /* if the value on the top of the stack is record type, copy it */
+       if (item_type->type_class == record_type)
+       {
+               int class_index;
+               int constructor_index;
+               int copy_index;
+
+               char type_name[16];
+               char copy_sig[64];
+
+               sprintf(type_name, "R_%d", item_type->unique_record_ID);
+               sprintf(copy_sig, "(L%s;)L%s;", type_name, type_name);
+
+               class_index = cp_add_class(type_name);
+               constructor_index = cp_add_methodref(type_name, "<init>", "()V");
+               copy_index = cp_add_methodref(type_name, "Copy", copy_sig);
+
+               bytecode_append(code, new$);
+               bytecode_append_short_int(code, class_index);
+               bytecode_append(code, dup_x1$);
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, constructor_index);
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, copy_index);
+       }
+
+       /* if the block is program block, load field instead of variable */
+       if ((is_field) || (item->unit_function == 1))
+       {
+               if (item->identifier_class == variable_name)
+               {
+                       char type_descriptor[128];
+
+                       lowercase(name);
+                       bytecode_append(code, putstatic$);
+                       get_field_descriptor(item->variable_type, type_descriptor);
+
+                       if (item->unit_function == 0)
+                       {
+                               if (compiling_unit == 0)
+                                       bytecode_append_short_int(code, cp_add_fieldref("M", name, type_descriptor));
+                               else
+                                       bytecode_append_short_int(code, cp_add_fieldref(string_get_cstr(str_program_name), name, type_descriptor));
+                       }
+                       else
+                       {
+                               string *unit_name;
+
+                               if (item->container_unit->is_library == 0)
+                                       unit_name = string_create();
+                               else
+                                       unit_name = string_from_cstr("Lib_");
+
+                               lowercase(string_get_cstr(item->container_unit->unit_name));
+
+                               string_append(unit_name, item->container_unit->unit_name);
+
+                               bytecode_append_short_int(code, cp_add_fieldref(string_get_cstr(unit_name), name, type_descriptor));
+
+                               string_destroy(unit_name);
+                       }
+               }
+
+               return;
+       }
+
+       switch (item_type->type_class)
+       {
+       case integer_type:
+       case char_type:
+       case boolean_type:
+               switch(index)
+               {
+               case 0:
+                       bytecode_append(code, istore_0$);
+                       break;
+               case 1:
+                       bytecode_append(code, istore_1$);
+                       break;
+               case 2:
+                       bytecode_append(code, istore_2$);
+                       break;
+               case 3:
+                       bytecode_append(code, istore_3$);
+                       break;
+               default:
+                       bytecode_append(code, istore$);
+                       bytecode_append(code, index);
+                       break;
+               }
+
+               break;
+
+       case real_type:
+                       if (mathType == 1)
+                       {
+                               switch(index)
+                               {
+                               case 0:
+                                       bytecode_append(code, istore_0$);
+                                       break;
+                               case 1:
+                                       bytecode_append(code, istore_1$);
+                                       break;
+                               case 2:
+                                       bytecode_append(code, istore_2$);
+                                       break;
+                               case 3:
+                                       bytecode_append(code, istore_3$);
+                                       break;
+                               default:
+                                       bytecode_append(code, istore$);
+                                       bytecode_append(code, index);
+                                       break;
+                               }
+                       }
+                       else
+                       {
+                               switch(index)
+                               {
+                               case 0:
+                                       bytecode_append(code, astore_0$);
+                                       break;
+                               case 1:
+                                       bytecode_append(code, astore_1$);
+                                       break;
+                               case 2:
+                                       bytecode_append(code, astore_2$);
+                                       break;
+                               case 3:
+                                       bytecode_append(code, astore_3$);
+                                       break;
+                               default:
+                                       bytecode_append(code, astore$);
+                                       bytecode_append(code, index);
+                                       break;
+                               }
+                       }
+                       break;
+
+       case string_type:
+       case record_type:
+       case array_type:
+       case image_type:
+       case command_type:
+       case stream_type:
+       case record_store_type:
+       case http_type:
+       case alert_type:
+               switch(index)
+               {
+               case 0:
+                       bytecode_append(code, astore_0$);
+                       break;
+               case 1:
+                       bytecode_append(code, astore_1$);
+                       break;
+               case 2:
+                       bytecode_append(code, astore_2$);
+                       break;
+               case 3:
+                       bytecode_append(code, astore_3$);
+                       break;
+               default:
+                       bytecode_append(code, astore$);
+                       bytecode_append(code, index);
+                       break;
+               }
+
+               break;
+
+       default:
+               die(15);
+       }
+}
+
+/*
+       The last instruction in the bytecode is aaload; it should be replaced with
+       the iaload, faload, aload or something like that.
+*/
+void replace_aaload_instruction(bytecode *code, type *element_type)
+{
+       /* delete the last instruction */
+       code->bytecode_pos --;
+
+       /* create the new instruction */
+       switch(element_type->type_class)
+       {
+       case integer_type:
+       case boolean_type:
+       case char_type:
+               bytecode_append(code, iaload$);
+               break;
+
+       case real_type:
+               if (mathType == 1)
+               {
+                       bytecode_append(code, iaload$);
+               }
+               else
+               {
+                       bytecode_append(code, aaload$);
+               }
+               break;
+
+       case record_type:
+       case string_type:
+       case image_type:
+       case command_type:
+       case stream_type:
+       case record_store_type:
+       case http_type:
+       case alert_type:
+               bytecode_append(code, aaload$);
+               break;
+
+       default:
+               die(24);
+       }
+}
+
+/*
+       Creates the code that adjustes array indices
+*/
+void adjust_indices(bytecode *code, type *dimension)
+{
+       if (dimension == NULL)
+               return;
+
+       switch(dimension->first_element)
+       {
+       case -1:
+               bytecode_append(code, iconst_m1$);
+               break;
+       case 0:
+               //bytecode_append(code, iconst_0$);
+               break;
+       case 1:
+               bytecode_append(code, iconst_1$); break;
+       case 2:
+               bytecode_append(code, iconst_2$); break;
+       case 3:
+               bytecode_append(code, iconst_3$); break;
+       case 4:
+               bytecode_append(code, iconst_4$); break;
+       case 5:
+               bytecode_append(code, iconst_5$); break;
+       default:
+               if (dimension->first_element < 128)
+               {
+                       bytecode_append(code, bipush$);
+                       bytecode_append(code, dimension->first_element);
+               }
+               else
+               {
+                       bytecode_append(code, sipush$);
+                       bytecode_append_short_int(code, dimension->first_element);
+               }
+       }
+       if (dimension->first_element != 0)
+               bytecode_append(code, isub$);
+
+}
diff --git a/MPC.3.5.LINUX/parser/parser.h b/MPC.3.5.LINUX/parser/parser.h
new file mode 100644 (file)
index 0000000..1464249
--- /dev/null
@@ -0,0 +1,59 @@
+/********************************************************************
+       
+       parser.h - recursive-descent parser declarations
+
+  Niksa Orlic, 2004-04-19
+
+********************************************************************/
+
+
+void parser_start();
+string* RD_program_header();
+void RD_uses_list();
+block* RD_block(block*);
+void RD_const_declaration();
+void RD_var_declaration(block*);
+string_list* RD_identifier_list(block*, int);
+void RD_type_declaration(block*);
+void RD_procedure_declaration(block*);
+void RD_function_declaration(block*);
+int RD_proc_block(block*, type*, type_list*);
+type_list* RD_param_list(block*);
+void RD_block_body(block*);
+void RD_inline_body(block*);
+void RD_statement(block *);
+void RD_if_statement(block *);
+void RD_case_statement(block *);
+void RD_case_list(block*, type*);
+void RD_while_statement(block*);
+void RD_repeat_statement(block*);
+void RD_for_statement(block*);
+type* RD_type(block*);
+type* RD_basic_type(block*);
+type* RD_array_declaration(block*);
+type* RD_record_declaration(block*);
+type* RD_file_declaration(block*);
+void RD_set_declaration(block*);
+type* RD_expression(block*);
+type* RD_sum(block*);
+type* RD_mult(block*);
+type* RD_not(block*);
+type* RD_neg(block*);
+void RD_assignment_or_procedure_call(block*); 
+type_list* RD_expression_list(block*);
+type_list* RD_expression_list_cast(block*, type_list*);
+type_list* RD_expression_list_array(block*, bytecode*, type*);
+void RD_with_statement(block*);
+type* RD_value(block*);
+
+void RD_unit_interface(block*);
+void RD_unit_implementation(block*);           
+void RD_unit_initialization(block*);
+void RD_unit_finalization(block*);
+
+void create_constant_bytecode(identifier*, bytecode*);
+void create_variable_bytecode(identifier*, bytecode*, char*, int);
+void create_put_variable_bytecode(identifier*, bytecode*, char*, int);
+
+void replace_aaload_instruction(bytecode*, type*);
+void adjust_indices(bytecode *code, type *dimension);
diff --git a/MPC.3.5.LINUX/parser/stdpas.c b/MPC.3.5.LINUX/parser/stdpas.c
new file mode 100644 (file)
index 0000000..24380f7
--- /dev/null
@@ -0,0 +1,3333 @@
+/********************************************************************
+
+       stdpas.c - initializes the parser/semantic checker with a
+       standard pascal types, constants etc.
+
+  Niksa Orlic, 2004-04-29
+
+********************************************************************/
+
+#include "../util/strings.h"
+#include "../util/error.h"
+//#include "../util/message.h"
+#include "../structures/type_list.h"
+#include "../structures/string_list.h"
+#include "../structures/type.h"
+#include "../structures/identifier.h"
+#include "../structures/name_table.h"
+#include "../classgen/bytecode.h"
+#include "../structures/block.h"
+//#include "../main/static_entry.h"
+
+#include "../classgen/constant_pool.h"
+
+#include "stdpas.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#pragma warning (disable:4305)
+#pragma warning (disable:4761)
+
+int procedure_linenum;
+extern char *source_file_name;
+int usesForms = 0; /* set to 1 if FS.class should be added into the generated JAR file */
+int usesSupport = 0; /* set to 1 if S.class should be added into the generated JAR file */
+int usesFloat = 0; /* set to 1 if Float.class should be added into the generated JAR file */
+int usesRecordStore = 0; /* set to 1 if RS.class should be added into the generated JAR file */
+int usesHttp = 0; /* if H.class should be added */
+int usesPlayer = 0; /* if P.class should be used */
+int usesSMS = 0;       /* if uses SM.class */
+extern int mathType;
+
+//int usesRegisteredFeature = 0;
+
+extern int canvasType;
+
+
+/*
+       Creates and initializes the root block
+       with standard pascal types, constants etc.
+*/
+block* initialize_root_block()
+{
+       block *root_block;
+
+       root_block = block_create(NULL, NULL);
+
+       add_std_types(root_block);
+       add_std_constants(root_block);
+       add_std_functions(root_block);
+
+       return root_block;
+}
+
+
+/*
+       Adds the standard pascal types into the block.
+*/
+void add_std_types(block *item)
+{
+       add_std_type(item, integer_type, "integer");
+       add_std_type(item, real_type, "real");
+       add_std_type(item, boolean_type, "boolean");
+       add_std_type(item, char_type, "char");
+       add_std_type(item, string_type, "string");
+       add_std_type(item, image_type, "image");
+       add_std_type(item, command_type, "command");
+       add_std_type(item, stream_type, "resource");
+       add_std_type(item, record_store_type, "recordstore");
+       add_std_type(item, http_type, "http");
+}
+
+/*
+       Adds some constants into the block
+*/
+void add_std_constants(block *item)
+{
+       add_real_constant(item, (float) 3.1415926535897932384626433832795, "pi");
+
+       /* key codes */
+       add_integer_constant(item, 0, "KE_NONE");
+       add_integer_constant(item, 0, "GA_NONE");
+
+       add_integer_constant(item, 1, "GA_UP");
+       add_integer_constant(item, 6, "GA_DOWN");
+       add_integer_constant(item, 2, "GA_LEFT");
+       add_integer_constant(item, 5, "GA_RIGHT");
+       add_integer_constant(item, 8, "GA_FIRE");
+       add_integer_constant(item, 9,  "GA_GAMEA");
+       add_integer_constant(item, 10, "GA_GAMEB");
+       add_integer_constant(item, 11, "GA_GAMEC");
+       add_integer_constant(item, 12, "GA_GAMED");
+
+       add_integer_constant(item, 48, "KE_KEY0");
+       add_integer_constant(item, 49, "KE_KEY1");
+       add_integer_constant(item, 50, "KE_KEY2");
+       add_integer_constant(item, 51, "KE_KEY3");
+       add_integer_constant(item, 52, "KE_KEY4");
+       add_integer_constant(item, 53, "KE_KEY5");
+       add_integer_constant(item, 54, "KE_KEY6");
+       add_integer_constant(item, 55, "KE_KEY7");
+       add_integer_constant(item, 56, "KE_KEY8");
+       add_integer_constant(item, 57, "KE_KEY9");
+       add_integer_constant(item, 42, "KE_STAR");
+       add_integer_constant(item, 35, "KE_POUND");
+
+       /* font constants */
+       add_integer_constant(item, 0, "FONT_FACE_SYSTEM");
+       add_integer_constant(item, 32, "FONT_FACE_MONOSPACE");
+       add_integer_constant(item, 64, "FONT_FACE_PROPORTIONAL");
+
+       add_integer_constant(item, 8, "FONT_SIZE_SMALL");
+       add_integer_constant(item, 0, "FONT_SIZE_MEDIUM");
+       add_integer_constant(item, 16, "FONT_SIZE_LARGE");
+
+       add_integer_constant(item, 0, "FONT_STYLE_PLAIN");
+       add_integer_constant(item, 1, "FONT_STYLE_BOLD");
+       add_integer_constant(item, 2, "FONT_STYLE_ITALIC");
+       add_integer_constant(item, 4, "FONT_STYLE_UNDERLINED");
+
+       /* command constants */
+       add_integer_constant(item, 1, "CM_SCREEN");
+       add_integer_constant(item, 2, "CM_BACK");
+       add_integer_constant(item, 3, "CM_CANCEL");
+       add_integer_constant(item, 4, "CM_OK");
+       add_integer_constant(item, 5, "CM_HELP");
+       add_integer_constant(item, 6, "CM_STOP");
+       add_integer_constant(item, 7, "CM_EXIT");
+       add_integer_constant(item, 8, "CM_ITEM");
+
+       /* text field constants */
+       add_integer_constant(item, 0, "TF_ANY");
+       add_integer_constant(item, 1, "TF_EMAIL");
+       add_integer_constant(item, 2, "TF_NUMERIC");
+       add_integer_constant(item, 3, "TF_PHONENUMBER");
+       add_integer_constant(item, 4, "TF_URL");
+       add_integer_constant(item,  0x10000, "TF_PASSWORD");
+
+       /* choice constants */
+       add_integer_constant(item, 1, "CH_EXCLUSIVE");
+       add_integer_constant(item, 2, "CH_MULTIPLE");
+       add_integer_constant(item, 3, "CH_IMPLICIT");
+
+       /* http constants */
+       add_string_constant(item, string_from_cstr("GET"), "GET");
+       add_string_constant(item, string_from_cstr("HEAD"), "HEAD");
+       add_string_constant(item, string_from_cstr("POST"), "POST");
+
+       /* date field constants */
+       add_integer_constant(item, 1, "DF_DATE");
+       add_integer_constant(item, 2, "DF_TIME");
+       add_integer_constant(item, 3, "DF_DATE_TIME");
+
+       add_integer_constant(item, 1000, "EOF");
+}
+
+
+/*
+       Adds standard functions and procedures
+*/
+void add_std_functions(block *item)
+{
+
+       add_special_function(item, real_type, real_type, "sqrt");
+       add_special_function(item, real_type, integer_type, "trunc");
+//     add_special_function(item, real_type, integer_type, "round");
+       add_special_function(item, real_type, real_type, "sin");
+       add_special_function(item, real_type, real_type, "cos");
+       add_special_function(item, real_type, real_type, "atan");
+       add_special_function(item, real_type, real_type, "log"); /* natural logarithm */
+       add_special_function(item, real_type, real_type, "exp");
+       add_special_function(item, real_type, real_type, "asin");
+       add_special_function(item, real_type, real_type, "acos");
+       add_special_function(item, real_type, real_type, "tan");
+       add_special_function(item, real_type, real_type, "toDegrees");
+       add_special_function(item, real_type, real_type, "toRadians");
+       add_special_function(item, real_type, real_type, "frac");
+    add_special_function2(item, real_type, real_type, real_type, "atan2");
+       add_special_function(item, real_type, real_type, "log10");
+       add_special_function2(item, real_type, real_type, real_type, "pow");
+       add_special_function2(item, string_type, integer_type, real_type, "stringToReal");
+       add_special_function(item, real_type, real_type, "rabs");
+
+       add_special_function(item, integer_type, integer_type, "sqr");
+       add_special_function(item, integer_type, integer_type, "abs");
+
+       add_special_function(item, integer_type, boolean_type, "odd");
+       add_special_function(item, integer_type, char_type, "chr");
+       add_special_function(item, char_type, integer_type, "ord");
+
+       add_special_function(item, void_type, void_type, "halt");
+       add_special_function(item, void_type, boolean_type, "isMidletPaused");
+
+       /* RNG functions */
+       add_special_function(item, void_type, void_type, "randomize");
+       add_special_function(item, integer_type, integer_type, "random");
+
+       /* string functions */
+       add_special_function(item, string_type, string_type, "upcase");
+       add_special_function(item, string_type, string_type, "locase");
+       add_special_function(item, string_type, integer_type, "length");
+       add_special_function3(item, string_type, integer_type, integer_type, string_type, "copy");
+       add_special_function2(item, string_type, string_type, integer_type, "pos");
+       add_special_function(item, string_type, integer_type, "stringToInteger");
+       add_special_function(item, integer_type, string_type, "integerToString");
+       add_special_function2(item, string_type, integer_type, char_type, "getChar");
+       add_special_function3(item, string_type, char_type, integer_type, string_type, "setChar");
+
+       /* midlet functions */
+       add_special_function(item, string_type, string_type, "getproperty");
+
+
+       /* time functions */
+       add_special_function(item, integer_type, void_type, "delay");
+       add_special_function(item, void_type, integer_type, "getRelativeTimeMs");
+       add_special_function(item, void_type, integer_type, "getCurrentTime");
+       add_special_function(item, integer_type, integer_type, "getDay");
+       add_special_function(item, integer_type, integer_type, "getMonth");
+       add_special_function(item, integer_type, integer_type, "getYear");
+       add_special_function(item, integer_type, integer_type, "getSecond");
+       add_special_function(item, integer_type, integer_type, "getMinute");
+       add_special_function(item, integer_type, integer_type, "getHour");
+       add_special_function(item, integer_type, integer_type, "getWeekDay");
+       add_special_function(item, integer_type, integer_type, "getYearDay");
+
+
+       /* music functions */
+       add_special_function3(item, integer_type, integer_type, integer_type, void_type, "playTone");
+
+
+       /* action functions */
+       add_special_function(item, void_type, integer_type, "getKeyPressed");
+       add_special_function(item, void_type, integer_type, "getKeyClicked");
+       add_special_function(item, integer_type, integer_type, "keyToAction");
+
+
+       /* image functions */
+       add_special_function(item, string_type, image_type, "loadImage");
+       add_special_function(item, image_type, integer_type, "getImageWidth");
+       add_special_function(item, image_type, integer_type, "getImageHeight");
+       add_special_function5(item, image_type, integer_type, integer_type, integer_type, integer_type, image_type, "imageFromImage");
+       add_special_function4(item, integer_type, integer_type, integer_type, integer_type, image_type, "imageFromCanvas");
+       add_special_function2(item, string_type, integer_type, image_type, "imageFromBuffer");
+
+       /* drawing functions */
+       add_special_function(item, void_type, void_type, "repaint");
+
+       add_special_function(item, void_type, integer_type, "getWidth");
+       add_special_function(item, void_type, integer_type, "getHeight");
+       add_special_function(item, void_type, boolean_type, "isColorDisplay");
+       add_special_function(item, void_type, integer_type, "getColorsNum");
+
+
+       add_special_function3(item, string_type, integer_type, integer_type, void_type, "drawText");
+       add_special_function4(item, integer_type, integer_type, integer_type, integer_type, void_type, "setClip");
+       add_special_function4(item, integer_type, integer_type, integer_type, integer_type, void_type, "drawLine");
+       add_special_function3(item, integer_type, integer_type, integer_type, void_type, "setColor");
+       add_special_function4(item, integer_type, integer_type, integer_type, integer_type, void_type, "drawEllipse");
+       add_special_function4(item, integer_type, integer_type, integer_type, integer_type, void_type, "fillEllipse");
+       add_special_function4(item, integer_type, integer_type, integer_type, integer_type, void_type, "drawRect");
+       add_special_function4(item, integer_type, integer_type, integer_type, integer_type, void_type, "fillRect");
+       add_special_function6(item, integer_type, integer_type, integer_type, integer_type, integer_type, integer_type, void_type, "drawArc");
+       add_special_function2(item, integer_type, integer_type, void_type, "plot");
+       add_special_function(item, void_type, integer_type, "getColorRed");
+       add_special_function(item, void_type, integer_type, "getColorGreen");
+       add_special_function(item, void_type, integer_type, "getColorBlue");
+       add_special_function6(item, integer_type, integer_type, integer_type, integer_type, integer_type, integer_type, void_type, "drawRoundRect");
+       add_special_function6(item, integer_type, integer_type, integer_type, integer_type, integer_type, integer_type, void_type, "fillRoundRect");
+
+       add_special_function3(item, integer_type, integer_type, integer_type, void_type, "setFont");
+       add_special_function(item, void_type, void_type, "setDefaultFont");
+
+       add_special_function3(item, image_type, integer_type, integer_type, void_type, "drawImage");
+
+       add_special_function(item, string_type, integer_type, "getStringWidth");
+       add_special_function(item, string_type, integer_type, "getStringHeight");
+
+       /* debug functions */
+       add_special_function(item, string_type, void_type, "debug");
+       add_special_function(item, boolean_type, void_type, "assert");
+
+       /* command & form functions */
+       add_special_function3(item, string_type, integer_type, integer_type, command_type, "createCommand");
+       add_special_function(item, void_type, command_type, "getClickedCommand");
+       add_special_function(item, command_type, void_type, "addCommand");
+       add_special_function(item, command_type, void_type, "removeCommand");
+       add_special_function(item, void_type, command_type, "emptyCommand");
+
+       add_special_function(item, void_type, void_type, "showForm");
+       add_special_function(item, void_type, void_type, "showCanvas");
+
+       add_special_function(item, string_type, void_type, "setTicker");
+
+       add_special_function(item, void_type, void_type, "clearForm");
+       add_special_function(item, integer_type, void_type, "formRemove");
+       add_special_function(item, string_type, integer_type, "formAddString");
+       add_special_function(item, void_type, integer_type, "formAddSpace");
+       add_special_function(item, image_type, integer_type, "formAddImage");
+       add_special_function4(item, string_type, string_type, integer_type, integer_type, integer_type, "formAddTextField");
+       add_special_function4(item, string_type, boolean_type, integer_type, integer_type, integer_type, "formAddGauge");
+       add_special_function2(item, string_type, integer_type, integer_type, "formAddDateField");
+       add_special_function2(item, integer_type, integer_type, void_type, "formSetDate");
+       add_special_function(item, integer_type, integer_type, "formGetDate");
+
+       add_special_function2(item, string_type, integer_type, integer_type, "formAddChoice");
+
+       add_special_function(item, integer_type, integer_type, "formGetValue");
+       add_special_function(item, integer_type, string_type, "formGetText");
+       add_special_function2(item, integer_type, integer_type, void_type, "formSetValue");
+       add_special_function2(item, integer_type, string_type, void_type, "formSetText");
+
+       add_special_function2(item, integer_type, string_type, integer_type, "choiceAppendString");
+       add_special_function3(item, integer_type, string_type, image_type, integer_type, "choiceAppendStringImage");
+       add_special_function2(item, integer_type, integer_type, boolean_type, "choiceIsSelected");
+       add_special_function(item, integer_type, integer_type, "choiceGetSelectedIndex");
+
+       add_special_function(item, string_type, void_type, "setFormTitle");
+       add_special_function(item, void_type, void_type, "removeFormTitle");
+       add_special_function(item, void_type, string_type, "getFormTitle");
+
+       /* text box elements */
+       add_special_function4(item, string_type, string_type, integer_type, integer_type, void_type, "showTextBox");
+       add_special_function(item, void_type, string_type, "getTextBoxString");
+
+       /* alert elements */
+       add_special_function4(item, string_type, string_type, image_type, alert_type, void_type, "showAlert");
+       add_special_function(item, void_type, void_type, "playAlertSound");
+       add_special_function(item, void_type, alert_type, "ALERT_INFO");
+       add_special_function(item, void_type, alert_type, "ALERT_WARNING");
+       add_special_function(item, void_type, alert_type, "ALERT_ERROR");
+       add_special_function(item, void_type, alert_type, "ALERT_ALARM");
+       add_special_function(item, void_type, alert_type, "ALERT_CONFIRMATION");
+
+       /* menu functions */
+       add_special_function2(item, string_type, integer_type, void_type, "showMenu");
+       add_special_function(item, string_type, integer_type, "menuAppendString");
+       add_special_function2(item, string_type, image_type, integer_type, "menuAppendStringImage");
+       add_special_function(item, integer_type, boolean_type, "menuIsSelected");
+       add_special_function(item, void_type, integer_type, "menuGetSelectedIndex");
+
+
+       /* record store functions */
+       add_special_function(item, string_type, record_store_type, "openRecordStore");
+       add_special_function(item, record_store_type, void_type, "closeRecordStore");
+       add_special_function(item, string_type, void_type, "deleteRecordStore");
+       add_special_function2(item, record_store_type, integer_type, void_type, "deleteRecordStoreEntry");
+       add_special_function2(item, record_store_type, string_type, integer_type, "addRecordStoreEntry");
+       add_special_function2(item, record_store_type, integer_type, string_type, "readRecordStoreEntry");
+       add_special_function(item, record_store_type, integer_type, "getRecordStoreSize");
+       add_special_function3(item, record_store_type, string_type, integer_type, void_type, "modifyRecordStoreEntry");
+       add_special_function(item, record_store_type, integer_type, "getRecordStoreNextId");
+
+       /* http connectivity functions */
+       add_special_function2(item, http_type, string_type, boolean_type, "openHttp");
+       add_special_function(item, http_type, boolean_type, "isHttpOpen");
+       add_special_function(item, http_type, void_type, "closeHttp");
+       add_special_function3(item, http_type, string_type, string_type, void_type, "addHttpHeader");
+       add_special_function2(item, http_type, string_type, void_type, "setHttpMethod");
+       add_special_function(item, http_type, integer_type, "sendHttpMessage");
+       add_special_function2(item, http_type, string_type, string_type, "getHttpHeader");
+       add_special_function2(item, http_type, string_type, void_type, "addHttpBody");
+       add_special_function(item, http_type, string_type, "getHttpResponse");
+
+
+       /* resource-handling functions */
+       add_special_function(item, string_type, stream_type, "openResource");
+       add_special_function(item, stream_type, void_type, "closeResource");
+       add_special_function(item, stream_type, integer_type, "readByte");
+       add_special_function(item, stream_type, string_type, "readLine");
+       add_special_function(item, stream_type, boolean_type, "resourceAvailable");
+
+       /* player functions */
+       add_special_function2(item, string_type, string_type, boolean_type, "openPlayer");
+       add_special_function(item, void_type, boolean_type, "startPlayer");
+       add_special_function(item, void_type, void_type, "stopPlayer");
+       add_special_function(item, integer_type, boolean_type, "setPlayerCount");
+       add_special_function(item, void_type, integer_type, "getPlayerDuration");
+
+
+       /* SMS functions */
+       add_special_function2(item, string_type, string_type, boolean_type, "smsStartSend");
+       add_special_function(item, void_type, boolean_type, "smsIsSending");
+       add_special_function(item, void_type, boolean_type, "smsWasSuccessfull");
+
+}
+
+
+/*
+       Adds a single type into the block
+*/
+void add_std_type(block *item, enum en_type_class type_class, char *cstr_name)
+{
+       string *name;
+       identifier *descriptor;
+
+       name = string_from_cstr(cstr_name);
+       descriptor = identifier_create();
+       descriptor->identifier_class = type_name;
+       descriptor->defined_type = type_create();
+       descriptor->defined_type->type_class = type_class;
+       name_table_insert(item->names, name, descriptor);
+}
+
+
+/*
+       Add a standard function
+*/
+void add_std_function(block *item, char *cstr_name, type_list *params, type *return_type)
+{
+       string *name;
+       identifier *descriptor;
+
+       name = string_from_cstr(cstr_name);
+       descriptor = identifier_create();
+       descriptor->identifier_class = function_name;
+       descriptor->return_type = return_type;
+       descriptor->parameters = params;
+       descriptor->variables = NULL;
+       descriptor->standard_function = 1;
+       name_table_insert(item->names, name, descriptor);
+}
+
+
+/*
+       Add a standard procedure
+*/
+void add_std_procedure(block *item, char *cstr_name, type_list *params)
+{
+       string *name;
+       identifier *descriptor;
+
+       name = string_from_cstr(cstr_name);
+       descriptor = identifier_create();
+       descriptor->identifier_class = procedure_name;
+       descriptor->parameters = params;
+       descriptor->variables = NULL;
+       descriptor->standard_function = 1;
+       name_table_insert(item->names, name, descriptor);
+}
+
+
+/*
+       Creates the 'prefix' code, the code that is executed before the arguments are evaluated
+*/
+void create_std_function_prefix(bytecode *code, char *name)
+{
+       lowercase(name);
+
+       if ( (strcmp(name, "drawtext") == 0)
+         || (strcmp(name, "drawline") == 0)
+         || (strcmp(name, "setcolor") == 0)
+         || (strcmp(name, "drawellipse") == 0)
+         || (strcmp(name, "fillellipse") == 0)
+         || (strcmp(name, "drawrect") == 0)
+         || (strcmp(name, "fillrect") == 0)
+         || (strcmp(name, "drawarc") == 0)
+         || (strcmp(name, "plot") == 0)
+         || (strcmp(name, "getcolorred") == 0)
+         || (strcmp(name, "getcolorblue") == 0)
+         || (strcmp(name, "getcolorgreen") == 0)
+         || (strcmp(name, "drawroundrect") == 0)
+         || (strcmp(name, "fillroundrect") == 0)
+         || (strcmp(name, "setfont") == 0)
+         || (strcmp(name, "setdefaultfont") == 0)
+         || (strcmp(name, "drawimage") == 0)
+         || (strcmp(name, "getstringheight") == 0)
+         || (strcmp(name, "setclip") == 0)
+         )
+       {
+               int field_index = cp_add_fieldref("M", "G", "Ljavax/microedition/lcdui/Graphics;");
+
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, field_index);
+
+               return;
+       }
+
+       if ( (strcmp(name, "getwidth") == 0)
+         || (strcmp(name, "getheight") == 0)
+         )
+       {
+               int field_index = cp_add_fieldref("M", "I", "Ljavax/microedition/lcdui/Image;");
+
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, field_index);
+
+               return;
+       }
+
+       if ((strcmp(name, "getsecond") == 0)
+               || (strcmp(name, "getminute") == 0)
+               || (strcmp(name, "gethour") == 0)
+               || (strcmp(name, "getday") == 0)
+               || (strcmp(name, "getmonth") == 0)
+               || (strcmp(name, "getyear") == 0)
+               || (strcmp(name, "getweekday") == 0)
+               || (strcmp(name, "getyearday") == 0)
+               )
+       {
+               int method1, class1;
+               method1 = cp_add_methodref("java/util/Calendar", "getInstance", "()Ljava/util/Calendar;");
+               class1 = cp_add_class("java/util/Date");
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, method1);
+
+               bytecode_append(code, dup$);
+
+               bytecode_append(code, new$);
+               bytecode_append_short_int(code, class1);
+
+               bytecode_append(code, dup$);
+
+               return;
+       }
+
+       if (strcmp(name, "createcommand") == 0)
+       {
+               bytecode_append(code, new$);
+               bytecode_append_short_int(code, cp_add_class("javax/microedition/lcdui/Command"));
+               bytecode_append(code, dup$);
+
+               return;
+       }
+
+       if ((strcmp(name, "vibrate") == 0)
+               || (strcmp(name, "iscolordisplay") == 0)
+               || (strcmp(name, "getcolorsnum") == 0))
+       {
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "fw", "LFW;"));
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Display",
+                       "getDisplay", "(Ljavax/microedition/midlet/MIDlet;)Ljavax/microedition/lcdui/Display;"));
+               return;
+       }
+
+       if (strcmp(name, "showtextbox") == 0)
+       {
+               bytecode_append(code, new$);
+               bytecode_append_short_int(code, cp_add_class("javax/microedition/lcdui/TextBox"));
+               bytecode_append(code, dup$);
+               return;
+       }
+
+       if (strcmp(name, "showalert") == 0)
+       {
+               bytecode_append(code, new$);
+               bytecode_append_short_int(code, cp_add_class("javax/microedition/lcdui/Alert"));
+               bytecode_append(code, dup$);
+               return;
+       }
+
+       if (strcmp(name, "showmenu") == 0)
+       {
+               bytecode_append(code, new$);
+               bytecode_append_short_int(code, cp_add_class("javax/microedition/lcdui/List"));
+               bytecode_append(code, dup$);
+               return;
+       }
+
+       if ((strcmp(name, "menuappendstring") == 0)
+               || (strcmp(name, "menuappendstringimage") == 0)
+               || (strcmp(name, "menuisselected") == 0)
+               || (strcmp(name, "menugetselectedindex") == 0))
+       {
+
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "L", "Ljavax/microedition/lcdui/List;"));
+               return;
+       }
+
+       if (strcmp(name, "stringtoreal") == 0)
+       {
+               if (mathType != 1)
+               {
+                       bytecode_append(code, new$);
+                       bytecode_append_short_int(code, cp_add_class("Real"));
+                       bytecode_append(code, dup$);
+               }
+       }
+}
+
+
+/*
+       Create the bytecode for the standard function or procedure
+*/
+void create_std_function_code(bytecode *code, char *name)
+{
+       int count = 0;
+
+       lowercase(name);
+
+       switch(name[0])
+       {
+       case 'a': goto letter_a;
+       case 'b': goto letter_b;
+       case 'c': goto letter_c;
+       case 'd': goto letter_d;
+       case 'e': goto letter_e;
+       case 'f': goto letter_f;
+       case 'g': goto letter_g;
+       case 'h': goto letter_h;
+       case 'i': goto letter_i;
+       case 'j': goto letter_j;
+       case 'k': goto letter_k;
+       case 'l': goto letter_l;
+       case 'm': goto letter_m;
+       case 'n': goto letter_n;
+       case 'o': goto letter_o;
+       case 'p': goto letter_p;
+       case 'q': goto letter_q;
+       case 'r': goto letter_r;
+       case 's': goto letter_s;
+       case 't': goto letter_t;
+       case 'u': goto letter_u;
+       case 'v': goto letter_v;
+       case 'w': goto letter_w;
+       case 'x': goto letter_x;
+       case 'y': goto letter_y;
+       case 'z': goto letter_z;
+       }
+
+letter_a:
+       if (strcmp(name, "addhttpbody") == 0)
+       {
+               usesHttp = 1;
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("H", "o", "(Ljava/lang/String;)I"));
+               bytecode_append(code, pop$);
+               return;
+       }
+
+       if (strcmp(name, "addcommand") == 0)
+       {
+               if (canvasType == FULL_NOKIA)
+               {
+                       bytecode_append(code, getstatic$);
+                       bytecode_append_short_int(code, cp_add_fieldref("FW", "CD", "Ljavax/microedition/lcdui/Displayable;"));
+
+                       bytecode_append(code, dup$);
+                       bytecode_append(code, instanceof$);
+                       bytecode_append_short_int(code, cp_add_class("com/nokia/mid/ui/FullCanvas"));
+
+                       bytecode_append(code, ifne$);
+                       bytecode_append_short_int(code, 10);
+
+                       bytecode_append(code, swap$);
+                       bytecode_append(code, invokevirtual$);
+                       bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Displayable", "addCommand", "(Ljavax/microedition/lcdui/Command;)V"));
+                       bytecode_append(code, goto$);
+                       bytecode_append_short_int(code, 4);
+
+                       bytecode_append(code, pop2$);
+               }
+               else
+               {
+                       bytecode_append(code, getstatic$);
+                       bytecode_append_short_int(code, cp_add_fieldref("FW", "CD", "Ljavax/microedition/lcdui/Displayable;"));
+                       bytecode_append(code, swap$);
+                       bytecode_append(code, invokevirtual$);
+                       bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Displayable", "addCommand", "(Ljavax/microedition/lcdui/Command;)V"));
+               }
+
+               return;
+       }
+
+       if (strcmp(name, "addrecordstoreentry") == 0)
+       {
+               usesRecordStore = 1;
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code,
+                       cp_add_methodref("RS", "L", "(Ljavax/microedition/rms/RecordStore;Ljava/lang/String;)I"));
+               return;
+       }
+
+       if (strcmp(name, "assert") == 0)
+       {
+               char assert_text[128];
+               sprintf(assert_text, "Assertion failed at: %s:%d", source_file_name ,procedure_linenum);
+               bytecode_append(code, ifne$);
+               bytecode_append_short_int(code, 12);
+
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("java/lang/System", "out", "Ljava/io/PrintStream;"));
+               bytecode_append(code, ldc_w$);
+               bytecode_append_short_int(code, cp_add_string(assert_text));
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("java/io/PrintStream", "println", "(Ljava/lang/String;)V"));
+               return;
+       }
+
+       if (strcmp(name, "abs") == 0)
+       {
+               int method_index;
+
+               method_index = cp_add_methodref("java/lang/Math", "abs", "(I)I");
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+       if (strcmp(name, "atan") == 0)
+       {
+               usesFloat = 1;
+               if (mathType == 1)
+               {
+                       bytecode_append(code, invokestatic$);
+                       bytecode_append_short_int(code, cp_add_methodref("F", "atan", "(I)I"));
+               }
+               else
+               {
+                       bytecode_append(code, new$);
+                       bytecode_append_short_int(code, cp_add_class("Real"));
+                       bytecode_append(code, dup_x1$);
+                       bytecode_append(code, swap$);
+                       bytecode_append(code, invokespecial$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+                       bytecode_append(code, dup$);
+                       bytecode_append(code, invokevirtual$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "atan", "()V"));
+               }
+
+               return;
+       }
+
+       if (strcmp(name, "atan2") == 0)
+       {
+               usesFloat = 1;
+               if (mathType == 1)
+               {
+                       bytecode_append(code, invokestatic$);
+                       bytecode_append_short_int(code, cp_add_methodref("F", "atan2", "(II)I"));
+               }
+               else
+               {
+                       bytecode_append(code, new$);
+                       bytecode_append_short_int(code, cp_add_class("Real"));
+                       bytecode_append(code, dup_x1$);
+                       bytecode_append(code, swap$);
+                       bytecode_append(code, invokespecial$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+
+                       bytecode_append(code, swap$);
+
+                       bytecode_append(code, new$);
+                       bytecode_append_short_int(code, cp_add_class("Real"));
+                       bytecode_append(code, dup_x1$);
+                       bytecode_append(code, swap$);
+                       bytecode_append(code, invokespecial$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+
+                       bytecode_append(code, dup_x1$);
+                       bytecode_append(code, swap$);
+
+                       bytecode_append(code, invokevirtual$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "atan2", "(LReal;)V"));
+               }
+
+               return;
+       }
+
+       if (strcmp(name, "asin") == 0)
+       {
+               usesFloat = 1;
+               if (mathType == 1)
+               {
+                       bytecode_append(code, invokestatic$);
+                       bytecode_append_short_int(code, cp_add_methodref("F", "AS", "(I)I"));
+               }
+               else
+               {
+                       bytecode_append(code, new$);
+                       bytecode_append_short_int(code, cp_add_class("Real"));
+                       bytecode_append(code, dup_x1$);
+                       bytecode_append(code, swap$);
+                       bytecode_append(code, invokespecial$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+                       bytecode_append(code, dup$);
+                       bytecode_append(code, invokevirtual$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "asin", "()V"));
+               }
+
+               return;
+       }
+
+       if (strcmp(name, "acos") == 0)
+       {
+               usesFloat = 1;
+               if (mathType == 1)
+               {
+                       bytecode_append(code, invokestatic$);
+                       bytecode_append_short_int(code, cp_add_methodref("F", "AC", "(I)I"));
+               }
+               else
+               {
+                       bytecode_append(code, new$);
+                       bytecode_append_short_int(code, cp_add_class("Real"));
+                       bytecode_append(code, dup_x1$);
+                       bytecode_append(code, swap$);
+                       bytecode_append(code, invokespecial$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+                       bytecode_append(code, dup$);
+                       bytecode_append(code, invokevirtual$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "acos", "()V"));
+               }
+
+               return;
+       }
+
+       if (strcmp(name, "addhttpheader") == 0)
+       {
+               usesHttp = 1;
+               //usesRegisteredFeature = 1;
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("H", "L", "(Ljava/lang/String;Ljava/lang/String;)V"));
+               return;
+       }
+
+       if (strcmp(name, "alert_alarm") == 0)
+       {
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("javax/microedition/lcdui/AlertType",
+                                                                                                               "ALARM", "Ljavax/microedition/lcdui/AlertType;"));
+               return;
+       }
+
+       if (strcmp(name, "alert_confirmation") == 0)
+       {
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("javax/microedition/lcdui/AlertType",
+                                                                                                               "CONFIRMATION", "Ljavax/microedition/lcdui/AlertType;"));
+               return;
+       }
+
+       if (strcmp(name, "alert_error") == 0)
+       {
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("javax/microedition/lcdui/AlertType",
+                                                                                                               "ERROR", "Ljavax/microedition/lcdui/AlertType;"));
+               return;
+       }
+
+       if (strcmp(name, "alert_info") == 0)
+       {
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("javax/microedition/lcdui/AlertType",
+                                                                                                               "INFO", "Ljavax/microedition/lcdui/AlertType;"));
+               return;
+       }
+
+       if (strcmp(name, "alert_warning") == 0)
+       {
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("javax/microedition/lcdui/AlertType",
+                                                                                                               "WARNING", "Ljavax/microedition/lcdui/AlertType;"));
+               return;
+       }
+
+letter_b:
+letter_c:
+
+       if (strcmp(name, "closeresource") == 0)
+       {
+               usesSupport = 1;
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("S", "r", "(Ljava/io/InputStream;)V"));
+               return;
+       }
+
+       if (strcmp(name, "createcommand") == 0)
+       {
+               int method_index = cp_add_methodref("javax/microedition/lcdui/Command", "<init>", "(Ljava/lang/String;II)V");
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+       if (strcmp(name, "cos") == 0)
+       {
+               usesFloat = 1;
+               if (mathType == 1)
+               {
+                       bytecode_append(code, invokestatic$);
+                       bytecode_append_short_int(code, cp_add_methodref("F", "C", "(I)I"));
+               }
+               else
+               {
+                       bytecode_append(code, new$);
+                       bytecode_append_short_int(code, cp_add_class("Real"));
+                       bytecode_append(code, dup_x1$);
+                       bytecode_append(code, swap$);
+                       bytecode_append(code, invokespecial$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+                       bytecode_append(code, dup$);
+                       bytecode_append(code, invokevirtual$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "cos", "()V"));
+               }
+
+               return;
+       }
+
+       if (strcmp(name, "chr") == 0)
+       {
+               /* do nothing since we represent chars and integers internally in the same way */
+               return;
+       }
+
+       if (strcmp(name, "copy") == 0)
+       {
+               int method_index;
+
+               method_index = cp_add_methodref("java/lang/String", "substring", "(II)Ljava/lang/String;");
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+               return;
+       }
+
+       if (strcmp(name, "clearform") == 0)
+       {
+               bytecode_append(code, new$);
+               bytecode_append_short_int(code, cp_add_class("javax/microedition/lcdui/Form"));
+               bytecode_append(code, dup$);
+
+               bytecode_append(code, new$);
+               bytecode_append_short_int(code, cp_add_class("java/lang/String"));
+               bytecode_append(code, dup$);
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, cp_add_methodref("java/lang/String", "<init>", "()V"));
+
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Form", "<init>", "(Ljava/lang/String;)V"));
+
+               bytecode_append(code, dup$);
+               bytecode_append(code, putstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "F", "Ljavax/microedition/lcdui/Form;"));
+
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "fw", "LFW;"));
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Displayable", "setCommandListener", "(Ljavax/microedition/lcdui/CommandListener;)V"));
+
+               goto show_form;
+
+               return;
+       }
+
+       if(strcmp(name, "choiceappendstring") == 0)
+       {
+               usesForms = 1;
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("FS", "I", "(ILjava/lang/String;)I"));
+               return;
+       }
+
+       if(strcmp(name, "choiceappendstringimage") == 0)
+       {
+               usesForms = 1;
+               //usesRegisteredFeature = 1;
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("FS", "I", "(ILjava/lang/String;Ljavax/microedition/lcdui/Image;)I"));
+               return;
+       }
+
+       if(strcmp(name, "choiceisselected") == 0)
+       {
+               usesForms = 1;
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("FS", "L", "(II)I"));
+               return;
+       }
+
+       if (strcmp(name, ""))
+
+       if(strcmp(name, "choicegetselectedindex") == 0)
+       {
+               usesForms = 1;
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("FS", "L", "(I)I"));
+               return;
+       }
+
+       if (strcmp(name, "closerecordstore") == 0)
+       {
+               usesRecordStore = 1;
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("RS", "L", "(Ljavax/microedition/rms/RecordStore;)V"));
+               return;
+       }
+
+       if (strcmp(name, "closehttp") == 0)
+       {
+               usesHttp = 1;
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("H", "c", "()V"));
+               return;
+       }
+
+letter_d:
+       if (strcmp(name, "deleterecordstore") == 0)
+       {
+               usesRecordStore = 1;
+               //usesRegisteredFeature = 1;
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("RS", "L", "(Ljava/lang/String;)V"));
+               return;
+       }
+
+       if (strcmp(name, "deleterecordstoreentry") == 0)
+       {
+               usesRecordStore = 1;
+               //usesRegisteredFeature = 1;
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code,
+                       cp_add_methodref("RS", "L", "(Ljavax/microedition/rms/RecordStore;I)V"));
+               return;
+       }
+
+       if (strcmp(name, "debug") == 0)
+       {
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("java/lang/System", "out", "Ljava/io/PrintStream;"));
+               bytecode_append(code, swap$);
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("java/io/PrintStream", "println", "(Ljava/lang/String;)V"));
+               return;
+       }
+
+       if (strcmp(name, "delay") == 0)
+       {
+               int method_index;
+
+               method_index = cp_add_methodref("java/lang/Thread", "sleep", "(J)V");
+
+               bytecode_append(code, i2l$);
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+       if (strcmp(name, "drawtext") == 0)
+       {
+               int method_index;
+
+               method_index = cp_add_methodref("javax/microedition/lcdui/Graphics", "drawString", "(Ljava/lang/String;III)V");
+
+               bytecode_append(code, bipush$);
+               bytecode_append(code, 20);
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+       if (strcmp(name, "drawline") == 0)
+       {
+               int method_index;
+
+               method_index = cp_add_methodref("javax/microedition/lcdui/Graphics", "drawLine", "(IIII)V");
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+       if (strcmp(name, "drawellipse") == 0)
+       {
+               int method_index;
+
+               method_index = cp_add_methodref("javax/microedition/lcdui/Graphics", "drawArc", "(IIIIII)V");
+
+               bytecode_append(code, bipush$);
+               bytecode_append(code, 0);
+               bytecode_append(code, sipush$);
+               bytecode_append_short_int(code, 360);
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+       if (strcmp(name, "drawarc") == 0)
+       {
+               int method_index;
+
+               method_index = cp_add_methodref("javax/microedition/lcdui/Graphics", "drawArc", "(IIIIII)V");
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+       if (strcmp(name, "drawrect") == 0)
+       {
+               int method_index;
+
+               method_index = cp_add_methodref("javax/microedition/lcdui/Graphics", "drawRect", "(IIII)V");
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+       if (strcmp(name, "drawroundrect") == 0)
+       {
+               int method_index;
+
+               method_index = cp_add_methodref("javax/microedition/lcdui/Graphics", "drawRoundRect", "(IIIIII)V");
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+       if (strcmp(name, "drawimage") == 0)
+       {
+               int method_index = cp_add_methodref("javax/microedition/lcdui/Graphics", "drawImage", "(Ljavax/microedition/lcdui/Image;III)V");
+
+               bytecode_append(code, bipush$);
+               bytecode_append(code, 20);
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+               return;
+       }
+
+letter_e:
+       if (strcmp(name, "emptycommand") == 0)
+       {
+               bytecode_append(code, aconst_null$);
+               return;
+       }
+
+       if (strcmp(name, "exp") == 0)
+       {
+               usesFloat = 1;
+               if (mathType == 1)
+               {
+                       bytecode_append(code, invokestatic$);
+                       bytecode_append_short_int(code, cp_add_methodref("F", "e", "(I)I"));
+               }
+               else
+               {
+                       bytecode_append(code, new$);
+                       bytecode_append_short_int(code, cp_add_class("Real"));
+                       bytecode_append(code, dup_x1$);
+                       bytecode_append(code, swap$);
+                       bytecode_append(code, invokespecial$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+                       bytecode_append(code, dup$);
+                       bytecode_append(code, invokevirtual$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "exp", "()V"));
+               }
+
+               return;
+       }
+
+letter_f:
+       if (strcmp(name, "frac") == 0)
+       {
+               usesFloat = 1;
+               if (mathType == 1)
+               {
+                       bytecode_append(code, sipush$);
+                       bytecode_append_short_int(code, 0x0FFF);
+                       bytecode_append(code, iand$);
+               }
+               else
+               {
+                       bytecode_append(code, new$);
+                       bytecode_append_short_int(code, cp_add_class("Real"));
+                       bytecode_append(code, dup_x1$);
+                       bytecode_append(code, swap$);
+                       bytecode_append(code, invokespecial$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+                       bytecode_append(code, dup$);
+                       bytecode_append(code, invokevirtual$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "frac", "()V"));
+               }
+
+               return;
+       }
+
+       if (strcmp(name, "fillellipse") == 0)
+       {
+               int method_index;
+
+               method_index = cp_add_methodref("javax/microedition/lcdui/Graphics", "fillArc", "(IIIIII)V");
+
+               bytecode_append(code, bipush$);
+               bytecode_append(code, 0);
+               bytecode_append(code, sipush$);
+               bytecode_append_short_int(code, 360);
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+       if (strcmp(name, "fillrect") == 0)
+       {
+               int method_index;
+
+               method_index = cp_add_methodref("javax/microedition/lcdui/Graphics", "fillRect", "(IIII)V");
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+
+       if (strcmp(name, "fillroundrect") == 0)
+       {
+               int method_index;
+
+               method_index = cp_add_methodref("javax/microedition/lcdui/Graphics", "fillRoundRect", "(IIIIII)V");
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+       if (strcmp(name, "formaddstring") == 0)
+       {
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "F", "Ljavax/microedition/lcdui/Form;"));
+
+               bytecode_append(code, swap$);
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Form", "append", "(Ljava/lang/String;)I"));
+               return;
+       }
+
+       if (strcmp(name, "formaddimage") == 0)
+       {
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "F", "Ljavax/microedition/lcdui/Form;"));
+
+               bytecode_append(code, swap$);
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Form", "append", "(Ljavax/microedition/lcdui/Image;)I"));
+               return;
+       }
+
+       if (strcmp(name, "formadddatefield") == 0)
+       {
+               usesForms = 1;
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("FS", "dd", "(Ljava/lang/String;I)I"));
+               return;
+       }
+
+       if (strcmp(name, "formsetdate") == 0)
+       {
+               usesForms = 1;
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("FS", "dd", "(II)V"));
+               return;
+       }
+
+       if (strcmp(name, "formgetdate") == 0)
+       {
+               usesForms = 1;
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("FS", "dd", "(I)I"));
+               return;
+       }
+
+       if (strcmp(name, "formaddspace") == 0)
+       {
+               /* get Form */
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "F", "Ljavax/microedition/lcdui/Form;"));
+
+               /* new Spacer */
+               bytecode_append(code, new$);
+               bytecode_append_short_int(code, cp_add_class("javax/microedition/lcdui/Spacer"));
+
+               bytecode_append(code, dup$);
+
+               /* init spacer(10, 10)*/
+               bytecode_append(code, bipush$);
+               bytecode_append(code, 10);
+               bytecode_append(code, dup$);
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Spacer", "<init>", "(II)V"));
+
+               /* form.append(Spacer)*/
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Form", "append", "(Ljavax/microedition/lcdui/Item;)I"));
+               return;
+       }
+
+       if (strcmp(name, "formaddtextfield") == 0)
+       {
+               usesForms = 1;
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("FS", "Lj", "(Ljava/lang/String;Ljava/lang/String;II)I"));
+               return;
+       }
+
+       if (strcmp(name, "formaddgauge") == 0)
+       {
+               usesForms = 1;
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("FS", "Lj", "(Ljava/lang/String;III)I"));
+               return;
+       }
+
+       if (strcmp(name, "formremove") == 0)
+       {
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "F", "Ljavax/microedition/lcdui/Form;"));
+
+               bytecode_append(code, swap$);
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Form", "delete", "(I)V"));
+
+               return;
+       }
+
+       if (strcmp(name, "formaddchoice") == 0)
+       {
+               usesForms = 1;
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("FS", "Lj", "(Ljava/lang/String;I)I"));
+               return;
+       }
+
+       if (strcmp(name, "formgetvalue") == 0)
+       {
+               usesForms = 1;
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("FS", "Lja", "(I)I"));
+               return;
+       }
+
+       if (strcmp(name, "formsetvalue") == 0)
+       {
+               usesForms = 1;
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("FS", "Lja", "(II)V"));
+               return;
+       }
+
+       if (strcmp(name, "formgettext") == 0)
+       {
+               usesForms = 1;
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("FS", "ja", "(I)Ljava/lang/String;"));
+               return;
+       }
+
+       if (strcmp(name, "formsettext") == 0)
+       {
+               usesForms = 1;
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("FS", "ja", "(ILjava/lang/String;)V"));
+               return;
+       }
+
+letter_g:
+       if (strcmp(name, "getformtitle") == 0)
+       {
+               usesForms = 1;
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("FS", "gft", "()Ljava/lang/String;"));
+               return;
+       }
+
+       if (strcmp(name, "getrecordstorenextid") == 0)
+       {
+               usesRecordStore = 1;
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code,
+                       cp_add_methodref("RS", "Lja", "(Ljavax/microedition/rms/RecordStore;)I"));
+               return;
+       }
+
+       if (strcmp(name, "getplayerduration") == 0)
+       {
+               usesPlayer = 1;
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("P", "c", "()I"));
+               return;
+       }
+
+       if (strcmp(name, "getchar") == 0)
+       {
+               usesSupport = 1;
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("S", "gc", "(Ljava/lang/String;I)I"));
+               return;
+       }
+
+       if (strcmp(name, "getrecordstoresize") == 0)
+       {
+               usesRecordStore = 1;
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("RS", "j", "(Ljavax/microedition/rms/RecordStore;)I"));
+               return;
+       }
+
+       if (strcmp(name, "getclickedcommand") == 0)
+       {
+               /* return LC */
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "LC", "Ljavax/microedition/lcdui/Command;"));
+
+               /* set LC = null */
+               bytecode_append(code, aconst_null$);
+               bytecode_append(code, putstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "LC", "Ljavax/microedition/lcdui/Command;"));
+               return;
+       }
+
+       if (strcmp(name, "gettextboxstring") == 0)
+       {
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "TB", "Ljavax/microedition/lcdui/TextBox;"));
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/TextBox", "getString", "()Ljava/lang/String;"));
+               return;
+       }
+
+       if (strcmp(name, "getrelativetimems") == 0)
+       {
+               int method_index;
+
+               method_index = cp_add_methodref("java/lang/System", "currentTimeMillis", "()J");
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, method_index);
+               bytecode_append(code, l2i$);
+               return;
+       }
+
+       if (strcmp(name, "getcurrenttime") == 0)
+       {
+               int method_index;
+
+               method_index = cp_add_methodref("java/lang/System", "currentTimeMillis", "()J");
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, method_index);
+               bytecode_append(code, sipush$);
+               bytecode_append_short_int(code, 1000);
+               bytecode_append(code, i2l$);
+               bytecode_append(code, ldiv$);
+               bytecode_append(code, l2i$);
+               return;
+       }
+
+       if (strcmp(name, "getday") == 0)
+       {
+               int method1, method2, method3, method4;
+               method1 = cp_add_methodref("java/util/Calendar", "getInstance", "()Ljava/util/Calendar;");
+               method2 = cp_add_methodref("java/util/Calendar", "setTime", "(Ljava/util/Date;)V");
+               method3 = cp_add_methodref("java/util/Calendar", "get", "(I)I");
+               method4 = cp_add_methodref("java/util/Date", "<init>", "(J)V");
+
+               /* time as int-seconds traslate into millis-long */
+               bytecode_append(code, i2l$);
+               bytecode_append(code, sipush$);
+               bytecode_append_short_int(code, 1000);
+               bytecode_append(code, i2l$);
+               bytecode_append(code, lmul$);
+
+               /* the stack is now: ..., Calendar, Calendar, Date, Date, Millis */
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, method4);
+
+               /* stack is now Calendar, Calendar, Date*/
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method2);
+
+               bytecode_append(code, bipush$);
+               bytecode_append(code, 5);
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method3);
+
+               return;
+       }
+
+       if (strcmp(name, "getweekday") == 0)
+       {
+               int method1, method2, method3, method4;
+               method1 = cp_add_methodref("java/util/Calendar", "getInstance", "()Ljava/util/Calendar;");
+               method2 = cp_add_methodref("java/util/Calendar", "setTime", "(Ljava/util/Date;)V");
+               method3 = cp_add_methodref("java/util/Calendar", "get", "(I)I");
+               method4 = cp_add_methodref("java/util/Date", "<init>", "(J)V");
+
+               /* time as int-seconds traslate into millis-long */
+               bytecode_append(code, i2l$);
+               bytecode_append(code, sipush$);
+               bytecode_append_short_int(code, 1000);
+               bytecode_append(code, i2l$);
+               bytecode_append(code, lmul$);
+
+               /* the stack is now: ..., Calendar, Calendar, Date, Date, Millis */
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, method4);
+
+               /* stack is now Calendar, Calendar, Date*/
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method2);
+
+               bytecode_append(code, bipush$);
+               bytecode_append(code, 7);
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method3);
+
+               return;
+       }
+
+       if (strcmp(name, "getyearday") == 0)
+       {
+               int method1, method2, method3, method4;
+               method1 = cp_add_methodref("java/util/Calendar", "getInstance", "()Ljava/util/Calendar;");
+               method2 = cp_add_methodref("java/util/Calendar", "setTime", "(Ljava/util/Date;)V");
+               method3 = cp_add_methodref("java/util/Calendar", "get", "(I)I");
+               method4 = cp_add_methodref("java/util/Date", "<init>", "(J)V");
+
+               /* time as int-seconds traslate into millis-long */
+               bytecode_append(code, i2l$);
+               bytecode_append(code, sipush$);
+               bytecode_append_short_int(code, 1000);
+               bytecode_append(code, i2l$);
+               bytecode_append(code, lmul$);
+
+               /* the stack is now: ..., Calendar, Calendar, Date, Date, Millis */
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, method4);
+
+               /* stack is now Calendar, Calendar, Date*/
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method2);
+
+               bytecode_append(code, bipush$);
+               bytecode_append(code, 6);
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method3);
+
+               return;
+       }
+
+       if (strcmp(name, "getmonth") == 0)
+       {
+               int method1, method2, method3, method4;
+               method1 = cp_add_methodref("java/util/Calendar", "getInstance", "()Ljava/util/Calendar;");
+               method2 = cp_add_methodref("java/util/Calendar", "setTime", "(Ljava/util/Date;)V");
+               method3 = cp_add_methodref("java/util/Calendar", "get", "(I)I");
+               method4 = cp_add_methodref("java/util/Date", "<init>", "(J)V");
+
+               /* time as int-seconds traslate into millis-long */
+               bytecode_append(code, i2l$);
+               bytecode_append(code, sipush$);
+               bytecode_append_short_int(code, 1000);
+               bytecode_append(code, i2l$);
+               bytecode_append(code, lmul$);
+
+               /* the stack is now: ..., Calendar, Calendar, Date, Date, Millis */
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, method4);
+
+               /* stack is now Calendar, Calendar, Date*/
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method2);
+
+               bytecode_append(code, bipush$);
+               bytecode_append(code, 2);
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method3);
+
+               bytecode_append(code, iconst_0$);
+               bytecode_append(code, iadd$);
+
+               return;
+       }
+
+       if (strcmp(name, "getyear") == 0)
+       {
+               int method1, method2, method3, method4;
+               method1 = cp_add_methodref("java/util/Calendar", "getInstance", "()Ljava/util/Calendar;");
+               method2 = cp_add_methodref("java/util/Calendar", "setTime", "(Ljava/util/Date;)V");
+               method3 = cp_add_methodref("java/util/Calendar", "get", "(I)I");
+               method4 = cp_add_methodref("java/util/Date", "<init>", "(J)V");
+
+               /* time as int-seconds traslate into millis-long */
+               bytecode_append(code, i2l$);
+               bytecode_append(code, sipush$);
+               bytecode_append_short_int(code, 1000);
+               bytecode_append(code, i2l$);
+               bytecode_append(code, lmul$);
+
+               /* the stack is now: ..., Calendar, Calendar, Date, Date, Millis */
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, method4);
+
+               /* stack is now Calendar, Calendar, Date*/
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method2);
+
+               bytecode_append(code, bipush$);
+               bytecode_append(code, 1);
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method3);
+
+               return;
+       }
+
+       if (strcmp(name, "getsecond") == 0)
+       {
+               int method1, method2, method3, method4;
+               method1 = cp_add_methodref("java/util/Calendar", "getInstance", "()Ljava/util/Calendar;");
+               method2 = cp_add_methodref("java/util/Calendar", "setTime", "(Ljava/util/Date;)V");
+               method3 = cp_add_methodref("java/util/Calendar", "get", "(I)I");
+               method4 = cp_add_methodref("java/util/Date", "<init>", "(J)V");
+
+               /* time as int-seconds traslate into millis-long */
+               bytecode_append(code, i2l$);
+               bytecode_append(code, sipush$);
+               bytecode_append_short_int(code, 1000);
+               bytecode_append(code, i2l$);
+               bytecode_append(code, lmul$);
+
+               /* the stack is now: ..., Calendar, Calendar, Date, Date, Millis */
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, method4);
+
+               /* stack is now Calendar, Calendar, Date*/
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method2);
+
+               bytecode_append(code, bipush$);
+               bytecode_append(code, 13);
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method3);
+
+               return;
+       }
+
+       if (strcmp(name, "getminute") == 0)
+       {
+               int method1, method2, method3, method4;
+               method1 = cp_add_methodref("java/util/Calendar", "getInstance", "()Ljava/util/Calendar;");
+               method2 = cp_add_methodref("java/util/Calendar", "setTime", "(Ljava/util/Date;)V");
+               method3 = cp_add_methodref("java/util/Calendar", "get", "(I)I");
+               method4 = cp_add_methodref("java/util/Date", "<init>", "(J)V");
+
+               /* time as int-seconds traslate into millis-long */
+               bytecode_append(code, i2l$);
+               bytecode_append(code, sipush$);
+               bytecode_append_short_int(code, 1000);
+               bytecode_append(code, i2l$);
+               bytecode_append(code, lmul$);
+
+               /* the stack is now: ..., Calendar, Calendar, Date, Date, Millis */
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, method4);
+
+               /* stack is now Calendar, Calendar, Date*/
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method2);
+
+               bytecode_append(code, bipush$);
+               bytecode_append(code, 12);
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method3);
+
+               return;
+       }
+
+       if (strcmp(name, "gethour") == 0)
+       {
+               int method1, method2, method3, method4;
+               method1 = cp_add_methodref("java/util/Calendar", "getInstance", "()Ljava/util/Calendar;");
+               method2 = cp_add_methodref("java/util/Calendar", "setTime", "(Ljava/util/Date;)V");
+               method3 = cp_add_methodref("java/util/Calendar", "get", "(I)I");
+               method4 = cp_add_methodref("java/util/Date", "<init>", "(J)V");
+
+               /* time as int-seconds traslate into millis-long */
+               bytecode_append(code, i2l$);
+               bytecode_append(code, sipush$);
+               bytecode_append_short_int(code, 1000);
+               bytecode_append(code, i2l$);
+               bytecode_append(code, lmul$);
+
+               /* the stack is now: ..., Calendar, Calendar, Date, Date, Millis */
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, method4);
+
+               /* stack is now Calendar, Calendar, Date*/
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method2);
+
+               bytecode_append(code, bipush$);
+               bytecode_append(code, 11);
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method3);
+
+               return;
+       }
+
+       if (strcmp(name, "getkeypressed") == 0)
+       {
+               int field_index = cp_add_fieldref("M", "KP", "I");
+
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, field_index);
+
+               return;
+       }
+
+       if (strcmp(name, "getkeyclicked") == 0)
+       {
+               int field_index = cp_add_fieldref("M", "KC", "I");
+
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, field_index);
+               bytecode_append(code, iconst_0$);
+               bytecode_append(code, putstatic$);
+               bytecode_append_short_int(code, field_index);
+
+               return;
+       }
+
+       if (strcmp(name, "getcolorred") == 0)
+       {
+               int method_index;
+
+               method_index = cp_add_methodref("javax/microedition/lcdui/Graphics", "getRedComponent", "()I");
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+       if (strcmp(name, "getcolorgreen") == 0)
+       {
+               int method_index;
+
+               method_index = cp_add_methodref("javax/microedition/lcdui/Graphics", "getGreenComponent", "()I");
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+       if (strcmp(name, "getcolorblue") == 0)
+       {
+               int method_index;
+
+               method_index = cp_add_methodref("javax/microedition/lcdui/Graphics", "getBlueComponent", "()I");
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+       if (strcmp(name, "getwidth") == 0)
+       {
+               int method_index;
+
+               method_index = cp_add_methodref("javax/microedition/lcdui/Image", "getWidth", "()I");
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+       if (strcmp(name, "getheight") == 0)
+       {
+               int method_index;
+
+               method_index = cp_add_methodref("javax/microedition/lcdui/Image", "getHeight", "()I");
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+       if (strcmp(name, "getimagewidth") == 0)
+       {
+               int method_index = cp_add_methodref("javax/microedition/lcdui/Image", "getWidth", "()I");
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+               return;
+       }
+
+       if (strcmp(name, "getimageheight") == 0)
+       {
+               int method_index = cp_add_methodref("javax/microedition/lcdui/Image", "getHeight", "()I");
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+               return;
+       }
+
+       if (strcmp(name, "getstringheight") == 0)
+       {
+               int method_index;
+               method_index = cp_add_methodref("javax/microedition/lcdui/Graphics", "getFont", "()Ljavax/microedition/lcdui/Font;");
+               bytecode_append(code, pop$);
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+               method_index = cp_add_methodref("javax/microedition/lcdui/Font", "getHeight", "()I");
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+               return;
+       }
+
+       if (strcmp(name, "getstringwidth") == 0)
+       {
+               int method_index;
+               int field_index = cp_add_fieldref("M", "G", "Ljavax/microedition/lcdui/Graphics;");
+
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, field_index);
+
+               method_index = cp_add_methodref("javax/microedition/lcdui/Graphics", "getFont", "()Ljavax/microedition/lcdui/Font;");
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               bytecode_append(code, swap$);
+               method_index = cp_add_methodref("javax/microedition/lcdui/Font", "stringWidth", "(Ljava/lang/String;)I");
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+       if (strcmp(name, "getproperty") == 0)
+       {
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("java/lang/System", "getProperty", "(Ljava/lang/String;)Ljava/lang/String;"));
+               bytecode_append(code, dup$);
+               bytecode_append(code, ifnonnull$);
+               bytecode_append_short_int(code, 11);
+
+               /* if the returned string is null, create an empty string */
+               bytecode_append(code, pop$);
+               bytecode_append(code, new$);
+               bytecode_append_short_int(code, cp_add_class("java/lang/String"));
+               bytecode_append(code, dup$);
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, cp_add_methodref("java/lang/String", "<init>", "()V"));
+               return;
+       }
+
+       if (strcmp(name, "getcolorsnum") == 0)
+       {
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Display", "numColors", "()I"));
+               return;
+       }
+
+       if (strcmp(name, "gethttpheader") == 0)
+       {
+               usesHttp = 1;
+               //usesRegisteredFeature = 1;
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("H", "i", "(Ljava/lang/String;)Ljava/lang/String;"));
+               return;
+       }
+
+       if (strcmp(name, "gethttpresponse") == 0)
+       {
+               usesHttp = 1;
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("H", "j", "()Ljava/lang/String;"));
+               return;
+       }
+
+letter_h:
+       if (strcmp(name, "halt") == 0)
+       {
+               int field_index;
+               int method_index;
+
+               field_index = cp_add_fieldref("FW", "fw", "LFW;");
+               method_index = cp_add_methodref("FW", "destroyApp", "(Z)V");
+
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, field_index);
+               bytecode_append(code, iconst_1$);
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("java/lang/Thread", "currentThread", "()Ljava/lang/Thread;"));
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("java/lang/Thread", "join", "()V"));
+
+               bytecode_append(code, sipush$);
+               bytecode_append_short_int(code, 1000);
+               bytecode_append(code, i2l$);
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("java/lang/Thread", "sleep", "(J)V"));
+
+               return;
+       }
+
+letter_i:
+       if (strcmp(name, "imagefromimage") == 0)
+       {
+               usesSupport = 1;
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("S", "ii", "(Ljavax/microedition/lcdui/Image;IIII)Ljavax/microedition/lcdui/Image;"));
+               return;
+       }
+
+       if (strcmp(name, "imagefromcanvas") == 0)
+       {
+               usesSupport = 1;
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("S", "ii", "(IIII)Ljavax/microedition/lcdui/Image;"));
+               return;
+       }
+
+       if (strcmp(name, "imagefrombuffer") == 0)
+       {
+               usesSupport = 1;
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("S", "ii", "(Ljava/lang/String;I)Ljavax/microedition/lcdui/Image;"));
+               return;
+       }
+
+       if (strcmp(name, "integertostring") == 0)
+       {
+               bytecode_append(code, new$);
+               bytecode_append_short_int(code, cp_add_class("java/lang/StringBuffer"));
+               bytecode_append(code, dup$);
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, cp_add_methodref("java/lang/StringBuffer", "<init>", "()V"));
+
+               bytecode_append(code, swap$);
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("java/lang/StringBuffer", "append", "(I)Ljava/lang/StringBuffer;"));
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("java/lang/StringBuffer", "toString", "()Ljava/lang/String;"));
+               return;
+       }
+
+       if (strcmp(name, "ismidletpaused") == 0)
+       {
+               int field_index = cp_add_fieldref("FW", "MP", "I");
+
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, field_index);
+
+               return;
+       }
+
+       if (strcmp(name, "ishttpopen") == 0)
+       {
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("H", "L", "()I"));
+               return;
+       }
+
+       if (strcmp(name, "iscolordisplay") == 0)
+       {
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Display", "isColor", "()Z"));
+
+               bytecode_append(code, ifeq$);
+               bytecode_append_short_int(code, 7);
+
+               bytecode_append(code, iconst_m1$);
+               bytecode_append(code, goto$);
+               bytecode_append_short_int(code, 4);
+
+               bytecode_append(code, iconst_0$);
+
+               return;
+       }
+
+letter_j:
+letter_k:
+       if (strcmp(name, "keytoaction") == 0)
+       {
+               int field_index = cp_add_fieldref("M", "T", "LM;");
+
+               /* check if the argument is zero, goto (1)*/
+               bytecode_append(code, dup$);
+               bytecode_append(code, ifeq$);
+               bytecode_append_short_int(code, 13);
+
+               /* otherwise call the getGameAction*/
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, field_index);
+               bytecode_append(code, swap$);
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("M", "getGameAction", "(I)I"));
+
+               /* goto (2) */
+               bytecode_append(code, goto$);
+               bytecode_append_short_int(code, 5);
+
+               /* (1): pop the operands, push 0 to the stack */
+               bytecode_append(code, pop$);
+               bytecode_append(code, iconst_0$);
+
+               /* (2): continue */
+
+               return;
+       }
+
+letter_l:
+       if (strcmp(name, "log") == 0)
+       {
+               usesFloat = 1;
+               if (mathType == 1)
+               {
+                       bytecode_append(code, invokestatic$);
+                       bytecode_append_short_int(code, cp_add_methodref("F", "log", "(I)I"));
+               }
+               else
+               {
+                       bytecode_append(code, new$);
+                       bytecode_append_short_int(code, cp_add_class("Real"));
+                       bytecode_append(code, dup_x1$);
+                       bytecode_append(code, swap$);
+                       bytecode_append(code, invokespecial$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+                       bytecode_append(code, dup$);
+                       bytecode_append(code, invokevirtual$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "ln", "()V"));
+               }
+
+               return;
+       }
+
+       if (strcmp(name, "log10") == 0)
+       {
+               usesFloat = 1;
+               if (mathType == 1)
+               {
+                       bytecode_append(code, invokestatic$);
+                       bytecode_append_short_int(code, cp_add_methodref("F", "log10", "(I)I"));
+               }
+               else
+               {
+                       bytecode_append(code, new$);
+                       bytecode_append_short_int(code, cp_add_class("Real"));
+                       bytecode_append(code, dup_x1$);
+                       bytecode_append(code, swap$);
+                       bytecode_append(code, invokespecial$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+                       bytecode_append(code, dup$);
+                       bytecode_append(code, invokevirtual$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "log10", "()V"));
+               }
+
+               return;
+       }
+
+       if (strcmp(name, "length") == 0)
+       {
+               int method_index = cp_add_methodref("java/lang/String", "length", "()I");
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+               return;
+       }
+
+       if (strcmp(name, "locase") == 0)
+       {
+               int init_index;
+               int class_index;
+               int method_index;
+
+               class_index = cp_add_class("java/lang/String");
+               init_index = cp_add_methodref("java/lang/String", "<init>", "(Ljava/lang/String;)V");
+               method_index = cp_add_methodref("java/lang/String", "toLowerCase", "()Ljava/lang/String;");
+
+               bytecode_append(code, new$);
+               bytecode_append_short_int(code, class_index);
+               bytecode_append(code, dup_x1$);
+               bytecode_append(code, swap$);
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, init_index);
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+               return;
+       }
+
+       if (strcmp(name, "loadimage") == 0)
+       {
+               int method_index = cp_add_methodref("javax/microedition/lcdui/Image", "createImage", "(Ljava/lang/String;)Ljavax/microedition/lcdui/Image;");
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, method_index);
+               return;
+       }
+
+letter_m:
+       if (strcmp(name, "modifyrecordstoreentry") == 0)
+       {
+               usesRecordStore = 1;
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code,
+                       cp_add_methodref("RS", "L", "(Ljavax/microedition/rms/RecordStore;Ljava/lang/String;I)V"));
+               return;
+       }
+
+
+       if (strcmp(name, "menuappendstring") == 0)
+       {
+               bytecode_append(code, aconst_null$);
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/List",
+                                                                                                                "append",
+                                                                                                                "(Ljava/lang/String;Ljavax/microedition/lcdui/Image;)I"));
+               return;
+       }
+
+       if (strcmp(name, "menuappendstringimage") == 0)
+       {
+               //usesRegisteredFeature = 1;
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/List",
+                                                                                                                "append",
+                                                                                                                "(Ljava/lang/String;Ljavax/microedition/lcdui/Image;)I"));
+               return;
+       }
+
+       if (strcmp(name, "menuisselected") == 0)
+       {
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/List",
+                                                                                                                "isSelected",
+                                                                                                                "(I)Z"));
+
+               bytecode_append(code, ifeq$);
+               bytecode_append_short_int(code, 7);
+               bytecode_append(code, iconst_m1$);
+               bytecode_append(code, goto$);
+               bytecode_append_short_int(code, 4);
+               bytecode_append(code, iconst_0$);
+
+               return;
+       }
+
+       if (strcmp(name, "menugetselectedindex") == 0)
+       {
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/List",
+                                                                                                                "getSelectedIndex",
+                                                                                                                "()I"));
+               return;
+       }
+
+
+
+letter_n:
+letter_o:
+
+       if (strcmp(name, "openplayer") == 0)
+       {
+               usesPlayer = 1;
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("P", "a", "(Ljava/lang/String;Ljava/lang/String;)I"));
+               return;
+       }
+
+       if (strcmp(name, "openresource") == 0)
+       {
+               usesSupport = 1;
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("S", "r", "(Ljava/lang/String;)Ljava/io/InputStream;"));
+               return;
+       }
+
+       if (strcmp(name, "ord") == 0)
+       {
+               /* do nothing, opposite of chr */
+               return;
+       }
+
+       if (strcmp(name, "openhttp") == 0)
+       {
+               usesHttp = 1;
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("H", "L", "(Ljava/lang/String;)I"));
+               return;
+       }
+
+       if (strcmp(name, "odd") == 0)
+       {
+               /* just leave the last bit: if it is zero, the number is even and the 0 (false)
+                  will be on the stack */
+               bytecode_append(code, iconst_1$);
+               bytecode_append(code, iand$);
+               bytecode_append(code, iconst_m1$);
+               bytecode_append(code, imul$);
+
+               return;
+       }
+
+       if (strcmp(name, "openrecordstore") == 0)
+       {
+               usesRecordStore = 1;
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("RS", "j", "(Ljava/lang/String;)Ljavax/microedition/rms/RecordStore;"));
+               return;
+       }
+
+letter_p:
+       if (strcmp(name, "playtone") == 0)
+       {
+               int method_index = cp_add_methodref("javax/microedition/media/Manager", "playTone", "(III)V");
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+       if (strcmp(name, "playalertsound") == 0)
+       {
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "A", "Ljavax/microedition/lcdui/Alert;"));
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Alert", "getType", "()Ljavax/microedition/lcdui/AlertType;"));
+
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "fw", "LFW;"));
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Display", "getDisplay", "(Ljavax/microedition/midlet/MIDlet;)Ljavax/microedition/lcdui/Display;"));
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref(
+                       "javax/microedition/lcdui/AlertType",
+                       "playSound",
+                       "(Ljavax/microedition/lcdui/Display;)Z"));
+
+               bytecode_append(code, pop$);
+               return;
+       }
+
+       if (strcmp(name, "pow") == 0)
+       {
+               usesFloat = 1;
+               if (mathType == 1)
+               {
+                       bytecode_append(code, invokestatic$);
+                       bytecode_append_short_int(code, cp_add_methodref("F", "p", "(II)I"));
+               }
+               else
+               {
+                       bytecode_append(code, new$);
+                       bytecode_append_short_int(code, cp_add_class("Real"));
+                       bytecode_append(code, dup_x1$);
+                       bytecode_append(code, swap$);
+                       bytecode_append(code, invokespecial$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+
+                       bytecode_append(code, swap$);
+
+                       bytecode_append(code, new$);
+                       bytecode_append_short_int(code, cp_add_class("Real"));
+                       bytecode_append(code, dup_x1$);
+                       bytecode_append(code, swap$);
+                       bytecode_append(code, invokespecial$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+
+                       bytecode_append(code, dup_x1$);
+                       bytecode_append(code, swap$);
+
+                       bytecode_append(code, invokevirtual$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "pow", "(LReal;)V"));
+               }
+
+               return;
+       }
+
+       if (strcmp(name, "pos") == 0)
+       {
+               int method_index;
+
+               method_index = cp_add_methodref("java/lang/String", "indexOf", "(Ljava/lang/String;)I");
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+               return;
+       }
+
+       if (strcmp(name, "plot") == 0)
+       {
+               int method_index;
+
+               method_index = cp_add_methodref("javax/microedition/lcdui/Graphics", "fillRect", "(IIII)V");
+
+               bytecode_append(code, iconst_1$);
+               bytecode_append(code, dup$);
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+letter_q:
+letter_r:
+       if (strcmp(name, "removeformtitle") == 0)
+       {
+               /* get Form */
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "F", "Ljavax/microedition/lcdui/Form;"));
+
+               /* set the form's title to null */
+               bytecode_append(code, aconst_null$);
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Form", "setTitle", "(Ljava/lang/String;)V"));
+
+               return;
+       }
+
+       if (strcmp(name, "resourceavailable") == 0)
+       {
+               bytecode_append(code, aconst_null$);
+               bytecode_append(code, if_acmpeq$);
+               bytecode_append_short_int(code, 7);
+
+               bytecode_append(code, iconst_m1$);
+               bytecode_append(code, goto$);
+               bytecode_append_short_int(code, 4);
+
+               bytecode_append(code, iconst_0$);
+               return;
+       }
+
+       if (strcmp(name, "readbyte") == 0)
+       {
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("S", "rb", "(Ljava/io/InputStream;)I"));
+               return;
+       }
+
+       if (strcmp(name, "readline") == 0)
+       {
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("S", "nl", "(Ljava/io/InputStream;)Ljava/lang/String;"));
+               return;
+       }
+
+       if (strcmp(name, "readrecordstoreentry") == 0)
+       {
+               usesRecordStore = 1;
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("RS", "j", "(Ljavax/microedition/rms/RecordStore;I)Ljava/lang/String;"));
+               return;
+       }
+
+       if (strcmp(name, "round") == 0)
+       {
+               int method_index;
+
+               method_index = cp_add_methodref("java/lang/Math", "round", "(F)I");
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+       if (strcmp(name, "rabs") == 0)
+       {
+               usesFloat = 1;
+               if (mathType == 1)
+               {
+                       bytecode_append(code, invokestatic$);
+                       bytecode_append_short_int(code, cp_add_methodref("F", "A", "(I)I"));
+               }
+               else
+               {
+                       bytecode_append(code, new$);
+                       bytecode_append_short_int(code, cp_add_class("Real"));
+                       bytecode_append(code, dup_x1$);
+                       bytecode_append(code, swap$);
+                       bytecode_append(code, invokespecial$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+                       bytecode_append(code, dup$);
+                       bytecode_append(code, invokevirtual$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "abs", "()V"));
+               }
+
+               return;
+       }
+
+       if (strcmp(name, "randomize") == 0)
+       {
+               /* re-initialize the random number generator */
+               int random_field_index;
+               int random_class_index;
+               int random_method_index;
+
+               random_field_index = cp_add_fieldref("M", "RNG", "Ljava/util/Random;");
+               random_class_index = cp_add_class("java/util/Random");
+               random_method_index = cp_add_methodref("java/util/Random", "<init>", "()V");
+
+               bytecode_append(code, new$);
+               bytecode_append_short_int(code, random_class_index);
+
+               bytecode_append(code, dup$);
+
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, random_method_index);
+
+               bytecode_append(code, putstatic$);
+               bytecode_append_short_int(code, random_field_index);
+               return;
+       }
+
+       if (strcmp(name, "random") == 0)
+       {
+               int rng_index;
+               int method_index;
+
+               rng_index = cp_add_fieldref("M", "RNG", "Ljava/util/Random;");
+               method_index = cp_add_methodref("java/util/Random", "nextInt", "()I");
+
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, rng_index);
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               // do abs
+               bytecode_append(code, iconst_m1$);
+               bytecode_append(code, iconst_1$);
+               bytecode_append(code, iushr$);
+               bytecode_append(code, iand$);
+
+               bytecode_append(code, swap$);
+               bytecode_append(code, irem$);
+
+               return;
+       }
+
+       if (strcmp(name, "removecommand") == 0)
+       {
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "CD", "Ljavax/microedition/lcdui/Displayable;"));
+               bytecode_append(code, swap$);
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Displayable", "removeCommand", "(Ljavax/microedition/lcdui/Command;)V"));
+               return;
+       }
+
+
+       if (strcmp(name, "repaint") == 0)
+       {
+               int method_index;
+               int field_index;
+
+               method_index = cp_add_methodref("M", "repaint", "()V");
+               field_index = cp_add_fieldref("M", "T", "LM;");
+
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, field_index);
+
+               bytecode_append(code, dup$);
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               method_index = cp_add_methodref("M", "serviceRepaints", "()V");
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+letter_s:
+       if (strcmp(name, "setformtitle") == 0)
+       {
+               /* get Form */
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "F", "Ljavax/microedition/lcdui/Form;"));
+
+               /* set the form's title */
+               bytecode_append(code, swap$);
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Form", "setTitle", "(Ljava/lang/String;)V"));
+
+               return;
+       }
+
+       if (strcmp(name, "setclip") == 0)
+       {
+               int method_index;
+
+               method_index = cp_add_methodref("javax/microedition/lcdui/Graphics", "setClip", "(IIII)V");
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+       if (strcmp("smsstartsend", name) == 0)
+       {
+               usesSMS = 1;
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("SM", "send", "(Ljava/lang/String;Ljava/lang/String;)I"));
+               return;
+       }
+
+       if (strcmp("smsissending", name) == 0)
+       {
+               usesSMS = 1;
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("SM", "IS", "()I"));
+               return;
+       }
+
+       if (strcmp("smswassuccessfull", name) == 0)
+       {
+               usesSMS = 1;
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("SM", "GS", "()I"));
+               return;
+       }
+
+       if (strcmp("startplayer", name) == 0)
+       {
+               usesPlayer = 1;
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("P", "a", "()I"));
+               return;
+       }
+
+       if (strcmp("stopplayer", name) == 0)
+       {
+               usesPlayer = 1;
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("P", "b", "()V"));
+               return;
+       }
+
+       if (strcmp("setplayercount", name) == 0)
+       {
+               usesPlayer = 1;
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("P", "a", "(I)I"));
+               return;
+       }
+
+       if (strcmp(name, "setchar") == 0)
+       {
+               usesSupport = 1;
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("S", "gc", "(Ljava/lang/String;II)Ljava/lang/String;"));
+               return;
+       }
+
+       if (strcmp(name, "sqr") == 0)
+       {
+               bytecode_append(code, dup$);
+               bytecode_append(code, imul$);
+
+               return;
+       }
+
+       if (strcmp(name, "setticker") == 0)
+       {
+               bytecode_append(code, new$);
+               bytecode_append_short_int(code, cp_add_class("javax/microedition/lcdui/Ticker"));
+               bytecode_append(code, dup_x1$);
+               bytecode_append(code, swap$);
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Ticker", "<init>", "(Ljava/lang/String;)V"));
+
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "F", "Ljavax/microedition/lcdui/Form;"));
+
+               bytecode_append(code, swap$);
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Form", "setTicker", "(Ljavax/microedition/lcdui/Ticker;)V"));
+               return;
+       }
+
+       if (strcmp(name, "stringtointeger") == 0)
+       {
+               usesSupport = 1;
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("S", "parseInt", "(Ljava/lang/String;)I"));
+               return;
+       }
+
+       if (strcmp(name, "stringtoreal") == 0)
+       {
+               usesFloat = 1;
+               //usesRegisteredFeature = 1;
+               if (mathType == 1)
+               {
+                       bytecode_append(code, invokestatic$);
+                       bytecode_append_short_int(code, cp_add_methodref("F", "fI", "(Ljava/lang/String;I)I"));
+               }
+               else
+               {
+                       bytecode_append(code, invokespecial$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "<init>", "(Ljava/lang/String;I)V"));
+               }
+
+               return;
+       }
+
+
+       if (strcmp(name, "sqrt") == 0)
+       {
+               usesFloat = 1;
+               if (mathType == 1)
+               {
+                       bytecode_append(code, invokestatic$);
+                       bytecode_append_short_int(code, cp_add_methodref("F", "S", "(I)I"));
+               }
+               else
+               {
+                       bytecode_append(code, new$);
+                       bytecode_append_short_int(code, cp_add_class("Real"));
+                       bytecode_append(code, dup_x1$);
+                       bytecode_append(code, swap$);
+                       bytecode_append(code, invokespecial$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+                       bytecode_append(code, dup$);
+                       bytecode_append(code, invokevirtual$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "sqrt", "()V"));
+               }
+
+               return;
+       }
+
+       if (strcmp(name, "sin") == 0)
+       {
+               usesFloat = 1;
+               if (mathType == 1)
+               {
+                       bytecode_append(code, invokestatic$);
+                       bytecode_append_short_int(code, cp_add_methodref("F", "s", "(I)I"));
+               }
+               else
+               {
+                       bytecode_append(code, new$);
+                       bytecode_append_short_int(code, cp_add_class("Real"));
+                       bytecode_append(code, dup_x1$);
+                       bytecode_append(code, swap$);
+                       bytecode_append(code, invokespecial$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+                       bytecode_append(code, dup$);
+                       bytecode_append(code, invokevirtual$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "sin", "()V"));
+               }
+
+               return;
+       }
+
+       if (strcmp(name, "setcolor") == 0)
+       {
+               int method_index;
+
+               method_index = cp_add_methodref("javax/microedition/lcdui/Graphics", "setColor", "(III)V");
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+
+
+       if (strcmp(name, "setfont") == 0)
+       {
+               int method_index = cp_add_methodref("javax/microedition/lcdui/Font", "getFont", "(III)Ljavax/microedition/lcdui/Font;");
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, method_index);
+
+               method_index = cp_add_methodref("javax/microedition/lcdui/Graphics", "setFont", "(Ljavax/microedition/lcdui/Font;)V");
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+
+       if (strcmp(name, "setdefaultfont") == 0)
+       {
+               int method_index = cp_add_methodref("javax/microedition/lcdui/Font", "getDefaultFont", "()Ljavax/microedition/lcdui/Font;");
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, method_index);
+
+               method_index = cp_add_methodref("javax/microedition/lcdui/Graphics", "setFont", "(Ljavax/microedition/lcdui/Font;)V");
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+
+               return;
+       }
+
+       if (strcmp(name, "sethttpmethod") == 0)
+       {
+               usesHttp = 1;
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("H", "c", "(Ljava/lang/String;)V"));
+               return;
+       }
+
+       if (strcmp(name, "sendhttpmessage") == 0)
+       {
+               usesHttp = 1;
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("H", "o", "()I"));
+               return;
+       }
+
+       if (strcmp(name, "showform") == 0)
+       {
+show_form:
+               /*
+                       Display.getDisplay(FW.fw).setCurrent(FW.F);
+               */
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "fw", "LFW;"));
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Display", "getDisplay", "(Ljavax/microedition/midlet/MIDlet;)Ljavax/microedition/lcdui/Display;"));
+
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "F", "Ljavax/microedition/lcdui/Form;"));
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Display", "setCurrent", "(Ljavax/microedition/lcdui/Displayable;)V"));
+
+               /*
+                       FW.CD = FW.F;
+               */
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "F", "Ljavax/microedition/lcdui/Form;"));
+
+               bytecode_append(code, putstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "CD", "Ljavax/microedition/lcdui/Displayable;"));
+
+               return;
+       }
+
+       if (strcmp(name, "showcanvas") == 0)
+       {
+               /*
+                       Display.getDisplay(FW.fw).setCurrent(M.T);
+               */
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "fw", "LFW;"));
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Display", "getDisplay", "(Ljavax/microedition/midlet/MIDlet;)Ljavax/microedition/lcdui/Display;"));
+
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("M", "T", "LM;"));
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Display", "setCurrent", "(Ljavax/microedition/lcdui/Displayable;)V"));
+
+               /*
+                       FW.CD = M.T;
+               */
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("M", "T", "LM;"));
+
+               bytecode_append(code, putstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "CD", "Ljavax/microedition/lcdui/Displayable;"));
+
+               return;
+       }
+
+
+       if (strcmp(name, "showtextbox") == 0)
+       {
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/TextBox", "<init>", "(Ljava/lang/String;Ljava/lang/String;II)V"));
+
+               bytecode_append(code, putstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "TB", "Ljavax/microedition/lcdui/TextBox;"));
+
+               /*
+                       Display.getDisplay(FW.fw).setCurrent(FW.TB);
+               */
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "fw", "LFW;"));
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Display", "getDisplay", "(Ljavax/microedition/midlet/MIDlet;)Ljavax/microedition/lcdui/Display;"));
+
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "TB", "Ljavax/microedition/lcdui/TextBox;"));
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Display", "setCurrent", "(Ljavax/microedition/lcdui/Displayable;)V"));
+
+               /*
+                       FW.CD = FW.TB;
+               */
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "TB", "Ljavax/microedition/lcdui/TextBox;"));
+
+               bytecode_append(code, putstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "CD", "Ljavax/microedition/lcdui/Displayable;"));
+
+
+               /*
+                       FW.TB.setCommandListener(FW.fw);
+               */
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "TB", "Ljavax/microedition/lcdui/TextBox;"));
+
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "fw", "LFW;"));
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Displayable", "setCommandListener", "(Ljavax/microedition/lcdui/CommandListener;)V"));
+
+               return;
+       }
+
+       if (strcmp(name, "showmenu") == 0)
+       {
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/List", "<init>", "(Ljava/lang/String;I)V"));
+
+               bytecode_append(code, putstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "L", "Ljavax/microedition/lcdui/List;"));
+
+               /*
+                       Display.getDisplay(FW.fw).setCurrent(FW.L);
+               */
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "fw", "LFW;"));
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Display", "getDisplay", "(Ljavax/microedition/midlet/MIDlet;)Ljavax/microedition/lcdui/Display;"));
+
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "L", "Ljavax/microedition/lcdui/List;"));
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Display", "setCurrent", "(Ljavax/microedition/lcdui/Displayable;)V"));
+
+               /*
+                       FW.CD = FW.L;
+               */
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "L", "Ljavax/microedition/lcdui/List;"));
+
+               bytecode_append(code, putstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "CD", "Ljavax/microedition/lcdui/Displayable;"));
+
+
+               /*
+                       FW.L.setCommandListener(FW.fw);
+               */
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "L", "Ljavax/microedition/lcdui/List;"));
+
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "fw", "LFW;"));
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Displayable", "setCommandListener", "(Ljavax/microedition/lcdui/CommandListener;)V"));
+
+
+               return;
+       }
+
+
+       if (strcmp(name, "showalert") == 0)
+       {
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Alert", "<init>", "(Ljava/lang/String;Ljava/lang/String;Ljavax/microedition/lcdui/Image;Ljavax/microedition/lcdui/AlertType;)V"));
+
+               bytecode_append(code, putstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "A", "Ljavax/microedition/lcdui/Alert;"));
+
+               /*
+                       Display.getDisplay(FW.fw).setCurrent(FW.A);
+               */
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "fw", "LFW;"));
+
+               bytecode_append(code, invokestatic$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Display", "getDisplay", "(Ljavax/microedition/midlet/MIDlet;)Ljavax/microedition/lcdui/Display;"));
+
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "A", "Ljavax/microedition/lcdui/Alert;"));
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Display", "setCurrent", "(Ljavax/microedition/lcdui/Displayable;)V"));
+
+               /*
+                       FW.CD = FW.A;
+               */
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "A", "Ljavax/microedition/lcdui/Alert;"));
+
+               bytecode_append(code, putstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "CD", "Ljavax/microedition/lcdui/Displayable;"));
+
+               /*
+                       FW.A.setCommandListener(FW.fw);
+               */
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "A", "Ljavax/microedition/lcdui/Alert;"));
+
+               bytecode_append(code, getstatic$);
+               bytecode_append_short_int(code, cp_add_fieldref("FW", "fw", "LFW;"));
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Alert", "setCommandListener", "(Ljavax/microedition/lcdui/CommandListener;)V"));
+
+
+               return;
+       }
+
+letter_t:
+       if (strcmp(name, "trunc") == 0)
+       {
+               usesFloat = 1;
+               if (mathType == 1)
+               {
+                       bytecode_append(code, invokestatic$);
+                       bytecode_append_short_int(code, cp_add_methodref("F", "tI", "(I)I"));
+               }
+               else
+               {
+                       bytecode_append(code, new$);
+                       bytecode_append_short_int(code, cp_add_class("Real"));
+                       bytecode_append(code, dup_x1$);
+                       bytecode_append(code, swap$);
+                       bytecode_append(code, invokespecial$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+                       bytecode_append(code, dup$);
+                       bytecode_append(code, invokevirtual$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "trunc", "()V"));
+                       bytecode_append(code, invokevirtual$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "toInteger", "()I"));
+               }
+
+               return;
+       }
+
+
+       if (strcmp(name, "tan") == 0)
+       {
+               usesFloat = 1;
+               if (mathType == 1)
+               {
+                       bytecode_append(code, invokestatic$);
+                       bytecode_append_short_int(code, cp_add_methodref("F", "tan", "(I)I"));
+               }
+               else
+               {
+                       bytecode_append(code, new$);
+                       bytecode_append_short_int(code, cp_add_class("Real"));
+                       bytecode_append(code, dup_x1$);
+                       bytecode_append(code, swap$);
+                       bytecode_append(code, invokespecial$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+                       bytecode_append(code, dup$);
+                       bytecode_append(code, invokevirtual$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "tan", "()V"));
+               }
+
+               return;
+       }
+
+
+
+       if (strcmp(name, "todegrees") == 0)
+       {
+               usesFloat = 1;
+               if (mathType == 1)
+               {
+                       bytecode_append(code, invokestatic$);
+                       bytecode_append_short_int(code, cp_add_methodref("F", "tD", "(I)I"));
+               }
+               else
+               {
+                       bytecode_append(code, new$);
+                       bytecode_append_short_int(code, cp_add_class("Real"));
+                       bytecode_append(code, dup_x1$);
+                       bytecode_append(code, swap$);
+                       bytecode_append(code, invokespecial$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+
+                       bytecode_append(code, dup$);
+                       bytecode_append(code, dup$);
+
+                       bytecode_append(code, sipush$);
+                       bytecode_append_short_int(code, 180);
+
+                       bytecode_append(code, invokevirtual$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "mul", "(I)V"));
+
+                       bytecode_append(code, getstatic$);
+                       bytecode_append_short_int(code, cp_add_fieldref("Real", "PI", "LReal;"));
+
+                       bytecode_append(code, invokevirtual$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "div", "(LReal;)V"));
+               }
+
+               return;
+       }
+
+       if (strcmp(name, "toradians") == 0)
+       {
+               usesFloat = 1;
+               if (mathType == 1)
+               {
+                       bytecode_append(code, invokestatic$);
+                       bytecode_append_short_int(code, cp_add_methodref("F", "tR", "(I)I"));
+               }
+               else
+               {
+                       bytecode_append(code, new$);
+                       bytecode_append_short_int(code, cp_add_class("Real"));
+                       bytecode_append(code, dup_x1$);
+                       bytecode_append(code, swap$);
+                       bytecode_append(code, invokespecial$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "<init>", "(LReal;)V"));
+
+                       bytecode_append(code, dup$);
+                       bytecode_append(code, dup$);
+
+                       bytecode_append(code, sipush$);
+                       bytecode_append_short_int(code, 180);
+
+                       bytecode_append(code, invokevirtual$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "div", "(I)V"));
+
+                       bytecode_append(code, getstatic$);
+                       bytecode_append_short_int(code, cp_add_fieldref("Real", "PI", "LReal;"));
+
+                       bytecode_append(code, invokevirtual$);
+                       bytecode_append_short_int(code, cp_add_methodref("Real", "mul", "(LReal;)V"));
+               }
+
+               return;
+       }
+letter_u:
+       if (strcmp(name, "upcase") == 0)
+       {
+               int init_index;
+               int class_index;
+               int method_index;
+
+               class_index = cp_add_class("java/lang/String");
+               init_index = cp_add_methodref("java/lang/String", "<init>", "(Ljava/lang/String;)V");
+               method_index = cp_add_methodref("java/lang/String", "toUpperCase", "()Ljava/lang/String;");
+
+               bytecode_append(code, new$);
+               bytecode_append_short_int(code, class_index);
+               bytecode_append(code, dup_x1$);
+               bytecode_append(code, swap$);
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, init_index);
+
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, method_index);
+               return;
+       }
+
+letter_v:
+       if (strcmp(name, "vibrate") == 0)
+       {
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Display", "vibrate", "(I)Z"));
+
+               bytecode_append(code, pop$);
+               return;
+       }
+letter_w:
+letter_x:
+letter_y:
+letter_z:
+
+       if (count == 0)
+       {
+               count ++;
+               goto letter_a;
+       }
+
+       die(25);
+}
+
+
+/*
+       Adds a function with 0 or 1 parameter
+*/
+void add_special_function(block *item, enum en_type_class parameter_en, enum en_type_class return_type_en, char *name)
+{
+       type_list *params;
+       type *param;
+       type *return_type;
+
+       params = type_list_create();
+       param = type_create();
+       return_type = type_create();
+       param->type_class = parameter_en;
+       return_type->type_class = return_type_en;
+       if (parameter_en != void_type)
+               type_list_append(params, param);
+       type_destroy(param);
+       if (return_type_en == void_type)
+               add_std_procedure(item, name, params);
+       else
+               add_std_function(item, name, params, return_type);
+}
+
+/*
+       Adds a function with 2 parameters
+*/
+void add_special_function2(block *item, enum en_type_class parameter_en1, enum en_type_class parameter_en2, enum en_type_class return_type_en, char *name)
+{
+       type_list *params;
+       type *param;
+       type *return_type;
+
+       params = type_list_create();
+       param = type_create();
+       return_type = type_create();
+       param->type_class = parameter_en1;
+       return_type->type_class = return_type_en;
+       type_list_append(params, param);
+       param->type_class = parameter_en2;
+       type_list_append(params, param);
+       type_destroy(param);
+
+       if (return_type_en == void_type)
+               add_std_procedure(item, name, params);
+       else
+               add_std_function(item, name, params, return_type);
+}
+
+/*
+       Adds a function with 3 parameters
+*/
+void add_special_function3(block *item, enum en_type_class parameter_en1, enum en_type_class parameter_en2, enum en_type_class parameter_en3, enum en_type_class return_type_en, char *name)
+{
+       type_list *params;
+       type *param;
+       type *return_type;
+
+       params = type_list_create();
+       param = type_create();
+       return_type = type_create();
+       param->type_class = parameter_en1;
+       return_type->type_class = return_type_en;
+       type_list_append(params, param);
+       param->type_class = parameter_en2;
+       type_list_append(params, param);
+       param->type_class = parameter_en3;
+       type_list_append(params, param);
+       type_destroy(param);
+
+       if (return_type_en == void_type)
+               add_std_procedure(item, name, params);
+       else
+               add_std_function(item, name, params, return_type);
+}
+
+/*
+       Adds a function with 4 parameters
+*/
+void add_special_function4(block *item, enum en_type_class parameter_en1, enum en_type_class parameter_en2, enum en_type_class parameter_en3, enum en_type_class parameter_en4, enum en_type_class return_type_en, char *name)
+{
+       type_list *params;
+       type *param;
+       type *return_type;
+
+       params = type_list_create();
+       param = type_create();
+       return_type = type_create();
+       param->type_class = parameter_en1;
+       return_type->type_class = return_type_en;
+       type_list_append(params, param);
+       param->type_class = parameter_en2;
+       type_list_append(params, param);
+       param->type_class = parameter_en3;
+       type_list_append(params, param);
+               param->type_class = parameter_en4;
+       type_list_append(params, param);
+       type_destroy(param);
+
+       if (return_type_en == void_type)
+               add_std_procedure(item, name, params);
+       else
+               add_std_function(item, name, params, return_type);
+}
+
+/*
+       Adds a function with 5 parameters
+*/
+void add_special_function5(block *item, enum en_type_class parameter_en1, enum en_type_class parameter_en2, enum en_type_class parameter_en3, enum en_type_class parameter_en4, enum en_type_class parameter_en5, enum en_type_class return_type_en, char *name)
+{
+       type_list *params;
+       type *param;
+       type *return_type;
+
+       params = type_list_create();
+       param = type_create();
+       return_type = type_create();
+       param->type_class = parameter_en1;
+       return_type->type_class = return_type_en;
+       type_list_append(params, param);
+       param->type_class = parameter_en2;
+       type_list_append(params, param);
+       param->type_class = parameter_en3;
+       type_list_append(params, param);
+       param->type_class = parameter_en4;
+       type_list_append(params, param);
+       param->type_class = parameter_en5;
+       type_list_append(params, param);
+       type_destroy(param);
+
+       if (return_type_en == void_type)
+               add_std_procedure(item, name, params);
+       else
+               add_std_function(item, name, params, return_type);
+}
+
+/*
+       Adds a function with 6 parameters
+*/
+void add_special_function6(block *item, enum en_type_class parameter_en1, enum en_type_class parameter_en2, enum en_type_class parameter_en3, enum en_type_class parameter_en4, enum en_type_class parameter_en5, enum en_type_class parameter_en6, enum en_type_class return_type_en, char *name)
+{
+       type_list *params;
+       type *param;
+       type *return_type;
+
+       params = type_list_create();
+       param = type_create();
+       return_type = type_create();
+       param->type_class = parameter_en1;
+       return_type->type_class = return_type_en;
+       type_list_append(params, param);
+       param->type_class = parameter_en2;
+       type_list_append(params, param);
+       param->type_class = parameter_en3;
+       type_list_append(params, param);
+       param->type_class = parameter_en4;
+       type_list_append(params, param);
+       param->type_class = parameter_en5;
+       type_list_append(params, param);
+       param->type_class = parameter_en6;
+       type_list_append(params, param);
+       type_destroy(param);
+
+       if (return_type_en == void_type)
+               add_std_procedure(item, name, params);
+       else
+               add_std_function(item, name, params, return_type);
+}
diff --git a/MPC.3.5.LINUX/parser/stdpas.h b/MPC.3.5.LINUX/parser/stdpas.h
new file mode 100644 (file)
index 0000000..0603f20
--- /dev/null
@@ -0,0 +1,27 @@
+/********************************************************************
+       
+       stdpas.h - initializes the parser/semantic checker with a
+       standard pascal types, constants etc.
+
+  Niksa Orlic, 2004-04-29
+
+********************************************************************/
+
+block* initialize_root_block();
+
+void add_std_types(block*);
+void add_std_constants(block*);
+void add_std_functions(block*);
+void add_std_type(block*, enum en_type_class , char*);
+void add_std_function(block*, char*, type_list*, type*);
+void add_std_procedure(block*, char*, type_list*);
+
+void create_std_function_code(bytecode*, char*);
+void create_std_function_prefix(bytecode*, char*);
+
+void add_special_function(block*, enum en_type_class, enum en_type_class, char*);
+void add_special_function2(block*, enum en_type_class, enum en_type_class, enum en_type_class, char*);
+void add_special_function3(block*, enum en_type_class, enum en_type_class, enum en_type_class, enum en_type_class, char*);
+void add_special_function4(block*, enum en_type_class, enum en_type_class, enum en_type_class, enum en_type_class, enum en_type_class, char*);
+void add_special_function5(block*, enum en_type_class, enum en_type_class, enum en_type_class, enum en_type_class, enum en_type_class, enum en_type_class, char*);
+void add_special_function6(block*, enum en_type_class, enum en_type_class, enum en_type_class, enum en_type_class, enum en_type_class, enum en_type_class, enum en_type_class, char*);
diff --git a/MPC.3.5.LINUX/preverifier/README.TXT b/MPC.3.5.LINUX/preverifier/README.TXT
new file mode 100644 (file)
index 0000000..90d6e5e
--- /dev/null
@@ -0,0 +1,15 @@
+PREVERIFIER TOOL
+
+This directory contains the source code of the 
+preverifier tool that is used for preprocessing
+Java class files for the KVM.  The preprocessed
+class files are regular Java class files, but 
+they contain some additional/modified information
+that will help speed up runtime verification.
+
+The preverifier implementation is derived from
+the J2SE class file verifier that was written
+originally for the "Classic" Java Virtual Machine.
+Therefore, the implementation style is quite 
+different from the rest of the KVM codebase.
+
diff --git a/MPC.3.5.LINUX/preverifier/check_class.c b/MPC.3.5.LINUX/preverifier/check_class.c
new file mode 100644 (file)
index 0000000..8d23460
--- /dev/null
@@ -0,0 +1,844 @@
+/*
+ * @(#)check_class.c   1.6 02/09/27
+ *
+ * Copyright 1995-1998 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ * 
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+/*=========================================================================
+ * SYSTEM:    Verifier
+ * SUBSYSTEM: Verifies ClassClass structure.
+ * FILE:      check_class.c
+ * OVERVIEW:  Code for verifying the ClassClass structure for internal
+ *            consistency.
+ * AUTHOR:    Sheng Liang, Consumer & Embedded 
+ *            Initial implementation based on the Classic VM Verifier.
+ *            Edited by Tasneem Sayeed, Java Consumer Technologies
+ *=======================================================================*/
+
+/*=========================================================================
+ * Include files
+ *=======================================================================*/
+
+#include <ctype.h>
+
+#include "oobj.h"
+#include "utf.h"
+#include "tree.h"
+#include "sys_api.h"
+
+/*=========================================================================
+ * Globals and extern declarations
+ *=======================================================================*/
+
+extern bool_t verify_class_codes(ClassClass *cb);
+
+//static bool_t verify_constant_pool(ClassClass *cb);
+
+//static bool_t is_legal_fieldname(ClassClass *cb, char *name, int type);
+//static bool_t is_legal_method_signature(ClassClass *cb, char *name, char *signature);
+//static bool_t is_legal_field_signature(ClassClass *cb, char *name, char *signature);
+
+//static char *skip_over_fieldname(char *name, bool_t slash_okay);
+//static char *skip_over_field_signature(char *name, bool_t void_okay);
+
+//static void CCerror (ClassClass *cb, char *format, ...);
+
+
+/* Argument for is_legal_fieldname */
+enum { LegalClass, LegalField, LegalMethod };
+
+
+/*=========================================================================
+ * FUNCTION:      VerifyClass
+ * OVERVIEW:      Verifies a class given a pointer to the ClassClass struct. 
+ *                Returns true if the class is ok. 
+ * INTERFACE:
+ *   parameters:  pointer to the ClassClass structure. 
+ *                
+ *   returns:     boolean type
+ *=======================================================================*/
+bool_t
+VerifyClass(ClassClass *cb)
+{
+       verify_class_codes(cb);
+       return TRUE;
+       /*
+    bool_t result = TRUE;
+    struct methodblock *mb;
+    struct fieldblock *fb;
+    int i;
+    if (!verify_constant_pool(cb)) 
+        return FALSE;
+    /* Make sure all the method names and signatures are okay 
+    for (i = cbMethodsCount(cb), mb = cbMethods(cb); --i >= 0; mb++) {
+       char *name = mb->fb.name;
+       char *signature = mb->fb.signature;
+       if (! (is_legal_fieldname(cb, name, LegalMethod)  &&
+              is_legal_method_signature(cb, name, signature)))
+           result = FALSE;
+    }
+    /* Make sure all the field names and signatures are okay 
+    for (i = cbFieldsCount(cb), fb = cbFields(cb); --i >= 0; fb++) {
+       if (!  (is_legal_fieldname(cb, fb->name, LegalField) &&
+               is_legal_field_signature(cb, fb->name, fb->signature))) 
+           result = FALSE;
+    }
+    /* Make sure we are not overriding any final methods or classes
+    if (cbIsInterface(cb)) { 
+       struct methodblock *mb;
+       if ((cbSuperclass(cb) == NULL) ||
+           (cbSuperclass(cb) != classJavaLangObject)) { 
+         //  CCerror(cb, "Interface %s has bad superclass", cbName(cb));
+           result = FALSE;
+       }
+       for (i = cbMethodsCount(cb), mb = cbMethods(cb); --i >= 0; mb++) {
+           if (mb->fb.access & ACC_STATIC) {
+               if (mb->fb.name[0] != '<') { 
+                   /* Only internal methods can be static 
+               //    CCerror(cb, "Illegal static method %s in interface %s",
+//                         mb->fb.name, cbName(cb));
+                   result = FALSE;
+               }
+           }
+       }
+    } else if (cbSuperclass(cb)) { 
+       ClassClass *super_cb;
+       unsigned bitvector_size = (unsigned)(cbMethodTableSize(cb) + 31) >> 5;
+       long *bitvector = sysCalloc(bitvector_size, sizeof(long));
+       for (super_cb = cbSuperclass(cb); ; super_cb = cbSuperclass(super_cb)) {
+           if (cbAccess(super_cb) & ACC_FINAL) {
+       //      CCerror(cb, "Class %s is subclass of final class %s",
+//                     cbName(cb), cbName(super_cb));
+               result = FALSE;
+           }
+           mb = cbMethods(super_cb);
+           for (i = cbMethodsCount(super_cb); --i >= 0; mb++) {
+               if (mb->fb.access & ACC_FINAL) {
+                   unsigned offset = mb->fb.u.offset;
+                   bitvector[offset >> 5] |= (1 << (offset & 0x1F));
+               }
+           }
+           if (cbSuperclass(super_cb) == NULL) break;
+       }
+       for (i = cbMethodsCount(cb), mb = cbMethods(cb); --i >= 0; mb++) {
+           unsigned offset = mb->fb.u.offset;
+           if ((offset > 0) 
+                  && bitvector[offset >> 5] & (1 << (offset & 0x1F))) {
+//             CCerror(cb, "Class %s overrides final method %s.%s",
+//                     cbName(cb), mb->fb.name, mb->fb.signature);
+               result = FALSE;
+           }
+       }
+       sysFree(bitvector);
+    } else if (cb != classJavaLangObject) {
+//     CCerror(cb, "Class %s does not have superclass", cbName(cb));
+       result = FALSE;
+    }
+       
+    if (result)
+       result = verify_class_codes(cb);
+    return result;*/
+}
+
+
+/*=========================================================================
+ * FUNCTION:      verify_constant_pool 
+ * OVERVIEW:      Verifies the constant pool given a pointer to the 
+ *                ClassClass structure. 
+ *                Makes two quick passes over the constant pool. The first
+ *                pass ensures that everything is of the right type.
+ *                Returns true if the constant pool is ok. 
+ * INTERFACE:
+ *   parameters:  pointer to the ClassClass structure. 
+ *                
+ *   returns:     boolean type
+ *=======================================================================*/
+/*
+static bool_t
+verify_constant_pool(ClassClass *cb)
+{
+    union cp_item_type *cp = cbConstantPool(cb);
+    long cp_count = cbConstantPoolCount(cb);
+    unsigned char *type_table;
+    int i, type;
+    
+    const int utf8_resolved = (CONSTANT_Utf8 | CONSTANT_POOL_ENTRY_RESOLVED);
+
+    if (cp_count == 0) /* Primitive classes 
+        return TRUE;
+    type_table = cp[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
+    /* Let's make two quick passes over the constant pool. The first one 
+     * checks that everything is of the right type.            
+    for (i = 1; i < cp_count; i++) {
+       switch(type = type_table[i]) {
+           case CONSTANT_String:
+           case CONSTANT_Class: {
+               int index = cp[i].i;
+               if (   (index < 1) 
+                      || (index >= cp_count)
+                      || (type_table[index] != utf8_resolved)) {
+       //          CCerror(cb, "Bad index in constant pool #%d", i);
+                   return FALSE;
+               }
+               break;
+           }
+               
+           case CONSTANT_String | CONSTANT_POOL_ENTRY_RESOLVED:
+               /* This can only happen if a string is the "initial" value of
+                * some final static String.  We assume that the checking has
+                * already been done.
+                
+               break;
+
+           case CONSTANT_Fieldref:
+           case CONSTANT_Methodref:
+           case CONSTANT_InterfaceMethodref: 
+           case CONSTANT_NameAndType: {
+               unsigned index = (unsigned)(cp[i].i);
+               int key1 = index >> 16;
+               int key2 = index & 0xFFFF;
+               if (key1 < 1 || key1 >= cp_count 
+                     || key2 < 1 || key2 >= cp_count) {
+       //          CCerror(cb, "Bad index in constant pool #%d", i);
+                   return FALSE;
+               }
+               if (type == CONSTANT_NameAndType) {
+                   if (   (type_table[key1] != utf8_resolved) 
+                       || (type_table[key2] != utf8_resolved)) {
+//                     CCerror(cb, "Bad index in constant pool.");
+                       return FALSE;
+                   }
+               } else {
+                   if (     ((type_table[key1] & CONSTANT_POOL_ENTRY_TYPEMASK) 
+                               != CONSTANT_Class)
+                         || ((type_table[key2] != CONSTANT_NameAndType))) {
+//                     CCerror(cb, "Bad index in constant pool #%d", i);
+                       return FALSE;
+                   }
+               }
+               break;
+           }
+               
+           case CONSTANT_Fieldref | CONSTANT_POOL_ENTRY_RESOLVED:
+           case CONSTANT_Methodref | CONSTANT_POOL_ENTRY_RESOLVED:
+           case CONSTANT_InterfaceMethodref | CONSTANT_POOL_ENTRY_RESOLVED:
+           case CONSTANT_NameAndType | CONSTANT_POOL_ENTRY_RESOLVED:
+//             CCerror(cb, "Improperly resolved constant pool #%d", i);
+               return FALSE;
+
+
+           case CONSTANT_Class | CONSTANT_POOL_ENTRY_RESOLVED:
+           case CONSTANT_Utf8 | CONSTANT_POOL_ENTRY_RESOLVED:
+           case CONSTANT_Integer | CONSTANT_POOL_ENTRY_RESOLVED:
+           case CONSTANT_Float | CONSTANT_POOL_ENTRY_RESOLVED:
+               break;
+
+           case CONSTANT_Long | CONSTANT_POOL_ENTRY_RESOLVED:
+           case CONSTANT_Double | CONSTANT_POOL_ENTRY_RESOLVED:
+               if ((i + 1 >= cp_count) || 
+                   (type_table[i + 1] != CONSTANT_POOL_ENTRY_RESOLVED)) {
+//                 CCerror(cb, "Improper constant pool long/double #%d", i);
+                   return FALSE;
+               } else {
+                   i++;        
+                   break;          
+               }
+
+           case CONSTANT_Integer:
+           case CONSTANT_Float:
+           case CONSTANT_Long:
+           case CONSTANT_Double:
+           case CONSTANT_Utf8:
+//             CCerror(cb, "Improperly unresolved constant pool #%d", i);
+               return FALSE;
+
+
+           default:
+//             CCerror(cb, "Illegal constant pool type at #%d", i);
+               return FALSE;
+
+
+       }
+    }
+    for (i = 1; i < cp_count; i++) {
+       switch(type = type_table[i]) {
+           case CONSTANT_Class: {
+               int index = cp[i].i;
+               if (!is_legal_fieldname(cb, cp[index].cp, LegalClass)) 
+                   return FALSE;
+               break;
+           }
+             
+           case CONSTANT_Fieldref:
+           case CONSTANT_Methodref:
+           case CONSTANT_InterfaceMethodref: {
+               unsigned index = (unsigned)(cp[i].i);
+               int name_type_index = index & 0xFFFF;
+               int name_type_key = cp[name_type_index].i;
+               int name_index = name_type_key >> 16;
+               int signature_index = name_type_key & 0xFFFF;
+               char *name = cp[name_index].cp;
+               char *signature = cp[signature_index].cp;
+
+               if (type == CONSTANT_Fieldref) {
+                   if (! (is_legal_fieldname(cb, name, LegalField) &&
+                          is_legal_field_signature(cb, name, signature)))
+                       return FALSE;
+               } else {
+                   if (! (is_legal_fieldname(cb, name, LegalMethod) &&
+                          is_legal_method_signature(cb, name, signature)))
+                       return FALSE;
+               }
+               break;
+           }
+       }
+    }
+    return TRUE;
+}
+           */
+
+/*=========================================================================
+ * FUNCTION:      is_legal_fieldname 
+ * OVERVIEW:      Returns true if the given name within the given ClassClass 
+ *                structure consists of a legal fieldname or a classname 
+ *                if the third argument is LegalClass.
+ * INTERFACE:
+ *   parameters:  pointer to the ClassClass structure. 
+ *                char*: legal field name or a classname
+ *                int: type of name (class or field name) 
+ *                
+ *   returns:     boolean type
+ *=======================================================================*/
+#if 0
+static bool_t 
+is_legal_fieldname(ClassClass *cb, char *name, int type)
+{
+    bool_t result;
+    if (name[0] == '<') {
+       result = (type == LegalMethod) && 
+                ((strcmp(name, "<init>") == 0) || 
+                 (strcmp(name, "<clinit>") == 0));
+    } else {
+       char *p;
+       if (type == LegalClass && name[0] == SIGNATURE_ARRAY) {
+           p = skip_over_field_signature(name, FALSE);
+       } else {
+           p = skip_over_fieldname(name, type == LegalClass);
+       }
+       result = (p != 0 && p[0] == '\0');
+    }
+    if (!result) {
+       char *thing =    (type == LegalField) ? "Field" 
+                      : (type == LegalMethod) ? "Method" : "Class";
+                        
+//     CCerror(cb, "Illegal %s name \"%s\"", thing, name);
+       return FALSE;
+    } else {
+        return TRUE;
+    
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      is_legal_field_signature
+ * OVERVIEW:      Returns true if the entire given string within the given 
+ *                ClassClass structure consists of a legal field signature.
+ * INTERFACE:
+ *   parameters:  pointer to the ClassClass structure. 
+ *                char*: field name 
+ *                char*: field signature 
+ *                
+ *   returns:     boolean type
+ *=======================================================================*/
+static bool_t 
+is_legal_field_signature(ClassClass *cb, char *fieldname, char *signature) 
+{
+    char *p = skip_over_field_signature(signature, FALSE);
+    if (p != 0 && p[0] == '\0') {
+       return TRUE;
+    } else {
+//     CCerror(cb, "Field \"%s\" has illegal signature \"%s\"", 
+//            fieldname, signature);
+       return FALSE;
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      is_legal_method_signature
+ * OVERVIEW:      Returns true if the entire given string within the given 
+ *                ClassClass structure consists of a legal method signature.
+ * INTERFACE:
+ *   parameters:  pointer to the ClassClass structure. 
+ *                char*: method name 
+ *                char*: method signature  
+ *                
+ *   returns:     boolean type
+ *=======================================================================*/
+static bool_t 
+is_legal_method_signature(ClassClass *cb, char *methodname, char *signature)
+{
+    char *p = signature;
+    char *next_p;
+    /* The first character must be a '(' */
+    if (*p++ == SIGNATURE_FUNC) {
+       /* Skip over however many legal field signatures there are */
+       while ((next_p = skip_over_field_signature(p, FALSE)) != 0) 
+           p = next_p;
+       /* The first non-signature thing better be a ')' */
+       if (*p++ == SIGNATURE_ENDFUNC) {
+           if (methodname[0] == '<') {
+               /* All internal methods must return void */
+               if ((p[0] == SIGNATURE_VOID) && (p[1] == '\0'))
+                   return TRUE;
+           } else {
+               /* Now, we better just have a return value. */
+               next_p =  skip_over_field_signature(p, TRUE);
+               if (next_p && next_p[0] == '\0')
+                   return TRUE;
+           }
+       }
+    }
+ //   CCerror(cb, "Method \"%s\" has illegal signature \"%s\"", 
+//        methodname, signature);
+    return FALSE;
+}
+       
+#endif
+
+#if 0
+
+/*=========================================================================
+ * Automatic code generation tables 
+ *=======================================================================*/
+  /* The following tables and code generated using: */
+  /* java GenerateCharacter -verbose -c -identifiers -spec UnicodeData-2.1.2.txt -template check_class.c.template -o check_class.c 8 4 4 */
+  /* The X table has 256 entries for a total of 256 bytes. */
+
+  static unsigned char X[256] = {
+      0,   1,   2,   3,   4,   5,   6,   7,  /* 0x0000 */
+      7,   8,   9,  10,  11,  12,  13,  14,  /* 0x0800 */
+     15,  16,   7,   7,   7,   7,   7,   7,  /* 0x1000 */
+      7,   7,   7,   7,   7,   7,  17,  18,  /* 0x1800 */
+     19,  20,   7,   7,   7,   7,   7,   7,  /* 0x2000 */
+      7,   7,   7,   7,   7,   7,   7,   7,  /* 0x2800 */
+     21,  22,   7,   7,   7,   7,   7,   7,  /* 0x3000 */
+      7,   7,   7,   7,   7,   7,   7,   7,  /* 0x3800 */
+      7,   7,   7,   7,   7,   7,   7,   7,  /* 0x4000 */
+      7,   7,   7,   7,   7,   7,  23,  23,  /* 0x4800 */
+     23,  23,  23,  23,  23,  23,  23,  23,  /* 0x5000 */
+     23,  23,  23,  23,  23,  23,  23,  23,  /* 0x5800 */
+     23,  23,  23,  23,  23,  23,  23,  23,  /* 0x6000 */
+     23,  23,  23,  23,  23,  23,  23,  23,  /* 0x6800 */
+     23,  23,  23,  23,  23,  23,  23,  23,  /* 0x7000 */
+     23,  23,  23,  23,  23,  23,  23,  23,  /* 0x7800 */
+     23,  23,  23,  23,  23,  23,  23,  23,  /* 0x8000 */
+     23,  23,  23,  23,  23,  23,  23,  23,  /* 0x8800 */
+     23,  23,  23,  23,  23,  23,  23,  23,  /* 0x9000 */
+     23,  23,  23,  23,  23,  23,  23,  24,  /* 0x9800 */
+      7,   7,   7,   7,   7,   7,   7,   7,  /* 0xA000 */
+      7,   7,   7,   7,  23,  23,  23,  23,  /* 0xA800 */
+     23,  23,  23,  23,  23,  23,  23,  23,  /* 0xB000 */
+     23,  23,  23,  23,  23,  23,  23,  23,  /* 0xB800 */
+     23,  23,  23,  23,  23,  23,  23,  23,  /* 0xC000 */
+     23,  23,  23,  23,  23,  23,  23,  23,  /* 0xC800 */
+     23,  23,  23,  23,  23,  23,  23,  25,  /* 0xD000 */
+      7,   7,   7,   7,   7,   7,   7,   7,  /* 0xD800 */
+      7,   7,   7,   7,   7,   7,   7,   7,  /* 0xE000 */
+      7,   7,   7,   7,   7,   7,   7,   7,  /* 0xE800 */
+      7,   7,   7,   7,   7,   7,   7,   7,  /* 0xF000 */
+      7,  23,  26,  27,  23,  28,  29,  30   /* 0xF800 */
+  };
+
+  /* The Y table has 496 entries for a total of 496 bytes. */
+
+  static unsigned char Y[496] = {
+      0,   0,   1,   2,   3,   4,   3,   5,  /*   0 */
+      0,   0,   6,   7,   8,   9,   8,   9,  /*   0 */
+      8,   8,   8,   8,   8,   8,   8,   8,  /*   1 */
+      8,   8,   8,   8,   8,   8,   8,  10,  /*   1 */
+      8,  11,   0,   0,   0,   8,   8,   8,  /*   2 */
+      8,   8,  12,  13,  14,  14,  15,   0,  /*   2 */
+     16,  16,  16,  16,  17,   0,  18,  19,  /*   3 */
+     20,   8,  21,   8,  22,  23,  24,  25,  /*   3 */
+     26,   8,   8,   8,   8,  26,   8,   8,  /*   4 */
+     27,   8,   8,   8,  28,   8,  29,  30,  /*   4 */
+      0,   0,   0,   3,   8,  31,   3,   8,  /*   5 */
+     11,  32,  33,  34,  35,   8,   5,  36,  /*   5 */
+      0,   0,   3,   5,  37,  38,   2,  39,  /*   6 */
+      8,   8,   8,  40,  22,  41,  42,   2,  /*   6 */
+      0,   0,   0,   0,   0,   0,   0,   0,  /*   7 */
+      0,   0,   0,   0,   0,   0,   0,   0,  /*   7 */
+     43,   8,   8,  44,  45,  46,  47,   0,  /*   8 */
+     48,  49,  50,  51,  52,  53,  47,  25,  /*   8 */
+     54,  49,  50,  55,  56,  57,  58,  59,  /*   9 */
+     60,  21,  50,  61,  62,   0,  63,   0,  /*   9 */
+     48,  49,  50,  64,  65,  66,  67,   0,  /*  10 */
+     68,  69,  70,  71,  72,  73,  74,   0,  /*  10 */
+     75,  24,  50,  76,  77,  78,  67,   0,  /*  11 */
+     79,  24,  50,  76,  77,  80,  67,   0,  /*  11 */
+     79,  24,  50,  81,  82,  73,  67,   0,  /*  12 */
+      0,   0,   0,   0,   0,   0,   0,   0,  /*  12 */
+      3,   8,  22,  83,  84,   2,   0,   0,  /*  13 */
+     85,  86,  87,  88,  89,  90,   0,   0,  /*  13 */
+      0,  91,   2,  92,  93,   8,  94,  32,  /*  14 */
+     95,  96,  45,  97,   0,   0,   0,   0,  /*  14 */
+      0,   0,   0,   0,   0,   0,   0,   0,  /*  15 */
+      0,   0,   8,   8,  98,   8,   8,  99,  /*  15 */
+      8,   8,   8,   8,   8, 100,   8,   8,  /*  16 */
+      8,   8, 101,   8,   8,   8,   8,  94,  /*  16 */
+      8,   8,   8,   8,   8,   8,   8,   8,  /*  17 */
+      8, 102,   8,   8,   8,   8,   8,  94,  /*  17 */
+      8, 103,   8,   8, 103, 104,   8, 105,  /*  18 */
+      8,   8,   8, 106, 107, 108, 109, 107,  /*  18 */
+      0,   0,   0, 110, 111,   0,   0, 110,  /*  19 */
+      0,   0, 109,   0,   0, 112, 113,   0,  /*  19 */
+    114, 115, 116, 117,   0,   0,   8,   8,  /*  20 */
+     36,   0,   0,   0,   0,   0,   0,   0,  /*  20 */
+    118,   0, 119, 120,   3,   8,   8,   8,  /*  21 */
+      8, 121,   3,   8,   8,   8,   8, 122,  /*  21 */
+    123,   8, 109,   3,   8,   8,   8,   8,  /*  22 */
+     22,   0,   0,   0,   0,   0,   0,   0,  /*  22 */
+      8,   8,   8,   8,   8,   8,   8,   8,  /*  23 */
+      8,   8,   8,   8,   8,   8,   8,   8,  /*  23 */
+      8,   8,   8,   8,   8,   8,   8,   8,  /*  24 */
+      8,   8,  98,   0,   0,   0,   0,   0,  /*  24 */
+      8,   8,   8,   8,   8,   8,   8,   8,  /*  25 */
+      8,   8,  25,   0,   0,   0,   0,   0,  /*  25 */
+      8,   8, 105,   0,   0,   0,   0,   0,  /*  26 */
+      0,   0,   0,   0,   0,   0,   0,   0,  /*  26 */
+     99, 124,  50, 125, 126,   8,   8,   8,  /*  27 */
+      8,   8,   8,  14,   0, 127,   8,   8,  /*  27 */
+      8,   8,   8, 105,   0,   8,   8,   8,  /*  28 */
+      8, 128,   8,   8,  11,   0,   0, 102,  /*  28 */
+      0,   0, 129, 130, 131,   0, 132, 133,  /*  29 */
+      8,   8,   8,   8,   8,   8,   8, 109,  /*  29 */
+      1,   2,   3,   4,   3,   5, 134,   8,  /*  30 */
+      8,   8,   8,  22, 135, 136, 137,   0   /*  30 */
+  };
+
+  /* The A table has 2208 entries for a total of 552 bytes. */
+
+  static unsigned long A[138] = {
+    0x00000000,  /*   0 */
+    0x00000300,  /*   1 */
+    0x00055555,  /*   2 */
+    0xFFFFFFFC,  /*   3 */
+    0xC03FFFFF,  /*   4 */
+    0x003FFFFF,  /*   5 */
+    0x00300FF0,  /*   6 */
+    0x00300C00,  /*   7 */
+    0xFFFFFFFF,  /*   8 */
+    0xFFFF3FFF,  /*   9 */
+    0xFFF00FFF,  /*  10 */
+    0x0000FFFF,  /*  11 */
+    0x0003FFFF,  /*  12 */
+    0xFFC3FFFF,  /*  13 */
+    0x0000000F,  /*  14 */
+    0x000003FF,  /*  15 */
+    0x55555555,  /*  16 */
+    0x00000555,  /*  17 */
+    0x00000005,  /*  18 */
+    0x00300000,  /*  19 */
+    0xF33F3000,  /*  20 */
+    0xFFFFFFCF,  /*  21 */
+    0x3FFFFFFF,  /*  22 */
+    0x33303FFF,  /*  23 */
+    0xFFFFFFF3,  /*  24 */
+    0x000000FF,  /*  25 */
+    0xF3FFFFFC,  /*  26 */
+    0x0000154F,  /*  27 */
+    0x03C3C3FF,  /*  28 */
+    0xF0FFFFFF,  /*  29 */
+    0x000F0FFF,  /*  30 */
+    0x000C3FFF,  /*  31 */
+    0x55555554,  /*  32 */
+    0x55555545,  /*  33 */
+    0x45455555,  /*  34 */
+    0x00000114,  /*  35 */
+    0x0000003F,  /*  36 */
+    0x557FFFFF,  /*  37 */
+    0x00000015,  /*  38 */
+    0xFFFFFFFD,  /*  39 */
+    0x3FF0FFFF,  /*  40 */
+    0x41555CFF,  /*  41 */
+    0x05517D55,  /*  42 */
+    0xFFFFFC54,  /*  43 */
+    0x5D0FFFFF,  /*  44 */
+    0x05555555,  /*  45 */
+    0xFFFF0154,  /*  46 */
+    0x5555505F,  /*  47 */
+    0xC3FFFC54,  /*  48 */
+    0xFFFFFFC3,  /*  49 */
+    0xFFF3FFFF,  /*  50 */
+    0x510FF033,  /*  51 */
+    0x05414155,  /*  52 */
+    0xCF004000,  /*  53 */
+    0xC03FFC10,  /*  54 */
+    0x510F3CF3,  /*  55 */
+    0x05414015,  /*  56 */
+    0x33FC0000,  /*  57 */
+    0x55555000,  /*  58 */
+    0x000003F5,  /*  59 */
+    0xCCFFFC54,  /*  60 */
+    0x5D0FFCF3,  /*  61 */
+    0x05454555,  /*  62 */
+    0x55555003,  /*  63 */
+    0x5D0FF0F3,  /*  64 */
+    0x05414055,  /*  65 */
+    0xCF005000,  /*  66 */
+    0x5555500F,  /*  67 */
+    0xF03FFC50,  /*  68 */
+    0xF33C0FF3,  /*  69 */
+    0xF03F03C0,  /*  70 */
+    0x500FCFFF,  /*  71 */
+    0x05515015,  /*  72 */
+    0x00004000,  /*  73 */
+    0x55554000,  /*  74 */
+    0xF3FFFC54,  /*  75 */
+    0x500FFCFF,  /*  76 */
+    0x05515155,  /*  77 */
+    0x00001400,  /*  78 */
+    0xF3FFFC50,  /*  79 */
+    0x30001400,  /*  80 */
+    0x500FFFFF,  /*  81 */
+    0x05515055,  /*  82 */
+    0xC01555F7,  /*  83 */
+    0x15557FFF,  /*  84 */
+    0x0C33C33C,  /*  85 */
+    0xFFFCFF00,  /*  86 */
+    0x3CF0CCFC,  /*  87 */
+    0x0D4555F7,  /*  88 */
+    0x055533FF,  /*  89 */
+    0x0F055555,  /*  90 */
+    0x00050000,  /*  91 */
+    0x50044400,  /*  92 */
+    0xFFFCFFFF,  /*  93 */
+    0x000FFFFF,  /*  94 */
+    0x00555155,  /*  95 */
+    0x55544555,  /*  96 */
+    0x00045554,  /*  97 */
+    0x00000FFF,  /*  98 */
+    0x00003FFF,  /*  99 */
+    0xC00FFFFF,  /* 100 */
+    0xFFFF003F,  /* 101 */
+    0x00FFFFFF,  /* 102 */
+    0x0FFF0FFF,  /* 103 */
+    0xCCCCFFFF,  /* 104 */
+    0x0FFFFFFF,  /* 105 */
+    0x33FFF3FF,  /* 106 */
+    0x03FFF3F0,  /* 107 */
+    0x00FFF0FF,  /* 108 */
+    0x03FFFFFF,  /* 109 */
+    0xC0000000,  /* 110 */
+    0x00000003,  /* 111 */
+    0x01555555,  /* 112 */
+    0x00000004,  /* 113 */
+    0xFFF0C030,  /* 114 */
+    0x0FFF0CFF,  /* 115 */
+    0xFFF33300,  /* 116 */
+    0x0003FFCF,  /* 117 */
+    0x0000CC00,  /* 118 */
+    0x555FFFFC,  /* 119 */
+    0x00000FFC,  /* 120 */
+    0x3FD403FF,  /* 121 */
+    0x3F3FFFFF,  /* 122 */
+    0xFFFFFC00,  /* 123 */
+    0xD000FFC0,  /* 124 */
+    0x33FF3FFF,  /* 125 */
+    0xFFFFF3CF,  /* 126 */
+    0xFFFFFFC0,  /* 127 */
+    0xFFFFFFF0,  /* 128 */
+    0x00000055,  /* 129 */
+    0x000003C0,  /* 130 */
+    0xFC000000,  /* 131 */
+    0x000C0000,  /* 132 */
+    0xFFFFF33F,  /* 133 */
+    0xFFFFF000,  /* 134 */
+    0xFFF0FFF0,  /* 135 */
+    0x03F0FFF0,  /* 136 */
+    0x00003C0F   /* 137 */
+  };
+
+  /* In all, the character property tables require 1304 bytes. */
+
+/*
+ * This code mirrors Character.isJavaIdentifierStart.  It determines whether
+ * the specified character is a legal start of a Java identifier as per JLS.
+ *
+ * The parameter ch is the character to be tested; return 1 if the 
+ * character is a letter, 0 otherwise.
+ */
+#define isJavaIdentifierStart(ch) (((A[Y[(X[ch>>8]<<4)|((ch>>4)&0xF)]]>>((ch&0xF)<<1))&3) & 0x2)
+
+/*
+ * This code mirrors Character.isJavaIdentifierPart.  It determines whether
+ * the specified character is a legal part of a Java identifier as per JLS.
+ * 
+ * The parameter ch is the character to be tested; return 1 if the
+ * character is a digit, 0 otherwise.
+ */  
+#define isJavaIdentifierPart(ch) (((A[Y[(X[ch>>8]<<4)|((ch>>4)&0xF)]]>>((ch&0xF)<<1))&3) & 0x1)
+
+
+/*=========================================================================
+ * FUNCTION:      skip_over_fieldname 
+ * OVERVIEW:      Skips over the longest part of the string that could be 
+ *                taken as a fieldname given a pointer to a string.
+ *                Allows '/' if slash_okay parameter is true.
+ *                Returns a pointer to just past the fieldname. 
+ *                Returns NULL if no fieldname is found, or in the case of
+ *                slash_okay being TRUE, we may see consecutive slashes 
+ *                (meaning that we were looking for a qualified path, but 
+ *                found something that was badly-formed.)
+ * INTERFACE:
+ *   parameters:  char*: name
+ *                boolean: slash_okay
+ *                
+ *   returns:     char* field name or NULL
+ *=======================================================================*/
+static char *
+skip_over_fieldname(char *name, bool_t slash_okay)
+{
+    bool_t first;
+    char *p;
+    unicode last_ch = 0;
+    for (p = name, first = TRUE; ; first = FALSE) {
+       char *old_p = p;
+       unicode ch = next_utf2unicode(&p);
+       if (isJavaIdentifierStart(ch) || (!first && isJavaIdentifierPart(ch)) 
+             || (slash_okay && ch == '/' && !first)
+             || ch == '_' || ch == '$') {
+           if (ch == '/' && last_ch == '/') {
+               return 0;       /* Don't permit consecutive slashes */
+           } else {
+               last_ch = ch;
+           }
+       } else {
+           return first ? 0 : old_p;
+       }
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      skip_over_field_signature 
+ * OVERVIEW:      Skips over the longest part of the string that could be 
+ *                taken as a field signature given a pointer to a string.
+ *                Allows "void" if void_okay parameter is true.
+ *                Returns a pointer to just past the signature. 
+ *                Returns NULL if no legal signature is found. 
+ * INTERFACE:
+ *   parameters:  char*: name
+ *                boolean: void_okay
+ *                
+ *   returns:     char* field signature or NULL
+ *=======================================================================*/
+static char *
+skip_over_field_signature(char *name, bool_t void_okay)
+{
+    for (;;) {
+       switch (name[0]) {
+            case SIGNATURE_VOID:
+               if (!void_okay) return 0;
+               /* FALL THROUGH */
+            case SIGNATURE_BOOLEAN:
+            case SIGNATURE_BYTE:
+            case SIGNATURE_CHAR:
+            case SIGNATURE_SHORT:
+            case SIGNATURE_INT:
+            case SIGNATURE_LONG:
+               return name + 1;
+
+            case SIGNATURE_FLOAT:
+            case SIGNATURE_DOUBLE:
+                return no_floating_point ? NULL : name + 1;
+
+           case SIGNATURE_CLASS: {
+               /* Skip over the classname, if one is there. */
+               char *p = skip_over_fieldname(name + 1, TRUE);
+               /* The next character better be a semicolon. */
+               if (p && p[0] == ';') {
+                   return p + 1;
+                }
+               return NULL;
+           }
+           
+           case SIGNATURE_ARRAY: 
+               /* The rest of what's there better be a legal signature.  */
+               name++;
+               void_okay = FALSE;
+               break;
+
+           default:
+               return NULL;
+       }
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      CCerror
+ * OVERVIEW:      Handles formating errors found during class file 
+ *                verification. 
+ * INTERFACE:
+ *   parameters:  pointer to the ClassClass structure. 
+ *                char *: format
+ *                
+ *   returns:     nothing 
+ *=======================================================================*/
+static void 
+CCerror (ClassClass *cb, char *format, ...)
+{
+    if (verbose) { 
+       va_list args;
+//     jio_fprintf(stderr, "VERIFIER CLASS ERROR %s:\n", cbName(cb));
+       va_start(args, format);
+           jio_vfprintf(stderr, format, args);        
+       va_end(args);
+//     jio_fprintf(stderr, "\n");
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      IsLegalClassname
+ * OVERVIEW:      Determines if the specified name is a legal UTF name for
+ *                a class name.
+ *                Note that this routine is intended for external use and 
+ *                expects the internal form of qualified classes 
+ *                (i.e. the dots should have been replaced by slashes.)
+ * INTERFACE:
+ *   parameters:  char*: name
+ *                boolean: allowArrayClass 
+ *                
+ *   returns:     boolean type 
+ *=======================================================================*/
+bool_t IsLegalClassname(char *name, bool_t allowArrayClass) 
+{ 
+    char *p;
+    if (name[0] == SIGNATURE_ARRAY) {
+       if (!allowArrayClass) {
+           return FALSE;
+       } else { 
+           /* Everything that's left better be a field signature */
+           p = skip_over_field_signature(name, FALSE);
+       }
+    } else {
+       /* skip over the fieldname.  Slashes are okay */
+       p = skip_over_fieldname(name, TRUE);
+    }
+    return (p != 0 && p[0] == '\0');
+}
+
+#endif
diff --git a/MPC.3.5.LINUX/preverifier/check_code.c b/MPC.3.5.LINUX/preverifier/check_code.c
new file mode 100644 (file)
index 0000000..96f535a
--- /dev/null
@@ -0,0 +1,3970 @@
+/*
+ * @(#)check_code.c    1.26 02/09/27
+ *
+ * Copyright 1995-1999 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ * 
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+/*=========================================================================
+ * SYSTEM:    Verifier
+ * SUBSYSTEM: Verifies codes within a method block.
+ * FILE:      check_code.c
+ * OVERVIEW:  Verifies that the code within a method block does not
+ *            exploit any security holes.
+ * AUTHOR:    Sheng Liang, Consumer & Embedded 
+ *            Initial implementation based on the Classic VM Verifier.
+ *            Edited by Tasneem Sayeed, Java Consumer Technologies
+ *=======================================================================*/
+
+
+/*=========================================================================
+ * Include files
+ *=======================================================================*/
+
+#include "check_code.h"
+
+#include "opcodes.length"
+#include "opcodes.in_out"
+
+//#include "winsock2.h"
+#define ntohl(x) (x)
+
+/*=========================================================================
+ * Globals and extern declarations
+ *=======================================================================*/
+
+#ifdef DEBUG_VERIFIER
+    int verify_verbose = 0;
+    static struct context_type *GlobalContext;
+#endif
+
+void rewriteCode(context_type *vcontext, struct methodblock *mb);
+static void verify_method(context_type *context, struct methodblock *mb);
+static void verify_field(context_type *context, struct fieldblock *fb);
+
+static void verify_opcode_operands (context_type *, int inumber, int offset);
+static void set_protected(context_type *, int inumber, int key, opcode_type);
+static bool_t isSuperClass(context_type *, fullinfo_type);
+
+static void initialize_exception_table(context_type *);
+static int instruction_length(unsigned char *iptr);
+static bool_t isLegalTarget(context_type *, int offset);
+static void verify_constant_pool_type(context_type *, int, unsigned);
+
+static void initialize_dataflow(context_type *);
+static void run_dataflow(context_type *context);
+static void check_register_values(context_type *context, int inumber);
+static void check_flags(context_type *context, int inumber);
+static void pop_stack(context_type *, int inumber, stack_info_type *);
+static void update_registers(context_type *, int inumber, register_info_type *);
+static void update_flags(context_type *, int inumber, 
+                        flag_type *new_and_flags, flag_type *new_or_flags);
+static void push_stack(context_type *, int inumber, stack_info_type *stack);
+
+static void merge_into_successors(context_type *, int inumber, 
+                                 register_info_type *register_info,
+                                 stack_info_type *stack_info, 
+                                 flag_type and_flags, flag_type or_flags);
+static void merge_into_one_successor(context_type *context, 
+                                    int from_inumber, int inumber, 
+                                    register_info_type *register_info,
+                                    stack_info_type *stack_info, 
+                                    flag_type and_flags, flag_type or_flags,
+                                    bool_t isException);
+static void merge_stack(context_type *, int inumber, int to_inumber, 
+                       stack_info_type *);
+static void merge_registers(context_type *, int inumber, int to_inumber, 
+                           register_info_type *);
+static void merge_flags(context_type *context, int from_inumber, int to_inumber,
+                       flag_type new_and_flags, flag_type new_or_flags);
+
+static stack_item_type *copy_stack(context_type *, stack_item_type *);
+static mask_type *copy_masks(context_type *, mask_type *masks, int mask_count);
+static mask_type *add_to_masks(context_type *, mask_type *, int , int);
+
+static fullinfo_type decrement_indirection(fullinfo_type);
+
+static fullinfo_type merge_fullinfo_types(context_type *context, 
+                                         fullinfo_type a, fullinfo_type b,
+                                         bool_t assignment);
+static bool_t isAssignableTo(context_type *,fullinfo_type a, fullinfo_type b);
+
+static ClassClass *object_fullinfo_to_classclass(context_type *, fullinfo_type);
+
+
+#define NEW(type, count) \
+        ((type *)CCalloc(context, (count)*(sizeof(type)), FALSE))
+#define ZNEW(type, count) \
+        ((type *)CCalloc(context, (count)*(sizeof(type)), TRUE))
+
+static void CCinit(context_type *context);
+static void CCreinit(context_type *context);
+static void CCdestroy(context_type *context);
+static void *CCalloc(context_type *context, int size, bool_t zero);
+
+static char *cp_index_to_fieldname(context_type *context, int cp_index);
+static char *cp_index_to_signature(context_type *context, int cp_index);
+static fullinfo_type cp_index_to_class_fullinfo(context_type *, int, bool_t);
+
+static char signature_to_fieldtype(context_type *context, 
+                                  char **signature_p, fullinfo_type *info);
+
+static void CCerror (context_type *, char *format, ...);
+
+#ifdef DEBUG_VERIFIER
+static void print_stack (context_type *, stack_info_type *stack_info);
+static void print_registers(context_type *, register_info_type *register_info);
+static void print_flags(context_type *, flag_type, flag_type);
+static void print_formatted_fieldname(context_type *context, int index);
+#endif
+
+
+/*
+ * Access local hash tables without locking. This extra level
+ * of naming is intended to emphasize the fact that locks are
+ * not held and also to do error handling. Although it is not
+ * strictly necessary, one should always use the "_Local"  
+ * versions of these functions on the verifier's local hash
+ * tables.
+ */
+#define Str2IDFree_Local(localHashRoot) Str2IDFree(localHashRoot)
+
+
+/*=========================================================================
+ * FUNCTION:      Str2ID_Local 
+ * OVERVIEW:      Access local hash tables without locking
+ *                This extra level of naming is intended to emphasize the
+ *                fact that locks are not held and also to do error handling. 
+ *                These functions could all be macros like Str2IDFree_Local(),
+ *                except that Str2ID() and ID2Str() can run out of memory, 
+ *                and the code in this file makes it inconvenient to check
+ *                for that. As an expedient, rather than throwing exceptions,
+ *                Str2ID_Local() is a function that calls CCerror() if 
+ *                necessary. 
+ *                Returns the index given the string which corresponds to the
+ *                hash table entry.
+ * INTERFACE:
+ *   parameters:  context_type *: context 
+ *                struct StrIDhash **: hash_ptr 
+ *                char *: s
+ *                void ***: param
+ *                int: Copy
+ *                
+ *   returns:     unsigned short 
+ *=======================================================================*/
+unsigned short
+Str2ID_Local(context_type *context, struct StrIDhash **hash_ptr, char *s,
+            void ***param, int Copy) {
+    unsigned short ret;
+    if ((ret = Str2ID(hash_ptr, s, param, Copy)) == 0) {
+//     CCerror(context, "Out of memory");
+    }
+
+    return ret;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      ID2Str_Local 
+ * OVERVIEW:      Access local hash tables without locking
+ *                This extra level of naming is intended to emphasize the
+ *                fact that locks are not held and also to do error handling. 
+ *                These functions could all be macros like Str2IDFree_Local(),
+ *                except that Str2ID() and ID2Str() can run out of memory, 
+ *                and the code in this file makes it inconvenient to check
+ *                for that. As an expedient, rather than throwing exceptions,
+ *                ID2Str_Local() is a function that calls CCerror() if 
+ *                necessary. 
+ *                Returns the string given the index which corresponds to the
+ *                hash table entry.
+ * INTERFACE:
+ *   parameters:  context_type *: context 
+ *                struct StrIDhash *: h 
+ *                unsigned short: ID 
+ *                void ***: param
+ *                
+ *   returns:     char * 
+ *=======================================================================*/
+char *
+ID2Str_Local(context_type *context, struct StrIDhash *h, unsigned short ID, 
+            void ***param) {
+    char *ret;
+    if ((ret = ID2Str(h, ID, param)) == 0) {
+//     CCerror(context, "Out of memory");
+    }
+
+    return ret;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      verify_class_codes 
+ * OVERVIEW:      Verifies the code for each of the methods in a class.
+ *                Invoked by verify_class(). 
+ *                Returns true if the class codes are ok. 
+ * INTERFACE:
+ *   parameters:  pointer to the ClassClass structure. 
+ *                
+ *   returns:     boolean type
+ *=======================================================================*/
+bool_t verify_class_codes(ClassClass *cb) {
+    context_type context_structure;
+    context_type *context = &context_structure;
+    bool_t result = TRUE;
+    void **addr;
+    int i;
+
+#ifdef DEBUG_VERIFIER
+    GlobalContext = context;
+#endif
+
+    /* Initialize the class-wide fields of the context. */
+    context->class = cb;
+
+    context->classHash = 0;
+    /* Zero method block field of the context, in case anyone calls CCerrror */
+    context->mb = 0;
+    context->superClasses = NULL;      /* filled in later */
+
+    /* Don't call CCerror or anything that can call it above the setjmp! */
+    if (!setjmp(context->jump_buffer)) {
+       struct methodblock *mb;
+       struct fieldblock *fb;
+
+       CCinit(context);                /* initialize heap; may throw */
+
+       context->object_info = 
+           MAKE_CLASSNAME_INFO(context, JAVAPKG "Object", &addr);
+       *addr = classJavaLangObject;
+       context->string_info =
+           MAKE_CLASSNAME_INFO(context, JAVAPKG "String", &addr);
+       *addr = classJavaLangString;
+       context->throwable_info =
+           MAKE_CLASSNAME_INFO(context, JAVAPKG "Throwable", &addr);
+       *addr = classJavaLangThrowable;
+       context->currentclass_info =
+           MAKE_CLASSNAME_INFO_WITH_COPY(context, cbName(cb), &addr);
+       *addr = cb;
+       if (cbSuperclass(cb) != 0) {
+           ClassClass *super = cbSuperclass(cb);
+           context->superclass_info =
+               MAKE_CLASSNAME_INFO_WITH_COPY(context, cbName(super), &addr);
+           *addr = super;
+       } else { 
+           context->superclass_info = 0;
+       }
+    
+       /* Look at each method */
+       for (i = cbFieldsCount(cb), fb = cbFields(cb); --i >= 0; fb++) 
+           verify_field(context, fb);
+
+        unhand(context->class)->new_class_entries = 
+           (char **)malloc((cbConstantPoolCount(context->class) * 3 + 100) * sizeof(char *));
+        unhand(context->class)->n_new_class_entries = 0;
+
+       for (i = cbMethodsCount(cb), mb = cbMethods(cb); --i >= 0; mb++) 
+           verify_method(context, mb);
+
+       unhand(context->class)->new_class_entries = 
+           (char **)realloc(unhand(context->class)->new_class_entries,
+                            unhand(context->class)->n_new_class_entries * sizeof(char *));
+
+       result = TRUE;
+    } else { 
+       result = FALSE;
+    }
+
+    /* Cleanup */
+    Str2IDFree_Local(&context->classHash);
+
+#ifdef DEBUG_VERIFIER
+    GlobalContext = 0;
+#endif
+
+    if (context->superClasses != NULL) {
+       sysFree(context->superClasses);
+    }
+    CCdestroy(context);                /* destroy heap */
+    return result;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      verify_field
+ * OVERVIEW:      Verifies the field block within each method of a class
+ *                file.
+ *                Invoked by verify_class_codes(). 
+ *                Returns true if the field block is ok. 
+ * INTERFACE:
+ *   parameters:  pointer to the context_type structure. 
+ *                pointer to the field block
+ *                
+ *   returns:     boolean type
+ *=======================================================================*/
+static void
+verify_field(context_type *context, struct fieldblock *fb)
+{
+    int access_bits = fb->access;
+
+    if (  ((access_bits & ACC_PUBLIC) != 0) && 
+         ((access_bits & (ACC_PRIVATE | ACC_PROTECTED)) != 0)) {
+       if (verbose) { 
+       //    jio_fprintf(stderr, "VERIFIER ERROR %s.%s:\n", 
+       //          cbName(fieldclass(fb)), fb->name);
+       //    jio_fprintf(stderr, "Inconsistent access bits.");
+       }
+       longjmp(context->jump_buffer, 1);
+    } 
+}
+
+
+/*=========================================================================
+ * FUNCTION:      get_type_name
+ * OVERVIEW:      Retrieves the type name information given the item type. 
+ *                Used by get_type_code() which is invoked by verify_method()
+ *                to retrieve the type code for the stack map entries. 
+ * INTERFACE:
+ *   parameters:  pointer to the context_type structure. 
+ *                fullinfo_type: type
+ *                char *: buf
+ *                
+ *   returns:     nothing
+ *=======================================================================*/
+static void 
+get_type_name(context_type *context, fullinfo_type type, char *buf)
+{
+    int i;
+    int indirection = GET_INDIRECTION(type);
+    for (i = indirection; i-- > 0; )
+       *buf++ = '[';
+    switch (GET_ITEM_TYPE(type)) {
+        case ITEM_Integer:       
+           *buf++ = 'I'; break;
+       case ITEM_Float:         
+           *buf++ = 'F'; break;
+       case ITEM_Double:        
+           *buf++ = 'D'; break;
+       case ITEM_Long:          
+           *buf++ = 'J'; break;
+       case ITEM_Char:
+           *buf++ = 'C'; break;
+       case ITEM_Short:
+           *buf++ = 'S'; break;
+       case ITEM_Byte:
+           *buf++ = 'B'; break;
+       case ITEM_Boolean:
+           *buf++ = 'Z'; break;
+       case ITEM_Object: {
+            unsigned short extra = GET_EXTRA_INFO(type);
+            if (indirection) *buf++ = 'L';
+            if (extra == 0) {
+//                panic("unexpected");
+            } else {
+                char *name = ID2Str_Local(context, context->classHash,
+                                          extra, 0);
+                strcpy(buf, name);
+                if (indirection) strcat(buf, ";");
+            }
+            return; 
+        }
+     //   default: 
+     //       panic("bad type");
+    }
+    *buf = '\0';
+}
+
+
+/*=========================================================================
+ * FUNCTION:      check_class_constant 
+ * OVERVIEW:      Checks and returns the index corresponding to the given
+ *                UTF8 constant entry within the constant pool.
+ *                Returns -1 if none was found.
+ *                Invoked by get_type_code(). 
+ * INTERFACE:
+ *   parameters:  pointer to the ClassClass structure. 
+ *                char *: utf8
+ *                
+ *   returns:     long type
+ *=======================================================================*/
+long check_class_constant(ClassClass *cb, char *utf8)
+{
+    int i;
+    cp_item_type *constant_pool = cbConstantPool(cb);
+    unsigned char *type_table = 
+        constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
+    for (i = 0; i < cbConstantPoolCount(cb); i++) {
+       if (type_table[i] == (CONSTANT_Class | CONSTANT_POOL_ENTRY_RESOLVED) &&
+           strcmp(utf8, cbName(constant_pool[i].clazz)) == 0) {
+           return i;
+       }
+       if (type_table[i] == CONSTANT_Class &&
+           strcmp(utf8, constant_pool[constant_pool[i].i].cp) == 0) {
+           return i;
+       }
+    }
+    return -1;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      get_type_code
+ * OVERVIEW:      Retrieves the type code entry given the item type. 
+ *                Invoked by verify_method() to retrieve the type code 
+ *                for the stack map entries. 
+ * INTERFACE:
+ *   parameters:  pointer to the context_type structure. 
+ *                fullinfo_type: type
+ *                
+ *   returns:     struct map_entry 
+ *=======================================================================*/
+struct map_entry get_type_code(context_type *context, fullinfo_type type)
+{
+    struct map_entry result = {0,0};
+    switch (type) {
+        case ITEM_Double_2:
+        case ITEM_Long_2:
+        case ITEM_Bogus:
+           result.type = CF_ITEM_Bogus;
+           return result;
+       case ITEM_Integer:
+           result.type = CF_ITEM_Integer;
+           return result;
+       case ITEM_Float:
+           result.type = CF_ITEM_Float;
+           return result;
+       case ITEM_Double:
+           result.type = CF_ITEM_Double;
+           return result;
+       case ITEM_Long:
+           result.type = CF_ITEM_Long;
+           return result;
+       case ITEM_InitObject:
+           result.type = CF_ITEM_InitObject;
+           return result;
+       default:
+       if (GET_ITEM_TYPE(type) == ITEM_NewObject) {
+           int inum = GET_EXTRA_INFO(type);
+           result.type = CF_ITEM_NewObject;
+           result.info = context->instruction_data[inum].offset;
+           return result;
+       } else if (GET_ITEM_TYPE(type) == ITEM_Object && GET_EXTRA_INFO(type) == 0) {
+           result.type = CF_ITEM_Null;
+           return result;
+        } else if (GET_ITEM_TYPE(type) == ITEM_Object || GET_INDIRECTION(type) > 0) {
+           char type_name[1024];
+           int i;
+           result.type = CF_ITEM_Object;
+           get_type_name(context, type, type_name);
+           i = check_class_constant(context->class, type_name);
+           if (i >= 0) {
+               result.info = i;
+               return result;
+           }
+           for (i = 0; i < unhand(context->class)->n_new_class_entries; i++) {
+               if (strcmp(type_name, unhand(context->class)->new_class_entries[i]) == 0) {
+                   result.info = ~i;
+                   return result;
+               }
+           }
+           { 
+               int entries = unhand(context->class)->n_new_class_entries;
+               unhand(context->class)->new_class_entries[entries] = strdup(type_name);
+               result.info = ~entries;
+               unhand(context->class)->n_new_class_entries = entries + 1;
+               return result;
+           }
+       } else {
+       //    panic("bad type code");
+               return result; /* not reached */
+       }
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      verify_method
+ * OVERVIEW:      Verifies the code for one method within a class file.
+ *                Invoked by verify_class_codes(). 
+ * INTERFACE:
+ *   parameters:  pointer to the context_type structure. 
+ *                struct methodblock*: mb
+ *                
+ *   returns:     nothing 
+ *=======================================================================*/
+static void
+verify_method(context_type *context, struct methodblock *mb)
+{
+    int access_bits = mb->fb.access;
+    unsigned char *code;
+    int code_length;
+    short *code_data;
+    instruction_data_type *idata = 0;
+    int instruction_count;
+    int i, offset, inumber;
+    int exception_count;
+    int n_stack_maps, dead_count, jsr_count;
+
+ again:
+    code = mb->code;
+    code_length = mb->code_length;
+
+    /* CCerror can give method-specific info once this is set */
+    context->mb = mb;
+
+    CCreinit(context);         /* initial heap */
+    code_data = NEW(short, code_length);
+
+#ifdef DEBUG_VERIFIER
+//    if (verify_verbose) {
+//     jio_fprintf(stdout, "Looking at %s.%s%s 0x%x\n", 
+//            cbName(fieldclass(&mb->fb)), mb->fb.name, mb->fb.signature, 
+//            (long)mb);
+//    }
+#endif
+
+    if (((access_bits & ACC_PUBLIC) != 0) && 
+       ((access_bits & (ACC_PRIVATE | ACC_PROTECTED)) != 0)) {
+//     CCerror(context, "Inconsistent access bits.");
+    } 
+
+    if ((access_bits & (ACC_ABSTRACT | ACC_NATIVE)) != 0) { 
+       /* not much to do for abstract or native methods */
+        return;
+    } 
+
+    if (code_length >= 65535) {
+//     CCerror(context, "Code of a method longer than 65535 bytes");
+    }
+
+    /* Run through the code.  Mark the start of each instruction, and give
+     * the instruction a number */
+    for (i = 0, offset = 0; offset < code_length; i++) {
+       int length = instruction_length(&code[offset]);
+       int next_offset = offset + length;
+//     if (length <= 0) 
+//         CCerror(context, "Illegal instruction found at offset %d", offset);
+//     if (next_offset > code_length) 
+//         CCerror(context, "Code stops in the middle of instruction "
+//                 " starting at offset %d", offset);
+       code_data[offset] = i;
+       while (++offset < next_offset)
+           code_data[offset] = -1; /* illegal location */
+    }
+    instruction_count = i;     /* number of instructions in code */
+    
+    /* Allocate a structure to hold info about each instruction. */
+    idata = NEW(instruction_data_type, instruction_count);
+
+    /* Initialize the heap, and other info in the context structure. */
+    context->code = code;
+    context->instruction_data = idata;
+    context->code_data = code_data;
+    context->instruction_count = instruction_count;
+    context->handler_info = NEW(struct handler_info_type, 
+                               mb->exception_table_length);
+    context->bitmask_size = (mb->nlocals + (BITS_PER_INT - 1))/BITS_PER_INT;
+    
+//    if (instruction_count == 0) 
+//     CCerror(context, "Empty code");
+       
+    for (inumber = 0, offset = 0; offset < code_length; inumber++) {
+       int length = instruction_length(&code[offset]);
+       instruction_data_type *this_idata = &idata[inumber];
+       this_idata->opcode = code[offset];
+       this_idata->offset = offset;
+       this_idata->length = length;
+       this_idata->stack_info.stack = NULL;
+       this_idata->stack_info.stack_size  = UNKNOWN_STACK_SIZE;
+       this_idata->register_info.register_count = UNKNOWN_REGISTER_COUNT;
+       this_idata->changed = FALSE;  /* no need to look at it yet. */
+       this_idata->protected = FALSE;  /* no need to look at it yet. */
+        /* Added for inlinejsr */
+          this_idata->is_target = FALSE;  /* no need to look at it yet. */
+       this_idata->and_flags = (flag_type) -1; /* "bottom" and value */
+       this_idata->or_flags = 0; /* "bottom" or value*/
+
+       /* This also sets up this_data->operand.  It also makes the 
+        * xload_x and xstore_x instructions look like the generic form. */
+       verify_opcode_operands(context, inumber, offset);
+       offset += length;
+    }
+    
+    
+    /* make sure exception table is reasonable. */
+    initialize_exception_table(context);
+    /* Set up first instruction, and start of exception handlers. */
+    initialize_dataflow(context);
+    /* Run data flow analysis on the instructions. */
+    context->redoJsr = FALSE;
+    run_dataflow(context);
+
+    for (inumber = 0; inumber < instruction_count; inumber++) {
+        instruction_data_type *this_idata = &idata[inumber];
+        if (  (this_idata->or_flags & FLAG_REACHED) && 
+              ((this_idata->opcode == opc_jsr) || 
+               (this_idata->opcode == opc_jsr_w)) && 
+              (this_idata->operand2.i == UNKNOWN_RET_INSTRUCTION)) { 
+            this_idata->changed = TRUE;
+            context->redoJsr = TRUE;
+        }
+    }
+    if (context->redoJsr) { 
+        run_dataflow(context);
+    }
+
+
+    /* verify checked exceptions, if any */
+    if ((exception_count = mb->nexceptions) > 0) {
+       unsigned short *exceptions = mb->exceptions;
+       for (i = 0; i < (int)exception_count; i++) {
+           /* Make sure the constant pool item is CONSTANT_Class */
+           verify_constant_pool_type(context, (int)exceptions[i],
+               1 << CONSTANT_Class);
+       }
+    }
+
+    
+    dead_count = jsr_count = 0;
+    for (inumber = 0; inumber < instruction_count; inumber++) {
+        instruction_data_type *this_idata = &idata[inumber];
+        if ((this_idata->or_flags & FLAG_REACHED) == 0) { 
+            dead_count++;
+        } else if (this_idata->opcode == opc_jsr ||
+                   this_idata->opcode == opc_jsr_w) { 
+            jsr_count++;
+        }
+    }
+    if (dead_count > 0 || jsr_count > 0) { 
+        rewriteCode(context, mb);
+        goto again;
+    }
+
+    n_stack_maps = 0;
+    for (inumber = 0; inumber < instruction_count; inumber++) {
+        instruction_data_type *this_idata = &idata[inumber];
+        if (this_idata->is_target) { 
+            n_stack_maps++;
+        }
+    }
+
+    mb->n_stack_maps = n_stack_maps;
+    mb->stack_maps = 
+        (struct stack_map *)malloc(n_stack_maps * sizeof(struct stack_map));
+
+    n_stack_maps = 0;
+    for (inumber = 0; inumber < instruction_count; inumber++) {
+       instruction_data_type *this_idata = &idata[inumber];
+       if (this_idata->is_target) {
+            struct stack_info_type *stack_info = &this_idata->stack_info;
+            struct register_info_type *register_info = &this_idata->register_info;
+            int register_count = register_info->register_count;
+           struct stack_item_type *stack;
+           struct map_entry *new_entries;
+           int index, index2;
+
+
+            /* We may be allocating too big a structure if there are longs 
+             * or doubles on the stack, but that's okay */
+           new_entries = (struct map_entry *)malloc(register_count * sizeof(struct map_entry));
+
+           for (index2 = 0, index = 0; index < register_count; index++) {
+                fullinfo_type info = register_info->registers[index];
+                if (info == ITEM_Double || info == ITEM_Long) { 
+                    if (index + 1 < register_count && 
+                           register_info->registers[index + 1] == info+1) {
+                        new_entries[index2++] = get_type_code(context, info);
+                        index++;
+                    } else {
+                        new_entries[index2++] = get_type_code(context, ITEM_Bogus);
+                    }
+                } else { 
+                    new_entries[index2++] = get_type_code(context, info);
+                }
+            }
+            mb->stack_maps[n_stack_maps].offset = this_idata->offset;
+           mb->stack_maps[n_stack_maps].locals = new_entries;
+           mb->stack_maps[n_stack_maps].nlocals = index2;
+
+
+           mb->stack_maps[n_stack_maps].nstacks = 0;
+           for (stack = stack_info->stack; stack; stack = stack->next) {
+               mb->stack_maps[n_stack_maps].nstacks++;
+           }
+           new_entries = (struct map_entry *)malloc(mb->stack_maps[n_stack_maps].nstacks * sizeof(struct map_entry));
+           index = 0;
+           for (stack = stack_info->stack; stack; stack = stack->next) {
+               new_entries[mb->stack_maps[n_stack_maps].nstacks - (++index)] = 
+                   get_type_code(context, stack->item);
+           }
+           mb->stack_maps[n_stack_maps].stacks = new_entries;
+
+           unhand(context->class)->has_stack_maps = 1;
+           n_stack_maps++;
+       }
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      verify_opcode_operands
+ * OVERVIEW:      Verifies the operands of a single instruction given an
+ *                instruction number and an offset.
+ *                Also, for simplicity, move the operand into the ->operand
+ *                field. 
+ *                Make sure that branches do not go into the middle
+ *                of nowhere.
+ *                Invoked by verify_method(). 
+ * INTERFACE:
+ *   parameters:  context_type *: context
+ *                int: inumber
+ *                int: offset
+ *                
+ *   returns:     nothing 
+ *=======================================================================*/
+static void
+verify_opcode_operands(context_type *context, int inumber, int offset)
+{
+    instruction_data_type *idata = context->instruction_data;
+    instruction_data_type *this_idata = &idata[inumber];
+    short *code_data = context->code_data;
+    struct methodblock *mb = context->mb;
+    unsigned char *code = context->code;
+    opcode_type opcode = this_idata->opcode;
+    int var; 
+    
+    this_idata->operand.i = 0;
+    this_idata->operand2.i = 0;
+
+    switch (opcode) {
+
+    case opc_jsr:
+       /* instruction of ret statement */
+       this_idata->operand2.i = UNKNOWN_RET_INSTRUCTION;
+       /* FALLTHROUGH */
+    case opc_ifeq: case opc_ifne: case opc_iflt: 
+    case opc_ifge: case opc_ifgt: case opc_ifle:
+    case opc_ifnull: case opc_ifnonnull:
+    case opc_if_icmpeq: case opc_if_icmpne: case opc_if_icmplt: 
+    case opc_if_icmpge: case opc_if_icmpgt: case opc_if_icmple:
+    case opc_if_acmpeq: case opc_if_acmpne:   
+    case opc_goto: {
+       /* Set the ->operand to be the instruction number of the target. */
+       int jump = (((signed char)(code[offset+1])) << 8) + code[offset+2];
+       int target = offset + jump;
+//     if (!isLegalTarget(context, target))
+//         CCerror(context, "Illegal target of jump or branch");
+       this_idata->operand.i = code_data[target];
+       break;
+    }
+       
+    case opc_jsr_w:
+       /* instruction of ret statement */
+       this_idata->operand2.i = UNKNOWN_RET_INSTRUCTION;
+       /* FALLTHROUGH */
+    case opc_goto_w: {
+       /* Set the ->operand to be the instruction number of the target. */
+       int jump = (((signed char)(code[offset+1])) << 24) + 
+                    (code[offset+2] << 16) + (code[offset+3] << 8) + 
+                    (code[offset + 4]);
+       int target = offset + jump;
+//     if (!isLegalTarget(context, target))
+//         CCerror(context, "Illegal target of jump or branch");
+       this_idata->operand.i = code_data[target];
+       break;
+    }
+
+    case opc_tableswitch: 
+    case opc_lookupswitch: {
+       /* Set the ->operand to be a table of possible instruction targets. */
+       long *lpc = (long *) UCALIGN(code + offset + 1);
+       long *lptr;
+       int *saved_operand;
+       int keys;
+       int k, delta;
+       if (opcode == opc_tableswitch) {
+           keys = ntohl(lpc[2]) -  ntohl(lpc[1]) + 1;
+           delta = 1;
+       } else { 
+           keys = ntohl(lpc[1]); /* number of pairs */
+           delta = 2;
+           /* Make sure that the tableswitch items are sorted */
+           for (k = keys - 1, lptr = &lpc[2]; --k >= 0; lptr += 2) {
+               long this_key = ntohl(lptr[0]); /* NB: ntohl may be unsigned */
+               long next_key = ntohl(lptr[2]);
+//             if (this_key >= next_key) { 
+//                 CCerror(context, "Unsorted lookup switch");
+//             }
+           }
+       }
+        /* This code has been changed for inlining.   We know have the keys
+         * in the same order that they occur in the code, with the default
+         * key being the first one.
+         */
+       saved_operand = NEW(int, keys + 2);
+//     if (!isLegalTarget(context, offset + ntohl(lpc[0]))) 
+//         CCerror(context, "Illegal default target in switch");
+
+        saved_operand[0] = keys + 1; /* number of successors */
+       saved_operand[1] = code_data[offset + ntohl(lpc[0])]; /* default */
+
+       for (k = 0, lptr = &lpc[3]; k < keys; lptr += delta, k++) {
+           int target = offset + ntohl(lptr[0]);
+          // if (!isLegalTarget(context, target))
+       //      CCerror(context, "Illegal branch in opc_tableswitch");
+           saved_operand[k + 2] = code_data[target];
+       }
+       this_idata->operand.ip = saved_operand;
+       break;
+    }
+       
+    case opc_ldc: {   
+       /* Make sure the constant pool item is the right type. */
+       int key = code[offset + 1];
+       int types = (1 << CONSTANT_Integer) | (1 << CONSTANT_Float) |
+                           (1 << CONSTANT_String);
+       this_idata->operand.i = key;
+       verify_constant_pool_type(context, key, types);
+       break;
+    }
+         
+    case opc_ldc_w: {   
+       /* Make sure the constant pool item is the right type. */
+       int key = (code[offset + 1] << 8) + code[offset + 2];
+       int types = (1 << CONSTANT_Integer) | (1 << CONSTANT_Float) |
+           (1 << CONSTANT_String);
+       this_idata->operand.i = key;
+       verify_constant_pool_type(context, key, types);
+       break;
+    }
+         
+    case opc_ldc2_w: { 
+       /* Make sure the constant pool item is the right type. */
+       int key = (code[offset + 1] << 8) + code[offset + 2];
+       int types = (1 << CONSTANT_Double) | (1 << CONSTANT_Long);
+       this_idata->operand.i = key;
+       verify_constant_pool_type(context, key, types);
+       break;
+    }
+
+    case opc_getfield: case opc_putfield:
+    case opc_getstatic: case opc_putstatic: {
+       /* Make sure the constant pool item is the right type. */
+       int key = (code[offset + 1] << 8) + code[offset + 2];
+       this_idata->operand.i = key;
+       verify_constant_pool_type(context, key, 1 << CONSTANT_Fieldref);        
+       if (opcode == opc_getfield || opcode == opc_putfield) 
+           set_protected(context, inumber, key, opcode);
+       break;
+    }
+
+    case opc_invokevirtual:
+    case opc_invokespecial: 
+    case opc_invokestatic:
+    case opc_invokeinterface: {
+       /* Make sure the constant pool item is the right type. */
+       int key = (code[offset + 1] << 8) + code[offset + 2];
+       char *methodname;
+       fullinfo_type clazz_info;
+       int kind = (opcode == opc_invokeinterface 
+                           ? 1 << CONSTANT_InterfaceMethodref
+                           : 1 << CONSTANT_Methodref);
+       /* Make sure the constant pool item is the right type. */
+       verify_constant_pool_type(context, key, kind);
+       methodname = cp_index_to_fieldname(context, key);
+       clazz_info = cp_index_to_class_fullinfo(context, key, TRUE);
+       this_idata->operand.i = key;
+       this_idata->operand2.fi = clazz_info;
+       if (strcmp(methodname, "<init>") == 0) {
+//         if (opcode != opc_invokespecial)
+//             CCerror(context, 
+//                     "Must call initializers using invokespecial");
+           this_idata->opcode = opc_invokeinit;
+       } else {
+//         if (methodname[0] == '<') 
+//             CCerror(context, "Illegal call to internal method");
+           if (opcode == opc_invokespecial 
+                  && clazz_info != context->currentclass_info  
+                  && clazz_info != context->superclass_info) {
+               ClassClass *cb = context->class;
+               for (; ; cb = cbSuperclass(cb)) { 
+                   if (clazz_info == MAKE_CLASSNAME_INFO_WITH_COPY(context, cbName(cb), 0))
+                       break;
+                   /* The optimizer make cause this to happen on local code */
+                   if (cbSuperclass(cb) == 0) {
+                       /* optimizer make cause this to happen on local code */
+       //              if (cbLoader(cb) != 0) 
+       //                  CCerror(context, 
+       //                          "Illegal use of nonvirtual function call");
+                       break;
+                   }
+               }
+           }
+       }
+       if (opcode == opc_invokeinterface) { 
+           char *signature = cp_index_to_signature(context, key);
+           unsigned int args1 = Signature2ArgsSize(signature) + 1;
+           unsigned int args2 = code[offset + 3];
+           if (args1 != args2) {
+       //      CCerror(context, 
+       //              "Inconsistent args_size for opc_invokeinterface");      
+           } 
+            if (code[offset + 4] != 0) {
+            //    CCerror(context,
+            //            "Fourth operand byte of invokeinterface must be zero");
+            }
+       } else if (opcode == opc_invokevirtual 
+                     || opcode == opc_invokespecial) 
+           set_protected(context, inumber, key, opcode);
+       break;
+    }
+       
+
+    case opc_instanceof: 
+    case opc_checkcast: 
+    case opc_new:
+    case opc_anewarray: 
+    case opc_multianewarray: {
+       /* Make sure the constant pool item is a class */
+       int key = (code[offset + 1] << 8) + code[offset + 2];
+       fullinfo_type target;
+       verify_constant_pool_type(context, key, 1 << CONSTANT_Class);
+       target = cp_index_to_class_fullinfo(context, key, FALSE);
+//     if (GET_ITEM_TYPE(target) == ITEM_Bogus) 
+//         CCerror(context, "Illegal type");
+       switch(opcode) {
+       case opc_anewarray:
+           if ((GET_INDIRECTION(target)) >= MAX_ARRAY_DIMENSIONS)
+               CCerror(context, "Array with too many dimensions");
+           this_idata->operand.fi = MAKE_FULLINFO(GET_ITEM_TYPE(target),
+                                                  GET_INDIRECTION(target) + 1,
+                                                  GET_EXTRA_INFO(target));
+           break;
+       case opc_new:
+//         if (WITH_ZERO_EXTRA_INFO(target) !=
+//                          MAKE_FULLINFO(ITEM_Object, 0, 0))
+//             CCerror(context, "Illegal creation of multi-dimensional array");
+           /* operand gets set to the "unitialized object".  operand2 gets
+            * set to what the value will be after it's initialized. */
+           this_idata->operand.fi = MAKE_FULLINFO(ITEM_NewObject, 0, inumber);
+           this_idata->operand2.fi = target;
+           break;
+       case opc_multianewarray:
+           this_idata->operand.fi = target;
+           this_idata->operand2.i = code[offset + 3];
+       //    if (    (this_idata->operand2.i > (int)GET_INDIRECTION(target))
+       //       || (this_idata->operand2.i == 0))
+       //      CCerror(context, "Illegal dimension argument");
+           break;
+       default:
+           this_idata->operand.fi = target;
+       }
+       break;
+    }
+       
+    case opc_newarray: {
+       /* Cache the result of the opc_newarray into the operand slot */
+       fullinfo_type full_info;
+       switch (code[offset + 1]) {
+           case T_INT:    
+               full_info = MAKE_FULLINFO(ITEM_Integer, 1, 0); break;
+           case T_LONG:   
+               full_info = MAKE_FULLINFO(ITEM_Long, 1, 0); break;
+           case T_FLOAT:  
+                full_info = MAKE_FULLINFO(ITEM_Float, 1, 0); break;
+           case T_DOUBLE: 
+               full_info = MAKE_FULLINFO(ITEM_Double, 1, 0); break;
+           case T_BYTE:
+               full_info = MAKE_FULLINFO(ITEM_Byte, 1, 0); break;
+           case T_BOOLEAN:
+               full_info = MAKE_FULLINFO(ITEM_Boolean, 1, 0); break;
+           case T_CHAR:   
+               full_info = MAKE_FULLINFO(ITEM_Char, 1, 0); break;
+           case T_SHORT:  
+               full_info = MAKE_FULLINFO(ITEM_Short, 1, 0); break;
+           default:
+                full_info = 0;  /* make GCC happy */
+       //      CCerror(context, "Bad type passed to opc_newarray");
+       }
+       this_idata->operand.fi = full_info;
+       break;
+    }
+         
+    /* Fudge iload_x, aload_x, etc to look like their generic cousin. */
+    case opc_iload_0: case opc_iload_1: case opc_iload_2: case opc_iload_3:
+       this_idata->opcode = opc_iload;
+       var = opcode - opc_iload_0;
+       goto check_local_variable;
+         
+    case opc_fload_0: case opc_fload_1: case opc_fload_2: case opc_fload_3:
+       this_idata->opcode = opc_fload;
+       var = opcode - opc_fload_0;
+       goto check_local_variable;
+
+    case opc_aload_0: case opc_aload_1: case opc_aload_2: case opc_aload_3:
+       this_idata->opcode = opc_aload;
+       var = opcode - opc_aload_0;
+       goto check_local_variable;
+
+    case opc_lload_0: case opc_lload_1: case opc_lload_2: case opc_lload_3:
+       this_idata->opcode = opc_lload;
+       var = opcode - opc_lload_0;
+       goto check_local_variable2;
+
+    case opc_dload_0: case opc_dload_1: case opc_dload_2: case opc_dload_3:
+       this_idata->opcode = opc_dload;
+       var = opcode - opc_dload_0;
+       goto check_local_variable2;
+
+    case opc_istore_0: case opc_istore_1: case opc_istore_2: case opc_istore_3:
+       this_idata->opcode = opc_istore;
+       var = opcode - opc_istore_0;
+       goto check_local_variable;
+       
+    case opc_fstore_0: case opc_fstore_1: case opc_fstore_2: case opc_fstore_3:
+       this_idata->opcode = opc_fstore;
+       var = opcode - opc_fstore_0;
+       goto check_local_variable;
+
+    case opc_astore_0: case opc_astore_1: case opc_astore_2: case opc_astore_3:
+       this_idata->opcode = opc_astore;
+       var = opcode - opc_astore_0;
+       goto check_local_variable;
+
+    case opc_lstore_0: case opc_lstore_1: case opc_lstore_2: case opc_lstore_3:
+       this_idata->opcode = opc_lstore;
+       var = opcode - opc_lstore_0;
+       goto check_local_variable2;
+
+    case opc_dstore_0: case opc_dstore_1: case opc_dstore_2: case opc_dstore_3:
+       this_idata->opcode = opc_dstore;
+       var = opcode - opc_dstore_0;
+       goto check_local_variable2;
+
+    case opc_wide: 
+       this_idata->opcode = code[offset + 1];
+       var = (code[offset + 2] << 8) + code[offset + 3];
+       switch(this_idata->opcode) {
+           case opc_lload:  case opc_dload: 
+           case opc_lstore: case opc_dstore:
+               goto check_local_variable2;
+           default:
+               goto check_local_variable;
+       }
+
+    case opc_iinc:             /* the increment amount doesn't matter */
+    case opc_ret: 
+    case opc_aload: case opc_iload: case opc_fload:
+    case opc_astore: case opc_istore: case opc_fstore:
+       var = code[offset + 1];
+    check_local_variable:
+       /* Make sure that the variable number isn't illegal. */
+       this_idata->operand.i = var;
+//     if (var >= (int)mb->nlocals) 
+//         CCerror(context, "Illegal local variable number");
+       break;
+           
+    case opc_lload: case opc_dload: case opc_lstore: case opc_dstore: 
+       var = code[offset + 1];
+    check_local_variable2:
+       /* Make sure that the variable number isn't illegal. */
+       this_idata->operand.i = var;
+//     if ((var + 1) >= (int)mb->nlocals)
+//         CCerror(context, "Illegal local variable number");
+       break;
+       
+ //   default:
+//     if (opcode >= opc_breakpoint) 
+//         CCerror(context, "Quick instructions shouldn't appear yet.");
+       break;
+    } /* of switch */
+}
+
+
+/*=========================================================================
+ * FUNCTION:      set_protected
+ * OVERVIEW:      Checks the field access to see if the instruction is 
+ *                protected, is private and is in the same class package, 
+ *                then the protected bit for the given instruction is set.
+ *                Invoked by verify_operands_opcodes() to set protected bit
+ *                for instructions of the following opcode types: 
+ *                opc_getfield, opc_putfield, and opc_invokevirtual. 
+ * INTERFACE:
+ *   parameters:  context_type *: context
+ *                int: instruction number
+ *                int: key
+ *                opcode_type: opcode    
+ *                
+ *   returns:     nothing 
+ *=======================================================================*/
+static void 
+set_protected(context_type *context, int inumber, int key, opcode_type opcode) 
+{
+ /*   fullinfo_type clazz_info = cp_index_to_class_fullinfo(context, key, TRUE);
+    if (isSuperClass(context, clazz_info)) {
+       char *name = cp_index_to_fieldname(context, key);
+       char *signature = cp_index_to_signature(context, key);
+       unsigned ID = NameAndTypeToHash(name, signature);
+       ClassClass *calledClass = 
+           object_fullinfo_to_classclass(context, clazz_info);
+       struct fieldblock *fb;
+
+       if (ID == 0) {  // NameAndTypeToHash returns 0 if out of memory 
+         //   CCerror(context, "Out of memory");
+            return;
+        }
+       if (opcode != opc_invokevirtual && opcode != opc_invokespecial) { 
+           int n = cbFieldsCount(calledClass);
+           fb = cbFields(calledClass);
+           for (; --n >= 0; fb++) {
+               if (fb->ID == ID) {
+                   goto haveIt;
+               }
+           }
+           return;
+       } else { 
+           struct methodblock *mb = cbMethods(calledClass);
+           int n = cbMethodsCount(calledClass);
+           for (; --n >= 0; mb++) {
+               if (mb->fb.ID == ID) {
+                   fb = &mb->fb;
+                   goto haveIt;
+               }
+           }
+           return;
+       }
+    haveIt:
+       if (IsProtected(fb->access)) {
+           if (IsPrivate(fb->access) ||
+                   !IsSameClassPackage(calledClass, context->class))
+               context->instruction_data[inumber].protected = TRUE;
+       }
+    }*/
+}
+
+
+/*=========================================================================
+ * FUNCTION:      isSuperClass
+ * OVERVIEW:      Determines which of the classes are superclasses.
+ *                Returns true if the given clazz_info corresponds to a 
+ *                a superclass.
+ * INTERFACE:
+ *   parameters:  context_type* : context 
+ *                fullinfo_type: clazz_info
+ *                
+ *   returns:     boolean type
+ *=======================================================================*/
+static bool_t 
+isSuperClass(context_type *context, fullinfo_type clazz_info) { 
+
+       //return TRUE;
+
+    fullinfo_type *fptr = context->superClasses;
+    if (fptr == NULL) { 
+       ClassClass *cb;
+       fullinfo_type *gptr;
+       int i;
+       /* Count the number of superclasses.  By counting ourselves, and
+        * not counting Object, we get the same number.    */
+       for (i = 0, cb = context->class;
+            cb != classJavaLangObject; 
+            i++, cb = cbSuperclass(cb));
+       /* Can't go on context heap since it survives more than one method */
+       context->superClasses = fptr 
+           = sysMalloc(sizeof(fullinfo_type)*(i + 1));
+       if (fptr == 0) {
+        //   CCerror(context, "Out of memory");
+       }
+       for (gptr = fptr, cb = context->class; cb != classJavaLangObject; ) { 
+           void **addr;
+           cb = cbSuperclass(cb);
+           *gptr++ = MAKE_CLASSNAME_INFO_WITH_COPY(context, cbName(cb), &addr); 
+           *addr = cb;
+       }
+       *gptr = 0;
+    } 
+    for (; *fptr != 0; fptr++) { 
+       if (*fptr == clazz_info)
+           return TRUE;
+    }
+    return FALSE;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      initialize_exception_table
+ * OVERVIEW:      Initializes the exception table.
+ *                Looks through each item on the exception table and ensures
+ *                that each of the fields refers to a legal instruction.
+ * INTERFACE:
+ *   parameters:  pointer to the context_type structure. 
+ *                
+ *   returns:     nothing 
+ *=======================================================================*/
+static void
+initialize_exception_table(context_type *context)
+{
+    struct methodblock *mb = context->mb;
+    struct CatchFrame *exception_table = mb->exception_table;
+    struct handler_info_type *handler_info = context->handler_info;
+    short *code_data = context->code_data;
+    unsigned long code_length = mb->code_length;
+
+    int i;
+    for (i = mb->exception_table_length; 
+            --i >= 0; exception_table++, handler_info++) {
+       unsigned long start = exception_table->start_pc;
+       unsigned long end = exception_table->end_pc;
+       unsigned long handler = exception_table->handler_pc;
+       unsigned catchType = exception_table->catchType;
+       stack_item_type *stack_item = NEW(stack_item_type, 1);
+       if (!(  start < end && start >= 0 
+             && isLegalTarget(context, start) 
+             && (end ==  code_length || isLegalTarget(context, end)))) {
+        //   CCerror(context, "Illegal exception table range");
+       }
+       if (!((handler > 0) && isLegalTarget(context, handler))) {
+        //   CCerror(context, "Illegal exception table handler");
+       }
+
+       handler_info->start = code_data[start];
+       /* end may point to one byte beyond the end of bytecodes. */
+       handler_info->end = (end == context->mb->code_length) ? 
+           context->instruction_count : code_data[end];
+       handler_info->handler = code_data[handler];
+       handler_info->stack_info.stack = stack_item;
+       handler_info->stack_info.stack_size = 1;
+
+       stack_item->next = NULL;
+       if (catchType != 0) {
+           union cp_item_type *cp = cbConstantPool(context->class);
+           char *classname;
+           verify_constant_pool_type(context, catchType, 1 << CONSTANT_Class);
+           classname = GetClassConstantClassName(cp, catchType);
+           stack_item->item = MAKE_CLASSNAME_INFO_WITH_COPY(context, classname, 0);
+       } else {
+           stack_item->item = context->throwable_info;
+       }
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      instruction_length
+ * OVERVIEW:      Given a pointer to an instruction, return its length.
+ *                Use the table opcode_length[] which is automatically built. 
+ * INTERFACE:
+ *   parameters:  pointer to the instruction
+ *                
+ *   returns:     int type
+ *=======================================================================*/
+static int instruction_length(unsigned char *iptr)
+{
+    int instruction = *iptr;
+    switch (instruction) {
+        case opc_tableswitch: {
+           long *lpc = (long *) UCALIGN(iptr + 1);
+           int index = ntohl(lpc[2]) - ntohl(lpc[1]);
+           if ((index < 0) || (index > 65535)) {
+               return -1;      /* illegal */
+           } else { 
+               return (unsigned char *)(&lpc[index + 4]) - iptr;
+            }
+       }
+           
+       case opc_lookupswitch: {
+           long *lpc = (long *) UCALIGN(iptr + 1);
+           int npairs = ntohl(lpc[1]);
+           if (npairs < 0 || npairs >= 8192) 
+               return  -1;
+           else 
+               return (unsigned char *)(&lpc[2 * (npairs + 1)]) - iptr;
+       }
+
+       case opc_wide: 
+           switch(iptr[1]) {
+               case opc_ret:
+               case opc_iload: case opc_istore: 
+               case opc_fload: case opc_fstore:
+               case opc_aload: case opc_astore:
+               case opc_lload: case opc_lstore:
+               case opc_dload: case opc_dstore: 
+                   return 4;
+               case opc_iinc:
+                   return 6;
+               default: 
+                   return -1;
+           }
+
+       default: {
+           /* A length of 0 indicates an error. */
+           int length = opcode_length[instruction];
+           return (length <= 0) ? -1 : length;
+       }
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      isLegalTarget
+ * OVERVIEW:      Given the target of a branch, make sure that it is a legal
+ *                target. Returns true if it is a legal target of a branch.
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                int: offset 
+ *                
+ *   returns:     boolean type
+ *=======================================================================*/
+static bool_t 
+isLegalTarget(context_type *context, int offset)
+{
+    struct methodblock *mb = context->mb;
+    int code_length = mb->code_length;
+    short *code_data = context->code_data;
+    return (offset >= 0 && offset < code_length && code_data[offset] >= 0);
+}
+
+
+/*=========================================================================
+ * FUNCTION:      verify_constant_pool_type 
+ * OVERVIEW:      Make sure that an element of the constant pool is really
+ *                of the indicated type.
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                int: index
+ *                unsigned: mask 
+ *   returns:     nothing 
+ *=======================================================================*/
+static void
+verify_constant_pool_type(context_type *context, int index, unsigned mask)
+{
+    ClassClass *cb = context->class;
+    union cp_item_type *constant_pool = cbConstantPool(cb);
+    int nconstants = cbConstantPoolCount(cb);
+    unsigned char *type_table =
+       constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
+    unsigned type;
+
+ //   if ((index <= 0) || (index >= nconstants))
+//     CCerror(context, "Illegal constant pool index");
+
+    type = CONSTANT_POOL_TYPE_TABLE_GET_TYPE(type_table, index);
+//    if ((mask & (1 << type)) == 0) 
+//     CCerror(context, "Illegal type in constant pool");
+}
+        
+
+/*=========================================================================
+ * Functions for Data Flow Analysis 
+ *=======================================================================*/
+
+/*=========================================================================
+ * FUNCTION:      initialize_dataflow 
+ * OVERVIEW:      Initialize for data flow analysis.
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *   returns:     nothing 
+ *=======================================================================*/
+static void
+initialize_dataflow(context_type *context) 
+{
+    instruction_data_type *idata = context->instruction_data;
+    struct methodblock *mb = context->mb;
+    fullinfo_type *reg_ptr;
+    fullinfo_type full_info;
+    char *p;
+
+    /* Initialize the function entry, since we know everything about it. */
+    idata[0].stack_info.stack_size = 0;
+    idata[0].stack_info.stack = NULL;
+    idata[0].register_info.register_count = mb->args_size;
+    idata[0].register_info.registers = NEW(fullinfo_type, mb->args_size);
+    idata[0].register_info.mask_count = 0;
+    idata[0].register_info.masks = NULL;
+    idata[0].and_flags = 0;    /* nothing needed */
+    idata[0].or_flags = FLAG_REACHED; /* instruction reached */
+    reg_ptr = idata[0].register_info.registers;
+
+    if ((mb->fb.access & ACC_STATIC) == 0) {
+       /* A non static method.  If this is an <init> method, the first
+        * argument is an uninitialized object.  Otherwise it is an object of
+        * the given class type.  java.lang.Object.<init> is special since
+        * we don't call its superclass <init> method.
+        */
+       if (strcmp(mb->fb.name, "<init>") == 0 
+               && context->currentclass_info != context->object_info) {
+           *reg_ptr++ = MAKE_FULLINFO(ITEM_InitObject, 0, 0);
+           idata[0].or_flags |= FLAG_NEED_CONSTRUCTOR;
+       } else {
+           *reg_ptr++ = context->currentclass_info;
+       }
+    }
+    /* Fill in each of the arguments into the registers. */
+    for (p = mb->fb.signature + 1; *p != SIGNATURE_ENDFUNC; ) {
+       char fieldchar = signature_to_fieldtype(context, &p, &full_info);
+      //  if (no_floating_point && (fieldchar == 'D' || fieldchar == 'F')) { 
+          //  CCerror(context, "Floating point arguments not allowed");
+      //  }
+       switch (fieldchar) {
+           case 'D': case 'L': 
+               *reg_ptr++ = full_info;
+               *reg_ptr++ = full_info + 1;
+               break;
+           default:
+               *reg_ptr++ = full_info;
+               break;
+       }
+    }
+    p++;                       /* skip over right parenthesis */
+    if (*p == 'V') {
+       context->return_type = MAKE_FULLINFO(ITEM_Void, 0, 0);
+    } else {
+       signature_to_fieldtype(context, &p, &full_info);
+       context->return_type = full_info;
+    }
+
+    /* Indicate that we need to look at the first instruction. */
+    idata[0].changed = TRUE;
+}      
+
+
+/*=========================================================================
+ * FUNCTION:      run_dataflow 
+ * OVERVIEW:      Execute the data flow analysis as long as there are things
+ *                to change.
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *   returns:     nothing 
+ *=======================================================================*/
+static void
+run_dataflow(context_type *context) {
+    struct methodblock *mb = context->mb;
+    int max_stack_size = mb->maxstack;
+    instruction_data_type *idata = context->instruction_data;
+    int icount = context->instruction_count;
+    bool_t work_to_do = TRUE;
+    int inumber;
+
+    /* Run through the loop, until there is nothing left to do. */
+    while (work_to_do) {
+       work_to_do = FALSE;
+       for (inumber = 0; inumber < icount; inumber++) {
+           instruction_data_type *this_idata = &idata[inumber];
+           if (this_idata->changed) {
+               register_info_type new_register_info;
+               stack_info_type new_stack_info;
+               flag_type new_and_flags, new_or_flags;
+               
+               this_idata->changed = FALSE;
+               work_to_do = TRUE;
+               /* Make sure the registers and flags are appropriate */
+               check_register_values(context, inumber);
+               check_flags(context, inumber);
+
+               /* Make sure the stack can deal with this instruction */
+               pop_stack(context, inumber, &new_stack_info);
+
+               /* Update the registers  and flags */
+               update_registers(context, inumber, &new_register_info);
+               update_flags(context, inumber, &new_and_flags, &new_or_flags);
+
+               /* Update the stack. */
+               push_stack(context, inumber, &new_stack_info);
+
+//             if (new_stack_info.stack_size > max_stack_size) 
+//                 CCerror(context, "Stack size too large");
+
+               /* Add the new stack and register information to any
+                * instructions that can follow this instruction.     */
+               merge_into_successors(context, inumber, 
+                                     &new_register_info, &new_stack_info,
+                                     new_and_flags, new_or_flags);
+           }
+       }
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      check_register_values 
+ * OVERVIEW:      Make sure that the registers contain a legitimate value
+ *                for the given instruction. 
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                int inumber
+ *   returns:     nothing 
+ *=======================================================================*/
+static void
+check_register_values(context_type *context, int inumber)
+{
+    instruction_data_type *idata = context->instruction_data;
+    instruction_data_type *this_idata = &idata[inumber];
+    opcode_type opcode = this_idata->opcode;
+    int operand = this_idata->operand.i;
+    int register_count = this_idata->register_info.register_count;
+    fullinfo_type *registers = this_idata->register_info.registers;
+    bool_t double_word = FALSE;        /* default value */
+    int type;
+    
+    switch (opcode) {
+        default:
+           return;
+        case opc_iload: case opc_iinc:
+           type = ITEM_Integer; break;
+        case opc_fload:
+           type = ITEM_Float; break;
+        case opc_aload:
+           type = ITEM_Object; break;
+        case opc_ret:
+           type = ITEM_ReturnAddress; break;
+        case opc_lload:        
+           type = ITEM_Long; double_word = TRUE; break;
+        case opc_dload:
+           type = ITEM_Double; double_word = TRUE; break;
+    }
+    if (!double_word) {
+       fullinfo_type reg = registers[operand];
+       /* Make sure we don't have an illegal register or one with wrong type */
+       if (operand >= register_count) {
+           CCerror(context, 
+                   "Accessing value from uninitialized register %d", operand);
+       } else if (WITH_ZERO_EXTRA_INFO(reg) == MAKE_FULLINFO(type, 0, 0)) {
+           /* the register is obviously of the given type */
+           return;
+       } else if (GET_INDIRECTION(reg) > 0 && type == ITEM_Object) {
+           /* address type stuff be used on all arrays */
+           return;
+       } else if (GET_ITEM_TYPE(reg) == ITEM_ReturnAddress) { 
+//         CCerror(context, "Cannot load return address from register %d", 
+//                           operand);
+           /* alternatively 
+                     (GET_ITEM_TYPE(reg) == ITEM_ReturnAddress)
+                   && (opcode == opc_iload) 
+                  && (type == ITEM_Object || type == ITEM_Integer)
+              but this never occurs
+           */
+       } else if (reg == ITEM_InitObject && type == ITEM_Object) {
+           return;
+       } else if (WITH_ZERO_EXTRA_INFO(reg) == 
+                       MAKE_FULLINFO(ITEM_NewObject, 0, 0) && 
+                  type == ITEM_Object) {
+           return;
+        } else {
+//         CCerror(context, "Register %d contains wrong type", operand);
+       }
+    } else {
+       /* Make sure we don't have an illegal register or one with wrong type */
+       if ((operand + 1) >= register_count) {
+//         CCerror(context, 
+//                 "Accessing value from uninitialized register pair %d/%d", 
+//                 operand, operand+1);
+       } else {
+           if ((registers[operand] == MAKE_FULLINFO(type, 0, 0)) &&
+               (registers[operand + 1] == MAKE_FULLINFO(type + 1, 0, 0))) {
+               return;
+           } else {
+//             CCerror(context, "Register pair %d/%d contains wrong type", 
+//                     operand, operand+1);
+           }
+       }
+    } 
+}
+
+
+/*=========================================================================
+ * FUNCTION:      check_flags 
+ * OVERVIEW:      Make sure that the flags contain legitimate values for this
+ *                instruction. 
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                int: instruction number
+ *   returns:     nothing 
+ *=======================================================================*/
+static void
+check_flags(context_type *context, int inumber)
+{
+    instruction_data_type *idata = context->instruction_data;
+    instruction_data_type *this_idata = &idata[inumber];
+    opcode_type opcode = this_idata->opcode;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      pop_stack 
+ * OVERVIEW:      Make sure that the top of the stack contains reasonable 
+ *                values for the given instruction. The post-pop values of
+ *                the stack and its size are returned in *new_stack_info. 
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                int: instruction number
+ *                stack_info_type: *new_stack_info
+ *   returns:     nothing 
+ *=======================================================================*/
+static void 
+pop_stack(context_type *context, int inumber, stack_info_type *new_stack_info)
+{
+    instruction_data_type *idata = context->instruction_data;
+    instruction_data_type *this_idata = &idata[inumber];
+    opcode_type opcode = this_idata->opcode;
+    stack_item_type *stack = this_idata->stack_info.stack;
+    int stack_size = this_idata->stack_info.stack_size;
+    char *stack_operands, *p;
+    char buffer[257];          /* for holding manufactured argument lists */
+    fullinfo_type stack_extra_info_buffer[256]; /* save info popped off stack */
+    fullinfo_type *stack_extra_info = &stack_extra_info_buffer[256];
+    fullinfo_type full_info, put_full_info;
+    
+    switch(opcode) {
+        default:
+           /* For most instructions, we just use a built-in table */
+           stack_operands = opcode_in_out[opcode][0];
+           break;
+
+        case opc_putstatic: case opc_putfield: {
+           /* The top thing on the stack depends on the signature of
+            * the object.                         */
+           int operand = this_idata->operand.i;
+           char *signature = cp_index_to_signature(context, operand);
+           char *ip = buffer;
+
+           if (opcode == opc_putfield)
+               *ip++ = 'A';    /* object for putfield */
+           *ip++ = signature_to_fieldtype(context, &signature, &put_full_info);
+           *ip = '\0';
+           stack_operands = buffer;
+           break;
+       }
+
+       case opc_invokevirtual: case opc_invokespecial:        
+        case opc_invokeinit:   /* invokespecial call to <init> */
+       case opc_invokestatic: case opc_invokeinterface: {
+           /* The top stuff on the stack depends on the method signature */
+           int operand = this_idata->operand.i;
+           char *signature = cp_index_to_signature(context, operand);
+           char *ip = buffer;
+           char *p;
+
+           if (opcode != opc_invokestatic) 
+               /* First, push the object */
+               *ip++ = (opcode == opc_invokeinit ? '@' : 'A');
+           for (p = signature + 1; *p != SIGNATURE_ENDFUNC; ) {
+               *ip++ = signature_to_fieldtype(context, &p, &full_info);
+       //      if (ip >= buffer + sizeof(buffer) - 1)
+       //          CCerror(context, "Signature %s has too many arguments", 
+       //                  signature);
+           }
+           *ip = 0;
+           stack_operands = buffer;
+           break;
+       }
+
+       case opc_multianewarray: {
+           /* Count can't be larger than 255. So can't overflow buffer */
+           int count = this_idata->operand2.i; /* number of ints on stack */
+           memset(buffer, 'I', count);
+           buffer[count] = '\0';
+           stack_operands = buffer;
+           break;
+       }
+
+    } /* of switch */
+
+    /* Run through the list of operands >>backwards<< */
+    for (   p = stack_operands + strlen(stack_operands);
+           p > stack_operands; 
+           stack = stack->next) {
+       int type = *--p;
+       fullinfo_type top_type = stack ? stack->item : 0;
+       int size = (type == 'D' || type == 'L') ? 2 : 1;
+       *--stack_extra_info = top_type;
+//     if (stack == NULL) 
+//         CCerror(context, "Unable to pop operand off an empty stack");
+       switch (type) {
+           case 'I': 
+            //   if (top_type != MAKE_FULLINFO(ITEM_Integer, 0, 0))
+                //   CCerror(context, "Expecting to find integer on stack");
+               break;
+               
+           case 'F': 
+       //      if (top_type != MAKE_FULLINFO(ITEM_Float, 0, 0))
+       //          CCerror(context, "Expecting to find float on stack");
+               break;
+               
+           case 'A':           /* object or array */
+               if (   (GET_ITEM_TYPE(top_type) != ITEM_Object) 
+                   && (GET_INDIRECTION(top_type) == 0)) { 
+                   /* The thing isn't an object or an array.  Let's see if it's
+                    * one of the special cases  */
+                   if (  (WITH_ZERO_EXTRA_INFO(top_type) == 
+                               MAKE_FULLINFO(ITEM_ReturnAddress, 0, 0))
+                       && (opcode == opc_astore)) 
+                       break;
+                   if (   (GET_ITEM_TYPE(top_type) == ITEM_NewObject 
+                           || (GET_ITEM_TYPE(top_type) == ITEM_InitObject))
+                       && ((opcode == opc_astore) || (opcode == opc_aload)))
+                       break;
+
+                    /* The 2nd edition VM of the specification allows field
+                     * initializations before the superclass initializer,
+                     * if the field is defined within the current class.
+                     */
+                     if (   (GET_ITEM_TYPE(top_type) == ITEM_InitObject)
+                         && (opcode == opc_putfield)) {
+                        
+                        int num_fields;
+                        int key = this_idata->operand.i;
+                        fullinfo_type clazz_info = cp_index_to_class_fullinfo(
+                                                            context, key, TRUE);
+                        char *name = cp_index_to_fieldname(context, key);
+                        char *signature = cp_index_to_signature(context, key);
+                        unsigned ID = NameAndTypeToHash(name, signature);
+
+                        ClassClass *calledClass =
+                             object_fullinfo_to_classclass(context, clazz_info);
+                        struct fieldblock *fb;
+                        if (ID == 0) {  
+                            /* NameAndTypeToHash returns 0 
+                             * if out of memory 
+                             */
+                          //  CCerror(context, "Out of memory");
+                            break;
+                        }
+                        num_fields = cbFieldsCount(calledClass);
+                        fb = cbFields(calledClass);
+                        for (; --num_fields >= 0; fb++) {
+                            if (fb->ID == ID) {
+                                break;
+                            }
+                        }
+                        if (num_fields != -1) {
+                            top_type = context->currentclass_info;
+                            *stack_extra_info = top_type;
+                            break;
+                        }
+                    }
+               //    CCerror(context, "Expecting to find object/array on stack");
+               }
+               break;
+
+           case '@': {         /* unitialized object, for call to <init> */
+               int item_type = GET_ITEM_TYPE(top_type);
+       //      if (item_type != ITEM_NewObject && item_type != ITEM_InitObject)
+       //          CCerror(context, 
+       //                  "Expecting to find unitialized object on stack");
+               break;
+           }
+
+           case 'O':           /* object, not array */
+       //      if (WITH_ZERO_EXTRA_INFO(top_type) != 
+       //             MAKE_FULLINFO(ITEM_Object, 0, 0))
+       //          CCerror(context, "Expecting to find object on stack");
+               break;
+
+           case 'a':           /* integer, object, or array */
+       //      if (      (top_type != MAKE_FULLINFO(ITEM_Integer, 0, 0)) 
+       //             && (GET_ITEM_TYPE(top_type) != ITEM_Object)
+       //             && (GET_INDIRECTION(top_type) == 0))
+       //          CCerror(context, 
+       //                  "Expecting to find object, array, or int on stack");
+               break;
+
+           case 'D':           /* double */
+       //      if (top_type != MAKE_FULLINFO(ITEM_Double, 0, 0))
+       //          CCerror(context, "Expecting to find double on stack");
+               break;
+
+           case 'L':           /* long */
+       //      if (top_type != MAKE_FULLINFO(ITEM_Long, 0, 0))
+       //          CCerror(context, "Expecting to find long on stack");
+               break;
+
+           case ']':           /* array of some type */
+               if (top_type == NULL_FULLINFO) { 
+                   /* do nothing */
+               } else switch(p[-1]) {
+                   case 'I':   /* array of integers */
+                     //  if (top_type != MAKE_FULLINFO(ITEM_Integer, 1, 0) && 
+                        //   top_type != NULL_FULLINFO)
+                        //   CCerror(context, 
+                       //          "Expecting to find array of ints on stack");
+                       break;
+
+                   case 'L':   /* array of longs */
+                    //   if (top_type != MAKE_FULLINFO(ITEM_Long, 1, 0))
+                        //   CCerror(context, 
+                       //         "Expecting to find array of longs on stack");
+                       break;
+
+                   case 'F':   /* array of floats */
+                   //    if (top_type != MAKE_FULLINFO(ITEM_Float, 1, 0))
+                        //   CCerror(context, 
+                       //       "Expecting to find array of floats on stack");
+                       break;
+
+                   case 'D':   /* array of doubles */
+                    //   if (top_type != MAKE_FULLINFO(ITEM_Double, 1, 0))
+                        //   CCerror(context, 
+                       //      "Expecting to find array of doubles on stack");
+                       break;
+
+                   case 'A': { /* array of addresses (arrays or objects) */
+               //      int indirection = GET_INDIRECTION(top_type);
+               //      if ((indirection == 0) || 
+               //          ((indirection == 1) && 
+               //              (GET_ITEM_TYPE(top_type) != ITEM_Object)))
+               //          CCerror(context, 
+               //              "Expecting to find array of objects or arrays "
+               //                  "on stack");
+                       break;
+                   }
+
+                   case 'b':   /* array of bytes or boolean */
+                   //    if (top_type != MAKE_FULLINFO(ITEM_Byte, 1, 0) &&
+                       //    top_type != MAKE_FULLINFO(ITEM_Boolean, 1, 0))
+                        //   CCerror(context, 
+                       //        "Expecting to find array of bytes or booleans on stack");
+                       break;
+
+                   case 'B':   /* array of bytes */
+                   //    if (top_type != MAKE_FULLINFO(ITEM_Byte, 1, 0))
+                        //   CCerror(context, 
+                       //        "Expecting to find array of bytes on stack");
+                       break;
+
+                   case 'Z':   /* array of boolean */
+                   //    if (top_type != MAKE_FULLINFO(ITEM_Boolean, 1, 0))
+                       //    CCerror(context, 
+                       //        "Expecting to find array of bytes on stack");
+                       break;
+
+                   case 'C':   /* array of characters */
+                   //    if (top_type != MAKE_FULLINFO(ITEM_Char, 1, 0))
+                       //    CCerror(context, 
+                       //        "Expecting to find array of chars on stack");
+                       break;
+
+                   case 'S':   /* array of shorts */
+                   //    if (top_type != MAKE_FULLINFO(ITEM_Short, 1, 0))
+                       //    CCerror(context, 
+                       //       "Expecting to find array of shorts on stack");
+                       break;
+
+                   case '?':   /* any type of array is okay */
+                   //    if (GET_INDIRECTION(top_type) == 0) 
+                       //    CCerror(context, 
+                       //          "Expecting to find array on stack");
+                       break;
+
+                   default:
+               //      CCerror(context, "Internal error #1");
+                       sysAssert(FALSE);
+                       break;
+               }
+               p -= 2;         /* skip over [ <char> */
+               break;
+
+           case '1': case '2': case '3': case '4': /* stack swapping */
+               if (top_type == MAKE_FULLINFO(ITEM_Double, 0, 0) 
+                   || top_type == MAKE_FULLINFO(ITEM_Long, 0, 0)) {
+                   if ((p > stack_operands) && (p[-1] == '+')) {
+                       context->swap_table[type - '1'] = top_type + 1;
+                       context->swap_table[p[-2] - '1'] = top_type;
+                       size = 2;
+                       p -= 2;
+                   } else {
+               //      CCerror(context, 
+               //              "Attempt to split long or double on the stack");
+                   }
+               } else {
+                   context->swap_table[type - '1'] = stack->item;
+                   if ((p > stack_operands) && (p[-1] == '+')) 
+                       p--;    /* ignore */
+               }
+               break;
+           case '+':           /* these should have been caught. */
+           default:
+       //      CCerror(context, "Internal error #2");
+               sysAssert(FALSE);
+       }
+       stack_size -= size;
+    }
+    
+    /* For many of the opcodes that had an "A" in their field, we really 
+     * need to go back and do a little bit more accurate testing.  We can, of
+     * course, assume that the minimal type checking has already been done. 
+     */
+    switch (opcode) {
+       default: break;
+       case opc_aastore: {     /* array index object  */
+           fullinfo_type array_type = stack_extra_info[0];
+           fullinfo_type object_type = stack_extra_info[2];
+           fullinfo_type target_type = decrement_indirection(array_type);
+            if (array_type == NULL_FULLINFO) {
+                break;
+            }
+           if ((WITH_ZERO_EXTRA_INFO(target_type) == 
+                            MAKE_FULLINFO(ITEM_Object, 0, 0)) &&
+                (WITH_ZERO_EXTRA_INFO(object_type) == 
+                            MAKE_FULLINFO(ITEM_Object, 0, 0))) {
+               /* I disagree.  But other's seem to think that we should allow
+                * an assignment of any Object to any array of any Object type.
+                * There will be an runtime error if the types are wrong.
+                */
+               break;
+           }
+       //    if (!isAssignableTo(context, object_type, target_type))
+       //      CCerror(context, "Incompatible types for storing into array of "
+       //                          "arrays or objects");
+           break;
+       }
+
+       case opc_putfield: 
+       case opc_getfield: 
+        case opc_putstatic: {  
+           int operand = this_idata->operand.i;
+           fullinfo_type stack_object = stack_extra_info[0];
+           if (opcode == opc_putfield || opcode == opc_getfield) {
+               if (!isAssignableTo(context, 
+                                   stack_object, 
+                                   cp_index_to_class_fullinfo(context, operand,
+                                                              TRUE))) {
+                 //  CCerror(context, 
+               //          "Incompatible type for getting or setting field");
+               }
+                /* FY:  Why is this commented out?? */
+               /*
+               if (this_idata->protected && 
+                   !isAssignableTo(context, stack_object, 
+                                   context->currentclass_info)) { 
+                   CCerror(context, "Bad access to protected data");
+               }*/
+           }
+           if (opcode == opc_putfield || opcode == opc_putstatic) { 
+               int item = (opcode == opc_putfield ? 1 : 0);
+               if (!isAssignableTo(context, 
+                                   stack_extra_info[item], put_full_info)) { 
+                //   CCerror(context, "Bad type in putfield/putstatic");
+               }
+           }
+           break;
+       }
+
+        case opc_athrow: 
+//         if (!isAssignableTo(context, stack_extra_info[0], 
+//                             context->throwable_info)) {
+//             CCerror(context, "Can only throw Throwable objects");
+//         }
+           break;
+
+       case opc_aaload: {      /* array index */
+           /* We need to pass the information to the stack updater */
+           fullinfo_type array_type = stack_extra_info[0];
+           context->swap_table[0] = decrement_indirection(array_type);
+           break;
+       }
+           
+        case opc_invokevirtual: case opc_invokespecial: 
+        case opc_invokeinit:
+       case opc_invokeinterface: case opc_invokestatic: {
+           int operand = this_idata->operand.i;
+           char *signature = cp_index_to_signature(context, operand);
+           int item;
+           char *p;
+           if (opcode == opc_invokestatic) {
+               item = 0;
+           } else if (opcode == opc_invokeinit) {
+               fullinfo_type init_type = this_idata->operand2.fi;
+               fullinfo_type object_type = stack_extra_info[0];
+               context->swap_table[0] = object_type; /* save value */
+               if (GET_ITEM_TYPE(stack_extra_info[0]) == ITEM_NewObject) {
+                   /* We better be calling the appropriate init.  Find the
+                    * inumber of the "opc_new" instruction", and figure 
+                    * out what the type really is. 
+                    */
+                   int new_inumber = GET_EXTRA_INFO(stack_extra_info[0]);
+                   fullinfo_type target_type = idata[new_inumber].operand2.fi;
+                   context->swap_table[1] = target_type;
+                //   if (target_type != init_type) {
+               //      CCerror(context, "Call to wrong initialization method");
+               //    }
+               } else {
+                   /* We better be calling super() or this(). */
+                   if (init_type != context->superclass_info && 
+                       init_type != context->currentclass_info) {
+               //      CCerror(context, "Call to wrong initialization method");
+                   }
+                   context->swap_table[1] = context->currentclass_info;
+               }
+               item = 1;
+           } else {
+               fullinfo_type target_type = this_idata->operand2.fi;
+               fullinfo_type object_type = stack_extra_info[0];
+               if (!isAssignableTo(context, object_type, target_type)){
+                //   CCerror(context, 
+               //          "Incompatible object argument for function call");
+               }
+                /* The specification of the structural constraints for
+                 * invokespecial needs to be more stringent.
+                 *
+                 * If invokespecial is used to invoke an instance method
+                 * that is not an instance initialization method, then the
+                 * type of the class instance, which is the target of method
+                 * invocation, must be assignment compatible with the
+                 * current class.
+                 */
+                if (opcode == opc_invokespecial
+                    && !isAssignableTo(context, object_type,
+                                       context->currentclass_info)) {
+                    /* Make sure object argument is assignment compatible
+                     * to current class
+                     */
+               //     CCerror(context,
+               //             "Incompatible object argument for invokespecial");
+                }
+
+               if (this_idata->protected 
+                   && !isAssignableTo(context, object_type, 
+                                      context->currentclass_info)) { 
+                   /* This is ugly. Special dispensation.  Arrays pretend to
+                      implement public Object clone() even though they don't */
+                   if ((target_type == context->object_info) && 
+                       (GET_INDIRECTION(object_type) > 0) &&
+                       (strcmp(cp_index_to_fieldname(context, this_idata->operand.i),
+                               "clone") == 0)) { 
+                   } else { 
+       //              CCerror(context, "Bad access to protected data");
+                   }
+               }
+               item = 1;
+           }
+           for (p = signature + 1; *p != SIGNATURE_ENDFUNC; item++)
+               if (signature_to_fieldtype(context, &p, &full_info) == 'A') {
+                   if (!isAssignableTo(context, 
+                                       stack_extra_info[item], full_info)) {
+       //              CCerror(context, "Incompatible argument to function");
+                   }
+               }
+
+           break;
+       }
+           
+        case opc_return:
+//         if (context->return_type != MAKE_FULLINFO(ITEM_Void, 0, 0)) 
+//             CCerror(context, "Wrong return type in function");
+           break;
+
+       case opc_ireturn: case opc_lreturn: case opc_freturn: 
+        case opc_dreturn: case opc_areturn: {
+           fullinfo_type target_type = context->return_type;
+           fullinfo_type object_type = stack_extra_info[0];
+           if (!isAssignableTo(context, object_type, target_type)) {
+//             CCerror(context, "Wrong return type in function");
+           }
+           break;
+       }
+
+        case opc_new: {
+           /* Make sure that nothing on the stack already looks like what
+            * we want to create.  I can't image how this could possibly happen
+            * but we should test for it anyway, since if it could happen, the
+            * result would be an unitialized object being able to masquerade
+            * as an initialized one. 
+            */
+           stack_item_type *item;
+           for (item = stack; item != NULL; item = item->next) { 
+       //      if (item->item == this_idata->operand.fi) { 
+       //          CCerror(context, 
+       //                  "Uninitialized object on stack at creating point");
+       //      }
+           }
+           /* Info for update_registers */
+           context->swap_table[0] = this_idata->operand.fi;
+           context->swap_table[1] = MAKE_FULLINFO(ITEM_Bogus, 0, 0);
+           
+           break;
+       }
+    }
+    new_stack_info->stack = stack;
+    new_stack_info->stack_size = stack_size;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      update_registers 
+ * OVERVIEW:      Perform the operation on the registers, and return the 
+ *                updated results in new_register_count_p and new_registers.
+ *                Note that the instruction has already been determined 
+ *                to be legal. 
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                int: instruction number
+ *                register_info_type: pointer to new register info
+ *
+ *   returns:     nothing 
+ *=======================================================================*/
+static void
+update_registers(context_type *context, int inumber, 
+                register_info_type *new_register_info)
+{
+    instruction_data_type *idata = context->instruction_data;
+    instruction_data_type *this_idata = &idata[inumber];
+    opcode_type opcode = this_idata->opcode;
+    int operand = this_idata->operand.i;
+    int register_count = this_idata->register_info.register_count;
+    fullinfo_type *registers = this_idata->register_info.registers;
+    stack_item_type *stack = this_idata->stack_info.stack;
+    int mask_count = this_idata->register_info.mask_count;
+    mask_type *masks = this_idata->register_info.masks;
+
+    /* Use these as default new values. */
+    int            new_register_count = register_count;
+    int            new_mask_count = mask_count;
+    fullinfo_type *new_registers = registers;
+    mask_type     *new_masks = masks;
+
+    enum { NONE, SINGLE, DOUBLE } access = NONE;
+    int i;
+    
+    /* Remember, we've already verified the type at the top of the stack. */
+    switch (opcode) {
+       default: break;
+        case opc_istore: case opc_fstore: case opc_astore:
+           access = SINGLE;
+           goto continue_store;
+
+        case opc_lstore: case opc_dstore:
+           access = DOUBLE;
+           goto continue_store;
+
+       continue_store: {
+           /* We have a modification to the registers.  Copy them if needed. */
+           fullinfo_type stack_top_type = stack->item;
+           int max_operand = operand + ((access == DOUBLE) ? 1 : 0);
+           
+           if (     max_operand < register_count 
+                 && registers[operand] == stack_top_type
+                 && ((access == SINGLE) || 
+                        (registers[operand + 1]== stack_top_type + 1))) 
+               /* No changes have been made to the registers. */
+               break;
+           new_register_count = MAX(max_operand + 1, register_count);
+           new_registers = NEW(fullinfo_type, new_register_count);
+           for (i = 0; i < register_count; i++) 
+               new_registers[i] = registers[i];
+           for (i = register_count; i < new_register_count; i++) 
+               new_registers[i] = MAKE_FULLINFO(ITEM_Bogus, 0, 0);
+           new_registers[operand] = stack_top_type;
+           if (access == DOUBLE)
+               new_registers[operand + 1] = stack_top_type + 1;
+           break;
+       }
+        
+        case opc_iload: case opc_fload: case opc_aload:
+        case opc_iinc: case opc_ret:
+           access = SINGLE;
+           break;
+
+        case opc_lload: case opc_dload:        
+           access = DOUBLE;
+           break;
+
+        case opc_jsr: case opc_jsr_w:
+           for (i = 0; i < new_mask_count; i++) 
+               if (new_masks[i].entry == operand) 
+                   CCerror(context, "Recursive call to jsr entry");
+            if (context->redoJsr 
+                   && this_idata->operand2.i == UNKNOWN_RET_INSTRUCTION) { 
+                /* Do nothing */
+            } else { 
+                new_masks = add_to_masks(context, masks, mask_count, operand);
+                new_mask_count++; 
+            }
+           break;
+           
+        case opc_invokeinit: 
+        case opc_new: {
+           /* For invokeinit, an uninitialized object has been initialized.
+            * For new, all previous occurrences of an uninitialized object
+            * from the same instruction must be made bogus.  
+            * We find all occurrences of swap_table[0] in the registers, and
+            * replace them with swap_table[1];   
+            */
+           fullinfo_type from = context->swap_table[0];
+           fullinfo_type to = context->swap_table[1];
+
+           int i;
+           for (i = 0; i < register_count; i++) {
+               if (new_registers[i] == from) {
+                   /* Found a match */
+                   break;
+               }
+           }
+           if (i < register_count) { /* We broke out loop for match */
+               /* We have to change registers, and possibly a mask */
+               bool_t copied_mask = FALSE;
+               int k;
+               new_registers = NEW(fullinfo_type, register_count);
+               memcpy(new_registers, registers, 
+                      register_count * sizeof(registers[0]));
+               for ( ; i < register_count; i++) { 
+                   if (new_registers[i] == from) { 
+                       new_registers[i] = to;
+                       for (k = 0; k < new_mask_count; k++) {
+                           if (!IS_BIT_SET(new_masks[k].modifies, i)) { 
+                               if (!copied_mask) { 
+                                   new_masks = copy_masks(context, new_masks, 
+                                                          mask_count);
+                                   copied_mask = TRUE;
+                               }
+                               SET_BIT(new_masks[k].modifies, i);
+                           }
+                       }
+                   }
+               }
+           }
+           break;
+       } 
+    } /* of switch */
+
+    if ((access != NONE) && (new_mask_count > 0)) {
+       int i, j;
+       for (i = 0; i < new_mask_count; i++) {
+           int *mask = new_masks[i].modifies;
+           if ((!IS_BIT_SET(mask, operand)) || 
+                 ((access == DOUBLE) && !IS_BIT_SET(mask, operand + 1))) {
+               new_masks = copy_masks(context, new_masks, mask_count);
+               for (j = i; j < new_mask_count; j++) {
+                   SET_BIT(new_masks[j].modifies, operand);
+                   if (access == DOUBLE) 
+                       SET_BIT(new_masks[j].modifies, operand + 1);
+               } 
+               break;
+           }
+       }
+    }
+
+    new_register_info->register_count = new_register_count;
+    new_register_info->registers = new_registers;
+    new_register_info->masks = new_masks;
+    new_register_info->mask_count = new_mask_count;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      update_flags
+ * OVERVIEW:      Update the flags now that we have already determined
+ *                the instruction to be legal and have already updated the
+ *                registers. 
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                int: instruction number
+ *                flag_type: pointer to new_and_flags
+ *                flag_type: pointer to new_or_flags
+ *
+ *   returns:     nothing 
+ *=======================================================================*/
+static void
+update_flags(context_type *context, int inumber, 
+            flag_type *new_and_flags, flag_type *new_or_flags)
+
+{
+    instruction_data_type *idata = context->instruction_data;
+    instruction_data_type *this_idata = &idata[inumber];
+    flag_type and_flags = this_idata->and_flags;
+    flag_type or_flags = this_idata->or_flags;
+
+    /* Set the "we've done a constructor" flag */
+    if (this_idata->opcode == opc_invokeinit) {
+       fullinfo_type from = context->swap_table[0];
+       if (from == MAKE_FULLINFO(ITEM_InitObject, 0, 0))
+           and_flags |= FLAG_CONSTRUCTED;
+    }
+    *new_and_flags = and_flags;
+    *new_or_flags = or_flags;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      push_stack
+ * OVERVIEW:      Perform the operation on the stack.
+ *                Note that the instruction has already been determined 
+ *                to be legal. 
+ *                new_stack_size_p and new_stack_p point to the results after
+ *                the pops have already been done. Do the pushes, and then
+ *                put the results back there.
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                int: instruction number
+ *                stack_info_type: pointer to new stack info
+ *
+ *   returns:     nothing 
+ *=======================================================================*/
+static void
+push_stack(context_type *context, int inumber, stack_info_type *new_stack_info)
+{
+    instruction_data_type *idata = context->instruction_data;
+    instruction_data_type *this_idata = &idata[inumber];
+    opcode_type opcode = this_idata->opcode;
+    int operand = this_idata->operand.i;
+
+    int stack_size = new_stack_info->stack_size;
+    stack_item_type *stack = new_stack_info->stack;
+    char *stack_results;
+       
+    fullinfo_type full_info = 0;
+    char buffer[5], *p;                /* actually [2] is big enough */
+
+    /* We need to look at all those opcodes in which either we can't tell the
+     * value pushed onto the stack from the opcode, or in which the value
+     * pushed onto the stack is an object or array.  For the latter, we need
+     * to make sure that full_info is set to the right value.
+     */
+    switch(opcode) {
+        default:
+           stack_results = opcode_in_out[opcode][1]; 
+           break;
+
+       case opc_ldc: case opc_ldc_w: case opc_ldc2_w: {
+           /* Look to constant pool to determine correct result. */
+           union cp_item_type *cp = cbConstantPool(context->class);
+           unsigned char *type_table = cp[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
+           switch (CONSTANT_POOL_TYPE_TABLE_GET_TYPE(type_table, operand)) {
+               case CONSTANT_Integer:   
+                   stack_results = "I"; break;
+               case CONSTANT_Float:     
+                   stack_results = "F"; break;
+               case CONSTANT_Double:    
+                   stack_results = "D"; break;
+               case CONSTANT_Long:      
+                   stack_results = "L"; break;
+               case CONSTANT_String: 
+                   stack_results = "A"; 
+                   full_info = context->string_info;
+                   break;
+               default:
+                //   CCerror(context, "Internal error #3");
+                   sysAssert(FALSE);
+           }
+           break;
+       }
+
+        case opc_getstatic: case opc_getfield: {
+           /* Look to signature to determine correct result. */
+           int operand = this_idata->operand.i;
+           char *signature = cp_index_to_signature(context, operand);
+#ifdef DEBUG_VERIFIER
+           if (verify_verbose) {
+               print_formatted_fieldname(context, operand);
+           }
+#endif
+           buffer[0] = signature_to_fieldtype(context, &signature, &full_info);
+           buffer[1] = '\0';
+           stack_results = buffer;
+           break;
+       }
+
+       case opc_invokevirtual: case opc_invokespecial:
+        case opc_invokeinit:
+       case opc_invokestatic: case opc_invokeinterface: {
+           /* Look to signature to determine correct result. */
+           int operand = this_idata->operand.i;
+           char *signature = cp_index_to_signature(context, operand);
+           char *result_signature = strchr(signature, SIGNATURE_ENDFUNC) + 1;
+           if (result_signature[0] == SIGNATURE_VOID) {
+               stack_results = "";
+           } else {
+               buffer[0] = signature_to_fieldtype(context, &result_signature, 
+                                                  &full_info);
+               buffer[1] = '\0';
+               stack_results = buffer;
+           }
+           break;
+       }
+           
+       case opc_aconst_null:
+           stack_results = opcode_in_out[opcode][1]; 
+           full_info = NULL_FULLINFO; /* special NULL */
+           break;
+
+       case opc_new: 
+       case opc_checkcast: 
+       case opc_newarray: 
+       case opc_anewarray: 
+        case opc_multianewarray:
+           stack_results = opcode_in_out[opcode][1]; 
+           /* Conventionally, this result type is stored here */
+           full_info = this_idata->operand.fi;
+            if (no_floating_point && (opcode == opc_newarray) 
+                && (full_info == MAKE_FULLINFO(ITEM_Float, 1, 0) || 
+                    full_info == MAKE_FULLINFO(ITEM_Double, 1, 0))) {
+              //  CCerror(context, "Cannot create floating point array");
+            }
+            break;
+                       
+       case opc_aaload:
+           stack_results = opcode_in_out[opcode][1]; 
+           /* pop_stack() saved value for us. */
+           full_info = context->swap_table[0];
+           break;
+               
+       case opc_aload:
+           stack_results = opcode_in_out[opcode][1]; 
+           /* The register hasn't been modified, so we can use its value. */
+           full_info = this_idata->register_info.registers[operand];
+           break;
+    } /* of switch */
+    
+    for (p = stack_results; *p != 0; p++) {
+       int type = *p;
+       stack_item_type *new_item = NEW(stack_item_type, 1);
+       new_item->next = stack;
+       stack = new_item;
+       switch (type) {
+           case 'I': 
+               stack->item = MAKE_FULLINFO(ITEM_Integer, 0, 0); break;
+           case 'F': 
+               // if (no_floating_point) {
+                  //  CCerror(context, "Floating point result not allowed");
+               // }
+               stack->item = MAKE_FULLINFO(ITEM_Float, 0, 0); 
+                break;
+           case 'D': 
+              //  if (no_floating_point) {
+                  //  CCerror(context, "Floating point result not allowed");
+              //  }
+               stack->item = MAKE_FULLINFO(ITEM_Double, 0, 0); 
+               stack_size++; 
+                break;
+           case 'L': 
+               stack->item = MAKE_FULLINFO(ITEM_Long, 0, 0); 
+               stack_size++; break;
+           case 'R': 
+               stack->item = MAKE_FULLINFO(ITEM_ReturnAddress, 0, operand);
+               break;
+           case '1': case '2': case '3': case '4': {
+               /* Get the info saved in the swap_table */
+               fullinfo_type stype = context->swap_table[type - '1'];
+               stack->item = stype;
+               if (stype == MAKE_FULLINFO(ITEM_Long, 0, 0) || 
+                   stype == MAKE_FULLINFO(ITEM_Double, 0, 0)) {
+                   stack_size++; p++;
+               }
+               break;
+           }
+           case 'A': 
+               /* full_info should have the appropriate value. */
+               sysAssert(full_info != 0);
+               stack->item = full_info;
+               break;
+           default:
+       //      CCerror(context, "Internal error #4");
+               sysAssert(FALSE);
+
+           } /* switch type */
+       stack_size++;
+    } /* outer for loop */
+
+    if (opcode == opc_invokeinit) {
+       /* If there are any instances of "from" on the stack, we need to
+        * replace it with "to", since calling <init> initializes all versions
+        * of the object, obviously.     */
+       fullinfo_type from = context->swap_table[0];
+       stack_item_type *ptr;
+       for (ptr = stack; ptr != NULL; ptr = ptr->next) {
+           if (ptr->item == from) {
+               fullinfo_type to = context->swap_table[1];
+               stack = copy_stack(context, stack);
+               for (ptr = stack; ptr != NULL; ptr = ptr->next) 
+                   if (ptr->item == from) ptr->item = to;
+               break;
+           }
+       }
+    }
+
+    new_stack_info->stack_size = stack_size;
+    new_stack_info->stack = stack;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      merge_into_successors
+ * OVERVIEW:      Executed an instruction, and have determined the new
+ *                registers and stack values. Look at all of the possibly
+ *                subsequent instructions, and merge this stack value into
+ *                theirs.
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                int: instruction number
+ *                stack_info_type: pointer to stack_info
+ *                flag_type: and_flags
+ *                flag_type: or_flags 
+ *
+ *   returns:     nothing 
+ *=======================================================================*/
+static void
+merge_into_successors(context_type *context, int inumber, 
+                     register_info_type *register_info,
+                     stack_info_type *stack_info, 
+                     flag_type and_flags, flag_type or_flags)
+{
+    instruction_data_type *idata = context->instruction_data;
+    instruction_data_type *this_idata = &idata[inumber];
+    opcode_type opcode = this_idata->opcode;
+    int operand = this_idata->operand.i;
+    struct handler_info_type *handler_info = context->handler_info;
+    int handler_info_length = context->mb->exception_table_length;
+
+
+    int buffer[2];             /* default value for successors */
+    int *successors = buffer;  /* table of successors */
+    int successors_count;
+    int i;
+    
+    switch (opcode) {
+    default:
+       successors_count = 1; 
+       buffer[0] = inumber + 1;
+       break;
+
+    case opc_ifeq: case opc_ifne: case opc_ifgt: 
+    case opc_ifge: case opc_iflt: case opc_ifle:
+    case opc_ifnull: case opc_ifnonnull:
+    case opc_if_icmpeq: case opc_if_icmpne: case opc_if_icmpgt: 
+    case opc_if_icmpge: case opc_if_icmplt: case opc_if_icmple:
+    case opc_if_acmpeq: case opc_if_acmpne:
+       successors_count = 2;
+       buffer[0] = inumber + 1; 
+       buffer[1] = operand;
+        idata[operand].is_target = TRUE; /* inlinejsr */
+       break;
+
+    case opc_jsr: case opc_jsr_w: 
+       if (this_idata->operand2.i != UNKNOWN_RET_INSTRUCTION) 
+           idata[this_idata->operand2.i].changed = TRUE;
+       /* FALLTHROUGH */
+    case opc_goto: case opc_goto_w:
+       successors_count = 1;
+       buffer[0] = operand;
+        idata[operand].is_target = TRUE; /* inlinejsr */
+       break;
+
+
+    case opc_ireturn: case opc_lreturn: case opc_return:       
+    case opc_freturn: case opc_dreturn: case opc_areturn: 
+    case opc_athrow:
+       /* The testing for the returns is handled in pop_stack() */
+       successors_count = 0;
+       break;
+
+    case opc_ret: {
+       /* This is slightly slow, but good enough for a seldom used instruction.
+        * The EXTRA_ITEM_INFO of the ITEM_ReturnAddress indicates the
+        * address of the first instruction of the subroutine.  We can return
+        * to 1 after any instruction that jsr's to that instruction.
+        */
+       if (this_idata->operand2.ip == NULL) {
+           fullinfo_type *registers = this_idata->register_info.registers;
+           int called_instruction = GET_EXTRA_INFO(registers[operand]);
+           int i, count, *ptr;;
+           for (i = context->instruction_count, count = 0; --i >= 0; ) {
+               if (((idata[i].opcode == opc_jsr) ||
+                    (idata[i].opcode == opc_jsr_w)) && 
+                   (idata[i].operand.i == called_instruction)) 
+                   count++;
+           }
+           this_idata->operand2.ip = ptr = NEW(int, count + 1);
+           *ptr++ = count;
+           for (i = context->instruction_count, count = 0; --i >= 0; ) {
+               if (((idata[i].opcode == opc_jsr) ||
+                    (idata[i].opcode == opc_jsr_w)) && 
+                   (idata[i].operand.i == called_instruction)) {
+                   *ptr++ = i + 1;
+                    idata[i + 1].is_target = TRUE; /* inlinejsr */
+                }
+           }
+       }
+       successors = this_idata->operand2.ip; /* use this instead */
+       successors_count = *successors++;
+       break;
+        
+    }
+
+    case opc_tableswitch:
+    case opc_lookupswitch: { 
+        int i;
+        successors = this_idata->operand.ip; /* use this instead */
+        successors_count = *successors++;
+        for (i = 0; i < successors_count; i++) { 
+            idata[successors[i]].is_target = TRUE; /* inlinejsr */
+        }
+        break;
+    }
+
+    }
+
+
+
+    handler_info = context->handler_info;
+    for (i = handler_info_length; --i >= 0; handler_info++) {
+       if (handler_info->start <= inumber && handler_info->end > inumber) {
+           int handler = handler_info->handler;
+            idata[handler].is_target = TRUE; /* inlinejsr */
+           if (opcode != opc_invokeinit) {
+               merge_into_one_successor(context, inumber, handler, 
+                                        &this_idata->register_info, /* old */
+                                        &handler_info->stack_info, 
+                                        (flag_type) (and_flags
+                                                     & this_idata->and_flags),
+                                        (flag_type) (or_flags
+                                                     | this_idata->or_flags),
+                                        TRUE);
+           } else {
+               /* We need to be a little bit more careful with this 
+                * instruction.  Things could either be in the state before
+                * the instruction or in the state afterwards */
+               fullinfo_type from = context->swap_table[0];
+               flag_type temp_or_flags = or_flags;
+               if (from == MAKE_FULLINFO(ITEM_InitObject, 0, 0))
+                   temp_or_flags |= FLAG_NO_RETURN;
+               merge_into_one_successor(context, inumber, handler, 
+                                        &this_idata->register_info, /* old */
+                                        &handler_info->stack_info, 
+                                        this_idata->and_flags,
+                                        this_idata->or_flags,
+                                        TRUE);
+               merge_into_one_successor(context, inumber, handler, 
+                                        register_info, 
+                                        &handler_info->stack_info, 
+                                        and_flags, temp_or_flags, TRUE);
+           }
+       }
+    }
+    for (i = 0; i < successors_count; i++) {
+       int target = successors[i];
+//     if (target >= context->instruction_count) 
+///        CCerror(context, "Falling off the end of the code");
+       merge_into_one_successor(context, inumber, target, 
+                                register_info, stack_info, and_flags, or_flags,
+                                FALSE);
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      merge_into_one_successor
+ * OVERVIEW:      Executed an instruction, and have determined a new
+ *                set of registers and stack values for a given instruction. 
+ *                Merge this new set into the values that are already there.
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                int: instruction number
+ *                stack_info_type: pointer to stack_info
+ *                flag_type: new_and_flags
+ *                flag_type: new_or_flags 
+ *                boolean type: isException
+ *
+ *   returns:     nothing 
+ *=======================================================================*/
+static void
+merge_into_one_successor(context_type *context, 
+                        int from_inumber, int to_inumber, 
+                        register_info_type *new_register_info,
+                        stack_info_type *new_stack_info,
+                        flag_type new_and_flags, flag_type new_or_flags,
+                        bool_t isException)
+{
+    instruction_data_type *idata = context->instruction_data;
+    register_info_type register_info_buf;
+    stack_info_type stack_info_buf;
+    instruction_data_type *this_idata = &idata[to_inumber];
+
+
+    /* All uninitialized objects are set to "bogus" when jsr and
+     * ret are executed. Thus uninitialized objects can't propagate
+     * into or out of a subroutine.
+     */
+    if (idata[from_inumber].opcode == opc_ret ||
+       idata[from_inumber].opcode == opc_jsr ||
+       idata[from_inumber].opcode == opc_jsr_w) {
+       int new_register_count = new_register_info->register_count;
+       fullinfo_type *new_registers = new_register_info->registers;
+        int i;
+       stack_item_type *item;
+
+       for (item = new_stack_info->stack; item != NULL; item = item->next) {
+           if (GET_ITEM_TYPE(item->item) == ITEM_NewObject) {
+               /* This check only succeeds for hand-contrived code.
+                * Efficiency is not an issue.
+                */
+               stack_info_buf.stack = copy_stack(context, 
+                                                 new_stack_info->stack);
+               stack_info_buf.stack_size = new_stack_info->stack_size;
+               new_stack_info = &stack_info_buf;
+               for (item = new_stack_info->stack; item != NULL; 
+                    item = item->next) {
+                   if (GET_ITEM_TYPE(item->item) == ITEM_NewObject) {
+                       item->item = MAKE_FULLINFO(ITEM_Bogus, 0, 0);
+                   }
+               }
+               break;
+           }
+       }
+       for (i = 0; i < new_register_count; i++) {
+           if (GET_ITEM_TYPE(new_registers[i]) == ITEM_NewObject) {
+               /* This check only succeeds for hand-contrived code.
+                * Efficiency is not an issue.
+                */
+               fullinfo_type *new_set = NEW(fullinfo_type, 
+                                            new_register_count);
+               for (i = 0; i < new_register_count; i++) {
+                   fullinfo_type t = new_registers[i];
+                   new_set[i] = GET_ITEM_TYPE(t) != ITEM_NewObject ?
+                       t : MAKE_FULLINFO(ITEM_Bogus, 0, 0);
+               }
+               register_info_buf.register_count = new_register_count;
+               register_info_buf.registers = new_set;
+               register_info_buf.mask_count = new_register_info->mask_count;
+               register_info_buf.masks = new_register_info->masks;
+               new_register_info = &register_info_buf;
+               break;
+           }
+       }
+    }
+
+    /* Returning from a subroutine is somewhat ugly.  The actual thing
+     * that needs to get merged into the new instruction is a joining
+     * of info from the ret instruction with stuff in the jsr instruction 
+     */
+    if (idata[from_inumber].opcode == opc_ret && !isException) {
+       int new_register_count = new_register_info->register_count;
+       fullinfo_type *new_registers = new_register_info->registers;
+       int new_mask_count = new_register_info->mask_count;
+       mask_type *new_masks = new_register_info->masks;
+       int operand = idata[from_inumber].operand.i;
+       int called_instruction = GET_EXTRA_INFO(new_registers[operand]);
+       instruction_data_type *jsr_idata = &idata[to_inumber - 1];
+       register_info_type *jsr_reginfo = &jsr_idata->register_info;
+       if (jsr_idata->operand2.i != from_inumber) {
+        //   if (jsr_idata->operand2.i != UNKNOWN_RET_INSTRUCTION)
+       //      CCerror(context, "Multiple returns to single jsr");
+           jsr_idata->operand2.i = from_inumber;
+       }
+       if (jsr_reginfo->register_count == UNKNOWN_REGISTER_COUNT) {
+           /* We don't want to handle the returned-to instruction until 
+            * we've dealt with the jsr instruction.   When we get to the
+            * jsr instruction (if ever), we'll re-mark the ret instruction
+            */
+           ;
+       } else { 
+           int register_count = jsr_reginfo->register_count;
+           fullinfo_type *registers = jsr_reginfo->registers;
+           int max_registers = MAX(register_count, new_register_count);
+           fullinfo_type *new_set = NEW(fullinfo_type, max_registers);
+           int *return_mask;
+           struct register_info_type new_new_register_info;
+           int i;
+           /* Make sure the place we're returning from is legal! */
+           for (i = new_mask_count; --i >= 0; ) 
+               if (new_masks[i].entry == called_instruction) 
+                   break;
+         //  if (i < 0)
+       //      CCerror(context, "Illegal return from subroutine");
+           /* pop the masks down to the indicated one.  Remember the mask
+            * we're popping off. */
+           return_mask = new_masks[i].modifies;
+           new_mask_count = i;
+           for (i = 0; i < max_registers; i++) {
+               if (IS_BIT_SET(return_mask, i)) 
+                   new_set[i] = i < new_register_count ? 
+                         new_registers[i] : MAKE_FULLINFO(ITEM_Bogus, 0, 0);
+               else 
+                   new_set[i] = i < register_count ? 
+                       registers[i] : MAKE_FULLINFO(ITEM_Bogus, 0, 0);
+           }
+           new_new_register_info.register_count = max_registers;
+           new_new_register_info.registers      = new_set;
+           new_new_register_info.mask_count     = new_mask_count;
+           new_new_register_info.masks          = new_masks;
+
+           merge_stack(context, to_inumber - 1, to_inumber, new_stack_info);
+           merge_registers(context, to_inumber - 1, to_inumber, 
+                           &new_new_register_info);
+            /* ADDED FOR JSR_INFO.  Is this correct?? */
+            merge_flags(context, from_inumber, to_inumber, 
+                        new_and_flags, new_or_flags);
+       }
+    } else {
+       merge_stack(context, from_inumber, to_inumber, new_stack_info);
+       merge_registers(context, from_inumber, to_inumber, new_register_info);
+       merge_flags(context, from_inumber, to_inumber, 
+                   new_and_flags, new_or_flags);
+    }
+
+
+}
+
+
+/*=========================================================================
+ * FUNCTION:      merge_stack
+ * OVERVIEW:      Used by merge_into_one_successor() for merging stack values 
+ *                from a given instruction to another specified instruction.
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                int: from instruction number
+ *                int: to instruction number
+ *                stack_info_type: pointer to new_stack_info
+ *
+ *   returns:     nothing 
+ *=======================================================================*/
+static void
+merge_stack(context_type *context, int from_inumber, int to_inumber, 
+           stack_info_type *new_stack_info)
+{
+    instruction_data_type *idata = context->instruction_data;
+    instruction_data_type *this_idata = &idata[to_inumber];
+
+    int new_stack_size =  new_stack_info->stack_size;
+    stack_item_type *new_stack = new_stack_info->stack;
+
+    int stack_size = this_idata->stack_info.stack_size;
+
+    if (stack_size == UNKNOWN_STACK_SIZE) {
+       /* First time at this instruction.  Just copy. */
+       this_idata->stack_info.stack_size = new_stack_size;
+       this_idata->stack_info.stack = new_stack;
+       this_idata->changed = TRUE;
+    } else if (new_stack_size != stack_size) {
+//     CCerror(context, "Inconsistent stack height %d != %d",
+//             new_stack_size, stack_size);
+    } else { 
+       stack_item_type *stack = this_idata->stack_info.stack;
+       stack_item_type *old, *new;
+       bool_t change = FALSE;
+       for (old = stack, new = new_stack; old != NULL; 
+                  old = old->next, new = new->next) {
+           if (!isAssignableTo(context, new->item, old->item)) {
+               change = TRUE;
+               break;
+           }
+       }
+       if (change) {
+           stack = copy_stack(context, stack);
+           for (old = stack, new = new_stack; old != NULL; 
+                         old = old->next, new = new->next) {
+                if (new == NULL) {
+                    break;
+                }
+               old->item = merge_fullinfo_types(context, old->item, new->item, 
+                                                FALSE);
+                if (GET_ITEM_TYPE(old->item) == ITEM_Bogus) {
+                 //   CCerror(context, "Mismatched stack types");
+                }
+           }
+            if (old != NULL || new != NULL) {
+             //   CCerror(context, "Mismatched stack types");
+            }
+           this_idata->stack_info.stack = stack;
+           this_idata->changed = TRUE;
+       }
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      merge_registers
+ * OVERVIEW:      Used by merge_into_one_successor() for merging registers
+ *                from a given instruction to another specified instruction.
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                int: from instruction number
+ *                int: to instruction number
+ *                stack_info_type: pointer to new_stack_info
+ *
+ *   returns:     nothing 
+ *=======================================================================*/
+static void
+merge_registers(context_type *context, int from_inumber, int to_inumber,
+                register_info_type *new_register_info)
+{
+    instruction_data_type *idata = context->instruction_data;
+    instruction_data_type *this_idata = &idata[to_inumber];
+    register_info_type   *this_reginfo = &this_idata->register_info;
+
+    int            new_register_count = new_register_info->register_count;
+    fullinfo_type *new_registers = new_register_info->registers;
+    int            new_mask_count = new_register_info->mask_count;
+    mask_type     *new_masks = new_register_info->masks;
+    
+
+    if (this_reginfo->register_count == UNKNOWN_REGISTER_COUNT) {
+       this_reginfo->register_count = new_register_count;
+       this_reginfo->registers = new_registers;
+       this_reginfo->mask_count = new_mask_count;
+       this_reginfo->masks = new_masks;
+       this_idata->changed = TRUE;
+    } else {
+       /* See if we've got new information on the register set. */
+       int register_count = this_reginfo->register_count;
+       fullinfo_type *registers = this_reginfo->registers;
+       int mask_count = this_reginfo->mask_count;
+       mask_type *masks = this_reginfo->masks;
+       
+       bool_t copy = FALSE;
+       int i, j;
+       if (register_count > new_register_count) {
+           /* Any register larger than new_register_count is now bogus */
+           this_reginfo->register_count = new_register_count;
+           register_count = new_register_count;
+           this_idata->changed = TRUE;
+       }
+       for (i = 0; i < register_count; i++) {
+           fullinfo_type prev_value = registers[i];
+           if ((i < new_register_count) 
+                 ? (!isAssignableTo(context, new_registers[i], prev_value))
+                 : (prev_value != MAKE_FULLINFO(ITEM_Bogus, 0, 0))) {
+               copy = TRUE; 
+               break;
+           }
+       }
+       
+       if (copy) {
+           /* We need a copy.  So do it. */
+           fullinfo_type *new_set = NEW(fullinfo_type, register_count);
+           for (j = 0; j < i; j++) 
+               new_set[j] =  registers[j];
+           for (j = i; j < register_count; j++) {
+               if (i >= new_register_count) 
+                   new_set[j] = MAKE_FULLINFO(ITEM_Bogus, 0, 0);
+               else 
+                   new_set[j] = merge_fullinfo_types(context, 
+                                                     new_registers[j], 
+                                                     registers[j], FALSE);
+           }
+           /* Some of the end items might now be bogus. This step isn't 
+            * necessary, but it may save work later. */
+           while (   register_count > 0
+                  && GET_ITEM_TYPE(new_set[register_count-1]) == ITEM_Bogus) 
+               register_count--;
+           this_reginfo->register_count = register_count;
+           this_reginfo->registers = new_set;
+           this_idata->changed = TRUE;
+       }
+       if (mask_count > 0) { 
+           /* If the target instruction already has a sequence of masks, then
+            * we need to merge new_masks into it.  We want the entries on
+            * the mask to be the longest common substring of the two.
+            *   (e.g.   a->b->d merged with a->c->d should give a->d)
+            * The bits set in the mask should be the or of the corresponding
+            * entries in each of the original masks.
+            */
+           int i, j, k;
+           int matches = 0;
+           int last_match = -1;
+           bool_t copy_needed = FALSE;
+           for (i = 0; i < mask_count; i++) {
+               int entry = masks[i].entry;
+               for (j = last_match + 1; j < new_mask_count; j++) {
+                   if (new_masks[j].entry == entry) {
+                       /* We have a match */
+                       int *prev = masks[i].modifies;
+                       int *new = new_masks[j].modifies;
+                       matches++; 
+                       /* See if new_mask has bits set for "entry" that 
+                        * weren't set for mask.  If so, need to copy. */
+                       for (k = context->bitmask_size - 1;
+                              !copy_needed && k >= 0;
+                              k--) 
+                           if (~prev[k] & new[k])
+                               copy_needed = TRUE;
+                       last_match = j;
+                       break;
+                   }
+               }
+           }
+           if ((matches < mask_count) || copy_needed) { 
+               /* We need to make a copy for the new item, since either the
+                * size has decreased, or new bits are set. */
+               mask_type *copy = NEW(mask_type, matches);
+               for (i = 0; i < matches; i++) {
+                   copy[i].modifies = NEW(int, context->bitmask_size);
+               }
+               this_reginfo->masks = copy;
+               this_reginfo->mask_count = matches;
+               this_idata->changed = TRUE;
+               matches = 0;
+               last_match = -1;
+               for (i = 0; i < mask_count; i++) {
+                   int entry = masks[i].entry;
+                   for (j = last_match + 1; j < new_mask_count; j++) {
+                       if (new_masks[j].entry == entry) {
+                           int *prev1 = masks[i].modifies;
+                           int *prev2 = new_masks[j].modifies;
+                           int *new = copy[matches].modifies;
+                           copy[matches].entry = entry;
+                           for (k = context->bitmask_size - 1; k >= 0; k--) 
+                               new[k] = prev1[k] | prev2[k];
+                           matches++;
+                           last_match = j;
+                           break;
+                       }
+                   }
+               }
+           }
+       }
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      merge_flags
+ * OVERVIEW:      Used by merge_into_one_successor() for merging flags
+ *                from a given instruction to a specified instruction.
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                int: from instruction number
+ *                int: to instruction number
+ *                flag_type: new_and_flags
+ *                flag_type: new_or_flags 
+ *
+ *   returns:     nothing 
+ *=======================================================================*/
+static void 
+merge_flags(context_type *context, int from_inumber, int to_inumber,
+           flag_type new_and_flags, flag_type new_or_flags) 
+{
+    /* Set this_idata->and_flags &= new_and_flags
+           this_idata->or_flags |= new_or_flags
+     */
+    instruction_data_type *idata = context->instruction_data;
+    instruction_data_type *this_idata = &idata[to_inumber];
+    flag_type this_and_flags = this_idata->and_flags;
+    flag_type this_or_flags = this_idata->or_flags;
+    flag_type merged_and = this_and_flags & new_and_flags;
+    flag_type merged_or = this_or_flags | new_or_flags;
+    
+    if ((merged_and != this_and_flags) || (merged_or != this_or_flags)) {
+       this_idata->and_flags = merged_and;
+       this_idata->or_flags = merged_or;
+       this_idata->changed = TRUE;
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      copy_stack
+ * OVERVIEW:      Make a copy of a stack.
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                stack_item_type: pointer to stack 
+ *
+ *   returns:     pointer to stack_item_type 
+ *=======================================================================*/
+static stack_item_type *
+copy_stack(context_type *context, stack_item_type *stack)
+{
+    int length;
+    stack_item_type *ptr;
+    
+    /* Find the length */
+    for (ptr = stack, length = 0; ptr != NULL; ptr = ptr->next, length++);
+    
+    if (length > 0) { 
+       stack_item_type *new_stack = NEW(stack_item_type, length);
+       stack_item_type *new_ptr;
+       for (    ptr = stack, new_ptr = new_stack; 
+                ptr != NULL;
+                ptr = ptr->next, new_ptr++) {
+           new_ptr->item = ptr->item;
+           new_ptr->next = new_ptr + 1;
+       }
+       new_stack[length - 1].next = NULL;
+       return new_stack;
+    } else {
+       return NULL;
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      copy_masks
+ * OVERVIEW:      Make a copy of the masks.
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                mask_type: pointer to masks
+ *                int: mask count
+ *
+ *   returns:     pointer to mask_type 
+ *=======================================================================*/
+static mask_type *
+copy_masks(context_type *context, mask_type *masks, int mask_count)
+{
+    mask_type *result = NEW(mask_type, mask_count);
+    int bitmask_size = context->bitmask_size;
+    int *bitmaps = NEW(int, mask_count * bitmask_size);
+    int i;
+    for (i = 0; i < mask_count; i++) { 
+       result[i].entry = masks[i].entry;
+       result[i].modifies = &bitmaps[i * bitmask_size];
+       memcpy(result[i].modifies, masks[i].modifies, bitmask_size * sizeof(int));
+    }
+    return result;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      add_to_masks
+ * OVERVIEW:      Used by Update_registers for adding entries to masks for
+ *                JSR instructions.
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                mask_type: pointer to masks
+ *                int: mask count
+ *                int: d
+ *
+ *   returns:     pointer to mask_type 
+ *=======================================================================*/
+static mask_type *
+add_to_masks(context_type *context, mask_type *masks, int mask_count, int d)
+{
+    mask_type *result = NEW(mask_type, mask_count + 1);
+    int bitmask_size = context->bitmask_size;
+    int *bitmaps = NEW(int, (mask_count + 1) * bitmask_size);
+    int i;
+    for (i = 0; i < mask_count; i++) { 
+       result[i].entry = masks[i].entry;
+       result[i].modifies = &bitmaps[i * bitmask_size];
+       memcpy(result[i].modifies, masks[i].modifies, bitmask_size * sizeof(int));
+    }
+    result[mask_count].entry = d;
+    result[mask_count].modifies = &bitmaps[mask_count * bitmask_size];
+    memset(result[mask_count].modifies, 0, bitmask_size * sizeof(int));
+    return result;
+}
+    
+
+/*=========================================================================
+ * Storage Management Operations 
+ *=======================================================================*/
+
+/* We create our own storage manager, since we malloc lots of little items, 
+ * and we do not want to keep track of them when they become free.
+ * It would have been nice if we had heaps, which could all be freed when
+ * done.
+ */
+
+#define CCSegSize 2000
+
+struct CCpool {                        /* a segment of allocated memory in the pool */
+    struct CCpool *next;
+    int segSize;               /* almost always CCSegSize */
+    char space[CCSegSize];
+};
+
+
+/*=========================================================================
+ * FUNCTION:      CCinit 
+ * OVERVIEW:      Initialize the context's heap. 
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *
+ *   returns:     nothing 
+ *=======================================================================*/
+static void CCinit(context_type *context)
+{
+    struct CCpool *new = (struct CCpool *) sysMalloc(sizeof(struct CCpool));
+    /* Set context->CCroot to 0 if new == 0 to tell CCdestroy to lay off */
+    context->CCroot = context->CCcurrent = new;
+    if (new == 0) {
+       CCerror(context, "Out of memory");
+    }
+    new->next = NULL;
+    new->segSize = CCSegSize;
+    context->CCfree_size = CCSegSize;
+    context->CCfree_ptr = &new->space[0];
+}
+
+
+/*=========================================================================
+ * FUNCTION:      CCreinit 
+ * OVERVIEW:      Reuse all the space that we have in the context's heap. 
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *
+ *   returns:     nothing 
+ *=======================================================================*/
+static void CCreinit(context_type *context)
+{
+    struct CCpool *first = context->CCroot;
+    context->CCcurrent = first;
+    context->CCfree_size = CCSegSize;
+    context->CCfree_ptr = &first->space[0];
+}
+
+
+/*=========================================================================
+ * FUNCTION:      CCdestroy
+ * OVERVIEW:      Destroy the context's heap. 
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *
+ *   returns:     nothing 
+ *=======================================================================*/
+static void CCdestroy(context_type *context)
+{
+    struct CCpool *this = context->CCroot;
+    while (this) {
+       struct CCpool *next = this->next;
+       sysFree(this);
+       this = next;
+    }
+    /* These two aren't necessary.  But can't hurt either */
+    context->CCroot = context->CCcurrent = NULL;
+    context->CCfree_ptr = 0;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      CCalloc
+ * OVERVIEW:      Allocate an object of the given size from the context's heap. 
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                int: size
+ *                bool_t: zero
+ *
+ *   returns:     pointer to void
+ *=======================================================================*/
+static void *
+CCalloc(context_type *context, int size, bool_t zero)
+{
+
+    register char *p;
+    /* Round CC to the size of a pointer */
+    size = (size + (sizeof(void *) - 1)) & ~(sizeof(void *) - 1);
+
+    if (context->CCfree_size <  size) {
+       struct CCpool *current = context->CCcurrent;
+       struct CCpool *new;
+       if (size > CCSegSize) { /* we need to allocate a special block */
+           new = (struct CCpool *)sysMalloc(sizeof(struct CCpool) + 
+                                            (size - CCSegSize));
+           if (new == 0) {
+               CCerror(context, "Out of memory");
+           }
+           new->next = current->next;
+           new->segSize = size;
+           current->next = new;
+       } else {
+           new = current->next;
+           if (new == NULL) {
+               new = (struct CCpool *) sysMalloc(sizeof(struct CCpool));
+               if (new == 0) {
+                   CCerror(context, "Out of memory");
+               }
+               current->next = new;
+               new->next = NULL;
+               new->segSize = CCSegSize;
+           }
+       }
+       context->CCcurrent = new;
+       context->CCfree_ptr = &new->space[0];
+       context->CCfree_size = new->segSize;
+    }
+    p = context->CCfree_ptr;
+    context->CCfree_ptr += size;
+    context->CCfree_size -= size;
+    if (zero) 
+       memset(p, 0, size);
+    return p;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      cp_index_to_signature
+ * OVERVIEW:      Get the signature associated with a particular field or 
+ *                method in the constant pool. 
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                int: constant pool index
+ *
+ *   returns:     char * type
+ *=======================================================================*/
+static char *
+cp_index_to_signature(context_type *context, int cp_index)
+{
+    union cp_item_type *cp = cbConstantPool(context->class);
+    int index = cp[cp_index].i; /* value of Fieldref field */
+    int key2 = index & 0xFFFF; /* index to NameAndType  */
+    int signature_index = cp[key2].i & 0xFFFF; 
+    char *signature = cp[signature_index].cp;
+    return signature;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      cp_index_to_fieldname
+ * OVERVIEW:      Get the fieldname for the specific index within the
+ *                constant pool. 
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                int: constant pool index
+ *
+ *   returns:     char * type
+ *=======================================================================*/
+static char *
+cp_index_to_fieldname(context_type *context, int cp_index)
+{
+    union cp_item_type *cp = cbConstantPool(context->class);
+    int index = cp[cp_index].i; /* value of Fieldref field */
+    int key2 = index & 0xFFFF; /* index to NameAndType  */
+    int name_index = cp[key2].i >> 16;
+    return cp[name_index].cp;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      cp_index_to_class_fullinfo
+ * OVERVIEW:      Get the class associated with a particular field or 
+ *                method or class in the constant pool. If is_field is true,
+ *                then it is a field or method. Otherwise, if false, it is a
+ *                class. 
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                int: constant pool index
+ *                bool_t: is_field
+ *
+ *   returns:     fullinfo_type
+ *=======================================================================*/
+static fullinfo_type
+cp_index_to_class_fullinfo(context_type *context, int cp_index, bool_t is_field)
+{
+    union cp_item_type *cp = cbConstantPool(context->class);
+    unsigned classkey = is_field ? (cp[cp_index].i >> 16) : cp_index;
+    char *classname = GetClassConstantClassName(cp, classkey);
+    if (classname[0] == SIGNATURE_ARRAY) {
+       fullinfo_type result;
+       /* This make recursively call us, in case of a class array */
+       signature_to_fieldtype(context, &classname, &result);
+       return result;
+    } else {
+       return MAKE_CLASSNAME_INFO_WITH_COPY(context, classname, 0);
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      CCerror 
+ * OVERVIEW:      Error handling
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                char: pointer to format
+ *
+ *   returns:     nothing 
+ *=======================================================================*/
+static void 
+CCerror (context_type *context, char *format, ...)
+{
+/*     va_list args;
+       struct methodblock *mb = context->mb;
+       printCurrentClassName();
+       if (mb != 0) {
+           jio_fprintf(stderr, "VERIFIER ERROR %s.%s%s:\n", 
+                   cbName(fieldclass(&mb->fb)), mb->fb.name, mb->fb.signature);
+       } else {
+           jio_fprintf(stderr, "VERIFIER ERROR class %s (mb uninitialized):\n",
+                   cbName(context->class));
+       }
+       va_start(args, format);
+          jio_vfprintf(stderr, format, args);        
+       va_end(args);
+       jio_fprintf(stderr, "\n");
+       exit(1);*/
+}
+
+
+/*=========================================================================
+ * FUNCTION:      signature_to_fieldtype
+ * OVERVIEW:      Given the full info type for a field, returns the field type
+ *                which corresponds to this signature.
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                char: **signature_p
+ *                fullinfo_type: *full_info_p
+ *
+ *   returns:     char
+ *=======================================================================*/
+static char 
+signature_to_fieldtype(context_type *context, 
+                      char **signature_p, fullinfo_type *full_info_p)
+{
+    char *p = *signature_p;
+    fullinfo_type full_info = MAKE_FULLINFO(0, 0, 0);
+    char result;
+    int array_depth = 0;
+    
+    for (;;) { 
+       switch(*p++) {
+            default:
+               full_info = MAKE_FULLINFO(ITEM_Bogus, 0, 0);
+               result = 0; 
+               break;
+
+            case SIGNATURE_BYTE: 
+               full_info = (array_depth > 0)
+                             ? MAKE_FULLINFO(ITEM_Byte, 0, 0)
+                             : MAKE_FULLINFO(ITEM_Integer, 0, 0);
+               result = 'I'; 
+               break;
+
+           case SIGNATURE_BOOLEAN: 
+               full_info = (array_depth > 0)
+                             ? MAKE_FULLINFO(ITEM_Boolean, 0, 0)
+                             : MAKE_FULLINFO(ITEM_Integer, 0, 0);
+               result = 'I'; 
+               break;
+
+            case SIGNATURE_CHAR:
+               full_info = (array_depth > 0)
+                             ? MAKE_FULLINFO(ITEM_Char, 0, 0)
+                             : MAKE_FULLINFO(ITEM_Integer, 0, 0);
+               result = 'I'; 
+               break;
+
+            case SIGNATURE_SHORT: 
+               full_info = (array_depth > 0)
+                             ? MAKE_FULLINFO(ITEM_Short, 0, 0)
+                             : MAKE_FULLINFO(ITEM_Integer, 0, 0);
+               result = 'I'; 
+               break;
+
+            case SIGNATURE_INT:
+               full_info = MAKE_FULLINFO(ITEM_Integer, 0, 0);
+               result = 'I'; 
+               break;
+
+            case SIGNATURE_FLOAT:
+               full_info = MAKE_FULLINFO(ITEM_Float, 0, 0);
+               result = 'F'; 
+               break;
+
+            case SIGNATURE_DOUBLE:
+               full_info = MAKE_FULLINFO(ITEM_Double, 0, 0);
+               result = 'D'; 
+               break;
+
+           case SIGNATURE_LONG:
+               full_info = MAKE_FULLINFO(ITEM_Long, 0, 0);
+               result = 'L'; 
+               break;
+
+            case SIGNATURE_ARRAY:
+               array_depth++;
+               continue;       /* only time we ever do the loop > 1 */
+
+            case SIGNATURE_CLASS: {
+               char buffer_space[256];
+               char *buffer = buffer_space;
+               char *finish = strchr(p, SIGNATURE_ENDCLASS);
+               int length = finish - p;
+               if (length + 1 > sizeof(buffer_space)) {
+                   buffer = sysMalloc(length + 1);
+                   if (buffer == 0) {
+       //              CCerror(context, "Out of memory");
+                   }
+               }
+               memcpy(buffer, p, length);
+               buffer[length] = '\0';
+               full_info = MAKE_CLASSNAME_INFO_WITH_COPY(context, buffer, 0);
+               result = 'A';
+               p = finish + 1;
+               if (buffer != buffer_space) 
+                   sysFree(buffer);
+               break;
+           }
+       } /* end of switch */
+       break;
+    }
+    *signature_p = p;
+    if (array_depth == 0 || result == 0) { 
+       /* either not an array, or result is bogus */
+       *full_info_p = full_info;
+       return result;
+    } else {
+//     if (array_depth > MAX_ARRAY_DIMENSIONS) 
+//         CCerror(context, "Array with too many dimensions");
+       *full_info_p = MAKE_FULLINFO(GET_ITEM_TYPE(full_info),
+                                    array_depth, 
+                                    GET_EXTRA_INFO(full_info));
+       return 'A';
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      decrement_indirection 
+ * OVERVIEW:      Given an array type, create the type that has one less
+ *                level of indirection.
+ * INTERFACE:
+ *   parameters:  fullinfo_type array_info 
+ *
+ *   returns:     fullinfo_type 
+ *=======================================================================*/
+static fullinfo_type
+decrement_indirection(fullinfo_type array_info)
+{
+    if (array_info == NULL_FULLINFO) { 
+       return NULL_FULLINFO;
+    } else { 
+       int type = GET_ITEM_TYPE(array_info);
+       int indirection = GET_INDIRECTION(array_info) - 1;
+       int extra_info = GET_EXTRA_INFO(array_info);
+       if (   (indirection == 0) 
+              && ((type == ITEM_Short || type == ITEM_Byte || type == ITEM_Boolean || type == ITEM_Char)))
+           type = ITEM_Integer;
+       return MAKE_FULLINFO(type, indirection, extra_info);
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      isAssignableTo 
+ * OVERVIEW:      Given an object of the "from" type, determine if it can be
+ *                assigned to an object of the "to" type.
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                fullinfo_type: from
+ *                fullinfo_type: to 
+ *
+ *   returns:     boolean type 
+ *=======================================================================*/
+static bool_t isAssignableTo(context_type *context, 
+                            fullinfo_type from, fullinfo_type to)
+{
+    return (merge_fullinfo_types(context, from, to, TRUE) == to);
+}
+
+
+/*=========================================================================
+ * FUNCTION:      merge_fullinfo_types 
+ * OVERVIEW:      Given two fullinfo_types, find their lowest common deno-
+ *                minator. If the assignable_p argument is non-null, we are
+ *                really just calling to find out if "<target> := <value>" 
+ *                is a legitimate assignment.
+ *                We treat all interfaces as if they were of type '
+ *                java/lang/Object, since the runtime will do the full
+ *                checking.
+ *
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                fullinfo_type: value 
+ *                fullinfo_type: target
+ *                bool_t for_assignment 
+ *
+ *   returns:     fullinfo_type 
+ *=======================================================================*/
+static fullinfo_type 
+merge_fullinfo_types(context_type *context, 
+                    fullinfo_type value, fullinfo_type target,
+                    bool_t for_assignment)
+{
+    if (value == target) {
+       /* If they're identical, clearly just return what we've got */
+       return value;
+    }
+
+    /* Both must be either arrays or objects to go further */
+    if (GET_INDIRECTION(value) == 0 && GET_ITEM_TYPE(value) != ITEM_Object)
+       return MAKE_FULLINFO(ITEM_Bogus, 0, 0);
+    if (GET_INDIRECTION(target) == 0 && GET_ITEM_TYPE(target) != ITEM_Object)
+       return MAKE_FULLINFO(ITEM_Bogus, 0, 0);
+    
+    /* If either is NULL, return the other. */
+    if (value == NULL_FULLINFO) 
+       return target;
+    else if (target == NULL_FULLINFO)
+       return value;
+
+    /* If either is java/lang/Object, that's the result. */
+    if (target == context->object_info)
+       return target;
+    else if (value == context->object_info) {
+       /* Minor hack.  For assignments, Interface := Object, return Interface
+        * rather than Object, so that isAssignableTo() will get the right
+        * result.      */
+       if (for_assignment && (WITH_ZERO_EXTRA_INFO(target) == 
+                                 MAKE_FULLINFO(ITEM_Object, 0, 0))) {
+           ClassClass *cb = object_fullinfo_to_classclass(context, target);
+           if (cb && cbIsInterface(cb)) 
+               return target;
+       }
+       return value;
+    }
+    if (GET_INDIRECTION(value) > 0 || GET_INDIRECTION(target) > 0) {
+       /* At least one is an array.  Neither is java/lang/Object or NULL.
+        * Moreover, the types are not identical.
+        * The result must either be Object, or an array of some object type.
+        */
+       int dimen_value = GET_INDIRECTION(value);
+       int dimen_target = GET_INDIRECTION(target);
+       
+       /* First, if either item's base type isn't ITEM_Object, promote it up
+         * to an object or array of object.  If either is elemental, we can
+        * punt.
+        */
+       if (GET_ITEM_TYPE(value) != ITEM_Object) { 
+           if (dimen_value == 0)
+               return MAKE_FULLINFO(ITEM_Bogus, 0, 0);
+           dimen_value--;
+           value = MAKE_Object_ARRAY(dimen_value);
+           
+       }
+       if (GET_ITEM_TYPE(target) != ITEM_Object) { 
+           if (dimen_target == 0)
+               return MAKE_FULLINFO(ITEM_Bogus, 0, 0);
+           dimen_target--;
+           target = MAKE_Object_ARRAY(dimen_target);
+       }
+       /* Both are now objects or arrays of some sort of object type */
+       if (dimen_value == dimen_target) { 
+            /* Arrays of the same dimension.  Merge their base types. */
+           fullinfo_type value_base = WITH_ZERO_INDIRECTION(value);
+           fullinfo_type target_base = WITH_ZERO_INDIRECTION(target);
+           fullinfo_type  result_base = 
+               merge_fullinfo_types(context, value_base, target_base,
+                                           for_assignment);
+           if (result_base == MAKE_FULLINFO(ITEM_Bogus, 0, 0))
+               /* bogus in, bogus out */
+               return result_base;
+           return MAKE_FULLINFO(ITEM_Object, dimen_value,
+                                GET_EXTRA_INFO(result_base));
+       } else { 
+            /* Arrays of different sizes.  Return Object, with a dimension
+             * of the smaller of the two.
+             */
+           int dimen = dimen_value < dimen_target ? dimen_value : dimen_target;
+           return MAKE_Object_ARRAY(dimen);
+       }
+    } else {
+       /* Both are non-array objects. Neither is java/lang/Object or NULL */
+       ClassClass *cb_value, *cb_target, *cb_super_value, *cb_super_target;
+       void **addr;
+       int value_info;
+
+       /* Let's get the classes corresponding to each of these.  Treat 
+        * interfaces as if they were java/lang/Object.  See hack note above. */
+       cb_target = object_fullinfo_to_classclass(context, target);
+       if (cb_target == 0) 
+           return MAKE_FULLINFO(ITEM_Bogus, 0, 0);
+       if (cbIsInterface(cb_target)) 
+           return for_assignment ? target : context->object_info;
+       cb_value = object_fullinfo_to_classclass(context, value);
+       if (cb_value == 0) 
+           return MAKE_FULLINFO(ITEM_Bogus, 0, 0);
+       if (cbIsInterface(cb_value))
+           return context->object_info;
+       
+       /* If this is for assignment of target := value, we just need to see if
+        * cb_target is a superclass of cb_value.  Save ourselves a lot of 
+        * work.
+        */
+       if (for_assignment) {
+           for (cb_super_value = cb_value; 
+                cbSuperclass(cb_super_value) != NULL; 
+                cb_super_value = cbSuperclass(cb_super_value)) {
+               if (cb_super_value == cb_target) {
+                   return target;
+               }
+           }
+           return context->object_info;
+       }
+
+       /* Find out whether cb_value or cb_target is deeper in the class
+        * tree by moving both toward the root, and seeing who gets there
+        * first.                                                          */
+       for (cb_super_value = cb_value, cb_super_target = cb_target;
+            cbSuperclass(cb_super_value) && cbSuperclass(cb_super_target); ) {
+           /* Optimization.  If either hits the other when going up looking
+            * for a parent, then might as well return the parent immediately */
+           if (cb_super_value == cb_target) 
+               return target;
+           if (cb_super_target == cb_value) 
+               return value;
+           cb_super_value= cbSuperclass(cb_super_value);
+           cb_super_target = cbSuperclass(cb_super_target);
+       } 
+       /* At most one of the following two while clauses will be executed. 
+        * Bring the deeper of cb_target and cb_value to the depth of the 
+        * shallower one. 
+        */
+       while (cbSuperclass(cb_super_value)) { /* cb_value is deeper */
+           cb_super_value= cbSuperclass(cb_super_value); 
+           cb_value= cbSuperclass(cb_value); 
+       }
+       while (cbSuperclass(cb_super_target)) { /* cb_target is deeper */
+           cb_super_target= cbSuperclass(cb_super_target); 
+           cb_target = cbSuperclass(cb_target); 
+       }
+       
+       /* Walk both up, maintaining equal depth, until a join is found.  We
+        * know that we will find one.  */
+       while (cb_value != cb_target) { 
+           cb_value =  cbSuperclass(cb_value);
+           cb_target =  cbSuperclass(cb_target);
+       }
+       /* Get the info for this guy.  We know its cb_value, so we should
+        * fill that in, while we're at it.                      */
+       value_info = Str2ID_Local(context, &context->classHash,
+                                 cbName(cb_value), &addr, TRUE);
+       *addr = cb_value;
+       return MAKE_FULLINFO(ITEM_Object, 0, value_info);
+    } /* both items are classes */
+}
+
+
+/*=========================================================================
+ * FUNCTION:      object_fullinfo_to_classclass 
+ * OVERVIEW:      Given a fullinfo_type corresponding to an Object, return the
+ *                pointer to the ClassClass structure of that type.
+ *                Returns 0 for an illegal class.
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                fullinfo_type: classinfo 
+ *
+ *   returns:     pointer to the ClassClass type
+ *=======================================================================*/
+static ClassClass *
+object_fullinfo_to_classclass(context_type *context, fullinfo_type classinfo)
+{
+    void **addr;
+    ClassClass *cb;
+           
+    unsigned short info = GET_EXTRA_INFO(classinfo);
+    char *classname = ID2Str_Local(context, context->classHash, info, &addr);
+    if ((cb = *addr) != 0) {
+       return cb;
+    } else {
+       *addr = cb = FindClassFromClass(0, classname, FALSE, context->class);
+//     if (cb == 0)
+//         CCerror(context, "Cannot find class %s", classname);
+       return cb;
+    }
+}
+
+
+/*=========================================================================
+ * The functions below are for debugging the preverifier 
+ *=======================================================================*/
+
+#ifdef DEBUG_VERIFIER
+
+static void print_fullinfo_type(context_type *, fullinfo_type, bool_t);
+
+
+/*=========================================================================
+ * FUNCTION:      print_stack
+ * OVERVIEW:      Prints stack information.
+ *               
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                stack_info: pointer to stack_info 
+ *
+ *   returns:     nothing
+ *=======================================================================*/
+static void 
+print_stack(context_type *context, stack_info_type *stack_info)
+{
+    stack_item_type *stack = stack_info->stack;
+    if (stack_info->stack_size == UNKNOWN_STACK_SIZE) {
+       jio_fprintf(stdout, "x");
+    } else {
+       jio_fprintf(stdout, "(");
+       for ( ; stack != 0; stack = stack->next) 
+           print_fullinfo_type(context, stack->item, verify_verbose > 1);
+       jio_fprintf(stdout, ")");
+    }
+}      
+
+
+/*=========================================================================
+ * FUNCTION:      print_registers
+ * OVERVIEW:      Prints registers.
+ *               
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                register_info_type: pointer to register_info 
+ *
+ *   returns:     nothing
+ *=======================================================================*/
+static void
+print_registers(context_type *context, register_info_type *register_info)
+{
+    int register_count = register_info->register_count;
+    if (register_count == UNKNOWN_REGISTER_COUNT) {
+       jio_fprintf(stdout, "x");
+    } else {
+       fullinfo_type *registers = register_info->registers;
+       int mask_count = register_info->mask_count;
+       mask_type *masks = register_info->masks;
+       int i, j;
+
+       jio_fprintf(stdout, "{");
+       for (i = 0; i < register_count; i++) 
+           print_fullinfo_type(context, registers[i], verify_verbose > 1);
+       jio_fprintf(stdout, "}");
+       for (i = 0; i < mask_count; i++) { 
+           char *separator = "";
+           int *modifies = masks[i].modifies;
+           jio_fprintf(stdout, "<%d: ", masks[i].entry);
+           for (j = 0; j < context->mb->nlocals; j++) 
+               if (IS_BIT_SET(modifies, j)) {
+                   jio_fprintf(stdout, "%s%d", separator, j);
+                   separator = ",";
+               }
+           jio_fprintf(stdout, ">");
+       }
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      print_flags
+ * OVERVIEW:      Prints flags.
+ *               
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                flag_type: and_flags
+ *                flag_type: or_flags
+ *
+ *   returns:     nothing
+ *=======================================================================*/
+static void
+print_flags(context_type *context, flag_type and_flags, flag_type or_flags)
+{ 
+    if (and_flags != ((flag_type)-1) || or_flags != 0) {
+       jio_fprintf(stdout, "<%x %x>", and_flags, or_flags);
+    }
+}          
+
+
+/*=========================================================================
+ * FUNCTION:      print_fullinfo_type
+ * OVERVIEW:      Prints fullinfo_type information.
+ *               
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                fullinfo_type: type
+ *                bool_t verbose
+ *
+ *   returns:     nothing
+ *=======================================================================*/
+static void 
+print_fullinfo_type(context_type *context, fullinfo_type type, bool_t verbose) 
+{
+    int i;
+    int indirection = GET_INDIRECTION(type);
+    for (i = indirection; i-- > 0; )
+       jio_fprintf(stdout, "[");
+    switch (GET_ITEM_TYPE(type)) {
+        case ITEM_Integer:       
+           jio_fprintf(stdout, "I"); break;
+       case ITEM_Float:         
+           jio_fprintf(stdout, "F"); break;
+       case ITEM_Double:        
+           jio_fprintf(stdout, "D"); break;
+       case ITEM_Double_2:      
+           jio_fprintf(stdout, "d"); break;
+       case ITEM_Long:          
+           jio_fprintf(stdout, "L"); break;
+       case ITEM_Long_2:        
+           jio_fprintf(stdout, "l"); break;
+       case ITEM_ReturnAddress: 
+           jio_fprintf(stdout, "a"); break;
+       case ITEM_Object:        
+           if (!verbose) {
+               jio_fprintf(stdout, "A");
+           } else {
+               unsigned short extra = GET_EXTRA_INFO(type);
+               if (extra == 0) {
+                   jio_fprintf(stdout, "/Null/");
+               } else {
+                   char *name = ID2Str_Local(context, context->classHash,
+                                             extra, 0);
+                   char *name2 = strrchr(name, '/');
+                   jio_fprintf(stdout, "/%s/", name2 ? name2 + 1 : name);
+               }
+           }
+           break;
+       case ITEM_Char:
+           jio_fprintf(stdout, "C"); break;
+       case ITEM_Short:
+           jio_fprintf(stdout, "S"); break;
+       case ITEM_Byte:
+           jio_fprintf(stdout, "B"); break;
+       case ITEM_Boolean:
+           jio_fprintf(stdout, "Z"); break;
+        case ITEM_NewObject:
+           if (!verbose) {
+               jio_fprintf(stdout, "@");
+           } else {
+               int inum = GET_EXTRA_INFO(type);
+               fullinfo_type real_type = 
+                   context->instruction_data[inum].operand2.fi;
+               jio_fprintf(stdout, ">");
+               print_fullinfo_type(context, real_type, TRUE);
+               jio_fprintf(stdout, "<");
+           }
+           break;
+        case ITEM_InitObject:
+           jio_fprintf(stdout, verbose ? ">/this/<" : "@");
+           break;
+
+       default: 
+           jio_fprintf(stdout, "?"); break;
+    }
+    for (i = indirection; i-- > 0; )
+       jio_fprintf(stdout, "]");
+}
+
+
+/*=========================================================================
+ * FUNCTION:      print_formatted_fieldname
+ * OVERVIEW:      Prints formatted fieldname associated with the given 
+ *                index within the constant pool.
+ *               
+ * INTERFACE:
+ *   parameters:  pointer to the context_type
+ *                int: index
+ *
+ *   returns:     nothing
+ *=======================================================================*/
+static void 
+print_formatted_fieldname(context_type *context, int index)
+{
+    union cp_item_type *constant_pool = cbConstantPool(context->class);
+    unsigned char *type_table = 
+           constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
+    unsigned type = CONSTANT_POOL_TYPE_TABLE_GET_TYPE(type_table, index);
+
+    unsigned key = constant_pool[index].i; 
+    unsigned classkey = key >> 16; 
+    unsigned nametypekey = key & 0xFFFF;
+    unsigned nametypeindex = constant_pool[nametypekey].i;
+    unsigned fieldnameindex = nametypeindex >> 16;
+    unsigned fieldtypeindex = nametypeindex & 0xFFFF;
+    jio_fprintf(stdout, "  <%s.%s%s%s>",
+           GetClassConstantClassName(constant_pool, classkey),
+           constant_pool[fieldnameindex].cp, 
+           type == CONSTANT_Fieldref ? " " : "",
+           constant_pool[fieldtypeindex].cp);
+}
+
+#endif /*DEBUG_VERIFIER*/
+
diff --git a/MPC.3.5.LINUX/preverifier/check_code.h b/MPC.3.5.LINUX/preverifier/check_code.h
new file mode 100644 (file)
index 0000000..ff9dd86
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * @(#)check_code.h    1.3 02/09/27
+ *
+ * Copyright 1995-1999 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ * 
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+#include <setjmp.h>
+
+#include "oobj.h"
+#include "opcodes.h"
+#include "tree.h"
+#include "sys_api.h"
+
+#define MAX_ARRAY_DIMENSIONS 255
+
+
+#define UNKNOWN_STACK_SIZE -1
+#define UNKNOWN_REGISTER_COUNT -1
+#define UNKNOWN_RET_INSTRUCTION -1
+
+#undef MAX
+#undef MIN 
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
+#define BITS_PER_INT   (CHAR_BIT * sizeof(int)/sizeof(char))
+#define SET_BIT(flags, i)  (flags[(i)/BITS_PER_INT] |= \
+                                      ((unsigned)1 << ((i) % BITS_PER_INT)))
+#define        IS_BIT_SET(flags, i) (flags[(i)/BITS_PER_INT] & \
+                                      ((unsigned)1 << ((i) % BITS_PER_INT)))
+
+typedef unsigned long fullinfo_type;
+typedef unsigned int *bitvector;
+
+#define GET_ITEM_TYPE(thing) ((thing) & 0x1F)
+#define GET_INDIRECTION(thing) (((thing) & 0xFFFF) >> 5)
+#define GET_EXTRA_INFO(thing) ((unsigned short)((thing) >> 16))
+#define WITH_ZERO_INDIRECTION(thing) ((thing) & ~(0xFFE0))
+#define WITH_ZERO_EXTRA_INFO(thing) ((thing) & 0xFFFF)
+
+#define MAKE_FULLINFO(type, indirect, extra) \
+     ((fullinfo_type)((type) + ((indirect) << 5) + ((extra) << 16)))
+#define MAKE_CLASSNAME_INFO(context, classname, addr) \
+       MAKE_FULLINFO(ITEM_Object, 0, \
+          Str2ID_Local(context, &context->classHash, (classname), (addr), FALSE))
+#define MAKE_CLASSNAME_INFO_WITH_COPY(context, classname, addr) \
+       MAKE_FULLINFO(ITEM_Object, 0, \
+          Str2ID_Local(context, &context->classHash, (classname), (addr), TRUE))
+#define MAKE_Object_ARRAY(indirect) \
+       (context->object_info + ((indirect) << 5))
+
+#define NULL_FULLINFO MAKE_FULLINFO(ITEM_Object, 0, 0)
+
+/* opc_invokespecial calls to <init> need to be treated special */
+#define opc_invokeinit 0x100   
+
+struct context_type {
+    /* these fields are per class */
+    ClassClass *class;         /* current class */
+    struct StrIDhash *classHash;
+    fullinfo_type object_info; /* fullinfo for java/lang/Object */
+    fullinfo_type string_info; /* fullinfo for java/lang/String */
+    fullinfo_type throwable_info; /* fullinfo for java/lang/Throwable */
+
+    fullinfo_type currentclass_info; /* fullinfo for context->class */
+    fullinfo_type superclass_info;   /* fullinfo for superclass */
+
+    /* these fields are per method */
+    struct methodblock *mb;    /* current method */
+    unsigned char *code;       /* current code object */
+    short *code_data;          /* offset to instruction number */
+    struct instruction_data_type *instruction_data; /* info about each */
+    struct handler_info_type *handler_info;
+    fullinfo_type *superClasses; /* null terminated superclasses */
+    int instruction_count;     /* number of instructions */
+    fullinfo_type return_type; /* function return type */
+    fullinfo_type swap_table[4]; /* used for passing information */
+    int bitmask_size;          /* words needed to hold bitmap of arguments */
+
+    /* Used by inliner */
+    bool_t redoJsr;
+
+    /* Used by the space allocator */
+    struct CCpool *CCroot, *CCcurrent;
+    char *CCfree_ptr;
+    int CCfree_size;
+
+    /* Jump here on any error. */
+    jmp_buf jump_buffer;
+};
+
+struct stack_info_type {
+    struct stack_item_type *stack;
+    int stack_size;
+};
+
+struct register_info_type {
+    int register_count;                /* number of registers used */
+    fullinfo_type *registers;
+    int mask_count;            /* number of masks in the following */
+    struct mask_type *masks;
+};
+
+struct mask_type {
+    int entry;
+    int *modifies;
+};
+
+typedef unsigned short flag_type;
+
+struct instruction_data_type {
+    opcode_type opcode;                /* may turn into "canonical" opcode */
+    unsigned changed:1;                /* has it changed */
+    unsigned protected:1;      /* must accessor be a subclass of "this" */
+    unsigned is_target:1;
+
+    union {
+       int i;                  /* operand to the opcode */
+       int *ip;
+       fullinfo_type fi;
+    } operand, operand2;
+    fullinfo_type p;
+    struct stack_info_type stack_info;
+    struct register_info_type register_info;
+#define FLAG_REACHED            0x01 /* instruction reached */
+#define FLAG_NEED_CONSTRUCTOR   0x02 /* must call this.<init> or super.<init> */
+#define FLAG_NO_RETURN          0x04 /* must throw out of method */
+    flag_type or_flags;                /* true for at least one path to this inst */
+#define FLAG_CONSTRUCTED        0x01 /* this.<init> or super.<init> called */
+    flag_type and_flags;       /* true for all paths to this instruction */
+    unsigned short offset;
+    unsigned short length;
+};
+
+struct handler_info_type {
+    int start, end, handler;
+    struct stack_info_type stack_info;
+};
+
+struct stack_item_type {
+    fullinfo_type item;
+    struct stack_item_type *next;
+};
+
+
+typedef struct context_type context_type;
+typedef struct instruction_data_type instruction_data_type;
+typedef struct stack_item_type stack_item_type;
+typedef struct register_info_type register_info_type;
+typedef struct stack_info_type stack_info_type;
+typedef struct mask_type mask_type;
diff --git a/MPC.3.5.LINUX/preverifier/classloader.c b/MPC.3.5.LINUX/preverifier/classloader.c
new file mode 100644 (file)
index 0000000..5cb4f34
--- /dev/null
@@ -0,0 +1,1783 @@
+/*
+ * @(#)classloader.c   1.37 02/09/27
+ *
+ * Copyright 1995-1999 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+/*=========================================================================
+ * SYSTEM:    Verifier
+ * SUBSYSTEM: class loader.
+ * FILE:      classloader.c
+ * OVERVIEW:  Routines for loading and resolving class definitions.
+ *            These routines should not be depending upon the interpreter
+ *            or the garbage collector.
+ * AUTHOR:    Sheng Liang, Sun Microsystems, Inc.
+ *            Modifications for JAR support and comments,
+ *            Tasneem Sayeed, Sun Microsystems
+ *=======================================================================*/
+
+/*=========================================================================
+ * Include files
+ *=======================================================================*/
+
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <stddef.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <setjmp.h>
+
+#include "jar.h"
+#include "oobj.h"
+#include "path.h"
+#include "tree.h"
+#include "signature.h"
+#include "convert_md.h"
+
+#include "sys_api.h"
+
+#ifdef UNIX
+#include <unistd.h>
+#endif
+
+
+/*=========================================================================
+ * Globals and extern declarations
+ *=======================================================================*/
+
+char *stat_source(ClassClass *cb, struct stat *s, char *pathbuf, int maxlen);
+
+extern ClassClass *allocClassClass();
+
+extern bool_t JARfile;
+
+extern char * zipFileName;
+
+extern zip_t * getZipEntry(char *zipFile, int len);
+
+extern bool_t findJARDirectories(zip_t *entry, struct stat *statbuf);
+
+extern JAR_DataStreamPtr loadJARfile(zip_t *entry, const char* filename);
+
+
+/*=========================================================================
+ * FUNCTION:      AddBinClass
+ * OVERVIEW:      Used by createInternalClass1() and createFakeArrayClass()
+ *                to add a class in the class table.
+ * INTERFACE:
+ *   parameters:  ClassClass: cb
+ *
+ *   returns:     nothing
+ *=======================================================================*/
+void
+AddBinClass(ClassClass * cb)
+{
+    register int left, right, middle, result, i;
+    char *name = cbName(cb);
+    struct Hjava_lang_ClassLoader *loader = cbLoader(cb);
+
+    BINCLASS_LOCK();
+    left = 0;
+    right = nbinclasses - 1;
+    result = 1;
+    while (left <= right) {
+        ClassClass *cb1;
+        middle = (left+right)/2;
+        cb1 = binclasses[middle];
+        result = strcmp(name, cbName(cb1));
+        if (result == 0) {
+            if (loader < cbLoader(cb1)) {
+                result = -1;
+            } else if (loader > cbLoader(cb1)) {
+                result = 1;
+            } else {
+                result = 0;
+            }
+        }
+        if (result < 0) {
+            right = middle-1;
+        } else if (result > 0) {
+            left = middle+1;
+        } else {
+            break;
+        }
+    }
+    if (result != 0) {
+        if (nbinclasses >= sizebinclasses) {
+            if (binclasses == 0)
+                binclasses = (ClassClass **)
+                sysMalloc(sizeof(ClassClass *) * (sizebinclasses = 50));
+            else
+                binclasses = (ClassClass **)
+                sysRealloc(binclasses, sizeof(ClassClass *)
+                    * (sizebinclasses = nbinclasses * 2));
+        }
+        if (binclasses == 0)
+            goto unlock;
+        right++;
+        for (i = nbinclasses; i > right; i--) {
+            binclasses[i] = binclasses[i-1];
+        }
+        binclasses[right] = cb;
+        nbinclasses++;
+    }
+
+unlock:
+    BINCLASS_UNLOCK();
+}
+
+
+/*=========================================================================
+ * FUNCTION:      DelBinClass
+ * OVERVIEW:      Intended for allowing deletion of classes from the class
+ *                table.
+ *
+ * INTERFACE:
+ *   parameters:  ClassClass: cb
+ *
+ *   returns:     nothing
+ *=======================================================================*/
+void
+DelBinClass(ClassClass * cb)
+{
+    register int i, j;
+    BINCLASS_LOCK();
+    for (i = nbinclasses; --i >= 0; )
+        if (binclasses[i] == cb) {
+            nbinclasses--;
+            for (j = i; j < nbinclasses; j++) {
+                binclasses[j] = binclasses[j+1];
+            }
+            break;
+        }
+    BINCLASS_UNLOCK();
+}
+
+
+/*=========================================================================
+ * FUNCTION:      MakeClassSticky
+ * OVERVIEW:      Used to lock certain system classes into memory during
+ *                initialization.
+ *
+ * INTERFACE:
+ *   parameters:  ClassClass: cb
+ *
+ *   returns:     nothing
+ *=======================================================================*/
+void
+MakeClassSticky(ClassClass *cb)
+{
+    /* monitorEnter(obj_monitor(cb));   */
+    CCSet(cb, Sticky);
+    /* monitorExit(obj_monitor(cb));    */
+}
+
+
+/*=========================================================================
+ * FUNCTION:      LoadClassFromFile
+ * OVERVIEW:      Loads a .class file normally from disk or a null if it fails.
+ *                When the interpreter requests for a file, it is actually
+ *                looking for a classblock structure to be created, and the
+ *                only way it can get one of those is by loading a compiled
+ *                class.
+ *                OpenCode() tries to open a .class file first. If it fails
+ *                to open the file, it returns a non-zero status. If it
+ *                returns a valid file descriptor, this usually means that
+ *                this is a valid .class file.
+ *                It then invokes createInternalClass() to actually create the
+ *                internal representation of the class.
+ *
+ * INTERFACE:
+ *   parameters:  char*: file name
+ *                char*: directory
+ *                char*: class name
+ *
+ *   returns:     nothing
+ *=======================================================================*/
+ClassClass *
+LoadClassFromFile(char *fn, char *dir, char *class_name)
+{
+    extern int OpenCode(char *, char *, char *, struct stat*);
+    struct stat st;
+    ClassClass *cb = 0;
+    int codefd = -1;
+    unsigned char *external_class;
+    char *detail;
+
+    codefd = OpenCode(fn, NULL, dir, &st);
+
+    if (codefd < 0)     /* open failed */
+        return 0;
+
+    /* Snarf the file into memory. */
+    external_class = (unsigned char *)sysMalloc(st.st_size);
+    if (external_class == 0)
+        goto failed;
+    if (sysRead(codefd, external_class, st.st_size) != st.st_size)
+        goto failed;
+    sysClose(codefd);
+    codefd = -1;
+
+    /* Create the internal class */
+    cb = allocClassClass();
+    if (cb == NULL ||
+        !createInternalClass(external_class, external_class + st.st_size,
+                 cb, NULL, class_name, &detail)) {
+        sysFree(external_class);
+        goto failed;
+    }
+    sysFree(external_class);
+
+    if (verbose)
+        jio_fprintf(stderr, "[Loaded %s]\n", fn);
+
+    return cb;
+failed:
+    if (codefd >= 0)
+        sysClose(codefd);
+    if (cb != 0)
+        FreeClass(cb);
+    return 0;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      LoadClassFromZip
+ * TYPE:          load class from a JAR or Zip file
+ * OVERVIEW:      Called by LoadClassLocally for loading classes from a Zip.
+ *
+ *                This function loads a .class file normally from a Zip or
+ *                JAR file.
+ *                It returns the class when it succeeds or NULL if it fails.
+ *
+ * INTERFACE:
+ *   parameters:  zip_t: zip file entry
+ *                char*: class file name to search for loading
+ *   returns:     Pointer to ClassClass when it succeeds, or NULL if it fails.
+ *=======================================================================*/
+static ClassClass *
+LoadClassFromZip(zip_t *zipEntry, char *class_name)
+{
+    ClassClass *cb = 0;
+    JAR_DataStreamPtr jdstream = NULL;
+    unsigned char *external_class;
+    int data_length;
+    char *detail;
+
+    jdstream = loadJARfile (zipEntry, class_name);
+
+    if (jdstream == NULL)
+        goto failed;
+
+    external_class = jdstream->data;
+    data_length = jdstream->dataLen;
+
+    /* Create the internal class */
+    cb = allocClassClass();
+    if (cb == NULL ||
+        !createInternalClass(external_class, external_class + data_length,
+                 cb, NULL, class_name, &detail)) {
+        goto failed;
+    }
+    if (jdstream != NULL) {
+        freeBytes(jdstream);
+    }
+
+    if (verbose) {
+        jio_fprintf(stderr, "[Loaded %s] from [%s]\n", class_name,
+                                                       zipEntry->name);
+    }
+    return cb;
+failed:
+    if (cb != 0)
+        FreeClass(cb);
+    if (jdstream != NULL) {
+        freeBytes(jdstream);
+    }
+    return 0;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      LoadClassLocally
+ * OVERVIEW:      Find a class file that is somewhere local, and not from a
+ *                class loader.
+ *                It still needs to be searched using the classpath.
+ *
+ * INTERFACE:
+ *   parameters:  char* : class file name
+ *   returns:     Pointer to ClassClass when it succeeds, or NULL if it fails.
+ *=======================================================================*/
+ClassClass *LoadClassLocally(char *name)
+{
+    ClassClass *cb = 0;
+    cpe_t **cpp;
+
+    if (name[0] == DIR_SEPARATOR || name[0] == SIGNATURE_ARRAY)
+        return 0;
+
+    for (cpp = sysGetClassPath(); cpp && *cpp != 0; cpp++) {
+        cpe_t *cpe = *cpp;
+        char *path;
+
+        if (cpe->type == CPE_DIR) {
+            path = (char *)sysMalloc(strlen(cpe->u.dir)
+                + sizeof(LOCAL_DIR_SEPARATOR)
+                + strlen(name)
+                + strlen(JAVAOBJEXT)
+                + 2);  /* 2 is for the . and the \0 */
+            if (sprintf(path,
+                 "%s%c%s." JAVAOBJEXT, cpe->u.dir,
+                 LOCAL_DIR_SEPARATOR, name) == -1) {
+                sysFree(path);
+                return 0;
+            }
+            if ((cb = LoadClassFromFile(sysNativePath(path),
+                                        cpe->u.dir, name))) {
+                sysFree(path);
+                return cb;
+            }
+        } else if (cpe->type == CPE_ZIP) {
+           // if (JAR_DEBUG && verbose)
+            //    jio_fprintf(stderr, "Loading classes from a ZIP file... \n");
+            if ((cb = LoadClassFromZip(cpe->u.zip, name))) {
+                return cb;
+            }
+        }
+
+    }
+    return cb;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      stat_source
+ * OVERVIEW:      Unused by the Verifier, but it is too late to remove it now.
+ *
+ * INTERFACE:
+ *   parameters:  ClassClass *: cb
+ *                struct stat*: s
+ *                char*: pathbuf
+ *                int: maxlen
+ *   returns:     char *, or NULL if it fails.
+ *=======================================================================*/
+char *
+stat_source(ClassClass *cb, struct stat *s, char *pathbuf, int maxlen)
+{
+#define NAMEBUFLEN 255
+    char nm[NAMEBUFLEN];
+    char *p, *q, *lp;
+    cpe_t **cpp;
+
+    /* don't bother searching if absolute */
+    /* REMIND: only here for compatibility */
+    if (sysIsAbsolute(cbSourceName(cb))) {
+        if (sysStat(cbSourceName(cb), s) == 0) {
+            if (jio_snprintf(pathbuf, maxlen, "%s", cbSourceName(cb)) == -1) {
+                return 0;
+            }
+            return pathbuf;
+        } else {
+            return 0;
+        }
+    }
+
+    /* parse the package name */
+    p = cbName(cb);
+    if (strlen(p) > NAMEBUFLEN - 1) {
+        return 0;
+    }
+    for (q = lp = nm ; *p ; p++) {
+        if (*p == DIR_SEPARATOR) {
+            *q++ = LOCAL_DIR_SEPARATOR;
+            lp = q;
+        } else {
+            *q++ = *p;
+        }
+    }
+
+    /* append the source file name */
+    p = cbSourceName(cb);
+    if (strlen(p) + (lp - nm) > NAMEBUFLEN - 1) {
+        return 0;
+    }
+    for (; *p ; p++) {
+        *lp++ = (*p == DIR_SEPARATOR ? LOCAL_DIR_SEPARATOR : *p);
+    }
+    *lp = '\0';
+
+    /* search the class path */
+    for (cpp = sysGetClassPath() ; cpp && *cpp != 0 ; cpp++) {
+        cpe_t *cpe = *cpp;
+        if (cpe->type == CPE_DIR) {
+            if (jio_snprintf(pathbuf, maxlen, "%s%c%s",
+                             cpe->u.dir, LOCAL_DIR_SEPARATOR, nm) == -1) {
+                return 0;
+            }
+            if (sysStat(pathbuf, s) == 0) {
+                return pathbuf;
+            }
+        }
+    }
+    return 0;
+}
+
+
+/*=========================================================================
+ * Globals and externs for Internal Class representation
+ *=======================================================================*/
+struct CICmallocs {
+    struct CICmallocs *next;
+    void * alignment_padding;
+
+/* Whatever follows will be 8-byte aligned, if the structure itself is
+   8-byte aligned. */
+};
+
+typedef struct CICmallocs CICmallocs;
+
+struct CICcontext {
+    unsigned char *ptr;
+    unsigned char *end_ptr;
+    ClassClass *cb;
+    jmp_buf jump_buffer;
+    char **detail;
+
+    int pass;         /* two passes, 1 or 2 */
+    int malloc_size;  /* space needed for everything other than <clinit> */
+    int clinit_size;  /* space needed for the <clinit> method */
+    int in_clinit;    /* indicates whether we are loading <clinit> method */
+
+    struct {
+        CICmallocs *mallocs; /* list of memory blocks used in the first pass */
+
+        void * alignment_padding;
+                             /* Whatever follows will be 8-byte aligned */
+    } pass1;
+
+    struct {
+        char *malloc_buffer; /* used to hold everything other than <clinit> */
+        char *malloc_ptr;    /* current point of allocation */
+
+        char *clinit_buffer; /* used to hold the <clinit> method */
+        char *clinit_ptr;    /* current point of allocation */
+    } pass2;
+
+};
+
+typedef struct CICcontext CICcontext;
+
+static char *getAsciz(CICcontext *, bool_t);
+static char *getAscizFromClass(CICcontext *, int i);
+
+static unsigned char get1byte(CICcontext *);
+static unsigned short get2bytes(CICcontext *);
+static unsigned long get4bytes(CICcontext *);
+static void getNbytes(CICcontext *, int count, char *buffer);
+static void *allocNBytes(CICcontext *, int size);
+static void freeBuffers(CICcontext *);
+
+static void LoadConstantPool(CICcontext *);
+static void ReadInCode(CICcontext *, struct methodblock *);
+static void ReadLineTable(CICcontext *, struct methodblock *mb);
+static void ReadExceptions(CICcontext *, struct methodblock *);
+static void ReadLocalVars(CICcontext *, struct methodblock *mb);
+
+static void
+createInternalClass0(CICcontext *context, ClassClass *cb,
+             struct Hjava_lang_ClassLoader *loader, char *name);
+
+bool_t
+createInternalClass1(unsigned char *ptr, unsigned char *end_ptr,
+             ClassClass *cb, struct Hjava_lang_ClassLoader *loader,
+             char *name, char **detail);
+
+
+/*=========================================================================
+ * FUNCTION:      createInternalClass
+ * OVERVIEW:      Invoked by LoadClassFromFile() or LoadClassFromZip() to
+ *                create an internal class. See createInternalClass1() for
+ *                details.
+ *
+ * INTERFACE:
+ *   parameters:  unsigned char *: ptr
+ *                unsigned char *: end_ptr
+ *                ClassClass *: cb
+ *                struct Hjava_lang_ClassLoader *: loader
+ *                char *: name
+ *                char **: detail
+ *
+ *   returns:     bool_t
+ *=======================================================================*/
+bool_t
+createInternalClass(unsigned char *ptr, unsigned char *end_ptr,
+            ClassClass *cb, struct Hjava_lang_ClassLoader *loader,
+            char *name, char **detail)
+{
+    bool_t res;
+    res = createInternalClass1(ptr, end_ptr, cb, loader, name, detail);
+
+    return res;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      JAVA_ERROR
+ * OVERVIEW:      Verifier error processing function.
+ *
+ * INTERFACE:
+ *   parameters:  CICcontext *: context
+ *                char *      : name
+ *
+ *   returns:     nothing
+ *=======================================================================*/
+void JAVA_ERROR(CICcontext *context, char *name) {
+    printCurrentClassName();
+    *(context->detail) = name;
+    EE()->class_loading_msg = name;
+    fprintf(stderr, "Class loading error: %s\n", name);
+    exit(1);
+}
+
+
+/*=========================================================================
+ * FUNCTION:      createInternalClass1
+ * OVERVIEW:      Auxiliary function for creating an internal class.
+ *                Invoked by createInternalClass().
+ *
+ *                Creates an internal class file from the indicated data.
+ *                It should be in a buffer for which the first byte is at
+ *                *ptr and the last byte is just before *end_ptr.
+ *                The class's classloader is indicated by the classloader
+ *                argument.
+ *
+ *                We go through the buffer twice. In the first pass, we
+ *                determine the amount of storage needed by the class.
+ *                We then allocate a single chunk of memory, free the
+ *                temporary storage, and load from the buffer for the second
+ *                time.
+ *
+ *                Since all storage needed by the class initialization method
+ *                <clinit> can be freed after the class is loaded, we count
+ *                the <clinit> space needs separately and store the <clinit>
+ *                method in a separate chunk of memory.
+ *
+ * INTERFACE:
+ *   parameters:  unsigned char *: ptr
+ *                unsigned char *: end_ptr
+ *                ClassClass *: cb
+ *                struct Hjava_lang_ClassLoader *: loader
+ *                char *: name
+ *                char **: detail
+ *
+ *   returns:     bool_t
+ *=======================================================================*/
+bool_t
+createInternalClass1(unsigned char *ptr, unsigned char *end_ptr,
+             ClassClass *cb, struct Hjava_lang_ClassLoader *loader,
+             char *name, char **detail)
+{
+    struct CICcontext context_block;
+    struct CICcontext *context = &context_block;
+
+    /* Set up the context */
+    context->ptr = ptr;
+    context->end_ptr = end_ptr;
+    context->cb = cb;
+    context->detail = detail;
+
+    /* initialize the remaining fields of the context block */
+    context->pass = 0;
+    context->malloc_size = 0;
+    context->clinit_size = 0;
+    context->in_clinit = 0;
+    context->pass1.mallocs = 0;
+
+    context->pass2.malloc_buffer = NULL;
+    context->pass2.malloc_ptr = NULL;
+    context->pass2.clinit_buffer = NULL;
+    context->pass2.clinit_ptr = NULL;
+
+
+    if (setjmp(context->jump_buffer)) {
+
+        /* We've gotten an error of some sort
+         * See comments below about zeroing these
+         * two fields before freeing the temporary
+         * buffer.
+         */
+
+        cbConstantPool(cb) = NULL;
+        cbFields(cb) = NULL;
+
+        /* Zero out the method so that freeClass will
+         * not try to free the clinit method.
+         */
+
+        cbMethodsCount(cb) = 0;
+        freeBuffers(context);
+        return FALSE;
+    }
+
+    /* The first pass allows us to uncover any class format
+     * errors and find out the size of the buffer needed.
+     */
+
+    context->pass = 1;
+    createInternalClass0(context, cb, loader, name);
+
+    /* We must set the following two fields to zero before we free
+     * the temporary buffers, because markClassClass may scan a
+     * partially constructed class block in the second pass.
+     * If these two fields are set to zero, markClassClass will
+     * not scan the constant pool and field blocks, which may
+     * point to freed memory.
+     */
+
+    cbConstantPool(cb) = NULL;
+    cbFields(cb) = NULL;
+
+    /* Zero out the method so that freeClass will not try
+     * to free the clinit method.
+     */
+
+    cbMethodsCount(cb) = 0;
+    freeBuffers(context);
+
+    context->ptr = ptr;   /* rewind the raw class data */
+
+    if (context->malloc_size > 0) {
+        context->pass2.malloc_buffer =
+                   (char *)sysCalloc(1, context->malloc_size);
+
+        if (context->pass2.malloc_buffer == 0)
+            JAVA_ERROR(context, "out of memory");
+    }
+
+    if (context->clinit_size > 0) {
+        context->pass2.clinit_buffer =
+                   (char *)sysCalloc(1, context->clinit_size * sizeof(char));
+
+        if (context->pass2.clinit_buffer == 0) {
+            sysFree(context->pass2.malloc_buffer);
+            JAVA_ERROR(context, "out of memory");
+        }
+    }
+
+    context->pass2.malloc_ptr = context->pass2.malloc_buffer;
+    context->pass2.clinit_ptr = context->pass2.clinit_buffer;
+
+    /* The second pass accomplishes the real task. */
+
+    context->pass = 2;
+    createInternalClass0(context, cb, loader, name);
+
+    /* Valid class - let's put it in the class table. */
+    AddBinClass(cb);
+
+    return TRUE;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      createInternalClass0
+ * OVERVIEW:      Auxiliary function invoked by createInternalClass1() during
+ *                the second pass to actually load the internal class file
+ *                structures such as the constant pool, method blocks, field
+ *                blocks and so on.
+ *
+ * INTERFACE:
+ *   parameters:  CICcontext *: ptr
+ *                ClassClass *: cb
+ *                struct Hjava_lang_ClassLoader *: loader
+ *                char *: name
+ *
+ *   returns:     nothing
+ *=======================================================================*/
+static void
+createInternalClass0(CICcontext *context, ClassClass *cb,
+             struct Hjava_lang_ClassLoader *loader, char *name)
+{
+    int i, j, len;
+    char buff[BUFSIZ];
+    char *UTFname = &buff[0];
+    union cp_item_type *constant_pool;
+    unsigned char *type_table;
+    int attribute_count;
+    unsigned fields_count;
+    struct methodblock *mb;
+    struct fieldblock *fb;
+    struct Classjava_lang_Class *ucb = unhand(cb);
+
+    int32_t tmp = get4bytes(context);
+    if (tmp != JAVA_CLASSFILE_MAGIC)
+        JAVA_ERROR(context, "Bad magic number");
+
+    ucb->minor_version = get2bytes(context);
+    ucb->major_version = get2bytes(context);
+    ucb->loader = loader;
+
+    /* Ignore version # so that the preverifier can work with JDK 1.4 onwards */
+    /*
+    if (ucb->major_version != JAVA_VERSION)
+        JAVA_ERROR(context, "Bad major version number");
+    */
+
+    LoadConstantPool(context);
+    constant_pool = ucb->constantpool;
+    type_table = constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
+
+    ucb->access = get2bytes(context) & ACC_WRITTEN_FLAGS;
+
+    /* Get the name of the class */
+    i = get2bytes(context); /* index in constant pool of class */
+    ucb->name = getAscizFromClass(context, i);
+
+    /* Conversion for Japanese filenames */
+    len = native2utf8(name, UTFname, BUFSIZ);
+
+    if (name != NULL && strcmp(ucb->name, UTFname) != 0)
+        JAVA_ERROR(context, "Wrong name");
+    constant_pool[i].clazz = cb;
+    CONSTANT_POOL_TYPE_TABLE_SET_RESOLVED(type_table, i);
+
+    if (loader) {
+        /* We don't trust a classloader to do the right thing. . . */
+        ClassClass **pcb, **end_pcb;
+        char *name = ucb->name;
+//        if (name == NULL || !IsLegalClassname(name, FALSE)) {
+//            JAVA_ERROR(context, "Bad name");
+//        }
+        BINCLASS_LOCK();
+        for (pcb = binclasses, end_pcb = pcb + nbinclasses;
+                               pcb < end_pcb; pcb++) {
+            ClassClass *cb = *pcb;
+            if ((cbLoader(cb) == loader) && (strcmp(name, cbName(cb)) == 0))
+                break;
+        }
+        BINCLASS_UNLOCK();
+        if (pcb < end_pcb)
+            /* There's already a class with the same name and loader */
+            JAVA_ERROR(context, "Duplicate name");
+    }
+
+    /* Get the super class name. */
+    i = get2bytes(context); /* index in constant pool of class */
+    if (i > 0) {
+        ucb->super_name = getAscizFromClass(context, i);
+               ucb->superclass_idx = i;
+//        if (!IsLegalClassname(ucb->super_name, FALSE)) {
+//            JAVA_ERROR(context, "Bad superclass name");
+//        }
+    }
+
+    i = ucb->implements_count = get2bytes(context);
+    if (i > 0) {
+        int j;
+        ucb->implements = allocNBytes(context, i * sizeof(short));
+        for (j = 0; j < i; j++) {
+            ucb->implements[j] = get2bytes(context);
+        }
+    }
+
+    fields_count = ucb->fields_count = get2bytes(context);
+    if (fields_count > 0)
+        ucb->fields = (struct fieldblock *)
+          allocNBytes(context, ucb->fields_count * sizeof(struct fieldblock));
+    for (i = fields_count, fb = ucb->fields; --i >= 0; fb++) {
+        fieldclass(fb) = cb;
+        fb->access = get2bytes(context) & ACC_WRITTEN_FLAGS;
+        fb->name = getAsciz(context, FALSE);
+        fb->signature = getAsciz(context, FALSE);
+        attribute_count = get2bytes(context);
+        for (j = 0; j < (int)attribute_count; j++) {
+            char *attr_name = getAsciz(context, FALSE);
+            int length = get4bytes(context);
+            if (strcmp(attr_name, "ConstantValue") == 0) {
+                if (fb->access & ACC_STATIC) {
+                    if (length != 2) {
+                        JAVA_ERROR(context, "Wrong size for VALUE attribute");
+                    }
+                    fb->access |= ACC_VALKNOWN;
+                    /* we'll change this below */
+                    fb->u.offset = get2bytes(context);
+                } else {
+                    getNbytes(context, length, NULL);
+                }
+            } else if (strcmp(attr_name, "Deprecated") == 0) {
+                if (length > 0) {
+                    JAVA_ERROR(context, "Bad deprecated size");
+                }
+                fb->deprecated = TRUE;
+            } else if (strcmp(attr_name, "Synthetic") == 0) {
+                if (length > 0) {
+                    JAVA_ERROR(context, "Bad synthetic attribute size");
+                }
+                fb->synthetic = TRUE;
+            } else {
+                getNbytes(context, length, NULL);
+            }
+        }
+        /*
+        if (fb->access & ACC_STATIC) {
+            InitializeStaticVar(fb, context);
+        }
+        */
+    }
+
+    if ((ucb->methods_count = get2bytes(context)) > 0)
+        ucb->methods = (struct methodblock *)
+          allocNBytes(context, ucb->methods_count * sizeof(struct methodblock));
+
+    for (i = cbMethodsCount(cb), mb = cbMethods(cb); --i >= 0; mb++) {
+        fieldclass(&mb->fb) = cb;
+        mb->fb.access = get2bytes(context) & ACC_WRITTEN_FLAGS;
+        mb->fb.name = getAsciz(context, FALSE);
+        mb->fb.signature = getAsciz(context, FALSE);
+
+        if (strcmp(mb->fb.name, "<clinit>") == 0 &&
+            strcmp(mb->fb.signature, "()V") == 0)
+            context->in_clinit = TRUE;
+
+        mb->args_size = Signature2ArgsSize(mb->fb.signature)
+                    + ((mb->fb.access & ACC_STATIC) ? 0 : 1);
+        if (mb->args_size > 255)
+            JAVA_ERROR(context, "Too many arguments");
+
+        attribute_count = get2bytes(context);
+        for (j = 0; j < attribute_count; j++) {
+            char *attr_name = getAsciz(context, FALSE);
+            if ((strcmp(attr_name, "Code") == 0)
+               && ((mb->fb.access & (ACC_NATIVE | ACC_ABSTRACT))==0)) {
+                ReadInCode(context, mb);
+            } else if (strcmp(attr_name, "Exceptions") == 0) {
+                ReadExceptions(context, mb);
+            } else {
+                int length = get4bytes(context);
+                if (strcmp(attr_name, "Deprecated") == 0) {
+                    if (length > 0) {
+                        JAVA_ERROR(context, "Bad deprecated size");
+                    }
+                    mb->fb.deprecated = TRUE;
+                } else if (strcmp(attr_name, "Synthetic") == 0) {
+                    if (length > 0) {
+                        JAVA_ERROR(context, "Bad synthetic attribute size");
+                    }
+                    mb->fb.synthetic = TRUE;
+                } else {
+                    getNbytes(context, length, NULL);
+                }
+            }
+        }
+        context->in_clinit = FALSE;
+    }
+
+    /* See if there are class attributes */
+    attribute_count = get2bytes(context);
+    for (j = 0; j < attribute_count; j++) {
+        char *attr_name = getAsciz(context, FALSE);
+        int length = get4bytes(context);
+        if (strcmp(attr_name, "SourceFile") == 0) {
+            if (length != 2) {
+                JAVA_ERROR(context, "Wrong size for VALUE attribute");
+            }
+            ucb->source_name = getAsciz(context, FALSE);
+        } else if (strcmp(attr_name, "AbsoluteSourcePath") == 0) {
+            if (length == 2) {
+                ucb->absolute_source_name = getAsciz(context, FALSE);
+            } else
+            getNbytes(context, length, NULL);
+        } else if (strcmp(attr_name, "TimeStamp") == 0) {
+            if (length == 8) {
+                ucb->hasTimeStamp = TRUE;
+                ucb->timestamp.high = get4bytes(context);
+                ucb->timestamp.low = get4bytes(context);
+            } else {
+                getNbytes(context, length, NULL);
+            }
+        } else if (strcmp(attr_name, "Deprecated") == 0) {
+            if (length > 0) {
+                JAVA_ERROR(context, "Bad deprecated size");
+            }
+            ucb->deprecated = TRUE;
+        } else if (strcmp(attr_name, "Synthetic") == 0) {
+            if (length > 0) {
+                JAVA_ERROR(context, "Bad synthetic attribute size");
+            }
+            ucb->synthetic = TRUE;
+        } else if (strcmp(attr_name, "InnerClasses") == 0) {
+            int count = get2bytes(context);
+            struct innerClasses *thisInnerClass = (struct innerClasses *)
+                 allocNBytes(context, count * sizeof(struct innerClasses));
+            struct innerClasses *lastInnerClass = thisInnerClass + count;
+
+            if (count * 8 + 2 != length) {
+                JAVA_ERROR(context, "Bad length of InnerClasses attribute");
+            }
+
+            ucb->inner_classes_count = count;
+            ucb->inner_classes = thisInnerClass;
+
+            for ( ; thisInnerClass < lastInnerClass; thisInnerClass++) {
+                thisInnerClass->inner_class = get2bytes(context);
+                thisInnerClass->outer_class = get2bytes(context);
+                thisInnerClass->inner_name = getAsciz(context, TRUE);
+                thisInnerClass->access = get2bytes(context);
+                if (thisInnerClass->inner_class != 0) {
+                    /* Make sure that inner_class really belongs to a CLASS */
+                    getAscizFromClass(context, thisInnerClass->inner_class);
+                }
+                if (thisInnerClass->outer_class != 0) {
+                    /* Make sure that outer_class really belongs to a CLASS */
+                    getAscizFromClass(context, thisInnerClass->outer_class);
+                }
+            }
+        } else {
+            getNbytes(context, length, NULL);
+        }
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      createFakeArrayClass
+ * OVERVIEW:      Invoked by Locked_FindArrayClassFromClass() for creating
+ *                a fake array class that has the specified fields.
+ *
+ * INTERFACE:
+ *   parameters:  char *: name
+ *                int : base type
+ *                int : depth  (array dimension)
+ *                ClassClass * : base type if T_CLASS
+ *                struct Hjava_lang_ClassLoader *: class loader
+ *
+ *   returns:     ClassClass *
+ *=======================================================================*/
+ClassClass *
+createFakeArrayClass(char *name,   /* name */
+             int base_type,        /* base_type */
+             int depth,            /* array dimension */
+             ClassClass *inner_cb, /* base type if T_CLASS */
+             struct Hjava_lang_ClassLoader *loader)
+{
+    ClassClass *cb = allocClassClass();
+    Classjava_lang_Class *ucb = unhand(cb);
+    cp_item_type *constant_pool =
+    sysCalloc(CONSTANT_POOL_ARRAY_LENGTH,
+          (sizeof(cp_item_type) + sizeof(unsigned char)));
+    unsigned char *type_table = (unsigned char *)
+        (constant_pool + CONSTANT_POOL_ARRAY_LENGTH);
+    sysAssert(name[0] == SIGNATURE_ARRAY);
+    ucb->major_version = JAVA_VERSION;
+    ucb->minor_version = JAVA_MINOR_VERSION;
+    ucb->name = strdup(name);
+    ucb->super_name = JAVAPKG "Object";
+    ucb->constantpool = constant_pool;
+    ucb->constantpool_count = CONSTANT_POOL_ARRAY_LENGTH;
+    ucb->loader = loader;
+
+    constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type = type_table;
+    constant_pool[CONSTANT_POOL_ARRAY_DEPTH_INDEX].i = depth;
+    constant_pool[CONSTANT_POOL_ARRAY_TYPE_INDEX].i = base_type;
+    type_table[CONSTANT_POOL_ARRAY_DEPTH_INDEX] =
+    CONSTANT_Integer | CONSTANT_POOL_ENTRY_RESOLVED;
+    type_table[CONSTANT_POOL_ARRAY_TYPE_INDEX] =
+    CONSTANT_Integer | CONSTANT_POOL_ENTRY_RESOLVED;
+
+    if (base_type == T_CLASS) {
+        /* Initialize the appropriate fields of the constant pool */
+        constant_pool[CONSTANT_POOL_ARRAY_CLASS_INDEX].clazz = inner_cb;
+        type_table[CONSTANT_POOL_ARRAY_CLASS_INDEX] =
+                      CONSTANT_Class | CONSTANT_POOL_ENTRY_RESOLVED;
+        /* The class is public iff its base class is public */
+        ucb->access = ACC_FINAL | ACC_ABSTRACT |
+                      (cbAccess(inner_cb) & ACC_PUBLIC);
+    } else {
+        /* Set the class field to something innocuous */
+        type_table[CONSTANT_POOL_ARRAY_CLASS_INDEX] =
+                      CONSTANT_Integer | CONSTANT_POOL_ENTRY_RESOLVED;
+        ucb->access = ACC_FINAL | ACC_ABSTRACT | ACC_PUBLIC;
+    }
+    AddBinClass(cb);
+    return cb;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      createPrimitiveClass
+ * OVERVIEW:      Creates a class block to represent a primitive type.
+ *                NOTE: this is not added to the built-in class table, so
+ *                      it should only be called once per primitive type.
+ *                      See FindPrimitiveClass().
+ *
+ * INTERFACE:
+ *   parameters:  char *: name
+ *                char  : sig
+ *                unsigned char: typecode
+ *                unsigned char: slotsize
+ *                unsigned char: elementsize
+ *
+ *   returns:     ClassClass *
+ *=======================================================================*/
+ClassClass *
+createPrimitiveClass(char *name, char sig, unsigned char typecode,
+    unsigned char slotsize, unsigned char elementsize)
+{
+    ClassClass *cb = allocClassClass();
+    Classjava_lang_Class *ucb = unhand(cb);
+
+    ucb->major_version = JAVA_VERSION;
+    ucb->minor_version = JAVA_MINOR_VERSION;
+    ucb->name = strdup(name);
+    ucb->super_name = JAVAPKG "Object";
+    ucb->constantpool = NULL;
+    ucb->constantpool_count = 0;
+    ucb->loader = NULL;
+    ucb->access = ACC_FINAL | ACC_ABSTRACT | ACC_PUBLIC;
+
+    CCSet(cb, Primitive);
+    cbTypeSig(cb) = sig;
+    cbTypeCode(cb) = typecode;
+    cbSlotSize(cb) = slotsize;
+    cbElementSize(cb) = elementsize;
+    MakeClassSticky(cb);
+
+    return cb;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      LoadConstantPool
+ * OVERVIEW:      Loads the constant pool given a pointer to the internal
+ *                class file.
+ *
+ * INTERFACE:
+ *   parameters:  CICcontext *: ptr
+ *
+ *   returns:     nothing
+ *=======================================================================*/
+static void LoadConstantPool(CICcontext *context)
+{
+    ClassClass *cb = context->cb;
+    int nconstants = get2bytes(context);
+    cp_item_type *constant_pool;
+    unsigned char *type_table;
+    int i;
+    Java8 t1;
+
+    if (nconstants > 16384) {
+        JAVA_ERROR(context, "Preverifier only "
+                   "handles constant pool size up to 16K");
+    }
+
+    t1.x[0] = 0; /* shut off warning */
+    if (nconstants < CONSTANT_POOL_UNUSED_INDEX) {
+        JAVA_ERROR(context, "Illegal constant pool size");
+    }
+
+    constant_pool = (cp_item_type *)
+        allocNBytes(context, nconstants * sizeof(cp_item_type));
+    type_table = allocNBytes(context, nconstants * sizeof(char));
+
+    for (i = CONSTANT_POOL_UNUSED_INDEX; i < nconstants; i++) {
+        int type = get1byte(context);
+        CONSTANT_POOL_TYPE_TABLE_PUT(type_table, i, type);
+        switch (type) {
+            case CONSTANT_Utf8: {
+                int length = get2bytes(context);
+                char *result = allocNBytes(context, length + 1);
+                getNbytes(context, length, result);
+                result[length] = '\0';
+                constant_pool[i].cp = result;
+                CONSTANT_POOL_TYPE_TABLE_SET_RESOLVED(type_table, i);
+                break;
+            }
+
+            case CONSTANT_Class:
+            case CONSTANT_String:
+                constant_pool[i].i = get2bytes(context);
+                break;
+
+            case CONSTANT_Fieldref:
+            case CONSTANT_Methodref:
+            case CONSTANT_InterfaceMethodref:
+            case CONSTANT_NameAndType:
+                constant_pool[i].i = get4bytes(context);
+                break;
+
+            case CONSTANT_Float:
+                if (no_floating_point) {
+                    panic("floating-point constants should not appear");
+                }
+
+            case CONSTANT_Integer:
+                constant_pool[i].i = get4bytes(context);
+                CONSTANT_POOL_TYPE_TABLE_SET_RESOLVED(type_table, i);
+                break;
+
+            case CONSTANT_Double:
+                if (no_floating_point) {
+                    panic("floating-point constants should not appear");
+                }
+            case CONSTANT_Long: {
+                /* We ignore endian problems, and just load the two
+                 * values.  The verifier never actually cares what
+                 * the actual value is.
+                 */
+                constant_pool[i].i = get4bytes(context);
+                CONSTANT_POOL_TYPE_TABLE_SET_RESOLVED(type_table, i);
+                i++;
+                if (i >= nconstants) {
+                    JAVA_ERROR(context, "illegal constant pool entry");
+                }
+                /* Indicate that the next object in the constant pool cannot
+                 * be accessed independently.
+                 */
+                constant_pool[i].i = get4bytes(context);
+                CONSTANT_POOL_TYPE_TABLE_PUT(type_table, i, 0);
+                CONSTANT_POOL_TYPE_TABLE_SET_RESOLVED(type_table, i);
+                break;
+            }
+
+            default:
+                JAVA_ERROR(context, "Illegal constant pool type");
+        }
+    }
+    /* It is important to only set these after everything is setup,
+       so that the GC sees a consistent state.*/
+    cbConstantPool(cb) = constant_pool;
+    cbConstantPoolCount(cb) = nconstants;
+    constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type = type_table;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      ReadInCode
+ * OVERVIEW:      Reads the code attributes given a pointer to the internal
+ *                class file and a pointer to the method block structure.
+ *                This includes line number and local variable tables.
+ *
+ * INTERFACE:
+ *   parameters:  CICcontext *: ptr
+ *                struct methodblock *: mb
+ *
+ *   returns:     nothing
+ *=======================================================================*/
+static void ReadInCode(CICcontext *context, struct methodblock *mb)
+{
+    int attribute_length = get4bytes(context);
+    unsigned char *end_ptr = context->ptr + attribute_length;
+    int attribute_count;
+    int code_length;
+    int i;
+
+    if (cbMinorVersion(context->cb) == JAVA_VERSION &&
+        cbMinorVersion(context->cb) <= 2) {
+        mb->maxstack = get1byte(context);
+        mb->nlocals = get1byte(context);
+        code_length = mb->code_length = get2bytes(context);
+    } else {
+        mb->maxstack = get2bytes(context);
+        mb->nlocals = get2bytes(context);
+        code_length = mb->code_length = get4bytes(context);
+    }
+    if (mb->nlocals < mb->args_size)
+        JAVA_ERROR(context, "Arguments can't fit into locals");
+
+    if (code_length > 65535) {
+        JAVA_ERROR(context, "Byte code size exceeds 65535 bytes");
+    }
+
+    mb->code = allocNBytes(context, code_length);
+
+    getNbytes(context, code_length, (char *)mb->code);
+    if ((mb->exception_table_length = get2bytes(context)) > 0) {
+        unsigned exception_table_size = mb->exception_table_length
+                                      * sizeof(struct CatchFrame);
+        mb->exception_table = allocNBytes(context, exception_table_size);
+        for (i = 0; i < (int)mb->exception_table_length; i++) {
+            mb->exception_table[i].start_pc = get2bytes(context);
+            mb->exception_table[i].end_pc = get2bytes(context);
+            mb->exception_table[i].handler_pc = get2bytes(context);
+            mb->exception_table[i].catchType = get2bytes(context);
+            mb->exception_table[i].compiled_CatchFrame = NULL;
+        }
+    }
+    attribute_count = get2bytes(context);
+    for (i = 0; i < attribute_count; i++) {
+        char *name = getAsciz(context, FALSE);
+        if (strcmp(name, "LineNumberTable") == 0) {
+            ReadLineTable(context, mb);
+        } else if (strcmp(name, "LocalVariableTable") == 0) {
+            ReadLocalVars(context, mb);
+        } else {
+            int length = get4bytes(context);
+            getNbytes(context, length, NULL);
+        }
+    }
+    if (context->ptr != end_ptr)
+        JAVA_ERROR(context, "Code segment was wrong length");
+}
+
+
+/*=========================================================================
+ * FUNCTION:      ReadLineTable
+ * OVERVIEW:      Reads the line number table given a pointer to the internal
+ *                class file and a pointer to the method block structure.
+ *
+ * INTERFACE:
+ *   parameters:  CICcontext *: ptr
+ *                struct methodblock *: mb
+ *
+ *   returns:     nothing
+ *=======================================================================*/
+static void ReadLineTable(CICcontext *context, struct methodblock *mb)
+{
+    int attribute_length = get4bytes(context);
+    unsigned char *end_ptr = context->ptr  + attribute_length;
+    int i;
+    if ((mb->line_number_table_length = get2bytes(context)) > 0) {
+        struct lineno *ln =
+               allocNBytes(context, mb->line_number_table_length *
+                           sizeof(struct lineno));
+        mb->line_number_table = ln;
+        for (i = mb->line_number_table_length; --i >= 0; ln++) {
+            ln->pc = get2bytes(context);
+            ln->line_number = get2bytes(context);
+        }
+    }
+    if (context->ptr != end_ptr)
+        JAVA_ERROR(context, "Line number table was wrong length?");
+}
+
+
+
+/*=========================================================================
+ * FUNCTION:      ReadLocalVars
+ * OVERVIEW:      Reads the localvar table given a pointer to the internal
+ *                class file and a pointer to the method block structure.
+ *
+ * INTERFACE:
+ *   parameters:  CICcontext *: ptr
+ *                struct methodblock *: mb
+ *
+ *   returns:     nothing
+ *=======================================================================*/
+static void ReadLocalVars(CICcontext *context, struct methodblock *mb)
+{
+    int attribute_length = get4bytes(context);
+    unsigned char *end_ptr = context->ptr  + attribute_length;
+    int i;
+    if ((mb->localvar_table_length = get2bytes(context)) > 0) {
+        struct localvar *lv =
+               allocNBytes(context, mb->localvar_table_length *
+                           sizeof(struct localvar));
+        mb->localvar_table = lv;
+        for (i = mb->localvar_table_length; --i >= 0; lv++) {
+            lv->pc0 = get2bytes(context);
+            lv->length = get2bytes(context);
+            lv->name = getAsciz(context, FALSE);
+            lv->signature = getAsciz(context, FALSE);
+            lv->slot = get2bytes(context);
+        }
+    }
+    if (context->ptr != end_ptr)
+        JAVA_ERROR(context, "Local variables table was wrong length?");
+}
+
+
+/*=========================================================================
+ * FUNCTION:      ReadExceptions
+ * OVERVIEW:      Reads the Exception attribute given a pointer to the internal
+ *                class file and a pointer to the method block structure.
+ *
+ * INTERFACE:
+ *   parameters:  CICcontext *: ptr
+ *                struct methodblock *: mb
+ *
+ *   returns:     nothing
+ *=======================================================================*/
+static void
+ReadExceptions(CICcontext *context, struct methodblock *mb)
+{
+    int attribute_length = get4bytes(context);
+    unsigned char *end_ptr = context->ptr + attribute_length;
+    unsigned short nexceptions = get2bytes(context);
+
+    if ((mb->nexceptions = nexceptions) > 0) {
+        unsigned short *ep, *exceptions =
+            allocNBytes(context, nexceptions * sizeof (unsigned short));
+        mb->exceptions = ep = exceptions;
+        while (nexceptions-- > 0) {
+            *ep++ = get2bytes(context);
+        }
+    }
+    if (context->ptr != end_ptr)
+        JAVA_ERROR(context, "Exceptions attribute has wrong length");
+}
+
+
+/*=========================================================================
+ * FUNCTION:      Signature2ArgsSize
+ * OVERVIEW:      Returns the size of arguments given a pointer to a method
+ *                signature.
+ *
+ * INTERFACE:
+ *   parameters:  char*: method_signature
+ *
+ *   returns:     unsigned
+ *=======================================================================*/
+unsigned Signature2ArgsSize(char *method_signature)
+{
+    char *p;
+    int args_size = 0;
+    for (p = method_signature; *p != SIGNATURE_ENDFUNC; p++) {
+        switch (*p) {
+            case SIGNATURE_FLOAT:
+                if (no_floating_point) {
+                    panic("floating-point arguments should not appear");
+                }
+
+            case SIGNATURE_BOOLEAN:
+            case SIGNATURE_BYTE:
+            case SIGNATURE_CHAR:
+            case SIGNATURE_SHORT:
+            case SIGNATURE_INT:
+                args_size += 1;
+                break;
+
+            case SIGNATURE_CLASS:
+                args_size += 1;
+                while (*p != SIGNATURE_ENDCLASS) p++;
+                break;
+
+            case SIGNATURE_ARRAY:
+                args_size += 1;
+                while ((*p == SIGNATURE_ARRAY)) p++;
+                    /* If an array of classes, skip over class name, too. */
+                    if (*p == SIGNATURE_CLASS) {
+                        while (*p != SIGNATURE_ENDCLASS)
+                            p++;
+                    }
+                break;
+
+            case SIGNATURE_DOUBLE:
+                if (no_floating_point) {
+                    panic("floating-point arguments should not appear");
+                }
+
+            case SIGNATURE_LONG:
+                args_size += 2;
+                break;
+
+            case SIGNATURE_FUNC:  /* ignore initial (, if given */
+                break;
+
+            default:              /* Indicates an error. */
+                return 0;
+        }
+    }
+    return args_size;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      free_clinit_memory
+ * OVERVIEW:      Frees clinit memory.
+ *
+ * INTERFACE:
+ *   parameters:  struct methodblock *: mb
+ *
+ *   returns:     nothing
+ *=======================================================================*/
+void free_clinit_memory(struct methodblock *mb)
+{
+    /* This function is somewhat a hack. It fixes the problem in 1.1.3
+     * and before. sysFree may be called on the wrong memory block if
+     * the exception attribute comes before the code attribute.
+     */
+    /* If there is no exceptions attribute, or if both have already
+     * been freed.
+     */
+    if (mb->exceptions == NULL) {
+        if (mb->code) {
+            sysFree(mb->code);
+            mb->code = NULL;
+        }
+        return;
+    }
+
+    /* If both attributes exist, free the one at the lower address */
+    if ((char *)mb->code < (char *)mb->exceptions)
+        sysFree(mb->code);
+    else
+        sysFree(mb->exceptions);
+
+    mb->code = NULL;
+    mb->exceptions = NULL;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      FreeClass
+ * OVERVIEW:      Frees class.
+ *
+ * INTERFACE:
+ *   parameters:  ClassClass *: cb
+ *
+ *   returns:     nothing
+ *=======================================================================*/
+void FreeClass(ClassClass *cb)
+{
+    int i;
+    struct methodblock *mb;
+
+    for (i = cbMethodsCount(cb), mb = cbMethods(cb); --i >= 0; mb++) {
+        if (strcmp(mb->fb.name, "<clinit>") == 0 &&
+            strcmp(mb->fb.signature, "()V") == 0 &&
+            mb->code_length /* not external */ )
+            free_clinit_memory(mb);
+    }
+
+    sysFree(cbConstantPool(cb));
+
+    sysFree(cbMethodTableMem(cb));
+    sysFree(cbSlotTable(cb));
+
+    /* Interface method tables can be shared between child and
+     * super classes.
+     */
+    if (cbImplementsCount(cb) != 0 || cbIsInterface(cb))
+        sysFree(cbIntfMethodTable(cb));
+}
+
+
+/*=========================================================================
+ * FUNCTION:      get1byte
+ * OVERVIEW:      Gets one byte from the class file.
+ *
+ * INTERFACE:
+ *   parameters:  CICcontext *: context
+ *
+ *   returns:     value read or 0 if an error occurred.
+ *=======================================================================*/
+static unsigned char get1byte(CICcontext *context)
+{
+    unsigned char *ptr = context->ptr;
+    if (context->end_ptr - ptr < 1) {
+        JAVA_ERROR(context, "Truncated class file");
+        return 0;
+    } else {
+        unsigned char *ptr = context->ptr;
+        unsigned char value = ptr[0];
+        (context->ptr) += 1;
+        return value;
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      get2bytes
+ * OVERVIEW:      Gets two bytes from the class file.
+ *
+ * INTERFACE:
+ *   parameters:  CICcontext *: context
+ *
+ *   returns:     value read or 0 if an error occurred.
+ *=======================================================================*/
+static unsigned short get2bytes(CICcontext *context)
+{
+    unsigned char *ptr = context->ptr;
+    if (context->end_ptr - ptr < 2) {
+        JAVA_ERROR(context, "Truncated class file");
+        return 0;
+    } else {
+        unsigned short value = (ptr[0] << 8) + ptr[1];
+        (context->ptr) += 2;
+        return value;
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      get4bytes
+ * OVERVIEW:      Gets four bytes from the class file.
+ *
+ * INTERFACE:
+ *   parameters:  CICcontext *: context
+ *
+ *   returns:     value read or 0 if an error occurred.
+ *=======================================================================*/
+static unsigned long get4bytes(CICcontext *context)
+{
+    unsigned char *ptr = context->ptr;
+    if (context->end_ptr - ptr < 4) {
+        JAVA_ERROR(context, "Truncated class file");
+        return 0;
+    } else {
+        unsigned long value = (ptr[0] << 24) + (ptr[1] << 16) +
+                                 (ptr[2] << 8) + ptr[3];
+        (context->ptr) += 4;
+        return value;
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      getNbytes
+ * OVERVIEW:      Gets N bytes from the class file specified by the count
+ *                parameter. If buffer is not null, it will also copy the
+ *                count number of bytes read into the buffer as well.
+ *                Note that this function seems to be always invoked with
+ *                a NULL argument for the buffer, except when it loads the
+ *                UTF8 entry from the constant pool and when the code
+ *                attribute is loaded.
+ *
+ * INTERFACE:
+ *   parameters:  CICcontext *: context
+ *                int: count
+ *                char *: buffer
+ *
+ *   returns:     nothing
+ *=======================================================================*/
+static void getNbytes(CICcontext *context, int count, char *buffer)
+{
+    unsigned char *ptr = context->ptr;
+    if (context->end_ptr - ptr < count)
+        JAVA_ERROR(context, "Truncated class file");
+    if (buffer != NULL)
+        memcpy(buffer, ptr, count);
+    (context->ptr) += count;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      getAsciz
+ * OVERVIEW:      Reads the next two bytes and uses this value to look up for
+ *                the corresponding constant pool entry.
+ *                Returns null if the value is 0 and zeroOkay flag is set.
+ *
+ * INTERFACE:
+ *   parameters:  CICcontext *: context
+ *                bool_t : zeroOkay
+ *
+ *   returns:     char * or NULL
+ *=======================================================================*/
+static char *getAsciz(CICcontext *context, bool_t zeroOkay)
+{
+    ClassClass *cb = context->cb;
+    union cp_item_type *constant_pool = cbConstantPool(cb);
+    int nconstants = cbConstantPoolCount(cb);
+    unsigned char *type_table =
+        constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
+
+    int value = get2bytes(context);
+    if (value == 0 && zeroOkay) {
+        return NULL;
+    } else if ((value == 0) || (value >= nconstants) ||
+        type_table[value] != (CONSTANT_Utf8 | CONSTANT_POOL_ENTRY_RESOLVED))
+        JAVA_ERROR(context, "Illegal constant pool index");
+    return constant_pool[value].cp;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      getAscizFromClass
+ * OVERVIEW:      Given the constant pool index, returns the name of the class
+ *                which corresponds to this constant pool entry.
+ *
+ * INTERFACE:
+ *   parameters:  CICcontext *: context
+ *                int: value
+ *
+ *   returns:     char * or NULL
+ *=======================================================================*/
+static char *getAscizFromClass(CICcontext *context, int value)
+{
+    ClassClass *cb = context->cb;
+    union cp_item_type *constant_pool = cbConstantPool(cb);
+    int nconstants = cbConstantPoolCount(cb);
+    unsigned char *type_table =
+    constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
+    if ((value > 0) && (value < nconstants)) {
+        if (type_table[value] == CONSTANT_Class) {
+            value = constant_pool[value].i;
+            if ((value <= 0) || (value >= nconstants) ||
+                (type_table[value] != (CONSTANT_Utf8 |
+                       CONSTANT_POOL_ENTRY_RESOLVED)))
+                JAVA_ERROR(context, "Illegal constant pool index");
+            return constant_pool[value].cp;
+        } else if (type_table[value] == (CONSTANT_Class |
+                                 CONSTANT_POOL_ENTRY_RESOLVED)) {
+            ClassClass *cb = constant_pool[value].clazz;
+            return cbName(cb);
+        } else {
+            JAVA_ERROR(context, "Illegal constant pool index");
+        }
+    } else {
+        JAVA_ERROR(context, "Illegal constant pool index");
+    }
+    return NULL; /* not reached */
+}
+
+/* In order to avoid possible alignment errors, round up all sizes to
+ * multiples of eight.
+ */
+#define ROUNDUP_SIZE(s) while ((s) % 8 != 0) (s)++
+
+
+/*=========================================================================
+ * FUNCTION:      allocNBytes
+ * OVERVIEW:      Memory allocation function for internal class file
+ *                structures.
+ *                It calculates the number of allocations needed for the
+ *                two passes, and the allocations required for the clinit
+ *                method.
+ *
+ * INTERFACE:
+ *   parameters:  CICcontext *: context
+ *                int : size
+ *
+ *   returns:     void *
+ *=======================================================================*/
+static void *allocNBytes(CICcontext *context, int size)
+{
+    void *result;
+    if (context->pass == 1) {
+        /* The first pass
+         * A more sophisticated scheme could reduce the number of mallocs.
+         */
+        CICmallocs *mallocs =
+           (CICmallocs *)sysCalloc(1, sizeof(CICmallocs) + size);
+        if (mallocs == 0)
+            JAVA_ERROR(context, "out of memory");
+        result = (void *)(mallocs + 1);
+        mallocs->next = context->pass1.mallocs;
+        ROUNDUP_SIZE(size);
+        if (context->in_clinit)
+            context->clinit_size += size;
+        else
+            context->malloc_size += size;
+        context->pass1.mallocs = mallocs;
+    } else {
+        /* The second pass */
+
+        ROUNDUP_SIZE(size);
+
+#define ALLOC_BLOCK(ptr,buf,sizelimit)     \
+        result = (ptr);                    \
+        (ptr) += (size);                   \
+        sysAssert((ptr) <= (buf) + (sizelimit))
+
+        if (context->in_clinit) {
+            /* Make sure that this clinit pointer is not null */
+            sysAssert(context->pass2.clinit_ptr != NULL);
+
+            ALLOC_BLOCK(context->pass2.clinit_ptr,
+            context->pass2.clinit_buffer,
+            context->clinit_size*sizeof(char));
+
+        } else {
+
+            /* Make sure that this malloc pointer is not null */
+            sysAssert(context->pass2.malloc_ptr != NULL);
+
+            ALLOC_BLOCK(context->pass2.malloc_ptr,
+            context->pass2.malloc_buffer,
+            context->malloc_size);
+        }
+    }
+    return result;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      freeBuffers
+ * OVERVIEW:      Frees buffers allocated by allocNBytes().
+ *
+ * INTERFACE:
+ *   parameters:  CICcontext *: context
+ *
+ *   returns:     nothing
+ *=======================================================================*/
+static void freeBuffers(CICcontext * context)
+{
+    if (context->pass == 1) {
+        CICmallocs *mallocs = context->pass1.mallocs;
+
+        while (mallocs) {
+            CICmallocs *tmp = mallocs;
+            mallocs = mallocs->next;
+            if (tmp != NULL) {
+                sysFree(tmp);
+            }
+        }
+        context->pass1.mallocs = 0;
+    } else { /* context->pass = 2 */
+
+/* Note: this code is here just for historical reasons. Actually, these
+ * buffers cannot really be freed here since the data in them is still
+ * pointed to by the class buffer (cb) and we are not yet done loading
+ * the class. If the class loading fails, FreeClass() will free the method
+ * blocks and the clinit memory.
+ */
+        if (context->pass2.malloc_buffer != NULL) {
+            sysFree(context->pass2.malloc_buffer);
+            /* Reset only if buffer was freed */
+            context->pass2.malloc_buffer = 0;
+        }
+
+        if (context->pass2.clinit_buffer != NULL) {
+            sysFree(context->pass2.clinit_buffer);
+            /* Initialize only if buffer was freed */
+            context->pass2.clinit_buffer = 0;
+        }
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      GetClassConstantClassName
+ * OVERVIEW:      Returns class name corresponding to the constant pool entry
+ *                for the given cpIndex. This is desirable in cases when we
+ *                may simply be interested in the name of the class, but may
+ *                not necessarily want to resolve the class reference if it
+ *                isn't already.
+ *
+ * INTERFACE:
+ *   parameters:  cp_item_type *: constant pool
+ *                int : index
+ *
+ *   returns:     char *: class name
+ *=======================================================================*/
+char *GetClassConstantClassName(cp_item_type *constant_pool, int index)
+{
+    unsigned char *type_table =
+        constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
+    switch(type_table[index]) {
+        case CONSTANT_Class | CONSTANT_POOL_ENTRY_RESOLVED: {
+            ClassClass *cb = constant_pool[index].clazz;
+            return cbName(cb);
+        }
+
+        case CONSTANT_Class: {
+            int name_index = constant_pool[index].i;
+            return constant_pool[name_index].cp;
+        }
+
+        default:
+            return (char *)0;
+    }
+}
+
diff --git a/MPC.3.5.LINUX/preverifier/classresolver.c b/MPC.3.5.LINUX/preverifier/classresolver.c
new file mode 100644 (file)
index 0000000..64df7df
--- /dev/null
@@ -0,0 +1,1269 @@
+/*
+ * @(#)classresolver.c 1.19 02/09/27
+ *
+ * Copyright 1995-1998 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ * 
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+/*=========================================================================
+ * SYSTEM:    Verifier
+ * SUBSYSTEM: class resolver.c.
+ * FILE:      classresolver.c
+ * OVERVIEW:  Routines for loading and resolving class definitions.
+ *            These routines should not be depending upon the interpreter
+ *            or the garbage collector.
+ * AUTHOR:    Sheng Liang, Sun Microsystems, Inc.
+ *            Modifications for CLDC compliance checks,
+ *            Tasneem Sayeed, Sun Microsystems
+ *            Frank Yellin, Sun Microsystems
+ *=======================================================================*/
+
+/*=========================================================================
+ * Include files
+ *=======================================================================*/
+
+#include <ctype.h>
+#include <string.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+
+#include "oobj.h"
+#include "tree.h"
+#include "signature.h"
+#include "path.h"
+#include "sys_api.h"
+#include "convert_md.h"
+
+/*=========================================================================
+ * Globals and extern declarations
+ *=======================================================================*/
+
+ClassClass *classJavaLangObject;
+ClassClass *classJavaLangClass = 0;
+ClassClass *classJavaLangString;
+ClassClass *classJavaLangThrowable;
+ClassClass *classJavaLangError;
+ClassClass *classJavaLangException;
+ClassClass *classJavaLangRuntimeException;
+ClassClass *classJavaLangThreadDeath;
+
+ClassClass *interfaceJavaLangCloneable;
+ClassClass *interfaceJavaIoSerializable;
+
+bool_t inline_jsr_on = TRUE;
+
+static bool_t RunClinit(ClassClass * cb);
+
+static ClassClass *InitializeAndResolveClass(ClassClass *cb, bool_t resolve);
+static char *Locked_InitializeClass(ClassClass * cb, char **detail);
+static char *Locked_LinkClass(ClassClass * cb, char **detail);
+char * LinkClass(ClassClass *cb, char **detail);
+static ClassClass *FindLoadedClass(char *name,
+                                  struct Hjava_lang_ClassLoader *loader);
+static ClassClass *Locked_FindArrayClassFromClass(struct execenv *ee, 
+                                                 char *name, 
+                                                 ClassClass *from);
+static void InitPrimitiveClasses();
+
+/* An Explanation of Class-related Locks
+ *
+ * There are two global locks related to class loading:
+ *
+ * LOADCLASS_LOCK: ensures that only one thread is loading a class at
+ * a given time. This eliminates the possibility of two threads loading
+ * classes with the same name and same loader.
+ *
+ * BINCLASS_LOCK: ensures that only one thread is updating the global
+ * class table (binclasses). This lock is also grabbed by the GC to ensure
+ * that the GC always sees a valid global class table state.
+ *
+ * In addition, each class may have its own associated locks that are
+ * created with monitorEnter(). ResolveClass, for example, need to
+ * first grab this lock to ensure that the class is resolved only by
+ * one thread, rather than simultaneously by multiple threads.
+ */
+
+sys_mon_t *_loadclass_lock;
+sys_mon_t *_binclass_lock;
+
+static struct fieldblock **
+addslots(struct fieldblock ** fb, ClassClass * cb)
+{
+    long n = cbFieldsCount(cb);
+    struct fieldblock *sfb = cbFields(cb);
+    if (cbSuperclass(cb))
+       fb = addslots(fb, cbSuperclass(cb));
+    while (--n >= 0) {
+       *fb++ = sfb;
+       sfb++;
+    }
+    return fb;
+}
+
+int
+Locked_makeslottable(ClassClass * clb)
+{
+    ClassClass *sclb;
+    int         nslots = 0;
+
+    if (cbSlotTable(clb)) {
+       return SYS_OK;
+    }
+    sclb = clb;
+    while (sclb) {
+       long        n = cbFieldsCount(sclb);
+       struct fieldblock *fb = cbFields(sclb);
+       while (--n >= 0) {
+           nslots++;
+           fb++;
+       }
+       if (cbSuperclass(sclb) == 0) {
+           break;
+       }
+       sclb = cbSuperclass(sclb);
+    }
+    cbSlotTableSize(clb) = nslots;
+    if (nslots == 0) {
+       nslots++;
+    }
+    cbSlotTable(clb) = (struct fieldblock **)
+       sysMalloc(nslots * sizeof(struct fieldblock *));
+    if (cbSlotTable(clb) == 0) {
+       return SYS_NOMEM;
+    }
+    addslots(cbSlotTable(clb), clb);
+    return SYS_OK;
+}
+
+int
+makeslottable(ClassClass * clb)
+{
+    int result;
+    LOADCLASS_LOCK();
+    result = Locked_makeslottable(clb);
+    LOADCLASS_UNLOCK();
+    return result;
+}
+
+#if 0
+static char *
+copyclassname(char *src, char *dst)
+{
+    sysAssert(*src == SIGNATURE_CLASS);
+    src++;
+    while (*src && *src != SIGNATURE_ENDCLASS)
+       *dst++ = *src++;
+    *dst = 0;
+    return src;
+}
+#endif
+
+static char *
+ResolveFields(ClassClass *cb, unsigned slot)
+{
+    struct fieldblock *fb;
+    int size;
+
+    fb = cbFields(cb);
+    for (size = 0; size < (int) cbFieldsCount(cb); size++, fb++) {
+       char *signature = fieldsig(fb);
+       int size = (((signature[0] == SIGNATURE_LONG || 
+                     signature[0] == SIGNATURE_DOUBLE)) ? 2 : 1);
+       fb->ID = NameAndTypeToHash(fb->name, signature);
+       if (fb->access & ACC_STATIC) {
+           /* Do nothing.  Handled when the class is loaded. */
+       } else {
+           fb->u.offset = slot;
+           slot += size * sizeof(OBJECT);
+       }
+#ifdef UNUSED
+       if ((fb->access & (ACC_STATIC | ACC_TRANSIENT)) == 0) {
+           for (s = fieldname(fb); (c = *s++) != 0;)
+               thishash = thishash * 7 + c;
+           for (s = fieldsig(fb); (c = *s++) != 0;)
+               thishash = thishash * 7 + c;
+       }
+#endif
+    }
+    if (slot > 65535) {
+        return "java/lang/InternalError";
+    }
+
+    cbInstanceSize(cb) = slot;
+#ifdef UNUSED
+    cbThisHash(cb) = thishash;
+    if (cbSuperclass(cb))
+       cbTotalHash(cb) = thishash - cbTotalHash(unhand(cbSuperclass(cb)));
+    else
+        cbTotalHash(cb) = thishash;
+    if (cbTotalHash(cb) < N_TYPECODES)
+       cbTotalHash(cb) += N_TYPECODES;
+#endif
+    return NULL;
+}
+
+
+static char *
+ResolveMethods(ClassClass *cb)
+{
+    struct methodblock *mb;
+    int size;
+    struct methodtable *new_table;
+    struct methodblock **super_methods;
+    int mslot, super_methods_count;
+    void *ptr;
+    static unsigned finalizerID = 0;
+    
+    if (finalizerID == 0)
+       finalizerID = NameAndTypeToHash(FINALIZER_METHOD_NAME,
+                                       FINALIZER_METHOD_SIGNATURE);
+    mb = cbMethods(cb);
+    for (size = 0; size < (int) cbMethodsCount(cb); size++, mb++) {
+       mb->fb.ID = NameAndTypeToHash(mb->fb.name, mb->fb.signature);
+       mb->fb.u.offset = 0;
+       mb->invoker = 0;
+    }
+
+    if (cbIsInterface(cb)) { 
+       /* We don't really need to built a method table for interfaces. */
+       cbMethodTable(cb) = NULL;
+       cbMethodTableSize(cb) = 0;
+       mb = cbMethods(cb);
+       /* Each method's offset is its index in the interface */
+       for (size = 0; size < (int) cbMethodsCount(cb); size++, mb++) {
+           mb->fb.u.offset = size;
+       }
+       return NULL;
+    }
+
+    if (cbSuperclass(cb) != NULL) { 
+       ClassClass *super = cbSuperclass(cb);
+       mslot = cbMethodTableSize(super);
+       super_methods = cbMethodTable(super)->methods;
+        super_methods_count = cbMethodTableSize(super);
+       /* Inherit one's parent's finalizer, if it has one */
+       cbFinalizer(cb) = cbFinalizer(cbSuperclass(cb));
+    } else { 
+       mslot = 1;
+       super_methods = NULL;
+       super_methods_count = 0;
+       cbFinalizer(cb) = NULL;
+    }
+
+    mb = cbMethods(cb);
+    for (size = 0; size < (int) cbMethodsCount(cb); size++, mb++) {
+       unsigned long ID = mb->fb.ID;
+       struct methodblock **super_methods_p;
+       int count;
+
+       if ((mb->fb.access & ACC_STATIC) || (mb->fb.access & ACC_PRIVATE))
+           continue;
+       if (strcmp(mb->fb.name, "<init>") == 0)
+           continue;
+
+       /* If this item has its own finalizer method, grab it */
+       if (mb->fb.ID == finalizerID) {
+           if (no_finalizers) {
+               panic("finalize methods should not appear");
+           }
+           cbFinalizer(cb) = mb;
+       }
+
+       for (super_methods_p = super_methods, count = super_methods_count;
+              count > 0;
+              super_methods_p++, count--) {
+           if ((*super_methods_p != NULL) && ((*super_methods_p)->fb.ID == ID)) { 
+             /* Private methods are not inherited outside of the class. */
+               if ((*super_methods_p)->fb.access & ACC_PRIVATE)
+                 continue;
+             /* Package-private methods are not inherited outside of the
+                package. */
+               if (((*super_methods_p)->fb.access & ACC_PROTECTED) ||
+                   ((*super_methods_p)->fb.access & ACC_PUBLIC) ||
+                   IsSameClassPackage((*super_methods_p)->fb.clazz, cb)) {
+                   mb->fb.u.offset = (*super_methods_p)->fb.u.offset;
+                   break;
+               } 
+             /*
+               jio_fprintf(stderr, "!!!%s.%s\n", cbName(cb), mb->fb.name);
+               */
+           }
+       }
+
+       if (mb->fb.u.offset == 0) { 
+           mb->fb.u.offset = mslot;
+           mslot++;
+       }
+    }
+
+    if (mslot > 65535) {
+        return "java/lang/InternalError";
+    }
+
+    /*
+     * This should be the only place that method tables are
+     * allocated.  We allocate more than we need here and mask the
+     * resulting pointer because the methodtable pointer field in
+     * object handles is overloaded and sometimes hold array types
+     * and array lengths.  We must ensure that method table pointers
+     * are allocated on an appropriate boundary so we don't lose any
+     * address bits when we mask off the type portion of the pointer.
+     */
+    ptr = sysMalloc(sizeof(struct methodtable)
+                      + (mslot - 1)* sizeof(struct methodblock *)
+                      + FLAG_MASK);
+    if (ptr == NULL) {
+       CCSet(cb, Error);
+       return JAVAPKG "OutOfMemoryError";
+    }
+    cbMethodTableMem(cb) = ptr;
+    new_table = (struct methodtable *)((((long)ptr) + FLAG_MASK) & LENGTH_MASK);
+    new_table->classdescriptor = cb;
+    memset((char *)new_table->methods, 0, mslot * sizeof(struct methodblock *));
+    if (super_methods) 
+       memcpy((char *) new_table->methods,
+              (char *) super_methods,
+              super_methods_count * sizeof(struct methodblock *));
+    mb = cbMethods(cb);
+    for (size = 0; size < (int) cbMethodsCount(cb); size++, mb++) {
+       int offset = (int)mb->fb.u.offset;
+       if (offset > 0) { 
+           sysAssert(offset < mslot);
+           mt_slot(new_table, offset) = mb;
+       }
+    }
+    cbMethodTable(cb) = new_table;
+    cbMethodTableSize(cb) = mslot;
+
+    return NULL;
+}
+
+
+static char *
+ResolveInterfaces(ClassClass *cb, char **detail)
+{
+    const int ITEM_SIZE =  sizeof(cbIntfMethodTable(cb)->itable[0]);
+    bool_t isInterface = cbIsInterface(cb);
+    if (cbImplementsCount(cb) == 0 && !isInterface) {
+       /* classes that don't implement their own interfaces can just inherit
+        * their parents imethodtable. */
+       if (cb == classJavaLangObject) {
+           /* We can preinitialize the imethodtable of java.lang.Object */
+           static struct imethodtable t = { 0 };
+           cbIntfMethodTable(cb) = &t;
+       } else { 
+           ClassClass *super = cbSuperclass(cb);
+           cbIntfMethodTable(cb) = cbIntfMethodTable(super);
+       } 
+       return NULL;
+    } else { 
+       cp_item_type *constant_pool = cbConstantPool(cb);
+       ClassClass *super = cbSuperclass(cb);
+       unsigned char *mallocSpace, *mallocSpaceEnd;
+       ClassClass *icb;        /* temporary */
+       struct imethodtable *super_itable = cbIntfMethodTable(super);
+       struct imethodtable *this_itable = NULL;
+       int super_itable_count = super_itable->icount;
+       int i, j, k, icount, mcount;
+       
+       /* Resolve all the interfaces that this class implements, and 
+        * make sure that they all really are interfaces 
+        *
+        * icount will total all the interfaces that this class implements,
+        *    (include interfaces implemented by our superclass, and by 
+        *    interfaces that we implement.)
+        * mcount will total the total amount of space (in sizeof(long)) for 
+        *    which we'll have to allocate space for in the offsets table.
+        */
+       icount = super_itable_count + (isInterface ? 1 : 0);
+       mcount = 0;
+       for (i = 0; i < (int)(cbImplementsCount(cb)); i++) {
+           int interface_index = cbImplements(cb)[i];
+           struct imethodtable *sub_itable;
+
+           icb = constant_pool[interface_index].clazz;
+           if (!cbIsInterface(icb)) {
+               *detail = "Implementing class";
+               return JAVAPKG "IncompatibleClassChangeError";
+           }
+           sub_itable = cbIntfMethodTable(icb);
+           icount += sub_itable->icount;
+           if (!isInterface) 
+               for (j = sub_itable->icount; --j >= 0; ) 
+                   mcount += cbMethodsCount(sub_itable->itable[j].classdescriptor);
+       }
+
+       { 
+           int this_itable_size = 
+               offsetof(struct imethodtable, itable) + icount * ITEM_SIZE;
+           int offsets_size = mcount * sizeof(unsigned long);
+           mallocSpace = sysMalloc(this_itable_size + offsets_size);
+           if (mallocSpace == NULL) { 
+               return JAVAPKG "OutOfMemoryError";
+           }
+           mallocSpaceEnd = mallocSpace + this_itable_size + offsets_size;
+           this_itable = (struct imethodtable *)mallocSpace;
+           mallocSpace += this_itable_size;
+           sysAssert(mallocSpace <= mallocSpaceEnd);
+       }
+       
+       cbIntfMethodTable(cb) = this_itable;
+
+       /* Start filling in the table. */
+       icount = 0;
+       if (isInterface) {
+           this_itable->itable[icount].classdescriptor = cb;
+           this_itable->itable[icount].offsets = NULL; 
+           icount++;
+       }
+       if (super_itable_count > 0) { 
+           /* We can copy our superclass's offset table.  The offsets
+              will stay the same.  */
+           memcpy(&this_itable->itable[icount], 
+                  &super_itable->itable[0], 
+                  super_itable_count * ITEM_SIZE);
+           icount += super_itable_count;
+       }
+       for (i = 0; i < (int)(cbImplementsCount(cb)); i++) {
+           /* Add the interfaces that we implement, either directly, or
+            * because those interfaces implement other interfaces.    */
+           int interface_index = cbImplements(cb)[i]; 
+           icb = constant_pool[interface_index].clazz;
+           memcpy(&this_itable->itable[icount], 
+                  &cbIntfMethodTable(icb)->itable[0],
+                  cbIntfMethodTable(icb)->icount * ITEM_SIZE);
+           icount += cbIntfMethodTable(icb)->icount;
+       }
+       sysAssert(!isInterface || super_itable_count == 0);
+       /* Delete duplicates from the table.  This is very rare, so it can
+        * be quite inefficient.  */
+       for (i = (isInterface ? 1 : super_itable_count); i < icount; i++) {
+           icb = this_itable->itable[i].classdescriptor;
+           for (j = 0; j < i; j++) { 
+               if (icb == this_itable->itable[j].classdescriptor) { 
+                   /* We have an overlap.  Item i is a duplicate.  Delete from
+                    * the table */
+                   for (k = i + 1; k < icount; k++) 
+                       this_itable->itable[k - 1] = this_itable->itable[k];
+                   icount--;
+                   i--;        /* Reconsider this entry! */
+                   break;
+               }
+           }
+       }
+       this_itable->icount = icount;
+       if (isInterface || cbIsAbstract(cb)) { 
+           /* Nothing more to do for interfaces or abstract classes */
+           return NULL;
+       }
+
+       /* For each additional interface . . . */
+       for (i = super_itable_count; i < icount; i++) { 
+           /* The table length is the number of interface methods */
+           ClassClass *intfi = this_itable->itable[i].classdescriptor;
+           int intfi_count = cbMethodsCount(intfi);
+           unsigned long *offsets = (unsigned long *)mallocSpace;
+           mallocSpace += intfi_count * sizeof(unsigned long);
+           sysAssert(mallocSpace <= mallocSpaceEnd);
+           this_itable->itable[i].offsets = offsets;
+           /* Look at each interface method */
+           for (j = 0; j < intfi_count; j++) { 
+               struct methodblock *imb = cbMethods(intfi) + j;
+               if ((imb->fb.access & ACC_STATIC) != 0) { 
+                   sysAssert(!strcmp(imb->fb.name, "<clinit>"));
+                   offsets[j] = 0; 
+               } else {
+                   /* Find the class method that implements the interface 
+                    * method */
+                   unsigned ID = imb->fb.ID;
+                   struct methodblock **mbt = cbMethodTable(cb)->methods;
+                   for (k = cbMethodTableSize(cb) - 1; k >= 0; --k) { 
+                       struct methodblock *mb = mbt[k];
+                       if (mb != NULL 
+                             && mb->fb.ID == ID && IsPublic(mb->fb.access)) {
+                           offsets[j] = mb->fb.u.offset;
+                           break;
+                       }
+                   }
+                    /*
+                   if (k == -1) { 
+                       *detail = "Unimplemented interface method";
+                       return JAVAPKG "IncompatibleClassChangeError";
+                   }
+                    */
+               }
+           }
+       }
+       return NULL;
+    }
+}
+
+
+char *
+InitializeClass(ClassClass * cb, char **detail) 
+{ 
+    char *result;
+    monitorEnter(obj_monitor(cb));
+    result = Locked_InitializeClass(cb, detail);
+    monitorExit(obj_monitor(cb));
+    return result;
+}
+
+
+char *
+ResolveClass(ClassClass *cb, char **detail) 
+{
+    char *result;
+    if (CCIs(cb, Resolved))
+        return 0;
+    result = LinkClass(cb, detail);
+    if (result == 0) {
+        if (!RunClinit(cb)) {
+           result = JAVAPKG "ExceptionInInitializerError";
+           *detail = cbName(cb);
+       }
+    }
+    return result;
+}
+
+char *
+LinkClass(ClassClass *cb, char **detail)
+{
+    char *result;
+    if (CCIs(cb, Linked))
+        return 0;
+    monitorEnter(obj_monitor(cb));
+    result = Locked_LinkClass(cb, detail);
+    monitorExit(obj_monitor(cb));
+    return result;
+}
+
+/*
+ * Detect class circularities from InitializeClass()
+ */
+
+static void
+pushSeen(ExecEnv *ee, struct seenclass *seen)
+{
+    struct seenclass *prev = ee->seenclasses.next;
+    ee->seenclasses.next = seen;
+    seen->next = prev;
+}
+
+static void
+popSeen(ExecEnv *ee, struct seenclass *seen)
+{
+    if (seen != ee->seenclasses.next) /* paranoia */
+       panic("popSeen: corrupt seen class stack");
+    ee->seenclasses.next = ee->seenclasses.next->next;
+}
+
+static bool_t
+checkSeen(ExecEnv *ee, ClassClass *cb)
+{
+    struct seenclass *seen = ee->seenclasses.next;
+    while (seen) {
+       if (cb == seen->cb)
+           return TRUE;
+       seen = seen->next;
+    }
+    return FALSE;
+}
+
+static char *
+Locked_InitializeClass(ClassClass * cb, char **detail)
+{
+    ClassClass *super = 0;
+    char *ret = 0;
+    bool_t noLoader;
+    int i;
+    char buff[BUFSIZ];
+    char *nativeName = &buff[0];
+
+    if (CCIs(cb, Initialized))
+       return NULL;
+
+#ifndef TRIMMED
+    if (verbose)
+       jio_fprintf(stderr, "[Initializing %s]\n", cbName(cb));
+#endif
+
+    noLoader = (cbLoader(cb) == 0);
+    if (cbFieldsCount(cb) > 2000) {
+       return JAVAPKG "ClassFormatError";
+    }
+    if ((strcmp(cbName(cb), CLS_RESLV_INIT_CLASS) == 0) && noLoader) {
+       /* Temporarily disable class circularity checks */
+       ExecEnv *ee = EE();
+       struct seenclass *save = ee->seenclasses.next;
+       ee->seenclasses.next = NULL;
+       /* Note: don't bother restoring on (fatal) error during bootstrap */
+
+       classJavaLangClass = cb;
+       MakeClassSticky(cb);
+       classJavaLangString =
+               FindStickySystemClass(NULL, JAVAPKG "String", TRUE);
+       if (classJavaLangString == 0) {
+           *detail = JAVAPKG "String";
+           return JAVAPKG "NoClassDefFoundError";
+       }
+/*     classJavaLangThreadDeath =
+               FindStickySystemClass(NULL, JAVAPKG "ThreadDeath", TRUE);
+       if (classJavaLangThreadDeath == 0) {
+           *detail = JAVAPKG "ThreadDeath";
+           return JAVAPKG "NoClassDefFoundError";
+       }
+       */
+       classJavaLangThrowable =
+               FindStickySystemClass(NULL, JAVAPKG "Throwable", TRUE);
+       if (classJavaLangThrowable == 0) {
+           *detail = JAVAPKG "Throwable";
+           return JAVAPKG "NoClassDefFoundError";
+       }
+       /*
+       classJavaLangException =
+               FindStickySystemClass(NULL, JAVAPKG "Exception", TRUE);
+       if (classJavaLangException == 0) {
+           *detail = JAVAPKG "Exception";
+           return JAVAPKG "NoClassDefFoundError";
+       }
+       classJavaLangError = 
+                FindStickySystemClass(NULL, JAVAPKG "Error", TRUE);
+       if (classJavaLangError == 0) {
+           *detail = JAVAPKG "Error";
+           return JAVAPKG "NoClassDefFoundError";
+       }
+       classJavaLangRuntimeException = 
+               FindStickySystemClass(NULL, JAVAPKG "RuntimeException", TRUE);
+       if (classJavaLangRuntimeException == 0) {
+           *detail = JAVAPKG "RuntimeException";
+           return JAVAPKG "NoClassDefFoundError";
+       }
+       interfaceJavaLangCloneable =
+               FindStickySystemClass(NULL, JAVAPKG "Cloneable", TRUE);
+       if (interfaceJavaLangCloneable == 0) {
+           *detail = JAVAPKG "Cloneable";
+           return JAVAPKG "NoClassDefFoundError";
+       }
+       interfaceJavaIoSerializable =
+               FindStickySystemClass(NULL, "java/io/Serializable", TRUE);
+       if (interfaceJavaIoSerializable == 0) {
+           *detail = "java/io/Serializable";
+           return JAVAPKG "NoClassDefFoundError";
+       }
+*/
+       /* Restore stack for class circularity checks */
+       ee->seenclasses.next = save;
+
+    } else if ((strcmp(cbName(cb), CLS_RESLV_INIT_OBJECT) == 0) && noLoader){
+       classJavaLangObject = cb;
+       MakeClassSticky(classJavaLangObject);
+    }
+
+    if (noLoader) { 
+       char *name = cbName(cb);
+       if (strcmp(name, CLS_RESLV_INIT_REF) == 0) {
+           CCSet(cb, SoftRef);
+       }
+       if (strncmp(name, "java/", 5) || strncmp(name, "sun/", 4)) {
+           CCSet(cb, SysLock);
+       }
+    }
+    if (cbSuperclass(cb) == NULL) {
+       if (cbSuperName(cb)) {
+           /* Check for class definition circularities */
+           ExecEnv *ee = EE();
+           struct seenclass this[1];
+           if (checkSeen(ee, cb)) {
+               *detail = cbName(cb);
+               CCSet(cb, Error);
+               return JAVAPKG "ClassCircularityError";
+           }
+           this->cb = cb;
+           this->next = NULL;
+           pushSeen(ee, this);
+           
+            /* Conversion for Japanese file names */
+            utf2native(cbSuperName(cb), nativeName, BUFSIZ);
+
+           super = FindClassFromClass(ee, nativeName, FALSE, cb);
+
+           popSeen(ee, this);
+           if (super != NULL) { 
+               sysAssert(CCIs(super, Initialized));
+               /* Don't allow a class to have a superclass it can't access */
+               if (!VerifyClassAccess(cb, super, FALSE)) { 
+                   super = NULL;
+               } 
+           }
+           if (super != NULL) {
+               cbSuperclass(cb) = cbHandle(super);
+               if (CCIs(super, SoftRef))
+                   CCSet(cb, SoftRef);
+           } else {
+               ret = JAVAPKG "NoClassDefFoundError";
+               *detail = cbSuperName(cb);
+               cbSuperclass(cb) = NULL;
+               CCSet(cb, Error);
+           } 
+       } else if (cb == classJavaLangObject) {
+           cbSuperclass(cb) = 0;           
+       } else {
+           *detail = cbName(cb);
+           return JAVAPKG "ClassFormatException";
+       }
+    }
+
+    for (i = 0; i < (int)(cbImplementsCount(cb)); i++) {
+        /* Be very careful, since not verified yet. . . 
+        */
+        int interface_index = cbImplements(cb)[i];
+       cp_item_type *constant_pool = cbConstantPool(cb);
+       unsigned char *type_table = 
+           constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
+       ClassClass *icb;
+       int nconstants = cbConstantPoolCount(cb);
+       int iname_index;
+       char *iname;
+
+       if (interface_index <= 0 ||
+           interface_index >= nconstants ||
+           type_table[interface_index] != CONSTANT_Class ||
+           !(iname_index = constant_pool[interface_index].i) ||
+           iname_index <= 0 ||
+           iname_index >= nconstants ||
+           type_table[iname_index] != 
+           (CONSTANT_Utf8 | CONSTANT_POOL_ENTRY_RESOLVED)) {
+               *detail = "Bad interface index";
+               return JAVAPKG "ClassFormatError";
+       }
+               
+       iname = constant_pool[iname_index].cp;
+//     if (iname == NULL || !IsLegalClassname(iname, FALSE)) {
+//         *detail = "Bad interface name";
+//         return JAVAPKG "ClassFormatError";
+//     }
+
+       {
+           ExecEnv *ee = EE();
+           struct seenclass this[1];
+           if (checkSeen(ee, cb)) {
+               *detail = cbName(cb);
+               CCSet(cb, Error);
+               return JAVAPKG "ClassCircularityError";
+           }
+           this->cb = cb;
+           this->next = NULL;
+           pushSeen(ee, this);
+           icb = FindClassFromClass(ee, iname, FALSE, cb);
+           popSeen(ee, this);
+           if (icb) {
+               constant_pool[interface_index].clazz = icb;
+               type_table[interface_index] |= CONSTANT_POOL_ENTRY_RESOLVED;
+           } else {
+               *detail = iname;
+               CCSet(cb, Error);
+               return JAVAPKG "NoClassDefFoundError";
+           }
+       }
+    }
+
+    CCSet(cb, Initialized);
+
+    /* Make sure we know what classJavaLangClass is, and that it's method table
+     * is filled in.
+     */
+    if (classJavaLangClass == 0) {
+       classJavaLangClass = 
+             FindClassFromClass(0, CLS_RESLV_INIT_CLASS, TRUE, cb);
+       if (classJavaLangClass == 0) {
+           return JAVAPKG "NoClassDefFoundError";
+       }
+    }
+    
+    /* The following may not do anything useful if classJavaLangClass hasn't
+     * been completely resolved.  But we clean up in ResolveClass 
+     */
+
+    cbHandle(cb)->methods = cbMethodTable(classJavaLangClass);
+    return ret;
+}
+
+static char *
+Locked_LinkClass(ClassClass * cb, char **detail)
+{
+    ClassClass *super = 0;
+    unsigned slot = 0;
+    char *ret = 0;
+    int i;
+
+    if (CCIs(cb, Error)) {
+       *detail = cbName(cb);
+       return JAVAPKG "NoClassDefFoundError";
+    }
+   
+    sysAssert(CCIs(cb, Initialized));
+
+    if (CCIs(cb, Linked)) {
+       return NULL;
+    }
+
+    if (cbSuperclass(cb)) {
+       /* If this object has a superclass. . . */
+       super = cbSuperclass(cb);
+       if (!CCIs(super, Linked)) {
+           if ((ret = LinkClass(super, detail)) != 0) {
+               CCSet(cb, Error);
+               return ret;
+           }
+       }
+       sysAssert(CCIs(super, Linked));
+       slot = cbInstanceSize(super);
+    }
+
+    for (i = 0; i < (int)(cbImplementsCount(cb)); i++) {
+        int interface_index = cbImplements(cb)[i];
+       cp_item_type *constant_pool = cbConstantPool(cb);
+       ClassClass *icb;
+       icb = constant_pool[interface_index].clazz;
+       if (!CCIs(icb, Linked)) {
+           if ((ret = LinkClass(icb, detail)) != 0) {
+               CCSet(cb, Error);
+               return ret;
+           }
+       }
+    }
+    
+    sysAssert(!CCIs(cb, Error));
+    sysAssert(!CCIs(cb, Linked));
+
+#ifndef TRIMMED
+    if (verbose)
+        jio_fprintf(stderr, "[Resolving %s]\n", cbName(cb));
+#endif
+    cbInstanceSize(cb) = -1;
+    if ((ret = ResolveFields(cb, slot))) { /* May return "InternalError" */
+        *detail = cbName(cb);
+       CCSet(cb, Error);
+       return ret;
+    }
+
+    if ((ret = ResolveMethods(cb))) {
+        /* May return "OutOfMemoryError" or "InternalError" */
+       *detail = cbName(cb);
+       CCSet(cb, Error);
+       return ret;
+    }
+
+    if ((ret = ResolveInterfaces(cb, detail))) { /* All sorts of errors */
+       CCSet(cb, Error);
+       return ret;
+    }
+
+    InitializeInvoker(cb);
+
+    if ((verifyclasses == VERIFY_ALL) ||
+        ((verifyclasses == VERIFY_REMOTE) && (cbLoader(cb) != NULL))) {
+        if (!VerifyClass(cb)) {
+            *detail = "";
+            return JAVAPKG "VerifyError";
+        }
+    }
+
+    CCSet(cb, Linked);
+
+    /* We need this for bootstrapping.  We can't set the Handle's class block
+     * pointer in Object or Class until Class has been resolved.
+     */
+    if (cb == classJavaLangClass) {
+       int         j;
+       ClassClass **pcb;
+       BINCLASS_LOCK();
+       for (j = nbinclasses, pcb = binclasses; --j >= 0; pcb++) {
+           cbHandle(*pcb)->methods = cbMethodTable(cb);
+       }
+       BINCLASS_UNLOCK();
+       InitPrimitiveClasses();
+    }
+    return NULL;
+}
+
+static bool_t
+RunClinit(ClassClass * cb)
+{
+
+    if (CCIs(cb, Resolved))
+        return TRUE;
+
+    if ((cbName(cb)[0] != SIGNATURE_ARRAY) && !cbIsPrimitive(cb)) {
+       /* Don't need to initialize or verify array or primitive classes */
+        return RunStaticInitializers(cb);
+    } else if (cbName(cb)[0] == SIGNATURE_ARRAY) {
+       ClassClass *inner_cb = 
+           cbConstantPool(cb)[CONSTANT_POOL_ARRAY_CLASS_INDEX].clazz;
+       if (inner_cb) {
+           char *detail = 0;
+           char *ret = ResolveClass(inner_cb, &detail);
+           if (ret != NULL) {
+               if (!exceptionOccurred(EE())) { 
+                   SignalError(0, ret, detail);
+               }
+               CCSet(cb, Error);
+               return FALSE;
+           } else {
+               CCSet(cb, Resolved);
+           }
+       } else {
+           CCSet(cb, Resolved);
+       }
+    } else {
+        CCSet(cb, Resolved);
+    }
+    return TRUE;
+}
+
+
+/* Find an already loaded class with the given name.  If no such class exists
+ * then return 0.
+ */
+
+#ifdef DEBUG
+void
+PrintLoadedClasses()
+{
+    int         j;
+    ClassClass **pcb, *cb;
+    BINCLASS_LOCK();
+    pcb = binclasses;
+    for (j = nbinclasses; --j >= 0; pcb++) {
+       cb = *pcb;
+       jio_fprintf(stdout, "class=%s, 0x%x\n", cbName(cb), cbLoader(cb));
+    }
+    BINCLASS_UNLOCK();
+}
+#endif
+
+static ClassClass *
+FindLoadedClass(char *name, struct Hjava_lang_ClassLoader *loader)
+{
+    int left, right, middle, result;
+    ClassClass *cb = NULL;
+
+    BINCLASS_LOCK();
+    left = 0;
+    right = nbinclasses - 1;
+    result = 1;
+    while (left <= right) {
+        middle = (left + right)/2;
+       cb = binclasses[middle];
+       result = strcmp(name, cbName(cb));
+       if (result == 0) {
+           if (loader < cbLoader(cb)) {
+               result = -1;
+           } else if (loader > cbLoader(cb)) {
+               result = 1;
+           } else {
+               result = 0;
+           }
+       }
+       if (result < 0) {
+           right = middle - 1;
+       } else if (result > 0) {
+           left = middle + 1;
+       } else {
+           break;
+       }
+    }
+
+    BINCLASS_UNLOCK();
+    if (result == 0) {
+        return cb;
+    }
+    return NULL;
+}
+
+/* We attempt to resolve it, also, if the "resolve" argument is true.
+ * Otherwise, we only perform a minimal initialization on it, such that
+ * it points to its superclass, which points to its superclass. . . .
+ */
+
+static ClassClass *
+InitializeAndResolveClass(ClassClass *cb, bool_t resolve)
+{
+    char *err, *detail = NULL;
+    if ((err = InitializeClass(cb, &detail))) {
+        /* Check for underlying error already posted */
+       if (!exceptionOccurred(EE()))
+           SignalError(0, err, detail);
+       return 0;
+    }
+    if (resolve) {
+        err = ResolveClass(cb, &detail);
+       if (err) {
+           /* Check for underlying error already posted */ 
+           if (!exceptionOccurred(EE())) 
+               SignalError(0, err, detail);
+           return 0;
+       }
+    }
+    return cb;
+}
+
+/* Find the class with the given name.  
+ * If "resolve" is true, then we completely resolve the class.  Otherwise,
+ * we only make sure that it points to its superclass, which points to its
+ * superclass, . . . .
+ */
+ClassClass *(*class_loader_func)(HObject *loader, char *name, long resolve) = 0;
+
+ClassClass *
+FindClass(struct execenv *ee, char *name, bool_t resolve)
+{
+    return FindClassFromClass(ee, name, resolve, 0);
+}
+
+
+/*
+ * lock_classes and unlock_classes are exported by the JIT interface,
+ * but no longer used anywhere else. It grabs both locks to ensure 
+ * backward compatibility with 1.0.2.
+ */
+void
+lock_classes()
+{
+    LOADCLASS_LOCK();
+    BINCLASS_LOCK();
+}
+
+void
+unlock_classes()
+{
+    BINCLASS_UNLOCK();
+    LOADCLASS_UNLOCK();
+}
+
+extern char *output_path;
+
+extern ClassClass *
+LoadClassFromFile(char *fn, char *dir, char *class_name);
+
+ClassClass *
+FindClassFromClass(struct execenv *ee, char *name, bool_t resolve,
+                  ClassClass *from)
+{
+       char fn[64];
+       sprintf(fn, "%s.class", name);
+       return LoadClassFromFile(fn, output_path, name);
+}
+
+/*
+ * FindStickySystemClass is a variant of FindClassFromClass that makes the 
+ * class sticky (immune to class GC) if the class can be found.  It is only
+ * used on system classes, i.e. classes with no class loader, so it's 
+ * equivalent to FindClassFromClass with "from" argument 0.  It returns 0
+ * if the class can't be found, and like FindClass assumes that the caller
+ * will deal with that.  Note that until the class has been made sticky it
+ * must be kept somewhere where GC will find it.
+ */
+ClassClass *
+FindStickySystemClass(struct execenv *ee, char *name, bool_t resolve)
+{
+    ClassClass *cb;
+    if ((cb = FindClassFromClass(ee, name, resolve, 0)) != NULL) {
+       MakeClassSticky(cb);
+    }
+    return cb;
+}
+
+/* Find the array class with the specified name.  */
+static ClassClass *
+Locked_FindArrayClassFromClass(struct execenv *ee, char *name, 
+                              ClassClass *from) { 
+    struct Hjava_lang_ClassLoader *fromLoader = 
+               (from  == NULL) ? NULL : cbLoader(from);
+    char *name_p;
+    int depth, base_type;
+    ClassClass *cb;
+    struct Hjava_lang_ClassLoader *loader;
+    ClassClass *inner_cb;
+
+    sysAssert(name[0] == SIGNATURE_ARRAY);
+
+    if (fromLoader == NULL) { 
+       /* quick optimization if we know that we don't need a class loader */
+       cb = FindLoadedClass(name, NULL);
+       if (cb != NULL) 
+           return cb;
+    }
+           
+
+
+    /* Strip off all the initial SIGNATURE_ARRAY's to determine the depth,
+     * and also what's left.  When we're done, name_p points at the first
+     * non-character, and depth is the count of the array depth
+     */
+    for (name_p = name, depth = 0; *name_p == SIGNATURE_ARRAY; 
+        name_p++, depth++);
+
+    /* Look at the character to determine what type of array we have. */
+    switch(*name_p++) {
+        case SIGNATURE_INT:    base_type = T_INT; break;
+       case SIGNATURE_LONG:   base_type = T_LONG; break;
+       case SIGNATURE_FLOAT:  base_type = T_FLOAT; break;
+       case SIGNATURE_DOUBLE: base_type = T_DOUBLE; break;
+       case SIGNATURE_BOOLEAN:base_type = T_BOOLEAN; break; 
+       case SIGNATURE_BYTE:   base_type = T_BYTE; break;
+       case SIGNATURE_CHAR:   base_type = T_CHAR; break;
+       case SIGNATURE_SHORT:  base_type = T_SHORT; break;
+       case SIGNATURE_CLASS:  base_type = T_CLASS; break;
+        default:              return NULL;     /* bad signature */
+    }
+    if (base_type == T_CLASS) { 
+       char buffer_space[50];
+       char *buffer = buffer_space;
+       char *endChar = strchr(name_p, SIGNATURE_ENDCLASS);
+       int nameLength = endChar - name_p;
+       if (endChar == NULL || endChar[1] != '\0')
+           return NULL;
+       if (nameLength >= sizeof(buffer_space)) /* need bigger buffer */
+           buffer = sysMalloc(nameLength + 1);
+       memcpy(buffer, name_p, nameLength);
+       buffer[nameLength] = '\0';
+       inner_cb = FindClassFromClass(ee, buffer, FALSE, from);
+       if (buffer != buffer_space) /* free buffer, if we malloc'ed it */
+           sysFree(buffer);
+       if (inner_cb == NULL) 
+           return NULL;
+       /* loader should either be fromLoader or NULL. */
+       loader = cbLoader(inner_cb);
+    } else { 
+       if (*name_p != '\0')                    /* bad signature */
+           return NULL;
+       inner_cb = NULL;
+       loader = NULL;
+    }
+
+
+    LOADCLASS_LOCK();
+    cb = FindLoadedClass(name, loader);
+    if (cb == NULL) { 
+       /* Create the fake array class corresponding to this.
+        */
+       cb = createFakeArrayClass(name, base_type, depth, inner_cb, loader);
+    } 
+    LOADCLASS_UNLOCK();
+    return cb;
+}
+
+/*
+ * Convert a name and type to a hash code
+ *
+ * We make copies of all strings that go into the hash table
+ * in case the class that is the source of the strings being
+ * inserted is eventually unloaded.
+ */
+unsigned NameAndTypeToHash(char *name, char *type)
+{
+    extern struct StrIDhash *nameTypeHash;
+
+    unsigned name_key;
+    unsigned type_key;
+    unsigned ret;
+
+    NAMETYPEHASH_LOCK();
+    if (((name_key = Str2ID(&nameTypeHash, name, 0, TRUE)) == 0) ||
+       ((type_key = Str2ID(&nameTypeHash, type, 0, TRUE)) == 0)) {
+       SignalError(0, JAVAPKG "OutOfMemoryError", 0);
+       ret = 0;
+    } else {
+       ret = (name_key << 16) + type_key;
+    }
+    NAMETYPEHASH_UNLOCK();
+
+    return ret;
+}
+
+/*
+ * Pseudo-classes to represent primitive Java types.
+ */
+
+ClassClass *class_void;
+ClassClass *class_boolean;
+ClassClass *class_byte;
+ClassClass *class_char;
+ClassClass *class_short;
+ClassClass *class_int;
+ClassClass *class_long;
+ClassClass *class_float;
+ClassClass *class_double;
+
+struct primtype {
+    char               *name;
+    char               typesig;
+    unsigned char      typecode;
+    unsigned char      slotsize;
+    unsigned char      elementsize;
+    ClassClass         **cellp;
+} const primitive_types[] = {
+    { "void",  SIGNATURE_VOID,    T_VOID,      0, 0,   &class_void },
+    { "boolean",SIGNATURE_BOOLEAN, T_BOOLEAN,  4, 1,   &class_boolean },
+    { "byte",  SIGNATURE_BYTE,    T_BYTE,      4, 1,   &class_byte },
+    { "char",  SIGNATURE_CHAR,    T_CHAR,      4, 2,   &class_char },
+    { "short", SIGNATURE_SHORT,   T_SHORT,     4, 2,   &class_short },
+    { "int",   SIGNATURE_INT,     T_INT,       4, 4,   &class_int },
+    { "long",  SIGNATURE_LONG,    T_LONG,      8, 8,   &class_long },
+    { "float", SIGNATURE_FLOAT,   T_FLOAT,     4, 4,   &class_float },
+    { "double",        SIGNATURE_DOUBLE,  T_DOUBLE,    8, 8,   &class_double }
+};
+
+#define        PRIMITIVE_TYPE_COUNT    \
+       (sizeof (primitive_types) / sizeof (primitive_types[0]))
+
+#define        GET_PRIMITIVE_CLASS(nm) \
+       (class_##nm ? class_##nm : FindPrimitiveClass(#nm))
+
+ClassClass *
+FindPrimitiveClass(char *name)
+{
+    int i;
+    ClassClass *cb;
+    const struct primtype *p;
+    
+    for (i = 0; i < PRIMITIVE_TYPE_COUNT; i++) {
+       p = &primitive_types[i];
+       if (strcmp(name, p->name) == 0) {
+           cb = *p->cellp;
+           if (cb == NULL) {
+               char *err, *detail = NULL;
+               cb = createPrimitiveClass(p->name, p->typesig, p->typecode,
+                   p->slotsize, p->elementsize);
+               sysAssert(cb != NULL);
+               if ((err = InitializeClass(cb, &detail)) != NULL)
+                   return NULL; /* XXX */
+               if ((err = ResolveClass(cb, &detail)) != NULL)
+                   return NULL; /* XXX*/
+               *p->cellp = cb;
+           }
+           return cb;
+       }
+    }
+    return NULL;
+}
+
+static void
+InitPrimitiveClasses()
+{
+    int i;
+    for (i = 0; i < PRIMITIVE_TYPE_COUNT; i++)
+       FindPrimitiveClass(primitive_types[i].name);
+}
diff --git a/MPC.3.5.LINUX/preverifier/convert_md.c b/MPC.3.5.LINUX/preverifier/convert_md.c
new file mode 100644 (file)
index 0000000..a19a5a4
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * @(#)convert_md.c    1.2 00/11/22
+ *
+ * Copyright 1995-1998 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+#include <stdio.h>
+//#include <errno.h>
+#include <string.h>
+
+#ifdef UNIX
+#include <langinfo.h>
+#include <iconv.h>
+#include <locale.h>
+#include <stdlib.h>
+
+#define UTF8 "UTF-8"
+
+static iconv_t
+open_iconv(const char* to, const char* from) {
+    iconv_t ic = iconv_open(to, from);
+    if (ic == (iconv_t)-1) {
+//        if (errno == EINVAL) {
+               //if (0)
+            /* There is a bug in some versions of Solaris in which
+             * nl_langinfo() returns a string beginning with ISO, but you
+             * have to remove the ISO before calling open_iconv.
+             */
+        //    if (strncmp(from, "ISO", 3) == 0) {
+        //        /* Try again, but with the ISO in front of the "from" */
+        //        return open_iconv(to, from + 3);
+        //    } else if (strncmp(to, "ISO", 3) == 0) {
+        //        /* Try again, but with the ISO in front of the "to" */
+        //        return open_iconv(to + 3, from);
+        //    } else {
+        //        fprintf(stderr, "%s to %s not supported on this platform\n",
+        //                from, to);
+        //    }
+        //} else {
+        //    perror("iconv_open error: ");
+        //}
+        exit(1);
+    }
+    return ic;
+}
+
+static char*
+get_langinfo_codeset()
+{
+    static char *name = NULL;
+
+    if (name == NULL) {
+        name = nl_langinfo(CODESET);
+        if (name == NULL || strlen(name) == 0) {
+            name = "ISO8859-1";
+        }
+    }
+    return name;
+}
+
+int native2utf8(const char* from, char* to, int buflen) {
+    int ret;
+    size_t ileft, oleft;
+    char *langinfo_codeset = get_langinfo_codeset();
+    iconv_t ic;
+    if (strncmp(langinfo_codeset, UTF8, 5) == 0) {
+        /* don't invoke 'iconv' functions to do the
+         * conversion if it's already in UTF-8 encoding
+         */
+        memcpy(to, from, buflen);
+        return 0;
+    }
+
+    ic = open_iconv(UTF8, get_langinfo_codeset());
+    memset(to, 0, buflen);
+    ileft = strlen(from);
+    oleft = buflen;
+
+    ret = iconv(ic, &from, &ileft, &to, &oleft);
+    if (ret == (size_t)-1) {
+        fprintf(stderr, "native2utf8:Failed to convert (err=%d)\n", ret);
+        exit(1);
+    }
+    iconv_close(ic);
+
+    return buflen-oleft;
+}
+
+int utf2native(const char* from, char* to, int buflen) {
+    int ret;
+    size_t ileft, oleft;
+
+    char *langinfo_codeset = get_langinfo_codeset();
+    iconv_t ic;
+
+    if (strncmp(langinfo_codeset, UTF8, 5) == 0) {
+        /* Don't do the conversion if it's
+         * already in UTF-8 encoding
+         * Copy over the 'from' to 'to'.
+         */
+        memcpy(to, from, buflen);
+        return 0;
+    }
+
+    ic = open_iconv(get_langinfo_codeset(), UTF8);
+    memset(to, 0, buflen);
+    ileft = strlen(from);
+    oleft = buflen;
+
+    ret = iconv(ic, &from, &ileft, &to, &oleft);
+    if (ret == (size_t)-1) {
+        fprintf(stderr, "utf2native:Failed to convert (err=%d)\n", ret);
+        exit(1);
+    }
+    iconv_close(ic);
+
+    return buflen-oleft;
+}
+
+
+#endif
+#ifdef WIN32
+
+#include <WINDOWS.H>
+
+#include "oobj.h"
+#include "utf.h"
+
+int native2utf8(const char* from, char* to, int buflen) {
+       int len;
+       unsigned short unicode[BUFSIZ];
+       len = MultiByteToWideChar(CP_ACP, 0, from, -1, &unicode[0], BUFSIZ);
+       unicode2utf(&unicode[0], len-1, to, buflen);
+       return utfstrlen(to);
+}
+int utf2native(const char* from, char* to, int buflen) {
+       int len, len2;
+       unsigned short unicode[BUFSIZ];
+       utf2unicode((char*)from, &unicode[0], BUFSIZ, &len);
+       len2 = WideCharToMultiByte(CP_ACP, 0, &unicode[0], len, to,
+               buflen, NULL, NULL);
+       to[len2]=0;
+       return len2;
+}
+#endif
+
diff --git a/MPC.3.5.LINUX/preverifier/convert_md.h b/MPC.3.5.LINUX/preverifier/convert_md.h
new file mode 100644 (file)
index 0000000..f341034
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * @(#)convert_md.h    1.2 00/11/22
+ *
+ * Copyright 1995-1998 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+#ifndef _CONVERT_MD_
+#define _CONVERT_MD_
+
+extern int native2utf8(const char* from, char* to, int buflen);
+extern int utf2native(const char* from, char* to, int buflen);
+
+#endif
diff --git a/MPC.3.5.LINUX/preverifier/file.c b/MPC.3.5.LINUX/preverifier/file.c
new file mode 100644 (file)
index 0000000..b53b648
--- /dev/null
@@ -0,0 +1,787 @@
+/*
+ * @(#)file.c  1.40 02/09/27
+ *
+ * Copyright 1995-1998 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+/*=========================================================================
+ * SYSTEM:    Verifier
+ * SUBSYSTEM: Operations on class files.
+ * FILE:      file.c
+ * OVERVIEW:  Routines for outputing the internal class file.
+ *
+ * AUTHOR(s): Original implementation,
+ *            Sheng Liang, Sun Microsystems, Inc.
+ *
+ *            Modifications for JAR support, debug support, CLDC compliance,
+ *            Tasneem Sayeed, Sun Microsystems
+ *
+ *            Added support for inner classes, fixes for stack maps, etc.
+ *            Frank Yellin, Sun Microsystems
+ *=======================================================================*/
+
+/*=========================================================================
+ * Include files
+ *=======================================================================*/
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stddef.h>
+
+#ifdef UNIX
+#include <unistd.h>
+#endif
+
+#include "oobj.h"
+#include "jar.h"
+#include "tree.h"
+#include "sys_api.h"
+#include "convert_md.h"
+
+#ifdef WIN32
+#include <direct.h>
+#endif
+
+/* initialize opnames[256]; */
+#include "opcodes.init"
+
+
+/*=========================================================================
+ * Globals and extern declarations
+ *=======================================================================*/
+
+extern char *progname;
+extern bool_t JARfile;
+extern bool_t tmpDirExists;
+
+char *current_class_name = NULL;
+
+bool_t stack_map_on = TRUE;
+
+static char *PrintableClassname(char *classname);
+
+extern char tmp_dir[32];
+
+char *output_dir = "output";
+unsigned char *class_buf;
+int class_buf_size = 0;
+int class_index;
+int last_not_utf8_index;
+
+#define INIT_CLASS_BUF_SIZE 256
+
+void ensure_capacity(int sz)
+{
+    if (class_index + sz >= class_buf_size) {
+        while (class_index + sz >= class_buf_size) {
+            class_buf_size *= 2;
+        }
+    }
+    class_buf = (unsigned char *)realloc(class_buf, class_buf_size);
+}
+
+void write_u1(unsigned long u1)
+{
+    ensure_capacity(1);
+    class_buf[class_index++] = (unsigned char)u1;
+}
+
+void write_u2(unsigned long u2)
+{
+    ensure_capacity(2);
+    class_buf[class_index++] = (unsigned char)(u2 >> 8);
+    class_buf[class_index++] = (unsigned char)u2;
+}
+
+void write_u4(unsigned long u4)
+{
+    ensure_capacity(4);
+    class_buf[class_index++] = (unsigned char)(u4 >> 24);
+    class_buf[class_index++] = (unsigned char)(u4 >> 16);
+    class_buf[class_index++] = (unsigned char)(u4 >> 8);
+    class_buf[class_index++] = (unsigned char)u4;
+}
+
+int new_utf8_index(ClassClass *cb, int index)
+{
+    if (index > last_not_utf8_index) {
+        return index + unhand(cb)->n_new_class_entries;
+    } else {
+        return index;
+    }
+}
+
+unsigned long lookup_utf8(ClassClass *cb, char *utf8)
+{
+    int i;
+    cp_item_type *constant_pool = cbConstantPool(cb);
+    int cpEntries, newEntries;
+    unsigned char *type_table =
+        constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
+    cpEntries = cbConstantPoolCount(cb);
+    newEntries = unhand(cb)->n_new_utf8_entries;
+    for (i = 0; i < cpEntries; i++) {
+        if (type_table[i] == (CONSTANT_Utf8 | CONSTANT_POOL_ENTRY_RESOLVED) &&
+            strcmp(utf8, constant_pool[i].cp) == 0) {
+            return new_utf8_index(cb, i);
+        }
+    }
+    for (i = 0; i < newEntries; i++) {
+        if (strcmp(unhand(cb)->new_utf8_entries[i], utf8) == 0) {
+            return i + cpEntries + unhand(cb)->n_new_class_entries;
+        }
+    }
+    unhand(cb)->new_utf8_entries[newEntries] = utf8;
+    unhand(cb)->n_new_utf8_entries = newEntries + 1;
+    return newEntries + cpEntries + unhand(cb)->n_new_class_entries;
+}
+
+
+unsigned long lookup_class(ClassClass *cb, char *name)
+{
+    int i;
+    cp_item_type *constant_pool = cbConstantPool(cb);
+    unsigned char *type_table =
+        constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
+    for (i = 0; i < cbConstantPoolCount(cb); i++) {
+        if (type_table[i] == (CONSTANT_Class | CONSTANT_POOL_ENTRY_RESOLVED) &&
+            strcmp(name, cbName(constant_pool[i].clazz)) == 0) {
+            return i;
+        }
+        if (type_table[i] == CONSTANT_Class &&
+            strcmp(name, constant_pool[constant_pool[i].i].cp) == 0) {
+            return i;
+        }
+    }
+//    panic("class expected to be in constant pool: %s", name);
+    return 0;
+}
+
+int get_last_not_utf8_index(ClassClass *cb)
+{
+    int i;
+    int result;
+    cp_item_type *constant_pool = cbConstantPool(cb);
+    unsigned char *type_table =
+        constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
+    for (i = 0, result = -1; i < cbConstantPoolCount(cb); i++) {
+        if (type_table[i] != (CONSTANT_Utf8 | CONSTANT_POOL_ENTRY_RESOLVED)) {
+            result = i;
+        }
+    }
+    return result;
+}
+
+void write_constant_pool_preverifier(ClassClass *cb)
+{
+    int i, j;
+    cp_item_type *constant_pool = cbConstantPool(cb);
+    unsigned char *type_table =
+        constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type;
+    unsigned int sealedValue;
+
+    last_not_utf8_index = get_last_not_utf8_index(cb);
+    if (stack_map_on && unhand(cb)->has_stack_maps) {
+        /* The maximum number of new utf8 entries we'll need is one
+         * for "StackMap", plus one for each of the new class entries.
+         * However, we bump the number to 2 in case we need to add another
+         * entry for the SourceFile attribute.
+         */
+        unhand(cb)->n_new_utf8_entries = 0;
+        unhand(cb)->new_utf8_entries =
+            (char **)malloc((unhand(cb)->n_new_class_entries + 2) *
+                            sizeof(char *));
+        /* Put sure we have all the Utf8 entries that we need, so that
+         * we'll know the final size of the constant pool.
+         */
+        lookup_utf8(cb, "StackMap");
+        for (i = 0; i < unhand(cb)->n_new_class_entries; i++) {
+            lookup_utf8(cb, unhand(cb)->new_class_entries[i]);
+        }
+    } else {
+        unhand(cb)->n_new_utf8_entries = 0;
+        unhand(cb)->new_utf8_entries = NULL;
+        unhand(cb)->n_new_class_entries = 0;
+        if (unhand(cb)->new_class_entries != NULL) {
+            free(unhand(cb)->new_class_entries);
+            unhand(cb)->new_class_entries = NULL;
+        }
+    }
+    /* At this, we should not add have to create any more utf8 entries.
+     * We  find the value of unhand(cb)->n_new_utf8_entries, and complain
+     * later if this value has changed.
+     */
+    sealedValue = unhand(cb)->n_new_utf8_entries;
+
+    write_u2(cbConstantPoolCount(cb) +
+             unhand(cb)->n_new_class_entries +
+             unhand(cb)->n_new_utf8_entries);
+
+    for (i = 1; i < cbConstantPoolCount(cb); i++) {
+        write_u1(type_table[i] & CONSTANT_POOL_ENTRY_TYPEMASK);
+        switch(type_table[i]) {
+        case CONSTANT_Utf8 | CONSTANT_POOL_ENTRY_RESOLVED:
+            write_u2(strlen(constant_pool[i].cp));
+            for (j = 0; j < (int)strlen(constant_pool[i].cp); j++) {
+                write_u1(constant_pool[i].cp[j]);
+            }
+            break;
+
+        case CONSTANT_Class:
+        case CONSTANT_String:
+            write_u2(new_utf8_index(cb, constant_pool[i].i));
+            break;
+
+        case CONSTANT_Class | CONSTANT_POOL_ENTRY_RESOLVED:
+            write_u2(lookup_utf8(cb, cbName(constant_pool[i].clazz)));
+            break;
+
+        case CONSTANT_Fieldref:
+        case CONSTANT_Methodref:
+        case CONSTANT_InterfaceMethodref:
+            write_u2(constant_pool[i].i >> 16);
+            write_u2(constant_pool[i].i & 0xFFFF);
+            break;
+
+        case CONSTANT_NameAndType:
+            write_u2(new_utf8_index(cb, constant_pool[i].i >> 16));
+            write_u2(new_utf8_index(cb, constant_pool[i].i & 0xFFFF));
+            break;
+
+        case CONSTANT_Integer | CONSTANT_POOL_ENTRY_RESOLVED:
+        case CONSTANT_Float | CONSTANT_POOL_ENTRY_RESOLVED:
+            write_u4(constant_pool[i].i);
+            break;
+
+        case CONSTANT_Long | CONSTANT_POOL_ENTRY_RESOLVED:
+        case CONSTANT_Double | CONSTANT_POOL_ENTRY_RESOLVED:
+            write_u4(constant_pool[i].i);
+            write_u4(constant_pool[i + 1].i);
+            i++;
+            break;
+
+    //    default:
+         //   panic("bad constant pool entry type: %d", type_table[i]);
+        }
+        if (i == last_not_utf8_index) {
+            /* Write extra CONSTANT_Class entries created by the stackmaps */
+            for (j = 0; j < unhand(cb)->n_new_class_entries; j++) {
+                char *classname = unhand(cb)->new_class_entries[j];
+                write_u1(CONSTANT_Class);
+                write_u2(lookup_utf8(cb, classname));
+            }
+        }
+    }
+    /* Write extra CONSTANT_Utf8 entries created by the stackmaps */
+    for (i = 0; i < unhand(cb)->n_new_utf8_entries; i++) {
+        char *string = unhand(cb)->new_utf8_entries[i];
+        int length = strlen(string);
+        write_u1(CONSTANT_Utf8);
+        write_u2(length);
+        for (j = 0; j < length; j++) {
+            write_u1(string[j]);
+        }
+    }
+    if (sealedValue != (unsigned int) unhand(cb)->n_new_utf8_entries) {
+     //   panic("New utf8 entries have been added???");
+    }
+
+}
+
+void write_interfaces(ClassClass *cb)
+{
+    int i;
+    write_u2(cbImplementsCount(cb));
+    for (i = 0; i < cbImplementsCount(cb); i++) {
+        write_u2(cbImplements(cb)[i]);
+    }
+}
+
+void write_fields(ClassClass *cb)
+{
+    int i;
+    write_u2(cbFieldsCount(cb));
+    for (i = 0; i < cbFieldsCount(cb); i++) {
+        struct fieldblock *fb = &cbFields(cb)[i];
+        write_u2(fb->access & ACC_WRITTEN_FLAGS);
+        write_u2(lookup_utf8(cb, fb->name));
+        write_u2(lookup_utf8(cb, fb->signature));
+        /* Number of attributes we're about to output.
+         * Each item in the following sum is a boolean that returns 1 or 0.
+         */
+        write_u2(  ((fb->access & ACC_VALKNOWN) != 0)
+                 + (fb->synthetic != 0)
+                 + (fb->deprecated != 0));
+        if (fb->access & ACC_VALKNOWN) {
+            write_u2(lookup_utf8(cb, "ConstantValue")); /* Attribute name */
+            write_u4(2);                                /* Length */
+            write_u2(fb->u.offset);
+        }
+        if (fb->deprecated) {
+            write_u2(lookup_utf8(cb, "Deprecated"));     /* Attribute name  */
+            write_u4(0);                                 /* Length */
+        }
+        if (fb->synthetic) {
+            write_u2(lookup_utf8(cb, "Synthetic"));      /* Attribute name  */
+            write_u4(0);                                 /* Length */
+        }
+    }
+}
+
+void write_stack_map(int nentries, struct map_entry *entries)
+{
+    int i;
+    for (i = 0; i < nentries; i++) {
+        struct map_entry *entry = entries + i;
+        write_u1(entry->type);
+        if (entry->type == CF_ITEM_NewObject) {
+            write_u2(entry->info);
+        }
+        if (entry->type == CF_ITEM_Object) {
+            /* This is ugly
+             * Non-negative entries refer to classes
+             *       in the original constant pool.
+             * Negative entries, ~(entry->info) is the entry's index
+             *       in the list of additional constant pool entries.
+             */
+            if (entry->info >= 0) {
+                write_u2(entry->info);
+            } else {
+                write_u2(last_not_utf8_index + 1 + ~entry->info);
+            }
+        }
+    }
+}
+
+int stack_map_size(int nentries, struct map_entry *entries)
+{
+    int i;
+    int result = 0;
+    for (i = 0; i < nentries; i++) {
+        struct map_entry *entry = entries + i;
+        result += 1;
+        if (entry->type == CF_ITEM_Object || entry->type == CF_ITEM_NewObject) {
+            result += 2;
+        }
+    }
+    return result;
+}
+
+void write_methods(ClassClass *cb)
+{
+    int i;
+    write_u2(cbMethodsCount(cb));
+    for (i = 0; i < cbMethodsCount(cb); i++) {
+        struct methodblock *mb = &cbMethods(cb)[i];
+        write_u2(mb->fb.access & ACC_WRITTEN_FLAGS);
+        write_u2(lookup_utf8(cb, mb->fb.name));
+        write_u2(lookup_utf8(cb, mb->fb.signature));
+
+        /* Attribute count
+         * Each item in the following sum is a boolean that returns 1 or 0.
+         */
+        write_u2(  (mb->code_length > 0)
+                 + (mb->nexceptions > 0)
+                 + (mb->fb.synthetic != 0)
+                 + (mb->fb.deprecated != 0));
+
+        if (mb->code_length > 0) {
+            int j;
+            int stack_map_attr_length = 0;   /* Stack Map attribute length */
+            int line_no_attr_length = 0;     /* line_number_table attr Length */
+            int localvar_attr_length = 0;    /* localVar_table attr Length */
+            int code_attrs = 0;        /* Attributes count for Code attribute */
+
+            if (stack_map_on && mb->n_stack_maps > 0) {
+                stack_map_attr_length = 8;
+                code_attrs++;                /* increment code attributes */
+                for (j = 0; j < mb->n_stack_maps; j++) {
+                    stack_map_attr_length += 6 +
+                        stack_map_size(mb->stack_maps[j].nlocals,
+                                       mb->stack_maps[j].locals) +
+                        stack_map_size(mb->stack_maps[j].nstacks,
+                                       mb->stack_maps[j].stacks);
+                }
+            }
+
+            /* attribute_name_index for "Code" attribute */
+            write_u2(lookup_utf8(cb, "Code"));
+            if (mb->line_number_table_length > 0) {
+                /* calculate the size of the line_number_table attribute */
+                /* Attribute length for line_number_table
+                 * sizeof line_number_table(4) * no. of table entries + 8
+                 * 8 bytes = 2 bytes for attr_name_index +
+                 *           4 bytes for attr_length +
+                 *           2 bytes for line_number_table_length
+                 */
+                code_attrs++;      /* increment code attributes */
+                line_no_attr_length = 4 * mb->line_number_table_length + 8;
+            }
+            if (mb->localvar_table_length > 0) {
+                /* calculate the size of the localvar_table attribute */
+                /* Attribute length for localvar_table
+                 * sizeof localvar_table (10) * no. of table entries + 8
+                 * 8 bytes = 2 bytes for attr_name_index +
+                 *           4 bytes for attr_length +
+                 *           2 bytes for line_number_table_length
+                 */
+                code_attrs++;      /* increment code attributes */
+                localvar_attr_length = 10 * mb->localvar_table_length + 8;
+            }
+
+            /* Attribute Length */
+            write_u4(12 + mb->code_length
+                     + mb->exception_table_length * 8
+                     + stack_map_attr_length
+                     + line_no_attr_length
+                     + localvar_attr_length);
+            write_u2(mb->maxstack);
+            write_u2(mb->nlocals);
+            write_u4(mb->code_length);
+            for (j = 0; j < (int)mb->code_length; j++) {
+                write_u1(mb->code[j]);
+            }
+            write_u2(mb->exception_table_length);
+            for (j = 0; j < (int)mb->exception_table_length; j++) {
+                write_u2(mb->exception_table[j].start_pc);
+                write_u2(mb->exception_table[j].end_pc);
+                write_u2(mb->exception_table[j].handler_pc);
+                write_u2(mb->exception_table[j].catchType);
+            }
+
+            /* Attributes count for Code attribute */
+            write_u2(code_attrs);
+
+            /* check if we have a valid line_number_table entries and
+             * if so, write out the pc and line_number entries.
+             */
+
+            if (mb->line_number_table_length > 0) {
+                /* line_number_table attribute exists */
+                /* attribute_name_index for "LineNumberTable" */
+                write_u2(lookup_utf8(cb, "LineNumberTable"));
+                /* Attribute length for line_number_table
+                 * (exclude initial 6 bytes = 2 bytes for attr_name_index +
+                 *                            4 bytes for attr_length)
+                 */
+                write_u4(line_no_attr_length - 6);
+                /* Length of line_number_table */
+                write_u2(mb->line_number_table_length);
+                /* write out the line_number_table entries */
+                for (j=0; j< (int) mb->line_number_table_length; j++) {
+                    if (mb->line_number_table != NULL) {
+                        write_u2(mb->line_number_table[j].pc);
+                        write_u2(mb->line_number_table[j].line_number);
+                    }
+                }
+            }
+
+            /* check if we have a valid localvar_table entries and
+             * if so, write out its entries
+             */
+
+            if (mb->localvar_table_length > 0) {
+                /* localvar_table attribute exists */
+                /* attribute_name_index for "LocalVariableTable" */
+                write_u2(lookup_utf8(cb, "LocalVariableTable"));
+
+                /* Attribute length for localvar_table
+                 * (exclude initial 6 bytes = 2 bytes for attr_name_index +
+                 *                            4 bytes for attr_length)
+                 */
+                write_u4(localvar_attr_length - 6);
+
+                /* Length of localvar_table */
+                write_u2(mb->localvar_table_length);
+
+                /* write out the localvar_table entries */
+                for (j=0; j< (int) mb->localvar_table_length; j++) {
+                    if (mb->localvar_table != NULL) {
+                        write_u2(mb->localvar_table[j].pc0);
+                        write_u2(mb->localvar_table[j].length);
+                        write_u2(lookup_utf8(cb,mb->localvar_table[j].name));
+                        write_u2(lookup_utf8(cb,mb->localvar_table[j].signature));
+                        write_u2(mb->localvar_table[j].slot);
+                    }
+                }
+            }
+
+            if (stack_map_on && mb->n_stack_maps > 0) {
+                write_u2(lookup_utf8(cb, "StackMap"));
+                write_u4(stack_map_attr_length - 6);
+                write_u2(mb->n_stack_maps);
+                for (j = 0; j < mb->n_stack_maps; j++) {
+                    write_u2(mb->stack_maps[j].offset);
+                    write_u2(mb->stack_maps[j].nlocals);
+                    write_stack_map(mb->stack_maps[j].nlocals,
+                                    mb->stack_maps[j].locals);
+                    write_u2(mb->stack_maps[j].nstacks);
+                    write_stack_map(mb->stack_maps[j].nstacks,
+                                    mb->stack_maps[j].stacks);
+                }
+            }
+        }
+        if (mb->nexceptions > 0) {
+            int j;
+            write_u2(lookup_utf8(cb, "Exceptions"));
+            write_u4(2 + mb->nexceptions * 2);
+            write_u2(mb->nexceptions);
+            for (j = 0; j < mb->nexceptions; j++) {
+                write_u2(mb->exceptions[j]);
+            }
+        }
+        if (mb->fb.deprecated) {
+            write_u2(lookup_utf8(cb, "Deprecated"));
+            write_u4(0);                                 /* Length */
+        }
+        if (mb->fb.synthetic) {
+            write_u2(lookup_utf8(cb, "Synthetic"));
+            write_u4(0);                                 /* Length */
+        }
+    }
+}
+
+void ensure_dir_exists(char *dir)
+{
+    struct stat stat_buf;
+    char *parent;
+    char *q;
+    if (dir[0] == 0) {
+        return;
+    }
+    parent = strdup(dir);
+    q = strrchr(parent, '/');
+    if (q) {
+        *q = 0;
+        ensure_dir_exists(parent);
+    }
+    if (stat(dir, &stat_buf) < 0) {
+        if (JAR_DEBUG && verbose) {
+        //    jio_fprintf(stderr, "Creating output directory [%s]\n", dir);
+        }
+#ifdef WIN32
+        mkdir(dir);
+#endif
+#ifdef UNIX
+        mkdir(dir, 0755);
+#endif
+    }
+    free(parent);
+}
+
+void ensure_dir_writable(char *dir)
+{
+    struct stat stat_buf;
+
+    stat(dir, &stat_buf);
+    if ((stat_buf.st_mode & S_IFMT) == S_IFDIR) { /* is dir ? */
+#ifdef WIN32
+        if (access(dir, 06) < 0) {
+#endif
+#ifdef UNIX
+        if (access(dir, R_OK | W_OK) < 0) {
+#endif
+         //   panic("%s is write protected\n", dir);
+        }
+    } else {
+     //   panic("%s is not a directory\n", dir);
+    }
+}
+
+extern char *output_path;
+
+void
+WriteClass(ClassClass *cb)
+{
+    int fd;
+    char fname[1024];
+    char buff[BUFSIZ];
+    char *nativeName = &buff[0];
+
+    class_buf = (unsigned char*)malloc(INIT_CLASS_BUF_SIZE);
+    if (class_buf == NULL) {
+     //   panic("out of memory");
+    }
+    class_buf_size = INIT_CLASS_BUF_SIZE;
+
+    class_index = 0;
+
+    write_u4(0xcafebabe);
+
+    write_u2(cbMinorVersion(cb));
+    write_u2(cbMajorVersion(cb));
+
+    write_constant_pool_preverifier(cb);
+
+    write_u2(cbAccess(cb) & ACC_WRITTEN_FLAGS);
+
+    write_u2(lookup_class(cb, cbName(cb)));
+    write_u2(unhand(cb)->superclass_idx);
+    write_interfaces(cb);
+    write_fields(cb);
+    write_methods(cb);
+
+
+    /* Output number of attributes
+     * Each item in the following sum is a boolean that returns 1 or 0.
+     */
+    write_u2(   (cbSourceName(cb) != NULL)
+              + (cbAbsoluteSourceName(cb) != NULL)
+              + (unhand(cb)->hasTimeStamp)
+              + (unhand(cb)->deprecated)
+              + (unhand(cb)->synthetic)
+              + (cbInnerClasses(cb) != NULL)
+            );
+    if (cbSourceName(cb) != NULL) {
+        /* write the source file attribute used for debugging purposes */
+        write_u2(lookup_utf8(cb, "SourceFile"));     /* SourceFile attribute */
+        write_u4(2);                                 /* Length */
+                                 /* CP entry containing the source name */
+        write_u2(lookup_utf8(cb, cbSourceName(cb)));
+    }
+    if (cbAbsoluteSourceName(cb) != NULL) {
+        /* write the source file attribute used for debugging purposes */
+        write_u2(lookup_utf8(cb, "AbsoluteSourcePath"));
+        write_u4(2);
+        write_u2(lookup_utf8(cb, cbAbsoluteSourceName(cb)));
+    }
+    if (unhand(cb)->hasTimeStamp) {
+        write_u2(lookup_utf8(cb, "TimeStamp"));
+        write_u4(8);
+        write_u4(cbTimestamp(cb).high);
+        write_u4(cbTimestamp(cb).low);
+    }
+    if (unhand(cb)->deprecated) {
+        write_u2(lookup_utf8(cb, "Deprecated"));     /* attribute name */
+        write_u4(0);                                 /* Length */
+    }
+    if (unhand(cb)->synthetic) {
+        write_u2(lookup_utf8(cb, "Synthetic"));     /* attribute name */
+        write_u4(0);                                /* Length */
+    }
+
+    if (cbInnerClasses(cb) != NULL) {
+        int count = cbInnerClassesCount(cb);
+        struct innerClasses *thisInnerClass= cbInnerClasses(cb);
+        struct innerClasses *lastInnerClass = thisInnerClass + count;
+        write_u2(lookup_utf8(cb, "InnerClasses"));  /* Attribute name */
+        write_u4(8 * count + 2);                    /* Length */
+        write_u2(count);
+        for ( ; thisInnerClass < lastInnerClass; thisInnerClass++) {
+            char *innerName = thisInnerClass->inner_name;
+            write_u2(thisInnerClass->inner_class);
+            write_u2(thisInnerClass->outer_class);
+            write_u2( (innerName != 0) ? lookup_utf8(cb, innerName) : 0);
+            write_u2(thisInnerClass->access);
+        }
+    }
+
+    /* Conversion for Japanese filenames */
+    utf2native(cbName(cb), nativeName, BUFSIZ);
+
+ //   if (JARfile) {
+        /* classes need to be put in a JAR file */
+ //       sprintf(fname, "%s/%s.class", tmp_dir, nativeName);
+ //   } else {
+        sprintf(fname, "%s/%s.class", output_path, nativeName);
+//    }
+
+    {
+        char *dir = strdup(fname);
+        char *q;
+
+        q = strrchr(dir, '/');
+        if (q) {
+            *q = 0;
+            ensure_dir_exists(dir);
+            ensure_dir_writable(dir);
+        }
+        free(dir);
+    }
+
+#ifdef UNIX
+    fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC , 0644);
+#endif
+#ifdef WIN32
+    fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
+#endif
+
+    if (fd < 0) {
+     //   panic("failed to open %s", fname);
+    }
+
+    tmpDirExists = TRUE;   /* tmpDir exists with verified classes */
+    write(fd, class_buf, class_index);
+    close(fd);
+    free(class_buf);
+    class_buf_size = 0;
+}
+
+void
+VerifyFile(char *fn)
+{
+    /* If this is the first class, we'll run into problems if loading the
+     * class forces Object to be loaded, when then forces this class to
+     * be loaded.  To prohibit such problems, we force Object to be loaded
+     */
+    FindClass(0, "java/lang/Object", TRUE);
+
+    {
+        ClassClass *cb = FindClass(0, fn, TRUE);
+        char *class_name = PrintableClassname(fn);
+
+        if (cb == NULL) {
+            errorCode = 1;  /* set error status to indicate error */
+         //   jio_fprintf(stderr, "Error loading class %s\n", class_name);
+        } else {
+            if (no_native_methods) {
+                /* Check for native methods in classes */
+                struct methodblock *mb;
+                int size;
+                mb = cbMethods(cb);
+                for (size=0; size < (int) cbMethodsCount(cb); size++, mb++) {
+                    if (mb->fb.access & ACC_NATIVE) {
+                        current_class_name = fn;
+                     //   panic("native methods should not appear");
+                    }
+                }
+            }
+
+                       VerifyClass(cb);
+
+            WriteClass(cb);
+        }
+    }
+}
+
+char *PrintableClassname(char *class_name)
+{
+    char *p;
+    static char class_copy[257];
+    strncpy(class_copy, class_name, 256);
+
+    /* Convert all slashes in the classname to periods */
+    for (p = class_copy; ((p = strchr(p, '/')) != 0); *p++ = '.');
+    return class_copy;
+}
+
+void printCurrentClassName(void)
+{
+    if (current_class_name) {
+      //  fprintf(stderr, "Error preverifying class %s\n    ",
+      //          PrintableClassname(current_class_name));
+    }
+}
diff --git a/MPC.3.5.LINUX/preverifier/inlinejsr.c b/MPC.3.5.LINUX/preverifier/inlinejsr.c
new file mode 100644 (file)
index 0000000..32f996d
--- /dev/null
@@ -0,0 +1,681 @@
+/*
+ * @(#)inlinejsr.c     1.22 02/09/27
+ *
+ * Copyright 1995-2001 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ * 
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+/*=========================================================================
+ * SYSTEM:    Verifier
+ * SUBSYSTEM: JSR inlining
+ * FILE:      inlinejsr.c
+ * OVERVIEW:  Routines for inlining of JSR and RET bytecodes.  
+ *
+ * AUTHOR:    Frank Yellin, Sun Microsystems, Inc.
+ *            Edited by Tasneem Sayeed, Sun Microsystems
+ *=======================================================================*/
+
+/*=========================================================================
+ * Include files
+ *=======================================================================*/
+
+#include "check_code.h"
+
+/*=========================================================================
+ * Globals and extern declarations
+ *=======================================================================*/
+
+/* Maximum byte code size is 64K. */
+#define MAX_CODE_SIZE 65535
+
+typedef struct SubrContext {
+    int id;                         /* id, for debugging */
+    int depth;                      /* depth of subroutine */
+    struct SubrContext *parent;     /* subroutine of caller */
+    struct CodeRef *caller;         /* jsr that got us there */
+    struct CodeRef *nextInstruction; /* first instruction following inlining */
+    int target;
+
+    struct SubrContext *next;   /* linked list of all subr contexts */
+} SubrContext;
+
+
+/* global context, keep track of info when a method is rewritten */
+typedef struct JsrContext {
+    context_type *vcontext;     /* The verifier's context */
+    struct CodeRef *codeRef;    /* big array of codeRef's */
+    struct CodeRef *codeRefEnd; /* pointer to next codeRef to fill in */
+    int scontext_id;            /* ID assigned to last SubrContext */
+    struct SubrContext *allSubrContexts; /* pointer to linked list */
+    struct CodeRef **mapping;   /* maps inumbers CodeRef's */
+} JsrContext;
+
+/* A single instruction in the resulting stream */
+typedef struct CodeRef { 
+    long inumber;               /* instruction number in original code */
+    SubrContext *subroutine;    /* subroutine call that this is part of */
+    enum { CRF_NORMAL,          /* normal instruction */
+           CRF_SKIP,            /* skip this instruction */
+           CRF_JSR_SIMPLE_GOTO, /* jsr to subroutine that doesn't return */
+           CRF_JSR_TARGETED_GOTO, /* jsr to subroutine that does return */
+           CRF_RET_SIMPLE_GOTO  /* ret that's not at the end of subroutine */
+    } flags;
+    /* My offset in the new code */
+    int offset;
+    struct CodeRef *next;       /* next codeRef with same "inumber" */
+} CodeRef;
+
+
+static bool_t matchSubroutine(JsrContext *, instruction_data_type*, 
+                            SubrContext *);
+static bool_t subroutineGoto(JsrContext *, SubrContext *, SubrContext *);
+
+
+static void
+rewriteOneSubroutine(JsrContext *context, SubrContext *subroutine);
+
+static void fixupCode(JsrContext*);
+static void fixupExceptionHandlers(JsrContext*);
+static void fixupLineNumberTable(JsrContext*);
+static void fixupVariableTable(JsrContext*);
+
+
+static void
+updateTarget(JsrContext *, 
+             int inumber, 
+             SubrContext* subroutine, 
+             void* target, int offset, int size);
+
+
+void
+rewriteCode(context_type *vcontext, struct methodblock *mb)
+{
+    JsrContext context_buf;
+    JsrContext *context = &context_buf;
+
+#if MYDEBUG
+    printf("Starting %s.%s%s\n", cbName(mb->fb.clazz), mb->fb.name, mb->fb.signature);
+#endif
+    /* Initialize the context */
+    memset(context, 0, sizeof(context));
+    context->vcontext = vcontext; /* The verifier context */
+    /* Allow up to MAX_CODE_SIZE instructions.  */
+    context->codeRef = (CodeRef *)malloc(MAX_CODE_SIZE * sizeof(CodeRef));
+    context->codeRefEnd = context->codeRef;
+    /* Id (for debugging) of last subroutine structure created */
+    context->scontext_id = 0;   
+    /* Keep a list of all subroutines, so that we can easily free() them */
+    context->allSubrContexts = NULL;
+    /* Make it easy to go from inumber to all CodeRef's that have that inumber*/
+    context->mapping = (CodeRef **)calloc(vcontext->instruction_count, 
+                                          sizeof(CodeRef **));
+
+    /* Fill in context->codeRef with this routine.  In line all subroutine
+     * calls, and delete all unreachable code */
+    rewriteOneSubroutine(context, NULL);
+
+    /* Modify mb->code and mb->code_length for the new code */
+    fixupCode(context);
+
+    /* Update the exception table */
+    if (mb->exception_table_length != 0) { 
+        fixupExceptionHandlers(context);
+    }
+
+    /* Update the line number table */
+    if (mb->line_number_table_length != 0) { 
+        fixupLineNumberTable(context);
+    }
+
+    /* Update the local variable table */
+    if (mb->localvar_table_length != 0) { 
+        fixupVariableTable(context);
+    }
+
+    /* Clean up */
+    free(context->codeRef);
+    free(context->mapping);
+
+    /* Free all the subroutine contexts that we created */
+    while (context->allSubrContexts != NULL) { 
+        SubrContext *this = context->allSubrContexts;
+        SubrContext *next = this->next;
+        free(this);
+        context->allSubrContexts = next;
+    }
+}
+
+static void
+rewriteOneSubroutine(JsrContext *context, SubrContext *subroutine)
+{ 
+    context_type *vcontext = context->vcontext;
+    int depth = subroutine ? subroutine->depth : 0;
+    instruction_data_type *idata = vcontext->instruction_data;
+    int instruction_count = vcontext->instruction_count;
+    CodeRef **mapping = context->mapping;
+
+    instruction_data_type *this_idata;
+    int inumber;
+    int count = 0;
+    CodeRef *retOpcode = NULL;
+    
+
+    for (    inumber = 0, this_idata = idata;
+             inumber < instruction_count;
+             inumber++, this_idata++) { 
+        if (    (this_idata->or_flags & FLAG_REACHED) 
+            &&  (this_idata->register_info.mask_count == depth)
+            &&  ((depth == 0) 
+                     || matchSubroutine(context, this_idata, subroutine))) { 
+            
+            /* We have an instruction that is part of this subroutine */
+
+            CodeRef *codeRef = context->codeRefEnd++;
+#if MYDEBUG
+            printf("\t%d:\t%d (%d)\t%s (%d)\n", 
+                   (codeRef - context->codeRef), /* new instruction index */
+                   inumber, (subroutine ? subroutine->id : 0),
+                   (this_idata->opcode == 256 
+                         ? "invokeinit" : opnames[this_idata->opcode]),
+                   this_idata->offset);
+#endif
+            codeRef->inumber = inumber;
+            codeRef->subroutine = subroutine;
+            codeRef->flags = CRF_NORMAL;
+            codeRef->next = mapping[inumber]; /* Add to inumber mapping */
+            mapping[inumber] = codeRef;
+
+            count++;
+
+            if (count == 1 && depth > 0) { 
+                /* This is the first instruction included as part of the
+                 * subroutine call.  If it's the target of the jsr that got
+                 * us here, then we can just "ignore" the jsr.  
+                 * Otherwise, we have to convert the 'jsr' into a 'goto'
+                 */
+                CodeRef *caller = subroutine->caller;
+                if (inumber != idata[caller->inumber].operand.i) { 
+                    caller->flags = CRF_JSR_TARGETED_GOTO;
+                }
+            }
+
+            switch(this_idata->opcode) { 
+                case opc_jsr: case opc_jsr_w: 
+                    if (this_idata->operand2.i == UNKNOWN_RET_INSTRUCTION) { 
+                        /* We're calling a subroutine that doesn't return.
+                         * The verifier has already made sure that the
+                         * subroutine doesn't have a deeper depth.
+                         * We turn the JSR into a goto */
+                        codeRef->flags = CRF_JSR_SIMPLE_GOTO;
+                    } else { 
+                        SubrContext *newSubr = malloc(sizeof(SubrContext));
+
+                        /* In rare cases, we'll have to change this in the
+                         * subroutine code */
+                        codeRef->flags = CRF_SKIP;
+
+                        /* Create a new subroutine, and inline it */
+                        newSubr->id = ++context->scontext_id;
+                        newSubr->caller = codeRef;
+                        newSubr->target = this_idata->operand.i;
+                        newSubr->depth = depth + 1;
+                        newSubr->nextInstruction = NULL; /* unknown for now */
+                        newSubr->parent = subroutine;
+                        /* Add this to the list of all subroutine contexts */
+                        newSubr->next = context->allSubrContexts;
+                        context->allSubrContexts = newSubr;
+                        /* Generate the code for this subroutine */
+                        rewriteOneSubroutine(context, newSubr);
+                    }
+                    break;
+
+                case opc_ret:
+                    if (retOpcode != NULL) { 
+                        /* There should only be one per subroutine */
+                        panic("Multiple return opcodes??");
+                    } else if (depth == 0) { 
+                        /* We're not in a subroutine */
+                        panic("Ret at depth = 0");
+                    }
+                    retOpcode = codeRef;
+                    /* Flags are set at the end of the loop, below */
+                    break;
+
+                case opc_astore: 
+                    /* We discard any astore's that move a return address
+                     * from the stack to a register. 
+                     */
+                    if (GET_ITEM_TYPE(this_idata->stack_info.stack->item) 
+                                        == ITEM_ReturnAddress) {
+                        codeRef->flags = CRF_SKIP; 
+                    } 
+                    break;
+
+                default: 
+                    /* Nothing to do */
+                    break;
+            }
+        }
+    }
+    if (depth > 0) { 
+        subroutine->nextInstruction = context->codeRefEnd;
+        if (retOpcode != NULL) { 
+            /* If the last instruction wasn't a 'ret', then we need to
+             * convert the 'ret' into a 'goto'.
+             */
+            if (context->codeRefEnd == retOpcode + 1) { 
+                retOpcode->flags = CRF_SKIP;
+            } else { 
+                retOpcode->flags = CRF_RET_SIMPLE_GOTO;
+            }
+        }
+    }
+}
+
+
+static void
+fixupCode(JsrContext *context) 
+{
+    context_type *vcontext = context->vcontext;
+    instruction_data_type *idata = vcontext->instruction_data;
+    struct methodblock *mb = vcontext->mb;
+    unsigned char *oldCode = mb->code;
+    CodeRef *codeRefEnd = context->codeRefEnd;
+
+    unsigned char *newCode;
+    CodeRef *codeRef;
+    int pc;
+    long newCodeLength;
+
+    /* Assign offsets to each instruction. */
+#if MYDEBUG
+    printf("Assigning offsets\n");
+#endif
+    for (pc = 0, codeRef = context->codeRef; codeRef < codeRefEnd; codeRef++) {
+        instruction_data_type *this_idata = &idata[codeRef->inumber];
+        opcode_type opcode = this_idata->opcode;
+        
+        codeRef->offset = pc;
+
+#if MYDEBUG
+        printf("\t%d:\t%d\tpc=%d\t%s (%d) %s\n", 
+               (codeRef - context->codeRef), 
+               (this_idata - vcontext->instruction_data), 
+               pc, 
+               (this_idata->opcode == 256 
+                    ? "invokeinit" : opnames[this_idata->opcode]),
+               this_idata->offset,
+               ((codeRef->flags == CRF_SKIP) ? " XX" : "")
+               );
+#endif
+        
+        /* Now increment the pc, depending on the instruction */
+        if (codeRef->flags == CRF_SKIP) { 
+            /* do nothing */
+        } else if (opcode == opc_tableswitch || opcode == opc_lookupswitch) {
+            /* This mysterious calculation works. 
+             * The first term increments pc and then rounds it up to a
+             * multiple of 4.   The second term is the size of the word-aligned
+             * values.
+             */
+            pc = ((pc + 1 + 3) & ~3) + ((this_idata->length - 1) & ~3);
+        } else if (opcode == opc_ret) { 
+            /* We must be turning it into an opc_goto */
+            pc += 3;
+        } else { 
+            pc += this_idata->length;
+        }
+    }
+
+    /* Create a new code object */
+    newCode = (unsigned char *)malloc(pc);
+    newCodeLength = pc;
+
+#if MYDEBUG
+    printf("Creating code of length %d\n", pc);
+#endif
+
+    for (codeRef = context->codeRef; codeRef < codeRefEnd; codeRef++) {
+        if (codeRef->flags != CRF_SKIP) { 
+            instruction_data_type *this_idata = &idata[codeRef->inumber];
+            opcode_type opcode = this_idata->opcode;
+            int pc = codeRef->offset;
+            unsigned char *source = &oldCode[this_idata->offset];
+            unsigned char *target = &newCode[pc];
+            
+#if MYDEBUG
+            printf("\t%d:\t%d\tpc=%d\t%s (%d) \n", 
+                   (codeRef - context->codeRef), 
+                   (this_idata - vcontext->instruction_data), 
+                   pc, 
+                   (this_idata->opcode == 256 
+                         ? "invokeinit" : opnames[this_idata->opcode]),
+                   this_idata->offset
+                   );
+#endif
+            
+            switch(opcode) { 
+                case opc_ifeq: case opc_ifne: case opc_iflt: 
+                case opc_ifge: case opc_ifgt: case opc_ifle:
+                case opc_ifnull: case opc_ifnonnull:
+                case opc_if_icmpeq: case opc_if_icmpne: case opc_if_icmplt: 
+                case opc_if_icmpge: case opc_if_icmpgt: case opc_if_icmple:
+                case opc_if_acmpeq: case opc_if_acmpne: 
+                case opc_goto: case opc_goto_w:
+                    target[0] = source[0];
+                    updateTarget(context, this_idata->operand.i, 
+                                 codeRef->subroutine, 
+                                 target + 1, pc, this_idata->length - 1);
+                    break;
+                
+                case opc_jsr: case opc_jsr_w: 
+                    target[0] = opc_goto;
+                    if (codeRef->flags == CRF_JSR_SIMPLE_GOTO) { 
+                        updateTarget(context, this_idata->operand.i, 
+                                     codeRef->subroutine, 
+                                     target + 1, pc, this_idata->length - 1);
+                    } else if (codeRef->flags == CRF_JSR_TARGETED_GOTO) { 
+                        updateTarget(context, this_idata->operand.i, 
+                                     codeRef[1].subroutine, 
+                                     target + 1, pc, this_idata->length - 1);
+                    } else { 
+                        panic("Shouldn't have anything referring to jsr");
+                    }
+                    break;
+
+                case opc_ret:
+                    if (codeRef->flags & CRF_RET_SIMPLE_GOTO) { 
+                        int gotoTarget = 
+                            codeRef->subroutine->nextInstruction->offset;
+                        target[0] = opc_goto;
+                        target[1] = (gotoTarget - pc) >> 8;
+                        target[2] = (gotoTarget - pc);
+                    } else { 
+                        panic("Shouldn't have anything referring to ret");
+                    }
+                    break;
+
+                default:
+                    memcpy(target, source, this_idata->length);
+                    break;
+
+
+                case opc_tableswitch: 
+                case opc_lookupswitch: {
+                    int *successors = this_idata->operand.ip;
+                    int keys = successors[0] - 1; /* don't include default */
+                    SubrContext *subroutine = codeRef->subroutine;
+                    int i;
+                    
+                    long *targetPtr, *sourcePtr;
+                    target[0] = source[0];
+                    target[1] = target[2] = target[3] = 0; /* clear alignment */
+                    
+                    targetPtr = (long *)UCALIGN(target + 1);
+                    sourcePtr = (long *)UCALIGN(source + 1);
+                    
+                    /* Update the default target */
+                    updateTarget(context, successors[1], subroutine, 
+                                 targetPtr, pc, 4);
+                    if (opcode == opc_tableswitch) { 
+                        targetPtr[1] = sourcePtr[1]; /* low */
+                        targetPtr[2] = sourcePtr[2]; /* high */
+                        for (i = 0; i < keys; i++) { 
+                            updateTarget(context, successors[2 + i], subroutine,
+                                         &targetPtr[3 + i], pc, 4);
+                        }
+                    } else { 
+                        targetPtr[1] = sourcePtr[1]; /* pairs */ 
+                        for (i = 0; i < keys; i++) { 
+                            targetPtr[2 + (i << 1)] = sourcePtr[2 + (i << 1)];
+                            updateTarget(context, successors[2 + i], subroutine,
+                                         &targetPtr[3 + (i << 1)], pc, 4);
+                        }
+                    }
+                    break;
+
+                }
+            }
+        }
+    }
+    mb->code = newCode;
+    mb->code_length = newCodeLength;
+}
+
+static void fixupExceptionHandlers(JsrContext *context) { 
+    const int catchFrameSize = sizeof(struct CatchFrame);
+    context_type *vcontext = context->vcontext;
+    struct methodblock *mb = vcontext->mb;
+
+    short *code_data = vcontext->code_data; /* maps offset to inumber */
+    
+    CodeRef *codeRefEnd = context->codeRefEnd;
+        
+    /* Structure to hold new catch frames */
+    struct CatchFrame *catchFrames = malloc(catchFrameSize * MAX_CODE_SIZE);
+    struct CatchFrame *currentCatchFrame = catchFrames;
+
+    CodeRef *hRef, *instRef;
+    unsigned long i;
+
+    /* Look at each exception handler */
+    for (i = 0; i < mb->exception_table_length; i++) { 
+        struct CatchFrame *this_handler = &mb->exception_table[i];
+        int start_inumber   = code_data[this_handler->start_pc];
+        int end_inumber     = code_data[this_handler->end_pc];
+        int handler_inumber = code_data[this_handler->handler_pc];
+            
+        /* First instruction that maps to the specified handler */
+        for (hRef = context->mapping[handler_inumber]
+                   ; hRef != NULL; hRef = hRef->next) {
+            /* Find all instructions that go to this handler. */
+            bool_t wasMatch = FALSE;
+            for (instRef = context->codeRef; instRef < codeRefEnd; instRef++) {
+                if (instRef->flags != CRF_SKIP) { 
+                    bool_t thisMatch = instRef->inumber >= start_inumber
+                                    && instRef->inumber < end_inumber
+                                    && subroutineGoto(context, 
+                                                      instRef->subroutine,
+                                                      hRef->subroutine);
+                    if (thisMatch && !wasMatch) { 
+                        /* Start a new catch frame */
+                        memcpy(currentCatchFrame, this_handler, catchFrameSize);
+                        currentCatchFrame->handler_pc = hRef->offset;
+                        currentCatchFrame->start_pc = instRef->offset;
+                        wasMatch = TRUE;
+                    } else if (wasMatch && !thisMatch) { 
+                        currentCatchFrame->end_pc = instRef->offset;
+                        currentCatchFrame++;
+                        wasMatch = FALSE;
+                    }
+                }
+            }
+            if (wasMatch) { 
+                /* We end the code still in the catch frame */
+                currentCatchFrame->end_pc = mb->code_length;
+                currentCatchFrame++;
+            }
+        }
+    }
+    /* free(mb->exception_table); */
+    mb->exception_table_length = currentCatchFrame - catchFrames;
+    mb->exception_table = realloc(catchFrames, 
+                             (char *)currentCatchFrame - (char *)catchFrames);
+
+}
+
+static void fixupLineNumberTable(JsrContext *context) {
+    context_type *vcontext = context->vcontext;
+    struct methodblock *mb = vcontext->mb;
+    int tableLength = mb->line_number_table_length;
+
+    instruction_data_type *idata = vcontext->instruction_data;
+    instruction_data_type *last_idata = &idata[vcontext->instruction_count - 1];
+    int oldCodeLength = last_idata->offset + last_idata->length;
+    struct lineno *lineTable = malloc(sizeof(struct lineno) * MAX_CODE_SIZE);
+    struct lineno *currentLineTableEntry = lineTable;
+    unsigned long *mapTable = calloc(sizeof(short *), oldCodeLength);
+    CodeRef *codeRefEnd = context->codeRefEnd;
+    CodeRef *codeRef;
+    int i, currentLineNumber;
+
+    { 
+        unsigned long startPC, endPC, line, pc;
+
+        for (i = 0; i < tableLength - 1; i++) { 
+            startPC = mb->line_number_table[i].pc;
+            endPC   = mb->line_number_table[i + 1].pc;
+            line    = mb->line_number_table[i].line_number;
+            for (pc = startPC; pc < endPC; pc++) { 
+                mapTable[pc] = line;
+            }
+        }
+        startPC = mb->line_number_table[tableLength - 1].pc;
+        endPC = oldCodeLength;
+        line = mb->line_number_table[tableLength - 1].line_number;
+        for (pc = startPC; pc < endPC; pc++) { 
+            mapTable[pc] = line;
+        }
+    }
+
+    currentLineNumber = -1;
+    for (codeRef = context->codeRef; codeRef < codeRefEnd; codeRef++) {
+        if (codeRef->flags != CRF_SKIP) { 
+            instruction_data_type *this_idata = &idata[codeRef->inumber];
+            int thisLineNumber = mapTable[this_idata->offset];
+            if (thisLineNumber != currentLineNumber) { 
+                currentLineTableEntry->line_number = thisLineNumber;
+                currentLineTableEntry->pc = codeRef->offset;
+                currentLineTableEntry++;
+                currentLineNumber = thisLineNumber;
+            }
+        }
+    }
+    
+    free(mapTable);
+    mb->line_number_table = realloc(lineTable, 
+                                    (char *)currentLineTableEntry - 
+                                    (char *)lineTable);
+    mb->line_number_table_length = currentLineTableEntry - lineTable;
+}
+
+
+static void fixupVariableTable(JsrContext *context) { 
+    context_type *vcontext = context->vcontext;
+    struct methodblock *mb = context->vcontext->mb;
+    instruction_data_type *idata = vcontext->instruction_data;
+    CodeRef *codeRefEnd = context->codeRefEnd;
+    CodeRef *codeRef;
+    unsigned long i;
+
+    struct localvar *localVars = 
+        malloc(sizeof(struct localvar) * MAX_CODE_SIZE);
+    struct localvar *currentLocalVar = localVars;
+
+    for (i = 0; i < mb->localvar_table_length; i++) { 
+        struct localvar *oldEntry = &mb->localvar_table[i];
+        int startPC = oldEntry->pc0;
+        int endPC = startPC + oldEntry->length; /* inclusive! */
+            
+        bool_t was_matching = FALSE;
+
+        for (codeRef = context->codeRef; codeRef < codeRefEnd; codeRef++) {
+            if (codeRef->flags != CRF_SKIP) { 
+                instruction_data_type *this_idata = &idata[codeRef->inumber];
+                bool_t is_matching = this_idata->offset >= startPC 
+                                  && this_idata->offset <= endPC;
+                if (!was_matching && is_matching) { 
+                    memcpy(currentLocalVar, oldEntry, sizeof(struct localvar));
+                    currentLocalVar->pc0 = codeRef->offset;
+                    was_matching = TRUE;
+                } else if (was_matching && !is_matching) { 
+                    currentLocalVar->length = 
+                        codeRef[-1].offset - currentLocalVar->pc0;
+                    currentLocalVar++;
+                    was_matching = FALSE;
+                }
+            }
+        }
+        if (was_matching) { 
+            currentLocalVar->length = 
+                codeRefEnd[-1].offset - currentLocalVar->pc0;
+            currentLocalVar++;
+        }
+    }
+                
+    /* free(mb->localvar_table); */
+    mb->localvar_table_length = currentLocalVar - localVars;
+    mb->localvar_table = realloc(localVars, 
+                                 (char *)currentLocalVar - (char *)localVars);
+}
+
+
+static void
+updateTarget(JsrContext *context, int inumber, 
+             SubrContext* subroutine, void* target, int offset, int size)
+{
+    CodeRef *codeRef;
+    for (codeRef = context->mapping[inumber];
+             codeRef != NULL;
+             codeRef = codeRef->next) { 
+        if (subroutineGoto(context, subroutine, codeRef->subroutine)) { 
+            int value = codeRef->offset - offset;
+            unsigned char *t = target;
+            if (size == 2) { 
+                t[0] = value >> 8;
+                t[1] = value;
+            } else if (size == 4) { 
+                t[0] = value >> 24;
+                t[1] = value >> 16;
+                t[2] = value >> 8;
+                t[3] = value;
+            } else { 
+                panic("Bad value passed for size");
+            }
+            return;
+        }
+    }
+    panic("Cannot find value for updateTarget");
+}
+
+
+
+static bool_t 
+subroutineGoto(JsrContext *context, SubrContext *from, SubrContext *to)
+{ 
+    if (to == NULL || to == from) { 
+        return TRUE;
+    } else if (from == NULL || to->depth >= from->depth) {
+        return FALSE;
+    } else { 
+        do { from = from->parent; } while (from->depth > to->depth);
+        return from == to;
+    }
+}
+
+
+static bool_t 
+matchSubroutine(JsrContext *context, 
+                instruction_data_type *this_idata, 
+                SubrContext *subroutine)
+{
+    int depth = subroutine->depth;
+    int i;
+    
+    for (i = depth - 1; i >= 0; --i) { 
+        if (this_idata->register_info.masks[i].entry != subroutine->target) { 
+            return FALSE;
+        }
+        subroutine = subroutine->parent;
+    }
+    return TRUE;
+}
+
diff --git a/MPC.3.5.LINUX/preverifier/jar.c b/MPC.3.5.LINUX/preverifier/jar.c
new file mode 100644 (file)
index 0000000..216c49f
--- /dev/null
@@ -0,0 +1,727 @@
+/*
+ * Copyright (c) 1999 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * This software is the confidential and proprietary information of Sun
+ * Microsystems, Inc. ("Confidential Information").  You shall not
+ * disclose such Confidential Information and shall use it only in
+ * accordance with the terms of the license agreement you entered into
+ * with Sun.
+ *
+ * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
+ * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
+ * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
+ * THIS SOFTWARE OR ITS DERIVATIVES.
+ *
+ * Use is subject to license terms.
+ */
+
+/*=========================================================================
+ * SYSTEM:    Verifier 
+ * SUBSYSTEM: JAR class loader.
+ * FILE:      jar.c
+ * OVERVIEW:  Routines for reading contents of a JAR file. The routines
+ *            are optimized to reduce code size and run-time memory
+ *            requirement so that they can run happily on small devices.
+ * AUTHOR:    Frank Yellin, Sun Microsystems, Inc.
+ *            Modifications for JAR support and comments, 
+ *            Tasneem Sayeed, Sun Microsystems 
+ *=======================================================================*/
+
+/*=========================================================================
+ * Include files
+ *=======================================================================*/
+
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <stddef.h>
+#include <assert.h>
+
+#include "oobj.h"
+#include "typedefs.h"
+#include "jar.h"
+#include "jarint.h"
+#include "jartables.h"
+
+/*=========================================================================
+ * Globals and extern declarations
+ *=======================================================================*/
+
+static bool_t decodeDynamicHuffmanTables(inflaterState *state,
+                                        HuffmanCodeTable **lcodesPtr,
+                                        HuffmanCodeTable **dcodesPtr);
+
+static HuffmanCodeTable *makeCodeTable(inflaterState *state,
+                                      unsigned char *codelen,
+                                      unsigned numElems,
+                                      unsigned maxQuickBits);
+
+
+static bool_t inflateHuffman(inflaterState *state, bool_t fixedHuffman);
+static bool_t inflateStored(inflaterState *state);
+
+
+/*===========================================================================
+ * FUNCTION:  inflate
+ * TYPE:      jar file decoding
+ * OVERVIEW   Used for decoding JAR files given the compressed data source,
+ *            compressed data length, buffer to store decompressed data and 
+ *            length of decompression buffer. 
+ *
+ * INTERFACE:
+ *   parameters: compressed data source, compressed data length,
+ *               buffer to store decompressed data, decompression buffer size
+ *   returns:    TRUE if the data was encoded in a supported <method> and the
+ *               size of the decoded data is exactly the same as <decompLen>
+ *               FALSE if an error occurs
+ * NOTE:
+ *    The caller of this method must insure that this function can safely get
+ *    up to INFLATER_EXTRA_BYTES beyond compData + compLen without causing
+ *    any problems.
+ *    The inflater algorithm occasionally reads one more byte than it needs
+ *    to.  But it double checks that it doesn't actually care what's in that
+ *    extra byte.
+ *===========================================================================*/
+
+
+/* Change some definitions so that this compiles nicely, even if it is
+ * compiled as part of something that requires real malloc() and free()
+ */
+#if !JAR_INFLATER_INSIDE_KVM
+#  undef START_TEMPORARY_ROOTS
+#  undef END_TEMPORARY_ROOTS
+#  undef MAKE_TEMPORARY_ROOT
+#  define START_TEMPORARY_ROOTS
+#  define END_TEMPORARY_ROOTS
+#  define MAKE_TEMPORARY_ROOT(x)
+#  define mallocBytes(x) malloc(x)
+#  define freeBytes(x)   if (x == NULL) {} else free(x)
+#else
+#  define freeBytes(x)
+#endif
+
+bool_t 
+inflate(JarCompressedType compData, /* compressed data source */
+       int compLen,            /* length of compressed data */
+       unsigned char *decompData, /* buffer to store decompressed data */
+       int decompLen)          /* length of decompression buffer */
+{
+    inflaterState stateStruct;
+    bool_t result;
+/* Temporarily define state, so that LOAD_IN, LOAD_OUT, etc. macros work */
+#define state (&stateStruct)
+    stateStruct.out = decompData;
+    stateStruct.outStart = decompData;
+    stateStruct.outEnd = decompData + decompLen;
+
+    stateStruct.inFile = compData;
+    stateStruct.inData = 0;
+    stateStruct.inDataSize = 0;
+    stateStruct.inRemaining = compLen + INFLATER_EXTRA_BYTES;
+
+#ifdef JAR_DEBUG_FILE 
+    { 
+       static int length = 0;
+       if (length == 0) {
+           struct stat stat_buffer;
+           stat(JAR_DEBUG_FILE, &stat_buffer);
+           length = stat_buffer.st_size;;
+       }
+       if (length == decompLen) {
+           FILE *f = fopen(JAR_DEBUG_FILE, "rb");
+           state->jarDebugBytes = malloc(length);
+           fseek(f, 0, SEEK_SET);
+           fread(state->jarDebugBytes, sizeof(char), length, f);
+           fclose(f);
+       } else { 
+           state->jarDebugBytes = NULL;
+       }
+    }
+#endif
+
+    for(;;) {
+       int type;
+       DECLARE_IN_VARIABLES
+
+       LOAD_IN;
+       NEEDBITS(3);
+       type = NEXTBITS(3);
+       DUMPBITS(3);
+       STORE_IN;
+
+       switch (type >> 1) {
+           default:
+           case BTYPE_INVALID:
+               ziperr("Invalid BTYPE");
+               result = FALSE;
+               break;
+
+           case BTYPE_NO_COMPRESSION:
+               result = inflateStored(state);
+               break;
+
+           case BTYPE_FIXED_HUFFMAN:
+               result = inflateHuffman(state, TRUE);
+               break;
+
+           case BTYPE_DYNA_HUFFMAN:
+               START_TEMPORARY_ROOTS
+                  result = inflateHuffman(state, FALSE);
+               END_TEMPORARY_ROOTS
+               break;
+       }
+
+       if (!result || (type & 1)) { 
+           break;
+       }
+    }
+
+    if (state->inRemaining + (state->inDataSize >> 3) != INFLATER_EXTRA_BYTES) { 
+       ziperr("Error on the input bits");
+       result = FALSE;
+    } else if (state->out != state->outEnd) {
+       ziperr("Error on the output bits");
+       result = FALSE;
+    }
+
+#ifdef JAR_DEBUG_FILE
+    if (state->jarDebugBytes != NULL) { 
+       free(state->jarDebugBytes);
+    }
+#endif
+
+    /* Remove temporary definition of state defined above */
+#undef state
+
+    return result;
+}
+
+
+/*=========================================================================
+ * FUNCTION:  inflateStored 
+ * TYPE:      Huffman code Decoding helper function
+ * OVERVIEW:  Used by inflate() for BTYPE_NO_COMPRESSION.
+ * INTERFACE:
+ *   parameters: inflaterState: *state 
+ *              
+ *   returns:    boolean type 
+ *=======================================================================*/
+static bool_t
+inflateStored(inflaterState *state)
+{
+    DECLARE_IN_VARIABLES
+    DECLARE_OUT_VARIABLES
+    unsigned len, nlen;
+
+    LOAD_IN; LOAD_OUT;
+
+    DUMPBITS(inDataSize & 7);  /* move to byte boundary */
+    NEEDBITS(32)
+    len = NEXTBITS(16);
+    DUMPBITS(16);
+    nlen = NEXTBITS(16);
+    DUMPBITS(16);
+
+    ASSERT(inDataSize == 0);
+
+    if (len + nlen != 0xFFFF) {
+       ziperr("Bad length field");
+       return FALSE;
+    } else if ((unsigned) inRemaining < len) {
+       ziperr("Input overflow");
+       return FALSE;
+    } else if (out + len > state->outEnd) {
+       ziperr("Output overflow");
+       return FALSE;
+    } else {
+       if (!COPY_N_BYTES(out, len)) { 
+           ziperr("Bad Read");
+           return FALSE;
+       }
+       inRemaining -= len;
+       out += len;
+    }
+    STORE_IN;
+    STORE_OUT;
+    return TRUE;
+}
+
+
+/*=========================================================================
+ * FUNCTION:  inflateHuffman
+ * TYPE:      Huffman code Decoding helper function
+ * OVERVIEW:  Used by inflate() for BTYPE_FIXED_HUFFMAN and BTYPE_DYNA_HUFFMAN.
+ * INTERFACE:
+ *   parameters: inflaterState: *state 
+ *               bool_t: fixedHuffman
+ *              
+ *   returns:    boolean type 
+ *=======================================================================*/
+static bool_t
+inflateHuffman(inflaterState *state, bool_t fixedHuffman)
+{
+    DECLARE_IN_VARIABLES
+    DECLARE_OUT_VARIABLES
+    unsigned char *outStart = state->outStart;
+    unsigned char *outEnd = state->outEnd;   
+
+    bool_t noerror = FALSE;
+    unsigned int quickDataSize = 0, quickDistanceSize = 0;
+    unsigned int code, litxlen;
+    HuffmanCodeTable *lcodes, *dcodes;
+
+    if (!fixedHuffman) {
+       if (!decodeDynamicHuffmanTables(state, &lcodes, &dcodes)) {
+           return FALSE;
+       }
+       quickDataSize = lcodes->h.quickBits;
+       quickDistanceSize = dcodes->h.quickBits;
+    }
+
+    LOAD_IN;
+    LOAD_OUT;
+
+    for (;;) {
+       if (inRemaining < 0) { 
+           goto done_loop;
+       }
+       NEEDBITS(MAX_BITS + MAX_ZIP_EXTRA_LENGTH_BITS);
+
+       if (fixedHuffman) {
+           /*   literal (hex)
+             * 0x100 - 0x117   7   0.0000.00   -  0.0101.11
+            *     0 -    8f   8   0.0110.000  -  1.0111.111
+            *   118 -   11f   8   1.1000.000  -  1.1000.111
+            *    90 -    ff   9   1.1001.0000 -  1.1111.1111
+            */
+
+           /* Get 9 bits, and reverse them. */
+           code = NEXTBITS(9);
+           code = REVERSE_9BITS(code);
+           if (code <  0x060) {
+               /* A 7-bit code  */
+               DUMPBITS(7);
+               litxlen = 0x100 + (code >> 2);
+           } else if (code < 0x190) {
+               DUMPBITS(8);
+               litxlen = (code >> 1) + ((code < 0x180) ? (0x000 - 0x030)
+                                                       : (0x118 - 0x0c0));
+           } else {
+               DUMPBITS(9);
+               litxlen = 0x90 + code - 0x190;
+           }
+       } else {
+           GET_HUFFMAN_ENTRY(lcodes, quickDataSize, litxlen, done_loop);
+       }
+
+       if (litxlen <= 255) {
+           if (out < outEnd) {
+#ifdef JAR_DEBUG_FILE
+               if (state->jarDebugBytes && state->jarDebugBytes[out - outStart] != litxlen) {
+                   ziperr("Dragon single byte");
+               }
+#endif
+               *out++ = litxlen;
+           } else {
+               goto done_loop;
+           }
+       } else if (litxlen == 256) {               /* end of block */
+           noerror = TRUE;
+           goto done_loop;
+       } else if (litxlen > 285) {
+           ziperr("Invalid literal/length");
+           goto done_loop;
+       } else {
+           unsigned int n = litxlen - LITXLEN_BASE;
+           unsigned int length = ll_length_base[n];
+           unsigned int moreBits = ll_extra_bits[n];
+           unsigned int d0, distance;
+
+           /* The NEEDBITS(..) above took care of this */
+           length += NEXTBITS(moreBits);
+           DUMPBITS(moreBits);
+
+           NEEDBITS(MAX_BITS);
+           if (fixedHuffman) {
+               d0 = REVERSE_5BITS(NEXTBITS(5));
+               DUMPBITS(5);
+           } else {
+               GET_HUFFMAN_ENTRY(dcodes, quickDistanceSize, d0, done_loop);
+           }
+
+           if (d0 > MAX_ZIP_DISTANCE_CODE) {
+               ziperr("Bad distance code");
+               goto done_loop;
+           }
+
+           NEEDBITS(MAX_ZIP_EXTRA_DISTANCE_BITS)
+           distance = dist_base[d0];
+           moreBits = dist_extra_bits[d0];
+           distance += NEXTBITS(moreBits);
+           DUMPBITS(moreBits);
+
+           if (out - distance < outStart) {
+               ziperr("copy underflow");
+               goto done_loop;
+           } else if (out + length > outEnd) {
+               ziperr("Output overflow");
+               goto done_loop;
+           } else {
+               unsigned char *prev = out - distance;
+               unsigned char *end  = out + length;
+               while (out != end) {
+#ifdef JAR_DEBUG_FILE              
+                   if (state->jarDebugBytes 
+                       && state->jarDebugBytes[out - outStart] != *prev) {
+                       ziperr("Dragon copy error");
+                   }
+#endif
+                   *out++ = *prev++;
+               }
+           }
+       }
+    }
+
+ done_loop:
+    STORE_IN;
+    STORE_OUT;
+
+    if (!JAR_INFLATER_INSIDE_KVM && !fixedHuffman) { 
+       freeBytes(lcodes);
+       freeBytes(dcodes);
+    }
+    return noerror;
+}
+
+
+/*=========================================================================
+ * FUNCTION:  decodeDynamicHuffmanTables
+ * TYPE:      Huffman code Decoding
+ * OVERVIEW:  Used by inflateHuffman() for decoding dynamic Huffman tables. 
+ * INTERFACE:
+ *   parameters: inflaterState: *state
+ *               HuffmanCodeTable: **lcodesPtr
+ *               HuffmanCodeTable: **dcodesPtr
+ * 
+ *   returns:    TRUE if successful in decoding or
+ *               FALSE if an error occurs
+ *=======================================================================*/
+
+static bool_t
+decodeDynamicHuffmanTables(inflaterState *state,
+                          HuffmanCodeTable **lcodesPtr,
+                          HuffmanCodeTable **dcodesPtr) {
+    DECLARE_IN_VARIABLES
+
+    HuffmanCodeTable *ccodes = NULL;
+    HuffmanCodeTable *lcodes = NULL;
+    HuffmanCodeTable *dcodes = NULL;
+
+    int hlit, hdist, hclen;
+    int i;
+    unsigned int quickBits;
+    unsigned char codelen[286 + 32];
+    unsigned char *codePtr, *endCodePtr;
+
+    LOAD_IN;
+
+    /* 5 Bits: HLIT, # of Literal/Length codes - 257 (257 - 286) */
+    /* 5 Bits: HDIST, # of Distance codes - 1        (1 - 32) */
+    /* 4 Bits: HCLEN, # of Code Length codes - 4     (4 - 19) */
+    NEEDBITS(14);
+    hlit = 257 + NEXTBITS(5);
+    DUMPBITS(5);
+    hdist = 1 + NEXTBITS(5);
+    DUMPBITS(5);
+    hclen = 4 + NEXTBITS(4);
+    DUMPBITS(4);
+
+    /*
+     * (HCLEN + 4) x 3 bits: code lengths for the code length
+     *  alphabet given just above, in the order: 16, 17, 18,
+     *  0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
+     *
+     *  These code lengths are interpreted as 3-bit integers
+     *  (0-7); as above, a code length of 0 means the
+     *  corresponding symbol (literal/length or distance code
+     *  length) is not used.
+     */
+    memset(codelen, 0x0, 19);
+    for (i=0; i<hclen; i++) {
+       NEEDBITS(3);            /* 3, plus 7 below */
+       if (inRemaining < 0) { 
+           goto error;
+       }
+       codelen[(int)ccode_idx[i]] = (unsigned char) NEXTBITS(3);
+       DUMPBITS(3);
+    }
+
+    ccodes = makeCodeTable(state, codelen, 19, MAX_QUICK_CXD);
+    if (ccodes == NULL) {
+       goto error;
+    }
+    quickBits = ccodes->h.quickBits;
+
+    /*
+     * HLIT + 257 code lengths for the literal/length alphabet,
+     * encoded using the code length Huffman code.
+     *
+     * HDIST + 1 code lengths for the distance alphabet,
+     * encoded using the code length Huffman code.
+     *
+     * The code length repeat codes can cross from HLIT + 257 to the
+     * HDIST + 1 code lengths.  In other words, all code lengths form
+     * a single sequence of HLIT + HDIST + 258 values.
+     */
+
+    memset(codelen, 0x0, sizeof(codelen));
+    for (   codePtr = codelen, endCodePtr = codePtr + hlit + hdist;
+           codePtr < endCodePtr; ) {
+       int val;
+
+       if (inRemaining < 0) { 
+           goto error;
+       }
+
+       NEEDBITS(MAX_BITS + 7); /* 7 is max repeat bits below */
+       GET_HUFFMAN_ENTRY(ccodes, quickBits, val, error);
+
+       /*
+        *  0 - 15: Represent code lengths of 0 - 15
+        *      16: Copy the previous code length 3 - 6 times.
+         *          3 + (2 bits of length)
+        *      17: Repeat a code length of 0 for 3 - 10 times.
+        *          3 + (3 bits of length)
+        *      18: Repeat a code length of 0 for 11 - 138 times
+        *          11 + (7 bits of length)
+        */
+       if (val <= 15) {
+           *codePtr++ = val;
+       } else if (val <= 18) {
+           unsigned repeat  = (val == 18) ? 11 : 3;
+           unsigned bits    = (val == 18) ? 7 : (val - 14);
+
+           repeat += NEXTBITS(bits); /* The NEEDBITS is above */
+           DUMPBITS(bits);
+
+           if (codePtr + repeat > endCodePtr) {
+               ziperr("Bad repeat code");
+           }
+
+           if (val == 16) {
+               if (codePtr == codelen) {
+                   ziperr("Bad repeat code");
+                   goto error;
+               }
+               memset(codePtr, codePtr[-1], repeat);
+           } else {
+               /* The values have already been set to zero, above, so
+                * we don't have to do anything */
+           }
+           codePtr += repeat;
+       } else {
+           ziperr("Bad code-length code");
+           goto error;
+       }
+    }
+
+
+    lcodes = makeCodeTable(state, codelen, hlit, MAX_QUICK_LXL);
+    if (lcodes == NULL) {
+        goto error;
+    }
+
+    dcodes = makeCodeTable(state, codelen + hlit, hdist, MAX_QUICK_CXD);
+    if (dcodes == NULL) {
+        goto error;
+    }
+
+    *lcodesPtr = lcodes;
+    *dcodesPtr = dcodes;
+    STORE_IN;
+    if (!JAR_INFLATER_INSIDE_KVM) { 
+       freeBytes(ccodes);
+    }
+    return TRUE;
+
+error:
+    if (!JAR_INFLATER_INSIDE_KVM) { 
+       freeBytes(ccodes);
+       freeBytes(dcodes);
+       freeBytes(lcodes);
+    }
+    return FALSE;
+}
+
+
+/*=========================================================================
+ * FUNCTION:  makeCodeTable
+ * TYPE:      Huffman code table creation
+ * INTERFACE:
+ *   parameters: inflaterState 
+ *               code length 
+ *               number of elements of the alphabet 
+ *               maxQuickBits 
+ *   returns:    Huffman code table created if successful or
+ *               NULL if an error occurs
+ *=======================================================================*/
+
+HuffmanCodeTable * makeCodeTable(
+       inflaterState *state,
+        unsigned char *codelen,        /* Code lengths */
+        unsigned numElems,      /* Number of elements of the alphabet */
+        unsigned maxQuickBits)  /* If the length of a code is longer than
+                                 * <maxQuickBits> number of bits, the code is
+                                 * stored in the sequential lookup table
+                                 * instead of the quick lookup array. */
+{
+    unsigned int bitLengthCount[MAX_BITS + 1];
+    unsigned int codes[MAX_BITS + 1];
+    unsigned bits, minCodeLen = 0, maxCodeLen = 0;
+    const unsigned char *endCodeLen = codelen + numElems;
+    unsigned int code, quickMask;
+    unsigned char *p;
+
+    HuffmanCodeTable * table;
+    int mainTableLength, longTableLength, numLongTables;
+    int tableSize;
+    int j;
+
+    unsigned short *nextLongTable;
+
+    /* Count the number of codes for each code length */
+    memset(bitLengthCount, 0, sizeof(bitLengthCount));
+    for (p = codelen; p < endCodeLen; p++) { 
+       bitLengthCount[*p]++;
+    }
+
+    if (bitLengthCount[0] == numElems) {
+       ziperr("Bad code table -- empty");
+        return NULL;
+    }
+
+    /* Find the minimum and maximum.  It's faster to do it in a separate
+     * loop that goes 1..MAX_BITS, than in the above loop that looks at
+     * every code element */
+    code = minCodeLen = maxCodeLen = 0;
+    for (bits = 1; bits <= MAX_BITS; bits++) {
+       codes[bits] = code;
+       if (bitLengthCount[bits] != 0) {
+           if (minCodeLen == 0) minCodeLen = bits;
+           maxCodeLen = bits;
+           code += bitLengthCount[bits] << (MAX_BITS - bits);
+       }
+    }
+
+    if (INCLUDEDEBUGCODE) { 
+       if (code != (1 << MAX_BITS)) {
+           code += (1 << (MAX_BITS - maxCodeLen));
+           if (code != (1 << MAX_BITS)) {
+               ziperr("Unexpected bit codes");
+           }
+       }
+    }
+
+    /* Calculate the size of the code table and allocate it. */
+    if (maxCodeLen <= maxQuickBits) {
+       /* We don't need any subtables.  We may even be able to get
+        * away with a table smaller than maxCodeLen 
+        */
+       maxQuickBits = maxCodeLen;
+       mainTableLength = (1 << maxCodeLen);
+       numLongTables = longTableLength = 0;
+    } else {
+       mainTableLength = (1 << maxQuickBits);
+       numLongTables = (1 << MAX_BITS) - codes[maxQuickBits + 1];
+       numLongTables = numLongTables >> (MAX_BITS - maxQuickBits);
+       longTableLength = 1 << (maxCodeLen - maxQuickBits);
+    }
+    ASSERT(mainTableLength == 1 << maxQuickBits);
+    tableSize = sizeof(HuffmanCodeTableHeader) 
+             + (mainTableLength + numLongTables * longTableLength) *
+                      sizeof(table->entries[0]);
+    table = (HuffmanCodeTable*)mallocBytes(tableSize);
+    nextLongTable = &table->entries[mainTableLength];
+    MAKE_TEMPORARY_ROOT(table);
+
+    memset(table, 0, tableSize);
+
+    table->h.maxCodeLen   = maxCodeLen;
+    table->h.quickBits    = maxQuickBits;
+
+    quickMask = (1 << maxQuickBits) - 1;
+
+    for (p = codelen; p < endCodeLen; p++) {
+       unsigned short huff;
+       bits = *p;
+       if (bits == 0) {
+           continue;
+       }
+       /* Get the next code of the current length */
+       code = codes[bits];
+       codes[bits] += 1 << (MAX_BITS - bits);
+       code = REVERSE_15BITS(code);
+       huff = ((p - codelen) << 4) + bits;
+       if (bits <= maxQuickBits) { 
+           unsigned stride = 1 << bits;
+           for (j = code; j < mainTableLength; j += stride) {
+               table->entries[j] = huff;
+           } 
+       } else {
+           unsigned short *thisLongTable;
+           unsigned stride = 1 << (bits - maxQuickBits);
+           unsigned int prefixCode = code & quickMask;
+           unsigned int suffixCode = code >> maxQuickBits;
+           if (table->entries[prefixCode] == 0) {
+               /* This in the first long code with the indicated prefix. 
+                * Create a pointer to the subtable */
+               long delta = (char *)nextLongTable - (char *)table;
+               table->entries[prefixCode] = (unsigned short)(HUFFINFO_LONG_MASK | delta);
+               thisLongTable = nextLongTable;
+               nextLongTable += longTableLength;
+           } else {
+               long delta = table->entries[prefixCode] & ~HUFFINFO_LONG_MASK;
+               thisLongTable = (unsigned short *)((char *)table + delta);
+           }
+           for (j = suffixCode; j < longTableLength; j += stride) {
+               thisLongTable[j] = huff;
+           }
+       }
+       if (INCLUDEDEBUGCODE && inflateVerbose > 0) {
+           putchar(' ');
+           
+           for (j = 15; j >= 0; j--) {
+               char c = (j >= (signed)bits) ? ' '
+                   : (code & (1 << j)) ? '1' : '0';
+               putchar(c);
+           }
+           fprintf(stdout, 
+                   "   Char = %02x, Code = %4x\n", (p - codelen), code);
+       }
+
+    }
+    ASSERT(nextLongTable == &table->entries[mainTableLength + numLongTables * longTableLength]);
+
+    return table;
+}
+
+
+#if INCLUDEDEBUGCODE
+
+/*=========================================================================
+ * FUNCTION:  ziperr 
+ * TYPE:      zip error processing function
+ * OVERVIEW:  Used by inflate() and other functions for zip error processing. 
+ * INTERFACE:
+ *   parameters: const char *message 
+ *              
+ *   returns:    nothing 
+ *=======================================================================*/
+static void
+ziperr(const char *message) {
+    fprintf(stderr, "Zip Error: %s\n", message);
+}
+
+#endif
diff --git a/MPC.3.5.LINUX/preverifier/jar.h b/MPC.3.5.LINUX/preverifier/jar.h
new file mode 100644 (file)
index 0000000..ce1ad40
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 1999 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * This software is the confidential and proprietary information of Sun
+ * Microsystems, Inc. ("Confidential Information").  You shall not
+ * disclose such Confidential Information and shall use it only in
+ * accordance with the terms of the license agreement you entered into
+ * with Sun.
+ *
+ * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
+ * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
+ * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
+ * THIS SOFTWARE OR ITS DERIVATIVES.
+ *
+ * Use is subject to license terms.
+ */
+
+/*=========================================================================
+ * SYSTEM:    KVM
+ * SUBSYSTEM: JAR file reader.
+ * FILE:      jar.h
+ * OVERVIEW:  Public header file for the JAR file reader module. 
+ *            The JAR DataStream API is used by the Pre-verifier for loading
+ *           JAR files.
+ * AUTHOR:    Tasneem Sayeed
+ *=======================================================================*/
+
+#ifndef _JAR_H_
+#define _JAR_H_
+
+#include "typedefs.h"
+#include "stdio.h"
+#include "sys/types.h"
+#include "stddef.h"
+
+
+/* 
+ * Debug flag for JAR support
+ */
+#define JAR_DEBUG 0 
+
+/*=========================================================================
+ * JAR file reader defines and macros
+ *=======================================================================*/
+
+/* 
+ * Supported compression types
+ */
+#define STORED     0
+#define DEFLATED    8
+
+#define MAX_BITS 15    /* Maximum number of codes in Huffman Code Table */
+
+/*
+ * Header sizes including signatures
+ */
+#define LOCHDRSIZ 30
+#define CENHDRSIZ 46
+#define ENDHDRSIZ 22
+
+/*
+ * Header field access macros
+ */
+#define CH(b, n) ((long)(((unsigned char *)(b))[n]))
+#define SH(b, n) ((long)(CH(b, n) | (CH(b, n+1) << 8)))
+#define LG(b, n) ((long)(SH(b, n) | (SH(b, n+2) << 16)))
+
+#define GETSIG(b) LG(b, 0)         /* signature */
+
+#define LOCSIG (('P' << 0) + ('K' << 8) + (3 << 16) + (4 << 24))
+#define CENSIG (('P' << 0) + ('K' << 8) + (1 << 16) + (2 << 24))
+#define ENDSIG (('P' << 0) + ('K' << 8) + (5 << 16) + (6 << 24))
+
+#define freeBytes(x) if (x == NULL) {} else free(x)
+
+
+/*
+ * Macros for getting local file header (LOC) fields
+ */
+#define LOCVER(b) SH(b, 4)         /* version needed to extract */
+#define LOCFLG(b) SH(b, 6)         /* encrypt flags */
+#define LOCHOW(b) SH(b, 8)         /* compression method */
+#define LOCTIM(b) LG(b, 10)        /* modification time */
+#define LOCCRC(b) LG(b, 14)        /* uncompressed file crc-32 value */
+#define LOCSIZ(b) LG(b, 18)        /* compressed size */
+#define LOCLEN(b) LG(b, 22)        /* uncompressed size */
+#define LOCNAM(b) SH(b, 26)        /* filename size */
+#define LOCEXT(b) SH(b, 28)        /* extra field size */
+
+/*
+ * Macros for getting central directory header (CEN) fields
+ */
+#define CENVEM(b) SH(b, 4)         /* version made by */
+#define CENVER(b) SH(b, 6)         /* version needed to extract */
+#define CENFLG(b) SH(b, 8)         /* general purpose bit flags */
+#define CENHOW(b) SH(b, 10)        /* compression method */
+#define CENTIM(b) LG(b, 12)        /* file modification time (DOS format) */
+#define CENCRC(b) LG(b, 16)        /* crc of uncompressed data */
+#define CENSIZ(b) LG(b, 20)        /* compressed size */
+#define CENLEN(b) LG(b, 24)        /* uncompressed size */
+#define CENNAM(b) SH(b, 28)        /* length of filename */
+#define CENEXT(b) SH(b, 30)        /* length of extra field */
+#define CENCOM(b) SH(b, 32)        /* file comment length */
+#define CENDSK(b) SH(b, 34)        /* disk number start */
+#define CENATT(b) SH(b, 36)        /* internal file attributes */
+#define CENATX(b) LG(b, 38)        /* external file attributes */
+#define CENOFF(b) LG(b, 42)        /* offset of local header */
+
+/*
+ * Macros for getting end of central directory header (END) fields
+ */
+#define ENDSUB(b) SH(b, 8)         /* number of entries on this disk */
+#define ENDTOT(b) SH(b, 10)        /* total number of entries */
+#define ENDSIZ(b) LG(b, 12)        /* central directory size */
+#define ENDOFF(b) LG(b, 16)        /* central directory offset */
+#define ENDCOM(b) SH(b, 20)        /* size of zip file comment */
+
+/*=========================================================================
+ * Macros for Huffman Codes used by the JAR file reader
+ *=======================================================================*/
+
+/*
+ * This is the algorithm for decoding Huffman-encoded
+ * data.
+ *
+ *     loop (until end of block code recognized)
+ *        decode literal/length value from input stream
+ *        if value < 256
+ *           copy value (literal byte) to output stream
+ *        otherwise
+ *           if value = end of block (256)
+ *              break from loop
+ *           otherwise (value = 257..285)
+ *              decode distance from input stream
+ *
+ *              move backwards distance bytes in the output
+ *              stream, and copy length bytes from this
+ *              position to the output stream.
+ *     end loop
+ */
+#define BTYPE_NO_COMPRESSION 0x00  
+#define BTYPE_FIXED_HUFFMAN  0x01  /* Fixed Huffman Code */
+#define BTYPE_DYNA_HUFFMAN   0x02  /* Dynamic Huffman code */
+#define BTYPE_INVALID        0x03  /* Invalid code */
+
+#define LITXLEN_BASE 257
+
+
+/*=========================================================================
+ * JAR DataStream API for reading and writing to/from JAR files
+ *=======================================================================*/
+
+#define JAR_READ 1             /* Mode for reading from a JAR data stream */
+#define JAR_WRITE 2            /* Mode for writing from a JAR data stream */
+#define JAR_RESOURCE 1         /* type of resource (see JAR_DataStream) */
+
+/*=========================================================================
+ * JAR Data Stream structure
+ *=======================================================================*/
+typedef struct JAR_DataStream {
+       unsigned char *data;    /* data stream for reading/writing */
+       int type;               /* indicates type of resource */
+       int dataLen;            /* length of data stream */
+       int dataIndex;          /* current position for reading */
+       int mode;               /* mode for reading or writing */
+                               /* mode must be either JAR_READ or JAR_WRITE */
+} JAR_DataStream;
+
+typedef struct JAR_DataStream* JAR_DataStreamPtr;
+
+/*=========================================================================
+ * Forward declarations for JAR DataStream API
+ *=======================================================================*/
+int JAR_ReadBytes(JAR_DataStream *ds, char *buf, int len);
+int JAR_WriteBytes(JAR_DataStream *ds, char *buf, int len);
+int JAR_SkipBytes(JAR_DataStream *ds, int len);
+
+/*=========================================================================
+ * Forward declarations for JAR file reader
+ *=======================================================================*/
+
+
+
+typedef FILE *JarCompressedType;
+/*
+typedef const unsigned char *JarCompressedType;
+*/
+
+bool_t inflate(JarCompressedType data, int compLen,
+              unsigned char *decompData, int decompLen);
+
+/* Any caller to inflate must ensure that it is safe to read at least
+ * this many bytes beyond compData + compLen
+ */
+#define INFLATER_EXTRA_BYTES 4
+
+
+/* 
+ * Indicates whether JAR inflater is executed from KVM or a stand-alone 
+ * program.
+ */
+#define JAR_INFLATER_INSIDE_KVM 0
+
+#endif /* _JAR_H_ */
diff --git a/MPC.3.5.LINUX/preverifier/jar_support.c b/MPC.3.5.LINUX/preverifier/jar_support.c
new file mode 100644 (file)
index 0000000..7748dde
--- /dev/null
@@ -0,0 +1,1347 @@
+/* * @(#)jar_support.c  1.24 01/07/19
+ *
+ * Copyright 1997, 1998 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+/*=========================================================================
+ * SYSTEM:    Verifier
+ * SUBSYSTEM: JAR support routines for the verifier.
+ * FILE:      jar_support.c
+ * OVERVIEW:  JAR support routines for verifying class files from a ZIP or
+ *            JAR file.
+ *            Note that the JAR file reader used is based on the KVM
+ *            implementation with some modifications.
+ * AUTHOR:    Tasneem Sayeed, Java Consumer Technologies, Sun Microsystems
+ *=======================================================================*/
+
+/*=========================================================================
+ * Include files
+ *=======================================================================*/
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <string.h>
+
+#include "sys_api.h"
+#include "path_md.h"
+#include "path.h"
+#include "oobj.h"
+#include "jar.h"
+#include "convert_md.h"
+
+#include <string.h>
+
+#ifdef WIN32
+#include <process.h>
+#endif
+/*=========================================================================
+ * Globals and extern declarations
+ *=======================================================================*/
+
+//extern int errno;
+char str_buffer[STRINGBUFFERSIZE];   /*  shared string buffer */
+bool_t JARfile = FALSE;    /* if true, indicates that output is in a
+                                                  JAR file */
+extern bool_t tmpDirExists;
+                           /* if true, indicates that a temp dir exists
+                              with classes to be verified */
+char *zipFileName = NULL;  /* stores name of the zip file */
+extern char tmp_dir[32];   /* temporary directory for storing
+                                                  verified classes */
+extern char *output_dir;   /* output directory */
+
+char manifestfile[1024];   /* used for saving the JAR manifest file name */
+
+extern void VerifyFile(register char *fn);
+
+
+/*=========================================================================
+ * FUNCTION:      isJARfile
+ * OVERVIEW:      Determines if the given file is a JAR or ZIP file.
+ *                Returns true if the suffix ends with ".jar" or ".zip".
+ * INTERFACE:
+ *   parameters:  fn:      name of the JAR file
+ *                length:  length of data, in bytes
+ *   returns:     boolean type
+ *=======================================================================*/
+bool_t
+isJARfile (char *fn, int length)
+{
+    char *suffix;
+
+
+    if (length >= 4 &&
+       (( suffix = fn + length - 4)[0] == '.') &&
+         ((( _toupper(suffix[1]) == 'Z') &&
+          ( _toupper(suffix[2]) == 'I') &&
+          ( _toupper(suffix[3]) == 'P')) ||
+         (( _toupper(suffix[1]) == 'J') &&
+          ( _toupper(suffix[2]) == 'A') &&
+          ( _toupper(suffix[3]) == 'R')))) {
+        return TRUE;
+    } else {
+        return FALSE;
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      isManifestfile
+ * OVERVIEW:      Determines if the given file is a JAR Manifest file.
+ *                Returns true if the file ends with "MANIFEST.MF".
+ * INTERFACE:
+ *   parameters:  fn:      name of the JAR manifest file
+ *                length:  length of data, in bytes
+ *   returns:     boolean type
+ *=======================================================================*/
+bool_t
+isManifestfile (char *fn, int length)
+{
+    if ((length >= 11) &&
+       (strcmp(fn + length - 11, "MANIFEST.MF") == 0)) {
+        return TRUE;
+    } else {
+        return FALSE;
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      ensure_tmpdir_exists
+ * OVERVIEW:      Validates to ensure that the tmpdir exists using the
+ *                system-specific directory delimiters.
+ *
+ * INTERFACE:
+ *   parameters:  char* dir name
+ *   returns:     nothing
+ *=======================================================================*/
+void ensure_tmpdir_exists(char *dir)
+{
+    struct stat stat_buf;
+    char *parent;
+    char *q;
+    if (dir[0] == 0) {
+        return;
+    }
+    parent = strdup(dir);
+    q = strrchr(parent, (char)LOCAL_DIR_SEPARATOR);
+    if (q) {
+        *q = 0;
+        ensure_tmpdir_exists(parent);
+    }
+    if (stat(dir, &stat_buf) < 0) {
+        if (JAR_DEBUG && verbose) {
+            jio_fprintf(stderr, "Creating output directory [%s]\n", dir);
+        }
+#ifdef WIN32
+        mkdir(dir);
+#endif
+#ifdef UNIX
+        mkdir(dir, 0755);
+#endif
+    }
+    free(parent);
+}
+
+
+/*=========================================================================
+ * FUNCTION:      JARname2fname
+ * OVERVIEW:      Converts JAR name to the system-specific file name with
+ *                the correct directory delimiters.
+ *
+ * INTERFACE:
+ *   parameters:  char* source JAR name
+ *                char* dest file name
+ *                int size
+ *   returns:     char*
+ *=======================================================================*/
+char*
+JARname2fname(char *src, char *dst, int size) {
+    char *buf = dst;
+    for (; (--size > 0) && (*src != '\0') ; src++, dst++) {
+    if (*src == '/') {
+        *dst = (char)LOCAL_DIR_SEPARATOR;
+    }  else {
+        *dst = *src;
+    }
+    }
+    dst++;
+    *dst = '\0';
+    return buf;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      getZipEntry
+ * OVERVIEW:      Converts a zip file to a Zip entry type.
+ * INTERFACE:
+ *   parameters:  zipFile:      name of the JAR file
+ *                len:          length of data, in bytes
+ *   returns:     zip entry type
+ *=======================================================================*/
+zip_t *
+getZipEntry (char *zipFile, int len) {
+    zip_t * zipEntry = NULL;  /* for processing errors */
+
+    if (JAR_DEBUG && verbose)
+        jio_fprintf(stderr,
+            "getZipEntry: JAR file [%s] Size [%d]\n", zipFile, len);
+
+    /* create the zip entry for loading the ZIP file */
+    zipEntry = (zip_t *) sysMalloc(sizeof(zip_t) + len);
+    if (zipEntry == NULL) {
+        fprintf(stderr, "getZipEntry: Out of memory\n");
+        exit(1);
+    }
+
+    memcpy(zipEntry->name, zipFile, len);
+
+    zipEntry->name[len] = '\0';
+
+    if (JAR_DEBUG && verbose)
+        jio_fprintf(stderr, "getZipEntry: Zip Entry Name [%s]\n", zipEntry->name);
+
+
+    zipEntry->type = '\0';
+    return zipEntry;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      findJARDirectories
+ * OVERVIEW:      Helper function used for JAR loading for locating JAR
+ *                directories.
+ *                It returns TRUE if it is successful in locating the
+ *                JAR directory headers, false otherwise.
+ *                If successful,
+ *                entry->jar.locpos is set to the position of the first
+ *                local header.
+ *                entry->jar.cenpos is set to the position of the first
+ *                central header.
+ *
+ *                Note that *locpos pointer is the logical "0" of the file.
+ *                All offsets extracted need to have this value added to them.
+ *
+ * INTERFACE:
+ *   parameters:  entry:     zipFileEntry
+ *                statbuf:   pointer to the stat buffer
+ *   returns:     boolean type
+ *=======================================================================*/
+
+bool_t
+findJARDirectories(zip_t *entry, struct stat *statbuf)
+{
+    bool_t result = FALSE;
+    long length = statbuf->st_size;
+    long position, minPosition;
+    char *bp;
+    FILE *file;
+
+    char *buffer = str_buffer;
+    unsigned const int bufferSize = STRINGBUFFERSIZE;
+
+    /* Calculate the smallest possible position for the end header.  It
+     * can be at most 0xFFFF + ENDHDRSIZ bytes from the end of the file, but
+     * the file must also have a local header and a central header
+     */
+    minPosition = length - (0xFFFF + ENDHDRSIZ);
+    if (minPosition < LOCHDRSIZ + CENHDRSIZ) {
+        minPosition = LOCHDRSIZ + CENHDRSIZ;
+    }
+
+    file = fopen(entry->name, "rb");
+    if (file == NULL) {
+        goto done;
+    }
+
+    /* Read in the last ENDHDRSIZ bytes into the buffer.  99% of the time,
+     * the file won't have a comment, and this is the only read we'll need */
+    if (   (fseek(file, -ENDHDRSIZ, SEEK_END) < 0)
+        || (fread(buffer, sizeof(char), ENDHDRSIZ, file) != ENDHDRSIZ)) {
+        goto done;
+    }
+    /* Get the position in the file stored into buffer[0] */
+    position = length - ENDHDRSIZ;  /* Position in file of buffer[0] */
+    bp = buffer;            /* Where to start looking */
+    for (;;) {
+        /* "buffer" contains a block of data from the file, starting at
+         * position "position" in the file.
+         * We investigate whether   position + (bp - buffer)  is the start
+         * of the end header in the zip file.  This file position is at
+         * position bp in the buffer.
+         */
+        /* Use simplified version of Knuth Morris Pratt search algorithm. */
+        switch(bp[0]) {
+            case '\006':   /* The header must start at least 3 bytes back */
+                bp -= 3; break;
+            case '\005':   /* The header must start at least 2 bytes back  */
+                bp -= 2; break;
+            case 'K':      /* The header must start at least 1 byte back  */
+                bp -= 1; break;
+            case 'P':      /* Either this is the header, or the header must
+                            * start at least 4  back
+                            */
+                if (bp[1] == 'K' && bp[2] == 5 && bp[3] == 6) {
+                    int endpos = position + (bp - buffer);
+                    if (endpos + ENDHDRSIZ + ENDCOM(bp) == length) {
+                        unsigned long cenpos = endpos - ENDSIZ(bp);
+                        unsigned long locpos = cenpos - ENDOFF(bp);
+                        entry->jar.cenpos = cenpos;
+                        entry->jar.locpos = locpos;
+                        result = TRUE;
+                        goto done;
+                    }
+                }
+            /* FALL THROUGH */
+            default:      /* This char isn't in the header signature, so
+                           * the header must start at least four chars back */
+                bp -= 4;
+        }
+
+        if (bp < buffer) {
+            /* We've moved outside our window into the file.  We must
+             * move the window backwards */
+            int count = position - minPosition; /* Bytes left in file */
+            if (count == 0) {
+                /* Nothing left to read.  Time to give up */
+                goto done;
+            } else {
+                /* up to ((bp - buffer) + ENDHDRSIZ) bytes in the buffer might
+                 * still be part of the end header, so the most bytes we can
+                 * actually read are
+                 *      bufferSize - ((bp - buffer) + ENDHDRSIZE).
+                 */
+                int available = (bufferSize - ENDHDRSIZ) + (buffer - bp);
+                if (count > available) {
+                    count = available;
+                }
+            }
+            /* Back up, while keeping our virtual position the same */
+            position -= count;
+            bp += count;
+            memmove(buffer + count, buffer, bufferSize - count);
+            if (   (fseek(file, position, SEEK_SET) < 0)
+              || (fread(buffer, sizeof(char), count, file) != (unsigned)count)) {
+                goto done;
+            }
+        }
+    } /* end of for loop */
+
+ done:
+    if (file != NULL) {
+        fclose(file);
+    }
+    return result;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      jarCRC32
+ * OVERVIEW:      Returns the CRC of an array of bytes, using the same
+ *                algorithm as used by the JAR reader.
+ * INTERFACE:
+ *   parameters:  data:     pointer to the array of bytes
+ *                length:   length of data, in bytes
+ *   returns:     CRC
+ *=======================================================================*/
+
+static unsigned long
+jarCRC32(unsigned char *data, unsigned long length) {
+    unsigned long crc = 0xFFFFFFFF;
+    unsigned int j;
+    for ( ; length > 0; length--, data++) {
+        crc ^= *data;
+        for (j = 8; j > 0; --j) {
+        crc = (crc & 1) ? ((crc >> 1) ^ 0xedb88320) : (crc >> 1);
+        }
+    }
+    return ~crc;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      loadJARfile()
+ * TYPE:          load JAR file
+ * OVERVIEW:      Internal function used by openClassfileInternal().
+ *
+ *  This function reads the specified class file from the JAR file.  The
+ *  result is returned as a JAR_DataStream*.  NULL is returned if it
+ *  cannot find the file, or there is some error.
+ *
+ * INTERFACE:
+ *   parameters:  entry:    zip file entry for the JAR file
+ *                filename: class file name to search for
+ *   returns:     JAR_DataStream* for saving the JAR file info, or NULL.
+ *=======================================================================*/
+
+JAR_DataStreamPtr
+loadJARfile(zip_t *entry, const char* filename)
+{
+    JAR_DataStreamPtr jdstream = NULL; /* result on error */
+    unsigned int filenameLength;
+    unsigned int nameLength;
+    char buff[BUFSIZ];
+    char *UTFfilename = &buff[0];
+    char *p = str_buffer;   /* temporary storage */
+    int offset;
+    char *fname = NULL;
+    FILE *file = fopen(entry->name, "rb");
+    if (file == NULL) {
+        goto done;
+    }
+
+    if (JAR_DEBUG && verbose)
+        jio_fprintf(stderr,
+               "loadJARfile: Opening zip file %s to search for [%s]\n",
+                entry->name, filename);
+
+    /* add the .class to the filename */
+
+
+    if (JAR_DEBUG && verbose)
+        jio_fprintf(stderr,
+        "loadJARfile: Adding '.class' to %s size [%d]\n", filename, strlen(filename));
+
+    /* Conversion for Japanese filenames */
+    native2utf8(filename, UTFfilename, BUFSIZ);
+
+    /* allocate fname large enough to hold .class + '\0' terminator */
+    fname = (char *)malloc(strlen(UTFfilename) + 6 + 1);
+    sprintf(fname, "%s.class", UTFfilename);
+    filenameLength=strlen(fname);
+    fname[filenameLength]='\0';
+
+    if (JAR_DEBUG && verbose)
+        jio_fprintf(stderr,
+        "loadJARfile: Searching for filename [%s]\n", fname);
+
+    /* Go to the start of the central headers */
+    offset = entry->jar.cenpos;
+    for (;;) {
+
+        if (/* Go to the next central header */
+            (fseek(file, offset, SEEK_SET) < 0)
+            /* Read the bytes */
+        || (fread(p, sizeof(char), CENHDRSIZ, file) != CENHDRSIZ)
+            /* Make sure it is a header */
+        || (GETSIG(p) != CENSIG)) {
+            goto done;
+        }
+
+        /* Get the nameLength */
+        nameLength = CENNAM(p);
+
+
+        if (nameLength == filenameLength) {
+            if (fread(p + CENHDRSIZ, sizeof(char), nameLength, file)
+                     != nameLength) {
+                goto done;
+            }
+            if (memcmp(p + CENHDRSIZ, fname, nameLength) == 0) {
+
+                if (JAR_DEBUG && verbose)
+                    jio_fprintf(stderr, "loadJARfile: Class name found [%s]...\n", fname);
+                break;
+            }
+        }
+
+        /* Set offset to the next central header */
+        offset += CENHDRSIZ + nameLength + CENEXT(p) + CENCOM(p);
+
+    } /* end loop */
+
+    /* p points at the central header for the file */
+    {
+    unsigned long decompLen = CENLEN(p); /* the decompressed length */
+    unsigned long compLen   = CENSIZ(p); /* the compressed length */
+    unsigned long method    = CENHOW(p); /* how it is stored */
+    unsigned long expectedCRC = CENCRC(p); /* expected CRC */
+    unsigned long actualCRC;
+
+    unsigned char *decompData;
+
+    /* Make sure file is not encrypted */
+    if ((CENFLG(p) & 1) == 1) {
+        fprintf(stderr, "Entry is encrypted");
+        goto done;
+    }
+
+
+    jdstream =
+        (JAR_DataStreamPtr)sysMalloc(sizeof(JAR_DataStream) + decompLen);
+    decompData = (unsigned char *)(jdstream + 1);
+
+    if (/* Go to the beginning of the LOC header */
+           (fseek(file, entry->jar.locpos + CENOFF(p), SEEK_SET) < 0)
+        /* Read it */
+        || (fread(p, sizeof(char), LOCHDRSIZ, file) != LOCHDRSIZ)
+        /* Skip over name and extension, if any */
+        || (fseek(file, LOCNAM(p) + LOCEXT(p), SEEK_CUR) < 0)) {
+        goto done;
+    }
+
+    switch (method) {
+        case STORED:
+            if (compLen != decompLen) {
+                return NULL;
+            }
+            fread(decompData, sizeof(char), decompLen, file);
+            break;
+
+        case DEFLATED: {
+            bool_t inflateOK;
+            inflateOK = inflate(file, compLen, decompData, decompLen);
+
+            if (!inflateOK) {
+                sysFree(jdstream);
+                jdstream = NULL;
+            }
+            break;
+        }
+
+        default:
+            sysFree(jdstream);
+            jdstream = NULL;
+        break;
+    }
+
+    actualCRC = jarCRC32(decompData, decompLen);
+    if (actualCRC != expectedCRC) {
+        printf("Unexpected CRC value");
+    }
+
+    done:
+    if (file != NULL) {
+        fclose(file);
+    }
+
+    if (fname != NULL) {
+        sysFree(fname);
+    }
+
+    if (jdstream != NULL) {
+
+        jdstream->type = JAR_RESOURCE;
+        jdstream->data = decompData;
+        jdstream->dataLen = decompLen;
+        jdstream->dataIndex = 0;
+        jdstream->mode = JAR_READ;
+    }
+    return jdstream;
+
+    }
+}
+
+
+/*=========================================================================
+ * FUNCTION:      ReadFromZip()
+ * TYPE:          Reads and verifies ZIP file entries
+ * OVERVIEW:      Internal function used by ProcessInputs() and recurse_dir.
+ *
+ *  This function reads all the Zip entries, and stores them temporarily in
+ *  tmpdir. If the ZIP entry read is a class file, then VerifyFile is invoked
+ *  to verify the class file. Otherwise, the file read is simply copied over
+ *  temporarily to the tmpdir. These are later used for generating a new JAR
+ *  file.
+ *
+ * INTERFACE:
+ *   parameters:  ZipEntry:  name of the zip file entry.
+ *   returns:     nothing
+ *=======================================================================*/
+
+void
+ReadFromZip(zip_t *entry)
+{
+    unsigned int nameLength;
+    char *filename = NULL;
+    char *p = str_buffer;               /* temporary storage */
+    int offset, nextOffset;
+    int fd;
+    int status;
+    JAR_DataStreamPtr jdstream = NULL;
+    struct stat stat_buf;
+    unsigned char *decompData;
+    unsigned long decompLen;     /* the decompressed length */
+
+    FILE *file = fopen(entry->name, "rb");
+    if (file == NULL) {
+        goto done;
+    }
+
+    if (JAR_DEBUG && verbose)
+        jio_fprintf(stderr,
+               "ReadFromZip: Opened zip file to read classes \n");
+
+    /* initialize */
+    memset(manifestfile, 0, 1024);
+
+    /* Go to the start of the central headers */
+    offset = entry->jar.cenpos;
+    for (;;) {
+
+        if (/* Go to the next central header */
+           (fseek(file, offset, SEEK_SET) < 0)
+        /* Read the bytes */
+        || (fread(p, sizeof(char), CENHDRSIZ, file) != CENHDRSIZ)
+        /* Make sure it is a header */
+        || (GETSIG(p) != CENSIG)) {
+            goto done;
+        }
+        /* Get the nameLength */
+        nameLength = CENNAM(p);
+
+        if (fread(p + CENHDRSIZ, sizeof(char), nameLength, file)
+            != nameLength) {
+            goto done;
+        }
+
+
+        /* initialize the filename with nulls every time */
+
+        filename = (char *) sysCalloc(STRINGBUFFERSIZE, nameLength);
+
+        if (filename == NULL) {
+            fprintf(stderr, "ReadFromZip: Out of memory \n");
+            exit(1);
+        }
+
+        memcpy(filename, p + CENHDRSIZ, nameLength);
+
+
+        /* We have to calculate nextOffset now, because VerifyFile bashes
+         * str_buffer
+         */
+        nextOffset = offset + CENHDRSIZ + nameLength + CENEXT(p) + CENCOM(p);
+
+        if (JAR_DEBUG && verbose)
+            jio_fprintf(stderr,
+               "ReadFromZip: filename read %s\n", filename);
+
+        /* extract the .class from the filename */
+        if (nameLength > 6 &&
+            strcmp(filename + nameLength - 6, ".class") == 0) {
+            /* Verify the class file */
+
+            if (JAR_DEBUG && verbose)
+                jio_fprintf(stderr,
+                 "ReadFromZip: Extracted '.class' from %s\n", filename);
+
+            filename[nameLength-6] = 0;
+
+            if (JAR_DEBUG && verbose)
+                jio_fprintf(stderr,
+                 "ReadFromZip: Verifying classfile %s\n", filename);
+
+            /* call VerifyFile to verify the class */
+            VerifyFile(filename);
+        } else {
+            /* Read and copy over the file to tmpdir */
+            /* p points at the central header for the file */
+            unsigned long compLen   = CENSIZ(p); /* the compressed length */
+            unsigned long method    = CENHOW(p); /* how it is stored */
+            unsigned long expectedCRC = CENCRC(p); /* expected CRC */
+            unsigned long actualCRC;
+
+            decompLen = CENLEN(p);
+
+            if (JAR_DEBUG && verbose)
+                jio_fprintf(stderr,
+                  "READFROMZIP: Reading file [%s]...\n", filename);
+
+            /* Make sure file is not encrypted */
+            if ((CENFLG(p) & 1) == 1) {
+                jio_fprintf(stderr, "Entry is encrypted\n");
+                goto done;
+            }
+
+            jdstream =
+                (JAR_DataStreamPtr)sysMalloc(sizeof(JAR_DataStream) + decompLen);
+            decompData = (unsigned char *)(jdstream + 1);
+
+            if (/* Go to the beginning of the LOC header */
+                   (fseek(file, entry->jar.locpos + CENOFF(p), SEEK_SET) < 0)
+                /* Read it */
+                || (fread(p, sizeof(char), LOCHDRSIZ, file) != LOCHDRSIZ)
+                /* Skip over name and extension, if any */
+                || (fseek(file, LOCNAM(p) + LOCEXT(p), SEEK_CUR) < 0)) {
+                goto done;
+            }
+
+            switch (method) {
+                case STORED:
+                    if (compLen != decompLen) {
+                        sysFree(jdstream);
+                        jdstream = NULL;
+                        goto done;
+                    }
+                    fread(decompData, sizeof(char), decompLen, file);
+                    break;
+
+                case DEFLATED: {
+                    bool_t inflateOK;
+                    inflateOK = inflate(file, compLen, decompData, decompLen);
+
+                    if (!inflateOK) {
+                        sysFree(jdstream);
+                        jdstream = NULL;
+                    }
+                    break;
+                }
+
+                default:
+                    sysFree(jdstream);
+                    jdstream = NULL;
+                break;
+            }
+
+            actualCRC = jarCRC32(decompData, decompLen);
+            if (actualCRC != expectedCRC) {
+                jio_fprintf(stderr, "Unexpected CRC value\n");
+            }
+
+            /* create the tempdir if it doesn't already exist */
+            {
+                char fname[1024];     /* file name restored from JAR */
+                char *dir;
+                char *q;
+                char *sfname = fname; /* system-specific file name */
+                char *dname = fname;  /* destination file name */
+
+
+                if (JAR_DEBUG && verbose)
+                    jio_fprintf(stderr,
+                        "Reading filename [%s] from JAR \n", filename);
+
+                sprintf(fname, "%s%c%s", tmp_dir,
+                                         (char) LOCAL_DIR_SEPARATOR,
+                                         filename);
+
+                if (JAR_DEBUG && verbose)
+                    jio_fprintf(stderr,
+                               "Before conversion: fname [%s]  sfname [%s]\n",
+                                fname, sfname);
+
+                /*
+                 * convert JAR name to the system-specific file name
+                 */
+
+                sfname = JARname2fname(fname, dname, strlen(fname)+1);
+
+                if (JAR_DEBUG && verbose)
+                    jio_fprintf(stderr,
+                                "After conversion: Converted [%s] to [%s]\n",
+                                 fname, sfname);
+
+
+                if (JAR_DEBUG && verbose)
+                    jio_fprintf(stderr,
+                      "Preparing to write file [%s]\n", sfname);
+
+                dir = strdup(sfname);
+                q = strrchr(dir, (char)LOCAL_DIR_SEPARATOR);
+                if (q) {
+                    *q = 0;
+                    ensure_tmpdir_exists(dir);
+                }
+                free(dir);
+
+
+                /* Attempt to stat or open only if this is NOT a directory */
+
+                if (!(sfname[strlen(sfname)-1] == (char)LOCAL_DIR_SEPARATOR)) {
+                    if (JAR_DEBUG && verbose)
+                        jio_fprintf(stderr,
+                        "Attempting stat on dir [%s]\n", sfname);
+
+                    status = stat(sfname, &stat_buf);
+
+                    if (JAR_DEBUG && verbose)
+                        jio_fprintf(stderr,
+                        "Status from stat of [%s] is %d\n", sfname, status);
+
+                    /* Attempt to open only if the file does not already exist.
+                     * This is indicated by the stat command returning -1.
+                     * And this is not a directory.
+                     */
+
+                    if ((status < 0) || !(stat_buf.st_mode & S_IFDIR)) {
+
+                        if (JAR_DEBUG && verbose)
+                            jio_fprintf(stderr,
+                                "Opening file [%s]\n", sfname);
+#ifdef UNIX
+                        fd = open(sfname, O_WRONLY | O_CREAT | O_TRUNC , 0644);
+#endif
+
+#ifdef WIN32
+                        fd = open(sfname, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
+#endif
+
+                        if (fd < 0) {
+                            panic("failed to open %s", sfname);
+                        }
+
+                        if (JAR_DEBUG && verbose)
+                            jio_fprintf(stderr,
+                            "Writing file [%s]...\n", sfname);
+
+                        /* write the file to the tmpdir just created */
+                        write(fd, decompData, decompLen);
+
+                        /* check for the JAR Manifest.mf file */
+
+                        if (isManifestfile(sfname, strlen(sfname))) {
+                            /* save it for using it later to create
+                             * the JAR file
+                             */
+                            memcpy(manifestfile, sfname + strlen(tmp_dir), strlen(sfname));
+
+                            if (JAR_DEBUG && verbose)
+                                jio_fprintf(stderr,
+                                            "Saving JAR manifest file [%s]\n",
+                                            manifestfile);
+                        }
+
+                        close(fd);
+                    }
+                }
+            }
+            if (jdstream != NULL) {
+                sysFree(jdstream);
+                jdstream = NULL;
+            }
+        }
+
+        /* Set offset to the next central header */
+        offset = nextOffset;
+        sysFree(filename);
+        filename = NULL;
+    }
+done:
+    if (file != NULL) {
+        fclose(file);
+    }
+
+    if (jdstream != NULL) {
+        jdstream->type = JAR_RESOURCE;
+        jdstream->data = decompData;
+        jdstream->dataLen = decompLen;
+        jdstream->dataIndex = 0;
+        jdstream->mode = JAR_READ;
+    }
+
+    if (filename != NULL)
+        sysFree(filename);
+}
+
+
+/*=========================================================================
+ * FUNCTION:      remove_dir()
+ * TYPE:          Handles removing files from recursive directories
+ * OVERVIEW:      Internal function called by ProcessJARfile().
+ *
+ *  This function reads a directory, searching for either another directory,
+ *  or an individual class name that is to be removed using the remove()
+ *  API call.
+ *
+ * INTERFACE:
+ *   parameters:  dirname   name of the directory entry.
+ *                pkgname   name of the package
+ *   returns:     nothing
+ *=======================================================================*/
+static void remove_dir(char *dirname, char *pkgname)
+{
+    struct dirent *ent;
+    char buf[MAXPACKAGENAME];
+    char pkgbuf[MAXPACKAGENAME];
+    char tmpbuf[MAXPACKAGENAME];
+    char tmppkg[MAXPACKAGENAME];
+    char tmppkgbuf[MAXPACKAGENAME];
+    char *name = NULL;
+    DIR *dir = opendir(dirname);
+    int err = 0;
+    int status;
+
+    /* Initialize the buffers to 0 */
+    memset(buf, 0, sizeof(buf));
+    memset(pkgbuf, 0, sizeof(pkgbuf));
+    memset(tmpbuf, 0, sizeof(tmpbuf));
+    memset(tmppkg, 0, sizeof(tmppkg));
+    memset(tmppkgbuf, 0, sizeof(tmppkgbuf));
+
+    if (dir == NULL) {
+        fprintf(stderr, "Can't open dir %s\n", dirname);
+        exit(1);
+    }
+    for (ent = readdir(dir); ent; ent = readdir(dir)) {
+        struct stat stat_buf;
+        int len;
+        name = ent->d_name;
+
+        if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
+            continue;
+        }
+
+        strcpy(pkgbuf, pkgname);
+        if (pkgname[0] != 0) {
+            /* concatenate '/' to the package name */
+            sprintf(tmppkgbuf, "%s%c", pkgbuf, (char)LOCAL_DIR_SEPARATOR);
+        }
+        if (JAR_DEBUG && verbose)
+            jio_fprintf(stderr,
+               "remove_dir: Reading filename [%s] from directory [%s]\n",
+                        name, dirname);
+
+        /* we just have a class file that needs to be removed */
+
+        len = strlen(name);
+
+        /* append the dirname and name */
+        strcpy(buf, dirname);
+        strcat(buf, name);
+
+
+        status = stat(buf, &stat_buf);
+
+        if ((status == 0) && !(stat_buf.st_mode & S_IFDIR)) {
+            /* remove if this is a file and not a directory */
+
+            if (JAR_DEBUG && verbose)
+                    jio_fprintf(stderr,
+                "remove_dir: Removing file [%s] \n", buf);
+
+            err = remove(buf);
+
+            if (JAR_DEBUG && verbose) {
+                jio_fprintf(stderr,
+                           "remove_dir: remove() returned error %d\n", err);
+            }
+
+        } else {
+            strcat(tmppkgbuf, name);
+            stat(buf, &stat_buf);
+            len = strlen(buf);
+
+            if (stat_buf.st_mode & S_IFDIR) {
+                /* handle the recursive directory found */
+
+                sprintf(tmpbuf, "%s%c", buf, (char)LOCAL_DIR_SEPARATOR);
+
+                if (JAR_DEBUG && verbose)
+                    jio_fprintf(stderr,
+                     "remove_dir: Recursive dir, calling remove_dir [%s,%s]\n",
+                      tmpbuf, tmppkgbuf);
+                remove_dir(tmpbuf, tmppkgbuf);
+                continue;
+            }
+        }
+
+    }
+
+    /* close the directory to free the dirp first */
+    closedir(dir);
+
+
+#ifdef WIN32
+    /* remove the trailing '\' from the directory */
+    {
+        int tmppkglen = strlen(dirname);
+        dirname[tmppkglen-1] = '\0';
+    }
+#endif
+
+    /* Remove the directory by calling rmdir() or remove() API as appropriate */
+
+    sprintf(tmppkg,"%s", dirname);
+
+    if (JAR_DEBUG && verbose)
+        jio_fprintf(stderr,
+                  "remove_dir: Removing [%s]\n", tmppkg);
+
+#ifdef WIN32
+    err = rmdir(tmppkg);
+
+    if (JAR_DEBUG && verbose) {
+        if (err != 0) {
+            jio_fprintf(stderr,
+                     "remove_dir: rmdir(%s) failed with error %d\n",
+                       tmppkg, err);
+        }
+    }
+#endif
+
+#ifdef UNIX
+    err = remove (tmppkg);
+
+    if (JAR_DEBUG && verbose) {
+        if (err != 0) {
+            jio_fprintf(stderr,
+                     "remove_dir: remove(%s) failed with error %d\n",
+                       tmppkg, err);
+        }
+    }
+#endif
+
+}
+/*=========================================================================
+ * FUNCTION:      ProcessJARfile()
+ * TYPE:          Processes ZIP file entries
+ * OVERVIEW:      Internal function called by ProcessInputs().
+ *
+ *  This function processes a JAR file by first creating a zip entry for
+ *  reading JAR directories, then calls ReadFromZip() to read the Zip
+ *  class names and verifies them. It finally creates a new JAR file and
+ *  places all the verified classes into it.
+ *  It returns a boolean type to indicate if a valid JAR file was found
+ *  and the contents of the JAR file were processed without errors.
+ *
+ * INTERFACE:
+ *   parameters:  buf:  JAR file name.
+ *                len:  size of the file
+ *   returns:     boolean type
+ *=======================================================================*/
+bool_t ProcessJARfile(char *buf, int len)  {
+
+    zip_t *zipEntry;
+    struct stat stat_buf;
+    char *fname = NULL;
+    char *buffer = NULL;
+    char *jarName = NULL;
+    char dirdelim = '\0';        /* directory delimiter */
+    int err = 0;
+    int tmpdir_len = 0;
+    int statcode;
+    char tmpdir_buf[MAXPACKAGENAME];
+
+    if (JAR_DEBUG && verbose)
+        jio_fprintf(stderr,
+               "ProcessJARfile: JAR file [%s] Size [%d]\n", buf, len);
+
+    statcode = stat(buf, &stat_buf);
+
+    /* Create the zip entry for searching the JAR directories.
+     * If the zip entry is NULL, it would indicate that we ran
+     * out of memory and would have exited already.
+     */
+
+    zipEntry = getZipEntry (buf, len);
+
+    if (JAR_DEBUG && verbose)
+        jio_fprintf(stderr, "Searching for JAR directories...\n");
+
+
+    /* search for the JAR directories */
+    if (findJARDirectories(zipEntry, &stat_buf)) {
+              /* the JAR directories were found */
+
+        JARfile = TRUE;
+        zipFileName = buf;
+        if (JAR_DEBUG && verbose) {
+            jio_fprintf(stderr,
+                        "ProcessJARfile: JAR directory [%s] found \n",
+                         zipEntry->name);
+        }
+
+        zipEntry->type = 'j';
+
+        /* Read and Verify the classes from the ZIP file */
+
+       if (JAR_DEBUG && verbose)
+           jio_fprintf(stderr, "ProcessJARfile: Verifying Zip class names...\n");
+
+       pushJarFileOntoClassPath(zipEntry);
+
+       ReadFromZip(zipEntry);
+
+       popClassPath();
+
+       /* Ensure that the output_dir also exists or create it if it
+        * does not already exist
+        */
+
+       if (output_dir != NULL) {
+           char *dir = strdup(output_dir);
+
+           if (JAR_DEBUG && verbose)
+               jio_fprintf(stderr, "ProcessJARfile: Checking if output [%s] exists\n",
+                   output_dir);
+           ensure_dir_exists(dir);
+           ensure_dir_writable(dir);
+           free(dir);
+       }
+
+       /* Create a JAR file only if the input parameter was a JAR file,
+        * the tmp_dir was created with classes verified and an output
+        * dir also exists.
+        */
+
+       if (JARfile && tmpDirExists && tmp_dir && output_dir) {
+           const char *p;
+
+           /* Allocate enough space to hold the JAR name */
+           jarName = (char *)sysCalloc(len+32, len);
+
+           if (jarName == NULL) {
+               fprintf(stderr, "ProcessJARfile: Out of memory");
+               exit(1);
+           }
+
+           if (JAR_DEBUG && verbose)
+               jio_fprintf(stderr, "ProcessJARfile: Creating JAR file of verified classes...\n");
+           /* search for the last '/' to get the actual JAR file name */
+           for (p = buf+len; ;) {
+               --p;
+
+               if (*p == '/' || *p == '\\') {
+                   dirdelim = *p;
+                   memcpy(jarName, p+1, (len-1)-(p-buf));
+                   if (JAR_DEBUG && verbose)
+                       jio_fprintf(stderr, "ProcessJARfile: JAR file [%s]\n", jarName);
+                   break;
+               }
+               if (p == buf) {
+                   /* no directories in path, get the individual JAR name */
+                   strncpy(jarName, buf, len);
+                   if (JAR_DEBUG && verbose)
+                       jio_fprintf(stderr, "ProcessJARfile: JAR filename [%s]\n", jarName);
+                   break;
+               }
+           }
+
+           /* move the verified classes into a JAR file */
+
+           /* Be sure to allocate enough space to hold the sprintfs below */
+           fname = (char *)malloc(strlen(output_dir)+ len+32);
+
+           if (fname == NULL) {
+               fprintf(stderr, "ProcessJARfile: Out of memory");
+               exit(1);
+           }
+
+           if (dirdelim != '\0') {
+               sprintf(fname, "%s%c%s", output_dir,
+               dirdelim, jarName);
+           } else {
+               sprintf(fname, "%s%c%s", output_dir,
+                       (char)LOCAL_DIR_SEPARATOR, jarName);
+           }
+
+           /* Be sure to allocate enough space to hold the sprintfs below */
+           /* The size here must be adjusted anytime the buffer used in the
+            * sprintfs is extended.
+            */
+
+           buffer = (char *)malloc(strlen(output_dir)+strlen(fname) +
+                    strlen(tmp_dir) + strlen(manifestfile) +
+                    strlen(tmp_dir) + 51);
+           if (buffer == NULL) {
+               fprintf(stderr, "ProcessJARfile: Out of memory");
+               exit(1);
+           }
+
+           if (verbose) {
+                   if (isManifestfile(manifestfile, strlen(manifestfile))) {
+                       /* use existing manifest if one exists */
+                       sprintf(buffer, "jar -cvfm \"%s\" %s%c%s -C %s .",
+                                       fname, tmp_dir,
+                                       (char)LOCAL_DIR_SEPARATOR,
+                                       manifestfile, tmp_dir);
+
+                   } else {
+
+               sprintf(buffer, "jar -cvfM \"%s\" -C %s .",
+                                        fname, tmp_dir);
+
+                   }
+           } else {
+               /* Run jar in non-verbose mode, and log errors in a file */
+
+                   if (isManifestfile(manifestfile, strlen(manifestfile))) {
+                       /* use existing manifest if one exists */
+
+#ifdef UNIX
+                       /* create JAR with existing manifest file */
+                       /* Redirect errors and stdout to jarlog.txt */
+                        sprintf(buffer,
+                          "sh -c \"jar -cfm \\\"%s\\\" %s%c%s -C %s .\" > \"%s%c\"%s",
+                          fname, tmp_dir, (char)LOCAL_DIR_SEPARATOR,
+                          manifestfile, tmp_dir, output_dir,
+                          (char)LOCAL_DIR_SEPARATOR,"jarlog.txt 2>&1");
+
+#else
+                       sprintf(buffer,
+                          "jar -cfm \"%s\" %s%c%s -C %s . ",
+                          fname, tmp_dir, (char)LOCAL_DIR_SEPARATOR,
+                          manifestfile, tmp_dir);
+#endif
+                   } else {
+#ifdef UNIX
+                       /* create JAR with no manifest since none exists */
+                       /* Redirect errors and stdout to jarlog.txt */
+                       sprintf(buffer,
+                           "sh -c \"jar -cfM \\\"%s\\\" -C %s .\" > \"%s%c\"%s",
+                           fname, tmp_dir, output_dir,
+                           (char)LOCAL_DIR_SEPARATOR,"jarlog.txt 2>&1");
+#else
+                       sprintf(buffer,
+                           "jar -cfM \"%s\" -C %s . ",
+                           fname, tmp_dir);
+#endif
+
+                   }
+           }
+           if (verbose) {
+               jio_fprintf(stderr, "Executing command [%s]\n", buffer);
+           }
+
+#ifdef WIN32
+           /* system() function does not return the exit code of the child
+            * process under Windows98.
+            * The documentation states:
+            *   "If command is not NULL, system returns the value that is
+            *    returned by the command interpreter.".
+            * Thus it is probably a bug within 'command.com'.
+            * Note that _spawnlp correctly returns the exit status of the
+            * new process.
+            */
+           if (verbose) {
+               err = _spawnlp(_P_WAIT, "jar", "jar", buffer+4, NULL);
+               if (err != 0) {
+                   fprintf(stderr, "%s\n", buffer);
+                   perror("Error");
+               }
+           } else {
+               int cstderr;
+               int cstdout;
+               FILE *logfile;
+
+               /* Save stderr and stdout*/
+               if ((cstderr = dup(_fileno(stderr))) == -1) {
+                   fprintf(stderr, "Cannot copy dup stderr\n");
+               }
+               if ((cstdout = dup(_fileno(stdout))) == -1) {
+                   fprintf(stderr, "Cannot copy dup stdout\n");
+               }
+
+               sprintf(tmpdir_buf, "%s\\%s", output_dir, "jarlog.txt");
+               if ((logfile = fopen(tmpdir_buf, "w")) == NULL) {
+                   fprintf(stderr, "Cannot create output file\n");
+                   exit(1);
+               }
+
+               if (_dup2(_fileno(logfile), _fileno(stderr)) == -1) {
+                   fprintf(stderr, "dup2 failed for stderr\n");
+                   exit(1);
+               }
+
+               if (_dup2(_fileno(logfile), _fileno(stdout)) == -1) {
+                   fprintf(stderr, "dup2 failed for stdout\n");
+                   exit(1);
+               }
+
+               err = _spawnlp(_P_WAIT, "jar", "jar", buffer+4, NULL);
+               if (err != 0) {
+                   fprintf(stderr, "%s\n", buffer);
+                   perror("Error");
+               }
+
+               fflush(stderr);
+               fflush(stdout);
+               fclose(logfile);
+
+               /* Restore stderr and stdout */
+               _dup2(cstderr, _fileno(stderr));
+               _dup2(cstdout, _fileno(stdout));
+
+               memset(tmpdir_buf,0,sizeof(tmpdir_buf));
+           }
+#else
+           err = system(buffer);
+#endif
+
+           if (err != 0) {
+               /* jar file creation failed - return back the error */
+               fprintf(stderr, "JAR file creation failed with error %d\n", err);
+               if (!verbose)
+                   fprintf(stderr,
+"The preverified classes if any are in %s. See jar log of errors in %s%c%s \n",
+                  tmp_dir, output_dir, (char)LOCAL_DIR_SEPARATOR, "jarlog.txt");
+           } else {
+               if (!verbose) {
+                   /* remove the jar log file if no error occurred */
+                   char *jarfn = NULL;
+                   int error;
+
+                   jarfn = (char *)malloc(strlen(output_dir)+10+1+1);
+
+                   if (jarfn == NULL) {
+                       fprintf(stderr, "ProcessJARfile: Out of memory");
+                           exit(1);
+                   }
+
+                   sprintf(jarfn, "%s%c%s", output_dir,
+                           (char)LOCAL_DIR_SEPARATOR, "jarlog.txt");
+                   error = remove(jarfn);    /* remove the file */
+
+                   if (jarfn != NULL)
+                       sysFree(jarfn);
+               }
+
+               /* prepare to remove the tmp directory */
+               /* copy the tmp directory name to a buffer */
+               strcpy(tmpdir_buf, tmp_dir);
+               tmpdir_len = strlen(tmp_dir);
+
+               /* Append dir separator if it does not yet exist */
+               if (tmpdir_buf[tmpdir_len - 1] != LOCAL_DIR_SEPARATOR &&
+                   tmpdir_buf[tmpdir_len - 1] != DIR_SEPARATOR) {
+                   tmpdir_buf[tmpdir_len] = LOCAL_DIR_SEPARATOR;
+                   tmpdir_buf[tmpdir_len + 1] = 0;
+               }
+
+               /* remove the tmp_dir and all its contents recursively */
+               remove_dir(tmpdir_buf, "");
+            } /* jar creation returned no error */
+        }
+    } else {
+        if (JAR_DEBUG && verbose)
+            jio_fprintf(stderr, "JAR directories not found for JAR file [%s]\n", buf);
+        if (fname != NULL)
+            sysFree(fname);
+        if (zipEntry != NULL)
+            sysFree(zipEntry);
+
+        return FALSE; /* could not locate JAR directories - invalid JAR file */
+    }
+
+    if (fname != NULL)
+        sysFree(fname);
+
+    if (zipEntry != NULL)
+        sysFree(zipEntry);
+
+    if (buffer != NULL)
+        sysFree(buffer);
+
+    if (jarName != NULL)
+        sysFree(jarName);
+
+    if ( err!=0 ) {
+        exit(errorCode = 1);
+    }
+
+    return JARfile;
+}
diff --git a/MPC.3.5.LINUX/preverifier/jarint.h b/MPC.3.5.LINUX/preverifier/jarint.h
new file mode 100644 (file)
index 0000000..18ec849
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 1999 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * This software is the confidential and proprietary information of Sun
+ * Microsystems, Inc. ("Confidential Information").  You shall not
+ * disclose such Confidential Information and shall use it only in
+ * accordance with the terms of the license agreement you entered into
+ * with Sun.
+ *
+ * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
+ * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
+ * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
+ * THIS SOFTWARE OR ITS DERIVATIVES.
+ *
+ * Use is subject to license terms.
+ */
+
+/*=========================================================================
+ * SYSTEM:    KVM
+ * SUBSYSTEM: JAR file reader.
+ * FILE:      jarint.h
+ * OVERVIEW:  Internal declarations for JAR file reader. This file should
+ *            be included only by files in the core KVM.
+ * AUTHOR:    Ioi Lam.
+ *=======================================================================*/
+
+#ifndef _JAR_INT_H_
+#define _JAR_INT_H_
+
+/*
+ * indicates whether JAR inflater uses standard i/o during decompression
+ */
+#define JAR_INFLATER_USES_STDIO 1
+
+/*
+ * The HuffmanCodeTable structure contains the dynamic huffman codes for
+ * the Code Length Codes or the Distance Codes. The structure is
+ * dynamically allocated. We just allocate enough space to contain all
+ * possible codes.
+ */
+
+typedef struct HuffmanCodeTableHeader {
+    unsigned short quickBits;  /* quick bit size */
+    unsigned short maxCodeLen; /* Max number of bits in any code */
+} HuffmanCodeTableHeader;
+
+
+/* If this bit is set in a huffman entry, it means that this is not
+ * really an entry, but a pointer into the long codes table.
+ * The remaining 15 bits is the offset (in bytes) from the table header
+ * to first "long" entry representing this item.
+ */
+
+#define HUFFINFO_LONG_MASK 0x8000 /*  high bit set */
+
+#define MAX_QUICK_CXD  6
+#define MAX_QUICK_LXL  9
+
+/* For debugging, the following can be set to the name of a file (in quotes).
+ * If we are decompressing something that is the exact same length as that
+ * file, this will check to make sure that the decompressed bytes look
+ * exactly the same as the bytes in the specified file.
+ * java/lang/String.class is a particularly useful file to try.
+ *
+ */
+
+#ifndef inflateVerbose
+#define inflateVerbose 0
+#endif
+
+#if INCLUDEDEBUGCODE
+    static void ziperr(const char * msg);
+#   define ASSERT(x) assert((x))
+#else
+#   define ziperr(msg)
+#   define ASSERT(x) (void)0
+#endif
+
+
+/* A normal sized huffman code table with a 9-bit quick bit */
+typedef struct HuffmanCodeTable { 
+    struct HuffmanCodeTableHeader h;
+    /* There are 1 << quickBit entries.  512 is just an example. 
+     * For each entry:
+     *     If the high bit is 0:
+     *        Next 11 bits give the character
+     *        Low   4 bits give the actual number of bits used
+     *     If the high bit is 1:
+     *        Next 15 bits give the offset (in bytes) from the header to 
+     *        the first long entry dealing with this long code.
+     */
+    unsigned short entries[512];
+} HuffmanCodeTable;
+
+
+/* A small sized huffman code table with a 9-bit quick bit.  We have
+ * this so that we can initialize fixedHuffmanDistanceTable in jartables.h
+ */
+typedef struct shortHuffmanCodeTable { 
+    struct HuffmanCodeTableHeader h;
+    unsigned short entries[32];
+} shortHuffmanCodeTable;
+
+
+typedef struct inflaterState {
+    /* The input stream */
+    JarCompressedType inFile;
+
+    int inRemaining;           /* Number of bytes left that we can read */
+    unsigned int inDataSize;   /* Number of good bits in inData */
+    unsigned long inData;      /* Low inDataSize bits are from stream.
+                                * High unused bits must be zero 
+                                */
+    /* The output stream */
+    unsigned char *out;                /* Current output position */
+    unsigned char *outStart;   /* Start and end of output buffer */
+    unsigned char *outEnd;
+#ifdef JAR_DEBUG_FILE  
+    unsigned char *jarDebugBytes;
+#endif
+} inflaterState;
+
+
+/*=========================================================================
+ * Macros used internally
+ *=======================================================================*/
+
+/* Call this macro to make sure that we have at least "j" bits of
+ * input available
+ */
+
+#define NEEDBITS(j) {  \
+      while (inDataSize < (j)) {                                \
+           inData |= ((unsigned long)NEXTBYTE) << inDataSize; \
+          inRemaining--; inDataSize += 8;                      \
+      }                                                                     \
+      ASSERT(inDataSize <= 32);                                     \
+}
+
+
+/* Return (without consuming) the next "j" bits of the input */
+#define NEXTBITS(j) \
+       (ASSERT((j) <= inDataSize), inData & ((1 << (j)) - 1))
+
+/* Consume (quietly) "j" bits of input, and make them no longer available
+ * to the user
+ */
+#define DUMPBITS(j) {                                          \
+       ASSERT((j) <= inDataSize);                             \
+       inData >>= (j);                                    \
+       inDataSize -= (j);                                 \
+    }  
+
+/* Read bits from the input stream and decode it using the specified
+ * table.  The resulting decoded character is placed into "result".
+ * If there is a problem, we goto "errorLabel"
+ *
+ * For speed, we assume that quickBits = table->h.quickBits and that
+ * it has been cached into a variable.
+ */
+
+
+#define GET_HUFFMAN_ENTRY(table, quickBits, result, errorLabel) { \
+    unsigned int huff = table->entries[NEXTBITS(quickBits)];      \
+    if (huff & HUFFINFO_LONG_MASK) {                             \
+        long delta = (huff & ~HUFFINFO_LONG_MASK);                \
+        unsigned short *table2 = (unsigned short *)((char *)table + delta); \
+       huff = table2[NEXTBITS(table->h.maxCodeLen) >> quickBits]; \
+    }                                                              \
+    if (huff == 0) { goto errorLabel; }                                   \
+    DUMPBITS(huff & 0xF);                                         \
+    result = huff >> 4;                                            \
+    }
+
+
+#if JAR_INFLATER_USES_STDIO
+#   define LOAD_INFILE_IF_NECESSARY
+#   define STORE_INFILE_IF_NECESSARY
+#   define INITIALIZE_INFILE_IF_NECESSARY  = state->inFile
+#   define NEXTBYTE                        fgetc(inFile)
+#   define COPY_N_BYTES(buffer, n)         (fread(buffer, 1, n, inFile) == n)
+
+#else 
+#   define LOAD_INFILE_IF_NECESSARY        inFile = state->inFile;
+#   define STORE_INFILE_IF_NECESSARY       state->inFile = inFile;
+#   define INITIALIZE_INFILE_IF_NECESSARY  
+#   define NEXTBYTE                        (*inFile++)
+#   define COPY_N_BYTES(buffer, n)         \
+                           (memcpy(buffer, inFile, n), inFile += n, TRUE)
+#endif
+
+
+/* Copy values from the inflaterState structure to local variables */
+#define LOAD_IN                       \
+    LOAD_INFILE_IF_NECESSARY          \
+    inData = state->inData;           \
+    inDataSize = state->inDataSize;   \
+    inRemaining = state->inRemaining; 
+
+
+/* Copy values from local variables back to the inflaterState structure */
+#define STORE_IN                      \
+    STORE_INFILE_IF_NECESSARY         \
+    state->inData = inData;           \
+    state->inDataSize = inDataSize;   \
+    state->inRemaining = inRemaining; 
+
+
+#define DECLARE_IN_VARIABLES \
+    register JarCompressedType inFile INITIALIZE_INFILE_IF_NECESSARY; \
+    register unsigned long inData;         \
+    register unsigned int inDataSize;      \
+    register long inRemaining;             \
+
+#define LOAD_OUT out = state->out;
+
+#define STORE_OUT state->out = out;
+
+#define DECLARE_OUT_VARIABLES \
+    register unsigned char *out;
+
+#endif /* JAR_INT_H_ */
diff --git a/MPC.3.5.LINUX/preverifier/jartables.h b/MPC.3.5.LINUX/preverifier/jartables.h
new file mode 100644 (file)
index 0000000..b6c2e8f
--- /dev/null
@@ -0,0 +1,779 @@
+/*
+ * Copyright (c) 1999 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * This software is the confidential and proprietary information of Sun
+ * Microsystems, Inc. ("Confidential Information").  You shall not
+ * disclose such Confidential Information and shall use it only in
+ * accordance with the terms of the license agreement you entered into
+ * with Sun.
+ *
+ * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
+ * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
+ * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
+ * THIS SOFTWARE OR ITS DERIVATIVES.
+ *
+ * Use is subject to license terms.
+ */
+
+/*=========================================================================
+ * SYSTEM:    KVM
+ * SUBSYSTEM: JAR file reader.
+ * FILE:      jartables.h
+ * OVERVIEW:  Public header file for the JAR file reader tables.
+ * AUTHOR:    Ioi Lam 
+ *            Tasneem Sayeed
+ *=========================================================================*/
+
+#ifndef _KJARTABLES_H_
+#define _KJARTABLES_H_
+
+static const unsigned char ll_extra_bits[] = {
+    /* 257 */   0,   /* 3       */
+    /* 258 */   0,   /* 4       */
+    /* 259 */   0,   /* 5       */
+    /* 260 */   0,   /* 6       */
+    /* 261 */   0,   /* 7       */
+    /* 262 */   0,   /* 8       */
+    /* 263 */   0,   /* 9       */
+    /* 264 */   0,   /* 10      */
+    /* 265 */   1,   /* 11,12   */
+    /* 266 */   1,   /* 13,14   */
+
+    /* 267 */   1,   /* 15,16   */
+    /* 268 */   1,   /* 17,18   */
+    /* 269 */   2,   /* 19-22   */
+    /* 270 */   2,   /* 23-26   */
+    /* 271 */   2,   /* 27-30   */
+    /* 272 */   2,   /* 31-34   */
+    /* 273 */   3,   /* 35-42   */
+    /* 274 */   3,   /* 43-50   */
+    /* 275 */   3,   /* 51-58   */
+    /* 276 */   3,   /* 59-66   */
+
+    /* 277 */   4,   /* 67-82   */
+    /* 278 */   4,   /* 83-98   */
+    /* 279 */   4,   /* 99-114  */
+    /* 280 */   4,   /* 115-130 */
+    /* 281 */   5,   /* 131-162 */
+    /* 282 */   5,   /* 163-194 */
+    /* 283 */   5,   /* 195-226 */
+    /* 284 */   5,   /* 227-257 */
+    /* 285 */   0,   /* 258     */
+};
+
+#define MAX_ZIP_EXTRA_LENGTH_BITS 5
+
+static const unsigned short ll_length_base[] = {
+    /* 257   0 */   3,
+    /* 258   0 */   4,
+    /* 259   0 */   5,
+    /* 260   0 */   6,
+    /* 261   0 */   7,
+    /* 262   0 */   8,
+    /* 263   0 */   9,
+    /* 264   0 */   10,
+    /* 265   1 */   11,  /* - 12 */ 
+    /* 266   1 */   13,  /* - 14 */ 
+
+    /* 267   1 */   15,  /* - 16 */ 
+    /* 268   1 */   17,  /* - 18 */ 
+    /* 269   2 */   19,  /* - 22 */ 
+    /* 270   2 */   23,  /* - 26 */ 
+    /* 271   2 */   27,  /* - 30 */ 
+    /* 272   2 */   31,  /* - 34 */ 
+    /* 273   3 */   35,  /* - 42 */ 
+    /* 274   3 */   43,  /* - 50 */ 
+    /* 275   3 */   51,  /* - 58 */ 
+    /* 276   3 */   59,  /* - 66 */ 
+
+    /* 277   4 */   67,  /* - 82 */ 
+    /* 278   4 */   83,  /* - 98 */ 
+    /* 279   4 */   99,  /* - 114 */ 
+    /* 280   4 */   115, /* - 130 */ 
+    /* 281   5 */   131, /* - 162 */ 
+    /* 282   5 */   163, /* - 194 */ 
+    /* 283   5 */   195, /* - 226 */ 
+    /* 284   5 */   227, /* - 257 */ 
+    /* 285   0 */   258
+};
+
+
+static const unsigned char dist_extra_bits[] = {
+    /*  0 */   0,    /* 1            */
+    /*  1 */   0,    /* 2            */
+    /*  2 */   0,    /* 3            */
+    /*  3 */   0,    /* 4            */
+    /*  4 */   1,    /* 5,6          */
+    /*  5 */   1,    /* 7,8          */
+    /*  6 */   2,    /* 9-12         */
+    /*  7 */   2,    /* 13-16        */
+    /*  8 */   3,    /* 17-24        */
+    /*  9 */   3,    /* 25-32        */
+
+    /* 10 */   4,    /* 33-48        */
+    /* 11 */   4,    /* 49-64        */
+    /* 12 */   5,    /* 65-96        */
+    /* 13 */   5,    /* 97-128       */
+    /* 14 */   6,    /* 129-192      */
+    /* 15 */   6,    /* 193-256      */
+    /* 16 */   7,    /* 257-384      */
+    /* 17 */   7,    /* 385-512      */
+    /* 18 */   8,    /* 513-768      */
+    /* 19 */   8,    /* 769-1024     */
+
+    /* 20 */   9,    /* 1025-1536    */
+    /* 21 */   9,    /* 1537-2048    */
+    /* 22 */   10,   /* 2049-3072    */
+    /* 23 */   10,   /* 3073-4096    */
+    /* 24 */   11,   /* 4097-6144    */
+    /* 25 */   11,   /* 6145-8192    */
+    /* 26 */   12,   /* 8193-12288   */
+    /* 27 */   12,   /* 12289-16384  */
+    /* 28 */   13,   /* 16385-24576  */
+    /* 29 */   13,   /* 24577-32768  */
+};
+
+#define MAX_ZIP_EXTRA_DISTANCE_BITS 13
+#define MAX_ZIP_DISTANCE_CODE 29
+
+static const unsigned int dist_base[] = {
+    /*  0   0  */   1,
+    /*  1   0  */   2,
+    /*  2   0  */   3,
+    /*  3   0  */   4,
+    /*  4   1  */   5,      /* -6      */
+    /*  5   1  */   7,      /* -8      */
+    /*  6   2  */   9,      /* -12     */
+    /*  7   2  */   13,     /* -16     */
+    /*  8   3  */   17,     /* -24     */
+    /*  9   3  */   25,     /* -32     */
+
+    /* 10   4  */   33,     /* -48    */
+    /* 11   4  */   49,     /* -64    */
+    /* 12   5  */   65,     /* -96    */
+    /* 13   5  */   97,     /* -128   */
+    /* 14   6  */   129,    /* -192   */
+    /* 15   6  */   193,    /* -256   */
+    /* 16   7  */   257,    /* -384   */
+    /* 17   7  */   385,    /* -512   */
+    /* 18   8  */   513,    /* -768   */
+    /* 19   8  */   769,    /* -1024   */
+    /* 20   9  */   1025,   /* -1536  */
+    /* 21   9  */   1537,   /* -2048  */
+    /* 22   10 */   2049,   /* -3072  */
+    /* 23   10 */   3073,   /* -4096  */
+    /* 24   11 */   4097,   /* -6144  */
+    /* 25   11 */   6145,   /* -8192  */
+    /* 26   12 */   8193,   /* -12288  */
+    /* 27   12 */   12289,  /* -16384  */
+    /* 28   13 */   16385,  /* -24576  */
+    /* 29   13 */   24577,  /* -32768  */
+};
+
+
+/*
+ * The order in which the code lengths of the Code Length Alphabet is
+ * given. See section 3.2.7 of RFC 1951.
+ */
+
+static const char ccode_idx[] = {
+    16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15,
+};
+
+/* A table for reversing 5 bits in a binary number */
+
+static const unsigned char reverse5[] = {
+    0x0, 0x10, 0x8, 0x18, 0x4, 0x14, 0xc, 0x1c,
+    0x2, 0x12, 0xa, 0x1a, 0x6, 0x16, 0xe, 0x1e,
+    0x1, 0x11, 0x9, 0x19, 0x5, 0x15, 0xd, 0x1d,
+    0x3, 0x13, 0xb, 0x1b, 0x7, 0x17, 0xf, 0x1f
+};
+
+#define REVERSE_5BITS(code) reverse5[code]
+#define REVERSE_9BITS(code) \
+      ((reverse5[((code) & 0x1F)] << 4) | reverse5[(code) >> 4])
+#define REVERSE_15BITS(code) \
+      (  (reverse5[code & 0x1F] << 10) | (reverse5[((code) >> 5) & 0x1F] << 5) \
+       | (reverse5[code >> 10]) )
+
+
+#define HUFFMAN_ENTRY(char, bits) ((char << 4) + bits)
+
+
+#ifdef USE_FIXED_HUFFMAN_CODE_TABLES
+
+/* The following tables are currently used, but they can be in
+ * releases that care for speed rather that size. 
+ *
+ * "Fixed Huffman" can use the following tables, rather than doing the
+ * complicated calculations that it does.
+ */
+
+
+static const struct HuffmanCodeTable fixedHuffmanCodeTable = { 
+    { 
+       7,                      /* min code length */
+       9,                      /* max code length */
+    }, 
+    { 
+       HUFFMAN_ENTRY(0x100, 7), 
+       HUFFMAN_ENTRY('P',   8), 
+       HUFFMAN_ENTRY(0x010, 8), 
+       HUFFMAN_ENTRY(0x118, 8), 
+       HUFFMAN_ENTRY(0x110, 7), 
+       HUFFMAN_ENTRY('p',   8), 
+       HUFFMAN_ENTRY('0',   8), 
+       HUFFMAN_ENTRY(0x0c0, 9), 
+       HUFFMAN_ENTRY(0x108, 7), 
+       HUFFMAN_ENTRY('`',   8), 
+       HUFFMAN_ENTRY(' ',   8), 
+       HUFFMAN_ENTRY(0x0a0, 9), 
+       HUFFMAN_ENTRY(0x000, 8), 
+       HUFFMAN_ENTRY(0x080, 8), 
+       HUFFMAN_ENTRY('@',   8), 
+       HUFFMAN_ENTRY(0x0e0, 9), 
+       HUFFMAN_ENTRY(0x104, 7), 
+       HUFFMAN_ENTRY('X',   8), 
+       HUFFMAN_ENTRY(0x018, 8), 
+       HUFFMAN_ENTRY(0x090, 9), 
+       HUFFMAN_ENTRY(0x114, 7), 
+       HUFFMAN_ENTRY('x',   8), 
+       HUFFMAN_ENTRY('8',   8), 
+       HUFFMAN_ENTRY(0x0d0, 9), 
+       HUFFMAN_ENTRY(0x10c, 7), 
+       HUFFMAN_ENTRY('h',   8), 
+       HUFFMAN_ENTRY('(',   8), 
+       HUFFMAN_ENTRY(0x0b0, 9), 
+       HUFFMAN_ENTRY(0x008, 8), 
+       HUFFMAN_ENTRY(0x088, 8), 
+       HUFFMAN_ENTRY('H',   8), 
+       HUFFMAN_ENTRY(0x0f0, 9), 
+       HUFFMAN_ENTRY(0x102, 7), 
+       HUFFMAN_ENTRY('T',   8), 
+       HUFFMAN_ENTRY(0x014, 8), 
+       HUFFMAN_ENTRY(0x11c, 8), 
+       HUFFMAN_ENTRY(0x112, 7), 
+       HUFFMAN_ENTRY('t',   8), 
+       HUFFMAN_ENTRY('4',   8), 
+       HUFFMAN_ENTRY(0x0c8, 9), 
+       HUFFMAN_ENTRY(0x10a, 7), 
+       HUFFMAN_ENTRY('d',   8), 
+       HUFFMAN_ENTRY('$',   8), 
+       HUFFMAN_ENTRY(0x0a8, 9), 
+       HUFFMAN_ENTRY(0x004, 8), 
+       HUFFMAN_ENTRY(0x084, 8), 
+       HUFFMAN_ENTRY('D',   8), 
+       HUFFMAN_ENTRY(0x0e8, 9), 
+       HUFFMAN_ENTRY(0x106, 7), 
+       HUFFMAN_ENTRY('\\',   8), 
+       HUFFMAN_ENTRY(0x01c, 8), 
+       HUFFMAN_ENTRY(0x098, 9), 
+       HUFFMAN_ENTRY(0x116, 7), 
+       HUFFMAN_ENTRY('|',   8), 
+       HUFFMAN_ENTRY('<',   8), 
+       HUFFMAN_ENTRY(0x0d8, 9), 
+       HUFFMAN_ENTRY(0x10e, 7), 
+       HUFFMAN_ENTRY('l',   8), 
+       HUFFMAN_ENTRY(',',   8), 
+       HUFFMAN_ENTRY(0x0b8, 9), 
+       HUFFMAN_ENTRY(0x00c, 8), 
+       HUFFMAN_ENTRY(0x08c, 8), 
+       HUFFMAN_ENTRY('L',   8), 
+       HUFFMAN_ENTRY(0x0f8, 9), 
+       HUFFMAN_ENTRY(0x101, 7), 
+       HUFFMAN_ENTRY('R',   8), 
+       HUFFMAN_ENTRY(0x012, 8), 
+       HUFFMAN_ENTRY(0x11a, 8), 
+       HUFFMAN_ENTRY(0x111, 7), 
+       HUFFMAN_ENTRY('r',   8), 
+       HUFFMAN_ENTRY('2',   8), 
+       HUFFMAN_ENTRY(0x0c4, 9), 
+       HUFFMAN_ENTRY(0x109, 7), 
+       HUFFMAN_ENTRY('b',   8), 
+       HUFFMAN_ENTRY('"',   8), 
+       HUFFMAN_ENTRY(0x0a4, 9), 
+       HUFFMAN_ENTRY(0x002, 8), 
+       HUFFMAN_ENTRY(0x082, 8), 
+       HUFFMAN_ENTRY('B',   8), 
+       HUFFMAN_ENTRY(0x0e4, 9), 
+       HUFFMAN_ENTRY(0x105, 7), 
+       HUFFMAN_ENTRY('Z',   8), 
+       HUFFMAN_ENTRY(0x01a, 8), 
+       HUFFMAN_ENTRY(0x094, 9), 
+       HUFFMAN_ENTRY(0x115, 7), 
+       HUFFMAN_ENTRY('z',   8), 
+       HUFFMAN_ENTRY(':',   8), 
+       HUFFMAN_ENTRY(0x0d4, 9), 
+       HUFFMAN_ENTRY(0x10d, 7), 
+       HUFFMAN_ENTRY('j',   8), 
+       HUFFMAN_ENTRY('*',   8), 
+       HUFFMAN_ENTRY(0x0b4, 9), 
+       HUFFMAN_ENTRY(0x00a, 8), 
+       HUFFMAN_ENTRY(0x08a, 8), 
+       HUFFMAN_ENTRY('J',   8), 
+       HUFFMAN_ENTRY(0x0f4, 9), 
+       HUFFMAN_ENTRY(0x103, 7), 
+       HUFFMAN_ENTRY('V',   8), 
+       HUFFMAN_ENTRY(0x016, 8), 
+       HUFFMAN_ENTRY(0x11e, 8), 
+       HUFFMAN_ENTRY(0x113, 7), 
+       HUFFMAN_ENTRY('v',   8), 
+       HUFFMAN_ENTRY('6',   8), 
+       HUFFMAN_ENTRY(0x0cc, 9), 
+       HUFFMAN_ENTRY(0x10b, 7), 
+       HUFFMAN_ENTRY('f',   8), 
+       HUFFMAN_ENTRY('&',   8), 
+       HUFFMAN_ENTRY(0x0ac, 9), 
+       HUFFMAN_ENTRY(0x006, 8), 
+       HUFFMAN_ENTRY(0x086, 8), 
+       HUFFMAN_ENTRY('F',   8), 
+       HUFFMAN_ENTRY(0x0ec, 9), 
+       HUFFMAN_ENTRY(0x107, 7), 
+       HUFFMAN_ENTRY('^',   8), 
+       HUFFMAN_ENTRY(0x01e, 8), 
+       HUFFMAN_ENTRY(0x09c, 9), 
+       HUFFMAN_ENTRY(0x117, 7), 
+       HUFFMAN_ENTRY('~',   8), 
+       HUFFMAN_ENTRY('>',   8), 
+       HUFFMAN_ENTRY(0x0dc, 9), 
+       HUFFMAN_ENTRY(0x10f, 7), 
+       HUFFMAN_ENTRY('n',   8), 
+       HUFFMAN_ENTRY('.',   8), 
+       HUFFMAN_ENTRY(0x0bc, 9), 
+       HUFFMAN_ENTRY(0x00e, 8), 
+       HUFFMAN_ENTRY(0x08e, 8), 
+       HUFFMAN_ENTRY('N',   8), 
+       HUFFMAN_ENTRY(0x0fc, 9), 
+       HUFFMAN_ENTRY(0x100, 7), 
+       HUFFMAN_ENTRY('Q',   8), 
+       HUFFMAN_ENTRY(0x011, 8), 
+       HUFFMAN_ENTRY(0x119, 8), 
+       HUFFMAN_ENTRY(0x110, 7), 
+       HUFFMAN_ENTRY('q',   8), 
+       HUFFMAN_ENTRY('1',   8), 
+       HUFFMAN_ENTRY(0x0c2, 9), 
+       HUFFMAN_ENTRY(0x108, 7), 
+       HUFFMAN_ENTRY('a',   8), 
+       HUFFMAN_ENTRY('!',   8), 
+       HUFFMAN_ENTRY(0x0a2, 9), 
+       HUFFMAN_ENTRY(0x001, 8), 
+       HUFFMAN_ENTRY(0x081, 8), 
+       HUFFMAN_ENTRY('A',   8), 
+       HUFFMAN_ENTRY(0x0e2, 9), 
+       HUFFMAN_ENTRY(0x104, 7), 
+       HUFFMAN_ENTRY('Y',   8), 
+       HUFFMAN_ENTRY(0x019, 8), 
+       HUFFMAN_ENTRY(0x092, 9), 
+       HUFFMAN_ENTRY(0x114, 7), 
+       HUFFMAN_ENTRY('y',   8), 
+       HUFFMAN_ENTRY('9',   8), 
+       HUFFMAN_ENTRY(0x0d2, 9), 
+       HUFFMAN_ENTRY(0x10c, 7), 
+       HUFFMAN_ENTRY('i',   8), 
+       HUFFMAN_ENTRY(')',   8), 
+       HUFFMAN_ENTRY(0x0b2, 9), 
+       HUFFMAN_ENTRY(0x009, 8), 
+       HUFFMAN_ENTRY(0x089, 8), 
+       HUFFMAN_ENTRY('I',   8), 
+       HUFFMAN_ENTRY(0x0f2, 9), 
+       HUFFMAN_ENTRY(0x102, 7), 
+       HUFFMAN_ENTRY('U',   8), 
+       HUFFMAN_ENTRY(0x015, 8), 
+       HUFFMAN_ENTRY(0x11d, 8), 
+       HUFFMAN_ENTRY(0x112, 7), 
+       HUFFMAN_ENTRY('u',   8), 
+       HUFFMAN_ENTRY('5',   8), 
+       HUFFMAN_ENTRY(0x0ca, 9), 
+       HUFFMAN_ENTRY(0x10a, 7), 
+       HUFFMAN_ENTRY('e',   8), 
+       HUFFMAN_ENTRY('%',   8), 
+       HUFFMAN_ENTRY(0x0aa, 9), 
+       HUFFMAN_ENTRY(0x005, 8), 
+       HUFFMAN_ENTRY(0x085, 8), 
+       HUFFMAN_ENTRY('E',   8), 
+       HUFFMAN_ENTRY(0x0ea, 9), 
+       HUFFMAN_ENTRY(0x106, 7), 
+       HUFFMAN_ENTRY(']',   8), 
+       HUFFMAN_ENTRY(0x01d, 8), 
+       HUFFMAN_ENTRY(0x09a, 9), 
+       HUFFMAN_ENTRY(0x116, 7), 
+       HUFFMAN_ENTRY('}',   8), 
+       HUFFMAN_ENTRY('=',   8), 
+       HUFFMAN_ENTRY(0x0da, 9), 
+       HUFFMAN_ENTRY(0x10e, 7), 
+       HUFFMAN_ENTRY('m',   8), 
+       HUFFMAN_ENTRY('-',   8), 
+       HUFFMAN_ENTRY(0x0ba, 9), 
+       HUFFMAN_ENTRY(0x00d, 8), 
+       HUFFMAN_ENTRY(0x08d, 8), 
+       HUFFMAN_ENTRY('M',   8), 
+       HUFFMAN_ENTRY(0x0fa, 9), 
+       HUFFMAN_ENTRY(0x101, 7), 
+       HUFFMAN_ENTRY('S',   8), 
+       HUFFMAN_ENTRY(0x013, 8), 
+       HUFFMAN_ENTRY(0x11b, 8), 
+       HUFFMAN_ENTRY(0x111, 7), 
+       HUFFMAN_ENTRY('s',   8), 
+       HUFFMAN_ENTRY('3',   8), 
+       HUFFMAN_ENTRY(0x0c6, 9), 
+       HUFFMAN_ENTRY(0x109, 7), 
+       HUFFMAN_ENTRY('c',   8), 
+       HUFFMAN_ENTRY('#',   8), 
+       HUFFMAN_ENTRY(0x0a6, 9), 
+       HUFFMAN_ENTRY(0x003, 8), 
+       HUFFMAN_ENTRY(0x083, 8), 
+       HUFFMAN_ENTRY('C',   8), 
+       HUFFMAN_ENTRY(0x0e6, 9), 
+       HUFFMAN_ENTRY(0x105, 7), 
+       HUFFMAN_ENTRY('[',   8), 
+       HUFFMAN_ENTRY(0x01b, 8), 
+       HUFFMAN_ENTRY(0x096, 9), 
+       HUFFMAN_ENTRY(0x115, 7), 
+       HUFFMAN_ENTRY('{',   8), 
+       HUFFMAN_ENTRY(';',   8), 
+       HUFFMAN_ENTRY(0x0d6, 9), 
+       HUFFMAN_ENTRY(0x10d, 7), 
+       HUFFMAN_ENTRY('k',   8), 
+       HUFFMAN_ENTRY('+',   8), 
+       HUFFMAN_ENTRY(0x0b6, 9), 
+       HUFFMAN_ENTRY(0x00b, 8), 
+       HUFFMAN_ENTRY(0x08b, 8), 
+       HUFFMAN_ENTRY('K',    8), 
+       HUFFMAN_ENTRY(0x0f6, 9), 
+       HUFFMAN_ENTRY(0x103, 7), 
+       HUFFMAN_ENTRY('W',    8), 
+       HUFFMAN_ENTRY(0x017, 8), 
+       HUFFMAN_ENTRY(0x11f, 8), 
+       HUFFMAN_ENTRY(0x113, 7), 
+       HUFFMAN_ENTRY('w',    8), 
+       HUFFMAN_ENTRY('7',    8), 
+       HUFFMAN_ENTRY(0x0ce, 9), 
+       HUFFMAN_ENTRY(0x10b, 7), 
+       HUFFMAN_ENTRY('g',    8), 
+       HUFFMAN_ENTRY('\'',   8), 
+       HUFFMAN_ENTRY(0x0ae, 9), 
+       HUFFMAN_ENTRY(0x007, 8), 
+       HUFFMAN_ENTRY(0x087, 8), 
+       HUFFMAN_ENTRY('G',   8), 
+       HUFFMAN_ENTRY(0x0ee, 9), 
+       HUFFMAN_ENTRY(0x107, 7), 
+       HUFFMAN_ENTRY('_',   8), 
+       HUFFMAN_ENTRY(0x01f, 8), 
+       HUFFMAN_ENTRY(0x09e, 9), 
+       HUFFMAN_ENTRY(0x117, 7), 
+       HUFFMAN_ENTRY(0x07f, 8), 
+       HUFFMAN_ENTRY('?',   8), 
+       HUFFMAN_ENTRY(0x0de, 9), 
+       HUFFMAN_ENTRY(0x10f, 7), 
+       HUFFMAN_ENTRY('o',   8), 
+       HUFFMAN_ENTRY('/',   8), 
+       HUFFMAN_ENTRY(0x0be, 9), 
+       HUFFMAN_ENTRY(0x00f, 8), 
+       HUFFMAN_ENTRY(0x08f, 8), 
+       HUFFMAN_ENTRY('O',   8), 
+       HUFFMAN_ENTRY(0x0fe, 9), 
+       HUFFMAN_ENTRY(0x100, 7), 
+       HUFFMAN_ENTRY('P',   8), 
+       HUFFMAN_ENTRY(0x010, 8), 
+       HUFFMAN_ENTRY(0x118, 8), 
+       HUFFMAN_ENTRY(0x110, 7), 
+       HUFFMAN_ENTRY('p',   8), 
+       HUFFMAN_ENTRY('0',   8), 
+       HUFFMAN_ENTRY(0x0c1, 9), 
+       HUFFMAN_ENTRY(0x108, 7), 
+       HUFFMAN_ENTRY('`',   8), 
+       HUFFMAN_ENTRY(' ',   8), 
+       HUFFMAN_ENTRY(0x0a1, 9), 
+       HUFFMAN_ENTRY(0x000, 8), 
+       HUFFMAN_ENTRY(0x080, 8), 
+       HUFFMAN_ENTRY('@',   8), 
+       HUFFMAN_ENTRY(0x0e1, 9), 
+       HUFFMAN_ENTRY(0x104, 7), 
+       HUFFMAN_ENTRY('X',   8), 
+       HUFFMAN_ENTRY(0x018, 8), 
+       HUFFMAN_ENTRY(0x091, 9), 
+       HUFFMAN_ENTRY(0x114, 7), 
+       HUFFMAN_ENTRY('x',   8), 
+       HUFFMAN_ENTRY('8',   8), 
+       HUFFMAN_ENTRY(0x0d1, 9), 
+       HUFFMAN_ENTRY(0x10c, 7), 
+       HUFFMAN_ENTRY('h',   8), 
+       HUFFMAN_ENTRY('(',   8), 
+       HUFFMAN_ENTRY(0x0b1, 9), 
+       HUFFMAN_ENTRY(0x008, 8), 
+       HUFFMAN_ENTRY(0x088, 8), 
+       HUFFMAN_ENTRY('H',   8), 
+       HUFFMAN_ENTRY(0x0f1, 9), 
+       HUFFMAN_ENTRY(0x102, 7), 
+       HUFFMAN_ENTRY('T',   8), 
+       HUFFMAN_ENTRY(0x014, 8), 
+       HUFFMAN_ENTRY(0x11c, 8), 
+       HUFFMAN_ENTRY(0x112, 7), 
+       HUFFMAN_ENTRY('t',   8), 
+       HUFFMAN_ENTRY('4',   8), 
+       HUFFMAN_ENTRY(0x0c9, 9), 
+       HUFFMAN_ENTRY(0x10a, 7), 
+       HUFFMAN_ENTRY('d',   8), 
+       HUFFMAN_ENTRY('$',   8), 
+       HUFFMAN_ENTRY(0x0a9, 9), 
+       HUFFMAN_ENTRY(0x004, 8), 
+       HUFFMAN_ENTRY(0x084, 8), 
+       HUFFMAN_ENTRY('D',   8), 
+       HUFFMAN_ENTRY(0x0e9, 9), 
+       HUFFMAN_ENTRY(0x106, 7), 
+       HUFFMAN_ENTRY('\\',  8), 
+       HUFFMAN_ENTRY(0x01c, 8), 
+       HUFFMAN_ENTRY(0x099, 9), 
+       HUFFMAN_ENTRY(0x116, 7), 
+       HUFFMAN_ENTRY('|',   8), 
+       HUFFMAN_ENTRY('<',   8), 
+       HUFFMAN_ENTRY(0x0d9, 9), 
+       HUFFMAN_ENTRY(0x10e, 7), 
+       HUFFMAN_ENTRY('l',   8), 
+       HUFFMAN_ENTRY(',',   8), 
+       HUFFMAN_ENTRY(0x0b9, 9), 
+       HUFFMAN_ENTRY(0x00c, 8), 
+       HUFFMAN_ENTRY(0x08c, 8), 
+       HUFFMAN_ENTRY('L',   8), 
+       HUFFMAN_ENTRY(0x0f9, 9), 
+       HUFFMAN_ENTRY(0x101, 7), 
+       HUFFMAN_ENTRY('R',   8), 
+       HUFFMAN_ENTRY(0x012, 8), 
+       HUFFMAN_ENTRY(0x11a, 8), 
+       HUFFMAN_ENTRY(0x111, 7), 
+       HUFFMAN_ENTRY('r',   8), 
+       HUFFMAN_ENTRY('2',   8), 
+       HUFFMAN_ENTRY(0x0c5, 9), 
+       HUFFMAN_ENTRY(0x109, 7), 
+       HUFFMAN_ENTRY('b',   8), 
+       HUFFMAN_ENTRY('"',   8), 
+       HUFFMAN_ENTRY(0x0a5, 9), 
+       HUFFMAN_ENTRY(0x002, 8), 
+       HUFFMAN_ENTRY(0x082, 8), 
+       HUFFMAN_ENTRY('B',   8), 
+       HUFFMAN_ENTRY(0x0e5, 9), 
+       HUFFMAN_ENTRY(0x105, 7), 
+       HUFFMAN_ENTRY('Z',   8), 
+       HUFFMAN_ENTRY(0x01a, 8), 
+       HUFFMAN_ENTRY(0x095, 9), 
+       HUFFMAN_ENTRY(0x115, 7), 
+       HUFFMAN_ENTRY('z',   8), 
+       HUFFMAN_ENTRY(':',   8), 
+       HUFFMAN_ENTRY(0x0d5, 9), 
+       HUFFMAN_ENTRY(0x10d, 7), 
+       HUFFMAN_ENTRY('j',   8), 
+       HUFFMAN_ENTRY('*',   8), 
+       HUFFMAN_ENTRY(0x0b5, 9), 
+       HUFFMAN_ENTRY(0x00a, 8), 
+       HUFFMAN_ENTRY(0x08a, 8), 
+       HUFFMAN_ENTRY('J',   8), 
+       HUFFMAN_ENTRY(0x0f5, 9), 
+       HUFFMAN_ENTRY(0x103, 7), 
+       HUFFMAN_ENTRY('V',   8), 
+       HUFFMAN_ENTRY(0x016, 8), 
+       HUFFMAN_ENTRY(0x11e, 8), 
+       HUFFMAN_ENTRY(0x113, 7), 
+       HUFFMAN_ENTRY('v',   8), 
+       HUFFMAN_ENTRY('6',   8), 
+       HUFFMAN_ENTRY(0x0cd, 9), 
+       HUFFMAN_ENTRY(0x10b, 7), 
+       HUFFMAN_ENTRY('f',   8), 
+       HUFFMAN_ENTRY('&',   8), 
+       HUFFMAN_ENTRY(0x0ad, 9), 
+       HUFFMAN_ENTRY(0x006, 8), 
+       HUFFMAN_ENTRY(0x086, 8), 
+       HUFFMAN_ENTRY('F',   8), 
+       HUFFMAN_ENTRY(0x0ed, 9), 
+       HUFFMAN_ENTRY(0x107, 7), 
+       HUFFMAN_ENTRY('^',   8), 
+       HUFFMAN_ENTRY(0x01e, 8), 
+       HUFFMAN_ENTRY(0x09d, 9), 
+       HUFFMAN_ENTRY(0x117, 7), 
+       HUFFMAN_ENTRY('~',   8), 
+       HUFFMAN_ENTRY('>',   8), 
+       HUFFMAN_ENTRY(0x0dd, 9), 
+       HUFFMAN_ENTRY(0x10f, 7), 
+       HUFFMAN_ENTRY('n',   8), 
+       HUFFMAN_ENTRY('.',   8), 
+       HUFFMAN_ENTRY(0x0bd, 9), 
+       HUFFMAN_ENTRY(0x00e, 8), 
+       HUFFMAN_ENTRY(0x08e, 8), 
+       HUFFMAN_ENTRY('N',   8), 
+       HUFFMAN_ENTRY(0x0fd, 9), 
+       HUFFMAN_ENTRY(0x100, 7), 
+       HUFFMAN_ENTRY('Q',   8), 
+       HUFFMAN_ENTRY(0x011, 8), 
+       HUFFMAN_ENTRY(0x119, 8), 
+       HUFFMAN_ENTRY(0x110, 7), 
+       HUFFMAN_ENTRY('q',   8), 
+       HUFFMAN_ENTRY('1',   8), 
+       HUFFMAN_ENTRY(0x0c3, 9), 
+       HUFFMAN_ENTRY(0x108, 7), 
+       HUFFMAN_ENTRY('a',   8), 
+       HUFFMAN_ENTRY('!',   8), 
+       HUFFMAN_ENTRY(0x0a3, 9), 
+       HUFFMAN_ENTRY(0x001, 8), 
+       HUFFMAN_ENTRY(0x081, 8), 
+       HUFFMAN_ENTRY('A',   8), 
+       HUFFMAN_ENTRY(0x0e3, 9), 
+       HUFFMAN_ENTRY(0x104, 7), 
+       HUFFMAN_ENTRY('Y',   8), 
+       HUFFMAN_ENTRY(0x019, 8), 
+       HUFFMAN_ENTRY(0x093, 9), 
+       HUFFMAN_ENTRY(0x114, 7), 
+       HUFFMAN_ENTRY('y',   8), 
+       HUFFMAN_ENTRY('9',   8), 
+       HUFFMAN_ENTRY(0x0d3, 9), 
+       HUFFMAN_ENTRY(0x10c, 7), 
+       HUFFMAN_ENTRY('i',   8), 
+       HUFFMAN_ENTRY(')',   8), 
+       HUFFMAN_ENTRY(0x0b3, 9), 
+       HUFFMAN_ENTRY(0x009, 8), 
+       HUFFMAN_ENTRY(0x089, 8), 
+       HUFFMAN_ENTRY('I',   8), 
+       HUFFMAN_ENTRY(0x0f3, 9), 
+       HUFFMAN_ENTRY(0x102, 7), 
+       HUFFMAN_ENTRY('U',   8), 
+       HUFFMAN_ENTRY(0x015, 8), 
+       HUFFMAN_ENTRY(0x11d, 8), 
+       HUFFMAN_ENTRY(0x112, 7), 
+       HUFFMAN_ENTRY('u',   8), 
+       HUFFMAN_ENTRY('5',   8), 
+       HUFFMAN_ENTRY(0x0cb, 9), 
+       HUFFMAN_ENTRY(0x10a, 7), 
+       HUFFMAN_ENTRY('e',   8), 
+       HUFFMAN_ENTRY('%',   8), 
+       HUFFMAN_ENTRY(0x0ab, 9), 
+       HUFFMAN_ENTRY(0x005, 8), 
+       HUFFMAN_ENTRY(0x085, 8), 
+       HUFFMAN_ENTRY('E',   8), 
+       HUFFMAN_ENTRY(0x0eb, 9), 
+       HUFFMAN_ENTRY(0x106, 7), 
+       HUFFMAN_ENTRY(']',   8), 
+       HUFFMAN_ENTRY(0x01d, 8), 
+       HUFFMAN_ENTRY(0x09b, 9), 
+       HUFFMAN_ENTRY(0x116, 7), 
+       HUFFMAN_ENTRY('}',   8), 
+       HUFFMAN_ENTRY('=',   8), 
+       HUFFMAN_ENTRY(0x0db, 9), 
+       HUFFMAN_ENTRY(0x10e, 7), 
+       HUFFMAN_ENTRY('m',   8), 
+       HUFFMAN_ENTRY('-',   8), 
+       HUFFMAN_ENTRY(0x0bb, 9), 
+       HUFFMAN_ENTRY(0x00d, 8), 
+       HUFFMAN_ENTRY(0x08d, 8), 
+       HUFFMAN_ENTRY('M',   8), 
+       HUFFMAN_ENTRY(0x0fb, 9), 
+       HUFFMAN_ENTRY(0x101, 7), 
+       HUFFMAN_ENTRY('S',   8), 
+       HUFFMAN_ENTRY(0x013, 8), 
+       HUFFMAN_ENTRY(0x11b, 8), 
+       HUFFMAN_ENTRY(0x111, 7), 
+       HUFFMAN_ENTRY('s',   8), 
+       HUFFMAN_ENTRY('3',   8), 
+       HUFFMAN_ENTRY(0x0c7, 9), 
+       HUFFMAN_ENTRY(0x109, 7), 
+       HUFFMAN_ENTRY('c',   8), 
+       HUFFMAN_ENTRY('#',   8), 
+       HUFFMAN_ENTRY(0x0a7, 9), 
+       HUFFMAN_ENTRY(0x003, 8), 
+       HUFFMAN_ENTRY(0x083, 8), 
+       HUFFMAN_ENTRY('C',   8), 
+       HUFFMAN_ENTRY(0x0e7, 9), 
+       HUFFMAN_ENTRY(0x105, 7), 
+       HUFFMAN_ENTRY('[',   8), 
+       HUFFMAN_ENTRY(0x01b, 8), 
+       HUFFMAN_ENTRY(0x097, 9), 
+       HUFFMAN_ENTRY(0x115, 7), 
+       HUFFMAN_ENTRY('{',   8), 
+       HUFFMAN_ENTRY(';',   8), 
+       HUFFMAN_ENTRY(0x0d7, 9), 
+       HUFFMAN_ENTRY(0x10d, 7), 
+       HUFFMAN_ENTRY('k',   8), 
+       HUFFMAN_ENTRY('+',   8), 
+       HUFFMAN_ENTRY(0x0b7, 9), 
+       HUFFMAN_ENTRY(0x00b, 8), 
+       HUFFMAN_ENTRY(0x08b, 8), 
+       HUFFMAN_ENTRY('K',   8), 
+       HUFFMAN_ENTRY(0x0f7, 9), 
+       HUFFMAN_ENTRY(0x103, 7), 
+       HUFFMAN_ENTRY('W',   8), 
+       HUFFMAN_ENTRY(0x017, 8), 
+       HUFFMAN_ENTRY(0x11f, 8), 
+       HUFFMAN_ENTRY(0x113, 7), 
+       HUFFMAN_ENTRY('w',   8), 
+       HUFFMAN_ENTRY('7',   8), 
+       HUFFMAN_ENTRY(0x0cf, 9), 
+       HUFFMAN_ENTRY(0x10b, 7), 
+       HUFFMAN_ENTRY('g',   8), 
+       HUFFMAN_ENTRY('\'',  8), 
+       HUFFMAN_ENTRY(0x0af, 9), 
+       HUFFMAN_ENTRY(0x007, 8), 
+       HUFFMAN_ENTRY(0x087, 8), 
+       HUFFMAN_ENTRY('G',   8), 
+       HUFFMAN_ENTRY(0x0ef, 9), 
+       HUFFMAN_ENTRY(0x107, 7), 
+       HUFFMAN_ENTRY('_',   8), 
+       HUFFMAN_ENTRY(0x01f, 8), 
+       HUFFMAN_ENTRY(0x09f, 9), 
+       HUFFMAN_ENTRY(0x117, 7), 
+       HUFFMAN_ENTRY(0x07f, 8), 
+       HUFFMAN_ENTRY('?',   8), 
+       HUFFMAN_ENTRY(0x0df, 9), 
+       HUFFMAN_ENTRY(0x10f, 7), 
+       HUFFMAN_ENTRY('o',   8), 
+       HUFFMAN_ENTRY('/',   8), 
+       HUFFMAN_ENTRY(0x0bf, 9), 
+       HUFFMAN_ENTRY(0x00f, 8), 
+       HUFFMAN_ENTRY(0x08f, 8), 
+       HUFFMAN_ENTRY('O',   8), 
+       HUFFMAN_ENTRY(0x0ff, 9), 
+    }
+};
+
+static const struct shortHuffmanCodeTable fixedHuffmanDistanceTable = { 
+    { 
+       5,                      /* quick bits */
+       5,                      /* max code length */
+    }, 
+    {
+       HUFFMAN_ENTRY(0x00, 5), 
+       HUFFMAN_ENTRY(0x10, 5), 
+       HUFFMAN_ENTRY(0x08, 5), 
+       HUFFMAN_ENTRY(0x18, 5), 
+       HUFFMAN_ENTRY(0x04, 5), 
+       HUFFMAN_ENTRY(0x14, 5), 
+       HUFFMAN_ENTRY(0x0c, 5), 
+       HUFFMAN_ENTRY(0x1c, 5), 
+       HUFFMAN_ENTRY(0x02, 5), 
+       HUFFMAN_ENTRY(0x12, 5), 
+       HUFFMAN_ENTRY(0x0a, 5), 
+       HUFFMAN_ENTRY(0x1a, 5), 
+       HUFFMAN_ENTRY(0x06, 5), 
+       HUFFMAN_ENTRY(0x16, 5), 
+       HUFFMAN_ENTRY(0x0e, 5), 
+       HUFFMAN_ENTRY(0x1e, 5), 
+       HUFFMAN_ENTRY(0x01, 5), 
+       HUFFMAN_ENTRY(0x11, 5), 
+       HUFFMAN_ENTRY(0x09, 5), 
+       HUFFMAN_ENTRY(0x19, 5), 
+       HUFFMAN_ENTRY(0x05, 5), 
+       HUFFMAN_ENTRY(0x15, 5), 
+       HUFFMAN_ENTRY(0x0d, 5), 
+       HUFFMAN_ENTRY(0x1d, 5), 
+       HUFFMAN_ENTRY(0x03, 5), 
+       HUFFMAN_ENTRY(0x13, 5), 
+       HUFFMAN_ENTRY(0x0b, 5), 
+       HUFFMAN_ENTRY(0x1b, 5), 
+       HUFFMAN_ENTRY(0x07, 5), 
+       HUFFMAN_ENTRY(0x17, 5), 
+       HUFFMAN_ENTRY(0x0f, 5), 
+       HUFFMAN_ENTRY(0x1f, 5), 
+    }
+};
+
+#endif
+
+#endif
diff --git a/MPC.3.5.LINUX/preverifier/locale_md.h b/MPC.3.5.LINUX/preverifier/locale_md.h
new file mode 100644 (file)
index 0000000..b4e198b
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * @(#)locale_md.h    1.0 00/11/22
+ *
+ * Copyright 1995-1998 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LOCALE_MD_
+#define _LOCALE_MD_
+
+#include <locale.h>
+#define SET_DEFAULT_LOCALE setlocale(LC_ALL,"")
+
+#endif
diff --git a/MPC.3.5.LINUX/preverifier/main.c b/MPC.3.5.LINUX/preverifier/main.c
new file mode 100644 (file)
index 0000000..1212e30
--- /dev/null
@@ -0,0 +1,479 @@
+/* * @(#)main.c        1.6 00/08/26
+ *
+ * Copyright 1997, 1998 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+/*=========================================================================
+ * SYSTEM:    Verifier
+ * SUBSYSTEM: main program
+ * FILE:      main.c
+ * OVERVIEW:  Runs the Java class verifier.
+ * AUTHOR:    Sheng Liang, Sun Microsystems, Inc.
+ *            Modifications for JAR support, CLDC compliance, and comments,
+ *            Tasneem Sayeed, Sun Microsystems
+ *=======================================================================*/
+
+
+/*=========================================================================
+ * Include files
+ *=======================================================================*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <string.h>
+
+#include "sys_api.h"
+#include "path_md.h"
+#include "path.h"
+#include "oobj.h"
+//#include "jar.h"
+#include "locale_md.h"
+
+/*
+#include "../util/strings.h"
+#include "../util/error.h"
+#include "../util/message.h"
+#include "../structures/type_list.h"
+#include "../structures/string_list.h"
+#include "../structures/type.h"
+#include "../structures/identifier.h"
+#include "../structures/name_table.h"
+#include "../classgen/bytecode.h"
+#include "../structures/block.h"
+
+#include "../parser/parser.h"
+
+#include "../util/memory.h"
+
+#include "../main/static_entry.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+*/
+/*=========================================================================
+ * Globals and extern declarations
+ *=======================================================================*/
+
+char str_buffer[STRINGBUFFERSIZE];   /*  shared string buffer */
+
+int processedfile = 0;
+int errorCode = 0;               /* Error code returned by program */
+
+bool_t no_native_methods = FALSE;
+bool_t no_floating_point = FALSE;
+bool_t no_finalizers = FALSE;
+char tmp_dir[32];               /* temporary directory for storing
+                                                  verified classes */
+extern char *output_dir;         /* output directory */
+bool_t tmpDirExists = FALSE;
+
+extern void VerifyFile(register char *fn);
+//extern bool_t ProcessJARfile(char *buf, int len);
+//extern bool_t isJARfile(char *fn, int length);
+
+//static void usage(char *progname);
+
+
+/*=========================================================================
+ * FUNCTION:      recurse_dir()
+ * TYPE:          Handles recursive directories
+ * OVERVIEW:      Internal function called by ProcessInputs().
+ *
+ *  This function reads a directory, searching for either another directory,
+ *  JAR file or an individual class name that is to be verified.
+ *
+ * INTERFACE:
+ *   parameters:  dirname   name of the directory entry.
+ *                pkgname   name of the package
+ *   returns:     nothing
+ *=======================================================================*/
+/*
+static void recurse_dir(char *dirname, char *pkgname)
+{
+       struct dirent *ent;
+        char buf[MAXPACKAGENAME];
+        char pkgbuf[MAXPACKAGENAME];
+       DIR *dir = opendir(dirname);
+
+       if (dir == NULL) {
+               fprintf(stderr, "Can't open dir %s\n", dirname);
+               exit(1);
+       }
+       for (ent = readdir(dir); ent; ent = readdir(dir)) {
+               struct stat stat_buf;
+               char *name = ent->d_name;
+               int len;
+
+               if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
+                       continue;
+               }
+
+               strcpy(pkgbuf, pkgname);
+               if (pkgname[0] != 0) {
+                       strcat(pkgbuf, "/");
+               }
+
+                if (JAR_DEBUG && verbose)
+                       jio_fprintf(stderr,
+                       "recurse_dir: Reading filename [%s] from directory [%s]\n",
+                        name, dirname);
+
+               strcat(pkgbuf, name);
+
+               strcpy(buf, dirname);
+               strcat(buf, name);
+
+               stat(buf, &stat_buf);
+               len = strlen(buf);
+
+               if (stat_buf.st_mode & S_IFDIR) {
+                   // handle the recursive directory found
+                       strcat(buf, "/");
+                       if (JAR_DEBUG && verbose)
+                           jio_fprintf(stderr,
+                          "recurse_dir: Recursive directory found, calling recurse_dir ([%s] [%s])\n",
+                          buf, pkgbuf);
+                       recurse_dir(buf, pkgbuf);
+                       continue;
+               } else if (isJARfile (buf, len)) {
+
+                   //
+                     // this directory contains a JAR file which contains
+                     // the classes to be verified
+                     //
+
+                    if (JAR_DEBUG && verbose)
+                       jio_fprintf(stderr,
+                            "recurse_dir: Found JAR file [%s] in dir!\n", buf);
+
+                   if (!ProcessJARfile(buf, len)) {
+
+                       fprintf(stderr, "Not a valid JAR file [%s]\n", buf);
+                       exit(1);
+                   }
+              }
+
+               // we just have a class file that needs verification
+
+               len = strlen(pkgbuf);
+               if (len > 6 && strcmp(pkgbuf + len - 6, ".class") == 0) {
+
+                    pkgbuf[len - 6] = 0;
+
+                    if (JAR_DEBUG && verbose)
+                       jio_fprintf(stderr,
+                               "recurse_dir: Verifying Class [%s] \n", pkgbuf);
+                   VerifyFile(pkgbuf);
+               }
+       }
+
+       closedir(dir);
+}
+*/
+
+/*=========================================================================
+ * FUNCTION:      ProcessInputs()
+ * TYPE:          Processes inputs
+ * OVERVIEW:      Internal function called by main().
+ *
+ *  This function processes input entries for specifying classes that are to
+ *  be verified. The inputs may be in 3 forms: a directory, or nested
+ *  directories, one or more JAR files, or one or more individual class files.
+ *  If a directory entry is specified, it may also contain one or more JAR
+ *  files, or one or more individual class files.
+ *
+ * INTERFACE:
+ *   parameters:  argname:  directory, JAR file or an individual class file.
+ *   returns:     nothing
+ *=======================================================================*/
+/*
+static void ProcessInputs(char *argname)
+{
+    char buf[MAXPACKAGENAME];
+    struct stat stat_buf;
+    int res = stat(argname, &stat_buf);
+    int len;
+
+
+    strcpy(buf, argname);
+    len = strlen(argname);
+
+
+    if ((res == 0) && (stat_buf.st_mode & S_IFDIR)) {
+        /* Append dir separator if it does not yet exist.
+        if (buf[len - 1] != LOCAL_DIR_SEPARATOR &&
+           buf[len - 1] != DIR_SEPARATOR) {
+           buf[len] = DIR_SEPARATOR;
+           buf[len + 1] = 0;
+        }
+        pushDirectoryOntoClassPath(buf);
+        recurse_dir(buf, "");
+        popClassPath();
+    } else if ((res == 0) && (isJARfile (buf, len))) {
+        /* the classes to be verified are in a JAR file
+        if (!ProcessJARfile(buf, len)) {
+           fprintf(stderr, "Not a valid JAR file [%s]\n", buf);
+           exit(1);
+        }
+    } else {
+        char *p;
+        /* Convert all periods in the argname to slashes
+        for (p = buf; ((p = strchr(p, '.')) != 0); *p++ = '/');
+            if (JAR_DEBUG && verbose)
+               jio_fprintf(stderr,
+                       "ProcessInputs: Verifying file [%s]\n", buf );
+           VerifyFile(buf);
+    }
+}*/
+
+
+/*=========================================================================
+ * FUNCTION:      main()
+ * TYPE:          Runs the verifier.
+ * OVERVIEW:      Main function.
+ *
+ *  This is the main function that invokes the Java class verifier.
+ *
+ * INTERFACE:
+ *   parameters:  argc: arg count.
+ *                argv: arg value(s)
+ *   returns:     nothing
+ *=======================================================================*/
+/*
+int main(argc, argv)
+    register char **argv;
+{
+    char *progname;
+    char *argv0 = argv[0];
+
+    SET_DEFAULT_LOCALE;
+
+    if ((progname = strrchr(argv[0], LOCAL_DIR_SEPARATOR)) != 0) {
+       progname++;
+    } else {
+       progname = argv[0];
+    }
+
+    // initialize tmp_dir
+    memset(tmp_dir, 0, 32);
+
+    // initialize the seed for the random number
+    srand(time(NULL));
+
+    // generate a random temp directory name
+    sprintf(tmp_dir, "%s%d%c", "tmp", rand(), '\0');
+
+    while (--argc > 0)
+       if ((++argv)[0][0] == '-') {
+            if (strcmp(argv[0], "-verbose") == 0) {
+                extern bool_t verbose;
+                verbose = TRUE;
+#ifdef DEBUG_VERIFIER
+           } else if (strcmp(argv[0], "-verify-verbose") == 0) {
+               extern int verify_verbose;
+               verify_verbose++;
+#endif
+            } else if (strcmp(argv[0], "-cldc") == 0) {
+                no_native_methods = TRUE;
+                no_floating_point = TRUE;
+                no_finalizers = TRUE;
+            } else if (strcmp(argv[0], "-nofinalize") == 0) {
+                no_finalizers = TRUE;
+            } else if (strcmp(argv[0], "-nonative") == 0) {
+                no_native_methods = TRUE;
+            } else if (strcmp(argv[0], "-nofp") == 0) {
+                no_floating_point = TRUE;
+            } else if (strcmp(argv[0], "-Xns") == 0) {
+                extern bool_t stack_map_on;
+                stack_map_on = FALSE;
+            } else if (strcmp(argv[0], "-Xni") == 0) {
+                extern bool_t inline_jsr_on;
+                inline_jsr_on = FALSE;
+            } else if (strcmp(argv[0], "-d") == 0) {
+                output_dir = strdup(argv[1]);
+               argc--; argv++;
+           } else if (strcmp(argv[0], "-classpath") == 0) {
+               if (argc > 1) {
+                   char *buf = (char *)malloc(strlen(argv[1]) + 32);
+                   sprintf(buf, "CLASSPATH=%s", argv[1]);
+                   putenv(buf);
+                   argc--; argv++;
+               } else {
+                   //fprintf(stderr,
+                       // "-classpath requires class path specification\n");
+//                 usage(progname);
+                   exit(1);
+               }
+           } else {
+               //fprintf(stderr, "%s: Illegal option %s\n\n", progname, argv[0]);
+//             usage(progname);
+               exit(1);
+           }
+       } else if (argv[0][0] == '@') {
+            char *new_argv[MAXOPTIONS];
+            char *buffer;
+           int new_argc = 1;
+            char *token;
+            bool_t done = FALSE;
+            struct stat sbuf;
+           FILE *fp;
+            int buflen;
+            int filelength;
+            int i;
+
+           new_argv[0] = argv0;
+
+           fp = fopen(&argv[0][1], "rt");
+           if (fp == NULL) {
+               fprintf(stderr, "Can't open %s\n", &argv[0][1]);
+               exit(1);
+           }
+
+            // get the size of the file
+            stat(&argv[0][1], &sbuf);
+            filelength = sbuf.st_size;
+
+            // allocate the buffer
+            if ((buffer = (char *) malloc(filelength+1)) == NULL) {
+                fprintf(stderr, "Out of memory\n");
+                exit(1);
+            }
+
+            if (fgets(buffer, filelength+1, fp) != NULL) {
+                buflen = strlen(buffer);
+
+                if (DEBUG_READFROMFILE) {
+                    fprintf(stderr, "Buffer = [%s]\n", buffer);
+                }
+                // get the first parameter
+                token = strtok(buffer, " \0\n\r\t\"");
+
+                // Search for parameters until none can be found
+                while (token != NULL && !done) {
+
+                    if ((strcmp(token, "\n") == 0) ||
+                        (strcmp(token, "\r") == 0) ||
+                        (strcmp(token, "\t") == 0)) {
+                        // <NL>, <CR> or <TAB>
+                        done = TRUE;
+                    } else {
+                        // On Win32, it's possible to have a <CR> <LF>
+                        // appended at the end of the token, which needs
+                        // to be extracted before restoring the arg
+                        //
+                        char *p;
+                        // Convert all <CR> <LF> to NULL
+                        for (p = token; *p != '\0'; p++) {
+                            if (*p == '\n' || *p == '\r')
+                                *p = '\0';
+                        }
+
+                        // save the parameter
+                        new_argv[new_argc++] = token;
+
+                        if ((strcmp(token, "-classpath") == 0) ||
+                            (strcmp(token, "-d")         == 0)) {
+                            // search for the beginning of a string literal
+                            token = strtok(NULL, "\"");
+
+                        } else { // get the next token
+                            token = strtok(NULL," \0\n\r\t\"");
+                        }
+                    }
+                }
+
+                if (DEBUG_READFROMFILE) {
+                    // print the arguments after restoring all of them
+                    for (i=0; i < new_argc; i++)
+                        fprintf(stderr, "new_argv[%d] = [%s]\n", i, new_argv[i]);
+                }
+            }
+
+           fclose(fp);
+           main(new_argc, new_argv);
+
+            if (buffer != NULL) {
+                free(buffer);
+            }
+           argc--; argv++;
+       } else {
+           processedfile++;
+            if (strlen(argv[0]) > MAXPACKAGENAME) {
+       //      fprintf(stderr,
+       //               "Package name for class exceeds max allowed size [1024]\n");
+//             usage(progname);
+               exit(1);
+            }
+
+
+
+           ProcessInputs(argv[0]);
+       }
+    if (processedfile == 0) {
+       usage(progname);
+       exit(1);
+    }
+    return errorCode;  // normal errorCode=0 indicates successful completion
+}*/
+/*
+static void usage(char *progname) {
+    fprintf(stderr, "Usage: %s [options] classnames|dirnames ...\n", progname);
+    fprintf(stderr, "\n");
+    fprintf(stderr, "where options include:\n");
+    fprintf(stderr, "   -classpath     <directories separated by '%c'>\n", (char)PATH_SEPARATOR);
+    fprintf(stderr, "                  Directories in which to look for classes\n");
+    fprintf(stderr, "   -d <directory> Directory in which output is written (default is ./output/)\n");
+
+    fprintf(stderr, "   -cldc          Checks for existence of language features prohibited\n");
+    fprintf(stderr, "                  by CLDC (native methods, floating point and finalizers)\n");
+
+    fprintf(stderr, "   -nofinalize    No finalizers allowed\n");
+    fprintf(stderr, "   -nonative      No native methods allowed\n");
+    fprintf(stderr, "   -nofp          No floating point operations allowed\n");
+    fprintf(stderr, "   @<filename>    Read command line arguments from a text file\n");
+    fprintf(stderr, "                  Command line arguments must all be on a single line\n");
+    fprintf(stderr, "                  Directory names must be enclosed in double quotes (\")\n");
+
+    fprintf(stderr, "\n");
+}
+    */
+
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+//static
+int
+OpenCode(char *fn, char *sfn, char *dir, struct stat * st)
+{
+    long codefd;
+       char *fullname = (char*) malloc(strlen(fn) + strlen(dir) + 10);
+       #ifdef WIN32
+       sprintf(fullname, "%s\\%s", dir, fn);
+       #endif
+       #ifdef UNIX
+       sprintf(fullname, "%s/%s", dir, fn);
+       #endif
+    if (fn == 0 || (codefd = open(fullname, O_BINARY, 0644)) < 0
+           || fstat(codefd, st) < 0)
+       {
+               free(fullname);
+               return -2;
+       }
+       free(fullname);
+    return codefd;
+}
diff --git a/MPC.3.5.LINUX/preverifier/oobj.h b/MPC.3.5.LINUX/preverifier/oobj.h
new file mode 100644 (file)
index 0000000..8ef2c96
--- /dev/null
@@ -0,0 +1,682 @@
+/*
+ * @(#)oobj.h   1.5 00/04/12
+ *
+ * Copyright 1995-1998 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+/*
+ * Java object header format
+ */
+
+#ifndef _OOBJ_H_
+#define _OOBJ_H_
+
+#include <stddef.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#include "typedefs.h"
+#include "signature.h"
+
+#define JAVA_CLASSFILE_MAGIC              0xCafeBabe
+
+#define JAVASRCEXT "java"
+#define JAVASRCEXTLEN 4
+#define JAVAOBJEXT "class"
+#define JAVAOBJEXTLEN 5
+
+#define JAVA_VERSION     45
+#define JAVA_MINOR_VERSION 3
+#define ARRAYHEADER     long alloclen
+
+/* The size (in bytes) of a statically allocated area that the
+ * verifier uses internally in various string operations.
+ */
+#ifndef STRINGBUFFERSIZE
+#define STRINGBUFFERSIZE 512
+#endif
+
+#define MAXOPTIONS 2048   /* maximum # of parameters */
+
+/* maximum size allowed for package name of a class file */
+#define MAXPACKAGENAME 1024
+
+#define MAXPATHLEN     255
+
+#define HandleTo(T) typedef struct H##T { Class##T *obj; struct methodtable *methods;} H##T
+
+
+typedef long OBJECT;
+typedef OBJECT Classjava_lang_Object;
+typedef OBJECT ClassObject;
+HandleTo(java_lang_Object);
+typedef Hjava_lang_Object JHandle;
+typedef Hjava_lang_Object HObject;
+
+typedef unsigned short unicode;
+
+extern unicode  *str2unicode(char *, unicode *, long);
+extern char *int642CString(int64_t number, char *buf, int buflen);
+
+#define ALIGN(n) (((n)+3)&~3)
+#define UCALIGN(n) ((unsigned char *)ALIGN((int)(n)))
+
+struct Hjava_lang_Class;    /* forward reference for some compilers */
+struct Classjava_lang_Class;    /* forward reference for some compilers */
+
+typedef struct Classjava_lang_Class Classjava_lang_Class;
+
+HandleTo(java_lang_Class);
+typedef struct Hjava_lang_Class ClassClass;
+
+
+struct fieldblock {
+    ClassClass *clazz;
+    char *signature;
+    char *name;
+    unsigned long ID;
+    unsigned short access;
+    union {
+    unsigned long offset;   /* info of data */
+    OBJECT static_value;
+    void *static_address;
+    } u;
+    unsigned deprecated:1;
+    unsigned synthetic:1;
+};
+
+#define fieldname(fb)    ((fb)->name)
+#define fieldsig(fb)     ((fb)->signature)
+#define fieldIsArray(fb) (fieldsig(fb)[0] == SIGNATURE_ARRAY)
+#define fieldIsClass(fb) (fieldsig(fb)[0] == SIGNATURE_CLASS)
+#define fieldclass(fb)   ((fb)->clazz)
+
+struct execenv;
+
+#define VERIFIER_TOOL
+
+/* Includes/eliminates a large amount of optional debugging code
+ * (such as class and stack frame printing operations) in/from
+ * the system.  By eliminating debug code, the system will be smaller.
+ * Inclusion of debugging code increases the size of the system but
+ * does not introduce any performance overhead unless calls to the
+ * debugging routines are added to the source code or various tracing
+ * options are turned on.
+ */
+
+#ifndef INCLUDEDEBUGCODE
+#define INCLUDEDEBUGCODE 0
+#endif
+
+#define DEBUG_VERIFIER 1
+#define DEBUG_READFROMFILE 0
+
+enum {
+    ITEM_Bogus,
+    ITEM_Void,          /* only as a function return value */
+    ITEM_Integer,
+    ITEM_Float,
+    ITEM_Double,
+    ITEM_Double_2,      /* 2nd word of double in register */
+    ITEM_Long,
+    ITEM_Long_2,        /* 2nd word of long in register */
+    ITEM_InitObject,        /* "this" is init method, before call
+                    to super() */
+    ITEM_Object,        /* Extra info field gives name. */
+    ITEM_NewObject,     /* Like object, but uninitialized. */
+    ITEM_ReturnAddress,     /* Extra info gives instr # of start pc */
+    /* The following three are only used within array types.
+     * Normally, we use ITEM_Integer, instead. */
+    ITEM_Boolean,
+    ITEM_Byte,
+    ITEM_Short,
+    ITEM_Char
+};
+
+/* These are the constants that appear in class files. */
+enum {
+    CF_ITEM_Bogus,
+    CF_ITEM_Integer,
+    CF_ITEM_Float,
+    CF_ITEM_Double,
+    CF_ITEM_Long,
+    CF_ITEM_Null,
+    CF_ITEM_InitObject,
+
+    CF_ITEM_Object,
+    CF_ITEM_NewObject,
+};
+
+struct map_entry {
+    unsigned char type;
+    long info;
+};
+
+struct stack_map {
+    int offset;
+    int nlocals;
+    struct map_entry *locals;
+    int nstacks;
+    struct map_entry *stacks;
+};
+
+struct methodblock {
+    struct fieldblock fb;
+    unsigned char       *code;  /* the code */
+    struct CatchFrame   *exception_table;
+    struct lineno       *line_number_table;
+    struct localvar     *localvar_table;
+
+    unsigned long        code_length;
+    unsigned long        exception_table_length;
+    unsigned long        line_number_table_length;
+    unsigned long        localvar_table_length;
+
+    bool_t  (*invoker)
+      (JHandle *o, struct methodblock *mb, int args_size, struct execenv *ee);
+    unsigned short       args_size; /* total size of all arguments */
+    unsigned short       maxstack;  /* maximum stack usage */
+    unsigned short       nlocals;   /* maximum number of locals */
+    /* 2 spare bytes here */
+    void                *CompiledCode; /* it's type is machine dependent */
+    void                *CompiledCodeInfo; /* it's type is machine dependent */
+    long                 CompiledCodeFlags; /* machine dependent bits */
+    unsigned long        inlining;      /* possible inlining of code */
+    unsigned short       nexceptions;   /* number of checked exceptions */
+    unsigned short       *exceptions;   /* constant pool indices */
+    char                 *mp_marks;
+    int                  n_stack_maps;
+    struct stack_map     *stack_maps;
+};
+
+struct HIOstream;
+
+struct methodtable {
+    ClassClass *classdescriptor;
+    struct methodblock *methods[1];
+};
+
+struct imethodtable {
+    int icount;         /* number of interfaces to follow */
+    struct {
+    ClassClass *classdescriptor;
+    unsigned long *offsets; /* info of data */
+    } itable[1];
+};
+
+typedef struct {
+    char body[1];
+} ArrayOfByte;
+typedef ArrayOfByte ClassArrayOfByte;
+HandleTo(ArrayOfByte);
+
+typedef struct {
+    unicode body[1];
+} ArrayOfChar;
+typedef ArrayOfChar ClassArrayOfChar;
+HandleTo(ArrayOfChar);
+
+typedef struct {
+    signed short body[1];
+} ArrayOfShort;
+typedef ArrayOfShort ClassArrayOfShort;
+HandleTo(ArrayOfShort);
+
+typedef struct {
+    long        body[1];
+} ArrayOfInt;
+typedef ArrayOfInt ClassArrayOfInt;
+HandleTo(ArrayOfInt);
+
+typedef struct {
+    int64_t        body[1];
+} ArrayOfLong;
+typedef ArrayOfLong ClassArrayOfLong;
+HandleTo(ArrayOfLong);
+
+typedef struct {
+    float       body[1];
+} ArrayOfFloat;
+typedef ArrayOfFloat ClassArrayOfFloat;
+HandleTo(ArrayOfFloat);
+
+typedef struct {
+    double       body[1];
+} ArrayOfDouble;
+typedef ArrayOfDouble ClassArrayOfDouble;
+HandleTo(ArrayOfDouble);
+
+typedef struct {
+    JHandle *(body[1]);
+} ArrayOfArray;
+typedef ArrayOfArray ClassArrayOfArray;
+HandleTo(ArrayOfArray);
+
+typedef struct {
+    HObject *(body[1]);
+} ArrayOfObject;
+typedef ArrayOfObject ClassArrayOfObject;
+HandleTo(ArrayOfObject);
+
+typedef struct Hjava_lang_String HString;
+
+typedef struct {
+    HString  *(body[1]);
+} ArrayOfString;
+typedef ArrayOfString ClassArrayOfString;
+HandleTo(ArrayOfString);
+
+
+/* Note: any handles in this structure must also have explicit
+   code in the ScanClasses() routine of the garbage collector
+   to mark the handle. */
+struct Classjava_lang_Class {
+    /* Things following here are saved in the .class file */
+    unsigned short       major_version;
+    unsigned short       minor_version;
+    char                    *name;
+    char                    *super_name;
+    char                    *source_name;
+    ClassClass              *superclass;
+    ClassClass              *HandleToSelf;
+    struct Hjava_lang_ClassLoader *loader;
+    struct methodblock      *finalizer;
+
+    union cp_item_type      *constantpool;
+    struct methodblock      *methods;
+    struct fieldblock       *fields;
+    short                   *implements;
+
+    struct methodtable      *methodtable;
+    struct methodtable      *methodtable_mem;
+    struct fieldblock      **slottable;
+
+       int superclass_idx;
+
+    HString         *classname;
+
+    union {
+    struct {
+        unsigned long   thishash;     /* unused */
+        unsigned long   totalhash;    /* unused */
+    } cbhash;
+    struct {
+        unsigned char   typecode;     /* VM typecode */
+        char        typesig;      /* signature constant */
+        unsigned char   slotsize;     /* (bytes) in slot */
+        unsigned char   elementsize;      /* (bytes) in array */
+        unsigned long   xxspare;
+    } cbtypeinfo;
+    } hashinfo;
+
+    unsigned short           constantpool_count;  /* number of items in pool */
+    unsigned short           methods_count;       /* number of methods */
+    unsigned short           fields_count;        /* number of fields */
+    unsigned short           implements_count;    /* number of protocols */
+
+    unsigned short           methodtable_size;    /* the size of method table */
+    unsigned short           slottbl_size;        /* size of slottable */
+    unsigned short           instance_size;       /* (bytes) of an instance */
+
+    unsigned short access;           /* how this class can be accesses */
+    unsigned short flags;        /* see the CCF_* macros */
+    struct HArrayOfObject   *signers;
+    struct   imethodtable   *imethodtable;
+
+    void                    *init_thread; /* EE of initializing thread */
+
+    ClassClass              *last_subclass_of;
+    void            *reserved_for_jit;
+    char                    *absolute_source_name;
+    struct { int high, low; } timestamp;
+    int                     n_new_class_entries;
+    char                    **new_class_entries;
+    int                     n_new_utf8_entries;
+    char                    **new_utf8_entries;
+    int             has_stack_maps;
+
+    int                     inner_classes_count;
+    struct innerClasses    *inner_classes;
+
+    unsigned deprecated:1;
+    unsigned synthetic:1;
+    unsigned hasTimeStamp:1;
+};
+
+struct innerClasses {
+    int inner_class;
+    int outer_class;
+    char *inner_name;
+    int access;
+};
+
+extern void FreeClass(ClassClass *cb);
+extern void MakeClassSticky(ClassClass *cb);
+
+#define cbAccess(cb)          ((unhand(cb))->access)
+#define cbClassname(cb)       ((unhand(cb))->classname)
+#define cbConstantPool(cb)    ((unhand(cb))->constantpool)
+#define cbConstantPoolCount(cb) ((unhand(cb))->constantpool_count)
+#define cbFields(cb)          ((unhand(cb))->fields)
+#define cbFieldsCount(cb)     ((unhand(cb))->fields_count)
+#define cbFinalizer(cb)       ((unhand(cb))->finalizer)
+#define cbFlags(cb)           ((unhand(cb))->flags)
+#define cbHandle(cb)          (cb)
+#define cbImplements(cb)      ((unhand(cb))->implements)
+#define cbImplementsCount(cb) ((unhand(cb))->implements_count)
+#define cbInstanceSize(cb)    ((unhand(cb))->instance_size)
+#define cbIntfMethodTable(cb) ((unhand(cb))->imethodtable)
+#define cbLastSubclassOf(cb)  ((unhand(cb))->last_subclass_of)
+#define cbLoader(cb)          ((unhand(cb))->loader)
+#define cbMajorVersion(cb)    ((unhand(cb))->major_version)
+#define cbMethods(cb)         ((unhand(cb))->methods)
+#define cbMethodsCount(cb)    ((unhand(cb))->methods_count)
+#define cbMethodTable(cb)     ((unhand(cb))->methodtable)
+#define cbMethodTableMem(cb)  ((unhand(cb))->methodtable_mem)
+#define cbMethodTableSize(cb) ((unhand(cb))->methodtable_size)
+#define cbMinorVersion(cb)    ((unhand(cb))->minor_version)
+#define cbName(cb)            ((unhand(cb))->name)
+#define cbSigners(cb)         ((unhand(cb))->signers)
+#define cbSlotTable(cb)       ((unhand(cb))->slottable)
+#define cbSlotTableSize(cb)   ((unhand(cb))->slottbl_size)
+#define cbSourceName(cb)      ((unhand(cb))->source_name)
+#define cbSuperclass(cb)      ((unhand(cb))->superclass)
+#define cbSuperName(cb)       ((unhand(cb))->super_name)
+#define cbThisHash(cb)        ((unhand(cb))->hashinfo.cbhash.thishash)
+#define cbTotalHash(cb)       ((unhand(cb))->hashinfo.cbhash.totalhash)
+#define cbInitThread(cb)      ((unhand(cb))->init_thread)
+#define cbInnerClasses(cb)     ((unhand(cb))->inner_classes)
+#define cbInnerClassesCount(cb)((unhand(cb))->inner_classes_count)
+
+
+
+#define cbAbsoluteSourceName(cb) ((unhand(cb))->absolute_source_name)
+#define cbTimestamp(cb)       ((unhand(cb))->timestamp)
+
+#define cbIsInterface(cb)       ((cbAccess(cb) & ACC_INTERFACE) != 0)
+#define cbIsAbstract(cb)        ((cbAccess(cb) & ACC_ABSTRACT) != 0)
+#define cbAccessNotAbstract(cb) ((unhand(cb))->access & ~ACC_ABSTRACT)
+
+/* These are currently only valid for primitive types */
+#define cbIsPrimitive(cb)      (CCIs(cb, Primitive))
+#define cbTypeCode(cb)         ((unhand(cb))->hashinfo.cbtypeinfo.typecode)
+#define cbTypeSig(cb)          ((unhand(cb))->hashinfo.cbtypeinfo.typesig)
+#define cbSlotSize(cb)         ((unhand(cb))->hashinfo.cbtypeinfo.slotsize)
+#define cbElementSize(cb)      ((unhand(cb))->hashinfo.cbtypeinfo.elementsize)
+
+extern char *classname2string(char *str, char *dst, int size);
+
+#define twoword_static_address(fb) ((fb)->u.static_address)
+#define normal_static_address(fb)  (&(fb)->u.static_value)
+
+/* ClassClass flags */
+#define CCF_IsSysLock     0x01  /* any instance treated as a "system" lock */
+#define CCF_IsResolved    0x02  /* has <clinit> been run? */
+#define CCF_IsError   0x04  /* Resolution caused an error */
+#define CCF_IsSoftRef     0x08  /* whether this is class Ref or subclass */
+#define CCF_IsInitialized 0x10  /* whether this is class has been inited */
+#define CCF_IsLinked      0x20  /* Has symbolic entries been linked */
+#define CCF_IsVerified    0x40  /* has the verifier been run */
+
+#define CCF_IsPrimitive   0x100 /* if pseudo-class for a primitive type */
+#define CCF_IsReferenced  0x200 /* Class is in use */
+#define CCF_IsSticky      0x400 /* Don't unload this class */
+
+#define CCIs(cb,flag) (((unhand(cb))->flags & CCF_Is##flag) != 0)
+#define CCSet(cb,flag) ((unhand(cb))->flags |= CCF_Is##flag)
+#define CCClear(cb,flag) ((unhand(cb))->flags &= ~CCF_Is##flag)
+
+/* map from pc to line number */
+struct lineno {
+    unsigned long pc,
+    line_number;
+};
+
+extern struct lineno *lntbl;
+extern long lntsize, lntused;
+
+/* Symbol table entry for local variables and parameters.
+   pc0/length defines the range that the variable is valid, slot
+   is the position in the local variable array in ExecEnv.
+   nameoff and sigoff are offsets into the string table for the
+   variable name and type signature.  A variable is defined with
+   DefineVariable, and at that time, the node for that name is
+   stored in the localvar entry.  When code generate is completed
+   for a particular scope, a second pass it made to replace the
+   src node entry with the correct length. */
+
+struct localvar {
+    long pc0;           /* starting pc for this variable */
+    long length;        /* -1 initially, end pc - pc when we're done */
+    char *name;                 /*  */
+    char *signature;
+    long slot;          /* local variable slot */
+};
+
+/* Try/catch is implemented as follows.  On a per class basis,
+   there is a catch frame handler (below) for each catch frame
+   that appears in the source.  It contains the pc range of the
+   corresponding try body, a pc to jump to in the event that that
+   handler is chosen, and a catchType which must match the object
+   being thrown if that catch handler is to be taken.
+
+   The list of catch frames are sorted by pc.  If one range is
+   inside another, then outer most range (the one that encompasses
+   the other) appears last in the list.  Therefore, it is possible
+   to search forward, and the first one that matches is the
+   innermost one.
+
+   Methods with catch handlers will layout the code without the
+   catch frames.  After all the code is generated, the catch
+   clauses are generated and table entries are created.
+
+   When the class is complete, the table entries are dumped along
+   with the rest of the class. */
+
+struct CatchFrame {
+    long    start_pc, end_pc;   /* pc range of corresponding try block */
+    long    handler_pc;         /* pc of catch handler */
+    void*   compiled_CatchFrame; /* space to be used by machine code */
+    short   catchType;          /* type of catch parameter */
+};
+
+#define MC_SUPER        (1<<5)
+#define MC_NARGSMASK    (MC_SUPER-1)
+#define MC_INT          (0<<6)
+#define MC_FLOAT        (1<<6)
+#define MC_VOID         (2<<6)
+#define MC_OTHER        (3<<6)
+#define MC_TYPEMASK     (3<<6)
+
+enum {
+    CONSTANT_Utf8 = 1,
+    CONSTANT_Unicode,       /* unused */
+    CONSTANT_Integer,
+    CONSTANT_Float,
+    CONSTANT_Long,
+    CONSTANT_Double,
+    CONSTANT_Class,
+    CONSTANT_String,
+    CONSTANT_Fieldref,
+    CONSTANT_Methodref,
+    CONSTANT_InterfaceMethodref,
+    CONSTANT_NameAndType
+};
+
+union cp_item_type {
+    int i;
+    float f;
+    char *cp;
+    unsigned char *type;        /* for type table */
+    ClassClass *clazz;
+    struct methodblock *mb;
+    struct fieldblock *fb;
+    struct Hjava_lang_String *str;
+    void *p;                    /* for very rare occasions */
+};
+
+typedef union cp_item_type cp_item_type;
+
+#define CONSTANT_POOL_ENTRY_RESOLVED 0x80
+#define CONSTANT_POOL_ENTRY_TYPEMASK 0x7F
+#define CONSTANT_POOL_TYPE_TABLE_GET(cp,i) (((unsigned char *)(cp))[i])
+#define CONSTANT_POOL_TYPE_TABLE_PUT(cp,i,v) (CONSTANT_POOL_TYPE_TABLE_GET(cp,i) = (v))
+#define CONSTANT_POOL_TYPE_TABLE_SET_RESOLVED(cp,i) \
+    (CONSTANT_POOL_TYPE_TABLE_GET(cp,i) |= CONSTANT_POOL_ENTRY_RESOLVED)
+#define CONSTANT_POOL_TYPE_TABLE_IS_RESOLVED(cp,i) \
+    ((CONSTANT_POOL_TYPE_TABLE_GET(cp,i) & CONSTANT_POOL_ENTRY_RESOLVED) != 0)
+#define CONSTANT_POOL_TYPE_TABLE_GET_TYPE(cp,i) \
+        (CONSTANT_POOL_TYPE_TABLE_GET(cp,i) & CONSTANT_POOL_ENTRY_TYPEMASK)
+
+#define CONSTANT_POOL_TYPE_TABLE_INDEX 0
+#define CONSTANT_POOL_UNUSED_INDEX 1
+
+/* The following are used by the constant pool of "array" classes. */
+
+#define CONSTANT_POOL_ARRAY_DEPTH_INDEX 1
+#define CONSTANT_POOL_ARRAY_TYPE_INDEX 2
+#define CONSTANT_POOL_ARRAY_CLASS_INDEX 3
+#define CONSTANT_POOL_ARRAY_LENGTH 4
+
+/*
+ * Package shorthand: this isn't obviously the correct place.
+ */
+#define JAVAPKG         "java/lang/"
+#define JAVAIOPKG       "java/io/"
+#define JAVANETPKG      "java/net/"
+
+#define unhand(o) ((o)->obj)
+
+
+extern ClassClass *classJavaLangClass;     /* class java/lang/Class */
+extern ClassClass *classJavaLangObject;    /* class java/lang/Object */
+extern ClassClass *classJavaLangString;    /* class java/lang/String */
+
+extern ClassClass *classJavaLangThrowable;
+extern ClassClass *classJavaLangException;
+extern ClassClass *classJavaLangError;
+extern ClassClass *classJavaLangRuntimeException;
+extern ClassClass *classJavaLangThreadDeath;
+
+extern ClassClass *interfaceJavaLangCloneable; /* class java/lang/Cloneable */
+extern ClassClass *interfaceJavaIoSerializable; /* class java/io/Serializable */
+
+enum { VERIFY_NONE, VERIFY_REMOTE, VERIFY_ALL };
+
+extern int verifyclasses;
+extern bool_t verbose;
+extern char * const opnames[];
+
+int jio_snprintf(char *str, size_t count, const char *fmt, ...);
+int jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args);
+
+int jio_printf(const char *fmt, ...);
+int jio_fprintf(FILE *, const char *fmt, ...);
+int jio_vfprintf(FILE *, const char *fmt, va_list args);
+
+struct StrIDhash;
+unsigned short Str2ID(struct StrIDhash **, char *, void ***, int);
+char *ID2Str(struct StrIDhash *, unsigned short, void ***);
+void Str2IDFree(struct StrIDhash **);
+
+unsigned NameAndTypeToHash(char *name, char *type);
+bool_t IsSameClassPackage(ClassClass *class1, ClassClass *class2);
+unsigned Signature2ArgsSize(char *method_signature);
+char *GetClassConstantClassName(cp_item_type *constant_pool, int index);
+ClassClass *FindClass(struct execenv *ee, char *name, bool_t resolve);
+ClassClass *FindClassFromClass(struct execenv *ee, char *name,
+                   bool_t resolve, ClassClass *from);
+
+bool_t createInternalClass(unsigned char *bytes, unsigned char *limit,
+                           ClassClass *cb, struct Hjava_lang_ClassLoader *,
+                            char *utfname, char **detail);
+
+bool_t VerifyClass(ClassClass *cb);
+//bool_t IsLegalClassname(char *name, bool_t allowArrayClass);
+bool_t verify_class_codes(ClassClass *cb);
+
+struct execenv {
+    /* Detecting class circularities */
+    struct seenclass {
+    ClassClass    *cb;
+    struct seenclass *next;
+    } seenclasses;
+
+    /* error message occurred during class loading */
+    char *class_loading_msg;
+};
+
+typedef struct execenv ExecEnv;
+
+extern ExecEnv * EE();
+
+ClassClass *FindStickySystemClass(struct execenv *, char *, bool_t resolve);
+bool_t VerifyClassAccess(ClassClass *, ClassClass *, bool_t);
+void InitializeInvoker(ClassClass *cb);
+bool_t RunStaticInitializers(ClassClass *cb);
+ClassClass *ClassLoaderFindClass(ExecEnv *ee,
+                 struct Hjava_lang_ClassLoader *loader,
+                 char *name, bool_t resolve);
+ClassClass *LoadClassLocally(char *name);
+ClassClass *createFakeArrayClass(char *name, int base_type, int depth,
+                 ClassClass *inner_cb,
+                 struct Hjava_lang_ClassLoader *);
+ClassClass *createPrimitiveClass(char *name, char sig, unsigned char typecode,
+    unsigned char slotsize, unsigned char elementsize);
+
+bool_t isJARfile(char *fn, int length);
+
+#define BINCLASS_LOCK()
+#define BINCLASS_UNLOCK()
+#define LOADCLASS_LOCK()
+#define LOADCLASS_UNLOCK()
+#define NAMETYPEHASH_LOCK()
+#define NAMETYPEHASH_UNLOCK()
+
+#define FINALIZER_METHOD_NAME "finalize"
+#define FINALIZER_METHOD_SIGNATURE "()V"
+
+#define CLS_RESLV_INIT_CLASS    "java/lang/Class"
+#define CLS_RESLV_INIT_OBJECT   "java/lang/Object"
+#define CLS_RESLV_INIT_REF      "sun/misc/Ref"
+
+#define METHOD_FLAG_BITS 5
+#define FLAG_MASK       ((1<<METHOD_FLAG_BITS)-1)  /* valid flag bits */
+#define METHOD_MASK     (~FLAG_MASK)  /* valid mtable ptr bits */
+#define LENGTH_MASK     METHOD_MASK
+
+#define mt_slot(methodtable, slot) (methodtable)->methods[slot]
+
+#define monitorEnter(m)
+#define monitorExit(m)
+
+#define exceptionOccurred(ee) 0
+void SignalError(struct execenv *, char *, char *);
+
+void panic(const char *format, ...);
+
+void printCurrentClassName(void);
+
+void ensure_dir_exists(char *dir);
+void ensure_dir_writable(char *dir);
+
+extern bool_t no_native_methods;
+extern bool_t no_floating_point;
+extern bool_t no_finalizers;
+
+extern int errorCode;         /* status error returned by program*/
+                              /* Set to 1 if any errors encountered
+                               * during class verification in VerifyFile()
+                               */
+#endif /* !_OOBJ_H_ */
diff --git a/MPC.3.5.LINUX/preverifier/opcodes.h b/MPC.3.5.LINUX/preverifier/opcodes.h
new file mode 100644 (file)
index 0000000..a797db4
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ * Copyright 1995-2002 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+typedef enum {
+  opc_nop = 0,
+  opc_aconst_null = 1,
+  opc_iconst_m1 = 2,
+  opc_iconst_0 = 3,
+  opc_iconst_1 = 4,
+  opc_iconst_2 = 5,
+  opc_iconst_3 = 6,
+  opc_iconst_4 = 7,
+  opc_iconst_5 = 8,
+  opc_lconst_0 = 9,
+  opc_lconst_1 = 10,
+  opc_fconst_0 = 11,
+  opc_fconst_1 = 12,
+  opc_fconst_2 = 13,
+  opc_dconst_0 = 14,
+  opc_dconst_1 = 15,
+  opc_bipush = 16,
+  opc_sipush = 17,
+  opc_ldc = 18,
+  opc_ldc_w = 19,
+  opc_ldc2_w = 20,
+  opc_iload = 21,
+  opc_lload = 22,
+  opc_fload = 23,
+  opc_dload = 24,
+  opc_aload = 25,
+  opc_iload_0 = 26,
+  opc_iload_1 = 27,
+  opc_iload_2 = 28,
+  opc_iload_3 = 29,
+  opc_lload_0 = 30,
+  opc_lload_1 = 31,
+  opc_lload_2 = 32,
+  opc_lload_3 = 33,
+  opc_fload_0 = 34,
+  opc_fload_1 = 35,
+  opc_fload_2 = 36,
+  opc_fload_3 = 37,
+  opc_dload_0 = 38,
+  opc_dload_1 = 39,
+  opc_dload_2 = 40,
+  opc_dload_3 = 41,
+  opc_aload_0 = 42,
+  opc_aload_1 = 43,
+  opc_aload_2 = 44,
+  opc_aload_3 = 45,
+  opc_iaload = 46,
+  opc_laload = 47,
+  opc_faload = 48,
+  opc_daload = 49,
+  opc_aaload = 50,
+  opc_baload = 51,
+  opc_caload = 52,
+  opc_saload = 53,
+  opc_istore = 54,
+  opc_lstore = 55,
+  opc_fstore = 56,
+  opc_dstore = 57,
+  opc_astore = 58,
+  opc_istore_0 = 59,
+  opc_istore_1 = 60,
+  opc_istore_2 = 61,
+  opc_istore_3 = 62,
+  opc_lstore_0 = 63,
+  opc_lstore_1 = 64,
+  opc_lstore_2 = 65,
+  opc_lstore_3 = 66,
+  opc_fstore_0 = 67,
+  opc_fstore_1 = 68,
+  opc_fstore_2 = 69,
+  opc_fstore_3 = 70,
+  opc_dstore_0 = 71,
+  opc_dstore_1 = 72,
+  opc_dstore_2 = 73,
+  opc_dstore_3 = 74,
+  opc_astore_0 = 75,
+  opc_astore_1 = 76,
+  opc_astore_2 = 77,
+  opc_astore_3 = 78,
+  opc_iastore = 79,
+  opc_lastore = 80,
+  opc_fastore = 81,
+  opc_dastore = 82,
+  opc_aastore = 83,
+  opc_bastore = 84,
+  opc_castore = 85,
+  opc_sastore = 86,
+  opc_pop = 87,
+  opc_pop2 = 88,
+  opc_dup = 89,
+  opc_dup_x1 = 90,
+  opc_dup_x2 = 91,
+  opc_dup2 = 92,
+  opc_dup2_x1 = 93,
+  opc_dup2_x2 = 94,
+  opc_swap = 95,
+  opc_iadd = 96,
+  opc_ladd = 97,
+  opc_fadd = 98,
+  opc_dadd = 99,
+  opc_isub = 100,
+  opc_lsub = 101,
+  opc_fsub = 102,
+  opc_dsub = 103,
+  opc_imul = 104,
+  opc_lmul = 105,
+  opc_fmul = 106,
+  opc_dmul = 107,
+  opc_idiv = 108,
+  opc_ldiv = 109,
+  opc_fdiv = 110,
+  opc_ddiv = 111,
+  opc_irem = 112,
+  opc_lrem = 113,
+  opc_frem = 114,
+  opc_drem = 115,
+  opc_ineg = 116,
+  opc_lneg = 117,
+  opc_fneg = 118,
+  opc_dneg = 119,
+  opc_ishl = 120,
+  opc_lshl = 121,
+  opc_ishr = 122,
+  opc_lshr = 123,
+  opc_iushr = 124,
+  opc_lushr = 125,
+  opc_iand = 126,
+  opc_land = 127,
+  opc_ior = 128,
+  opc_lor = 129,
+  opc_ixor = 130,
+  opc_lxor = 131,
+  opc_iinc = 132,
+  opc_i2l = 133,
+  opc_i2f = 134,
+  opc_i2d = 135,
+  opc_l2i = 136,
+  opc_l2f = 137,
+  opc_l2d = 138,
+  opc_f2i = 139,
+  opc_f2l = 140,
+  opc_f2d = 141,
+  opc_d2i = 142,
+  opc_d2l = 143,
+  opc_d2f = 144,
+  opc_i2b = 145,
+  opc_i2c = 146,
+  opc_i2s = 147,
+  opc_lcmp = 148,
+  opc_fcmpl = 149,
+  opc_fcmpg = 150,
+  opc_dcmpl = 151,
+  opc_dcmpg = 152,
+  opc_ifeq = 153,
+  opc_ifne = 154,
+  opc_iflt = 155,
+  opc_ifge = 156,
+  opc_ifgt = 157,
+  opc_ifle = 158,
+  opc_if_icmpeq = 159,
+  opc_if_icmpne = 160,
+  opc_if_icmplt = 161,
+  opc_if_icmpge = 162,
+  opc_if_icmpgt = 163,
+  opc_if_icmple = 164,
+  opc_if_acmpeq = 165,
+  opc_if_acmpne = 166,
+  opc_goto = 167,
+  opc_jsr = 168,
+  opc_ret = 169,
+  opc_tableswitch = 170,
+  opc_lookupswitch = 171,
+  opc_ireturn = 172,
+  opc_lreturn = 173,
+  opc_freturn = 174,
+  opc_dreturn = 175,
+  opc_areturn = 176,
+  opc_return = 177,
+  opc_getstatic = 178,
+  opc_putstatic = 179,
+  opc_getfield = 180,
+  opc_putfield = 181,
+  opc_invokevirtual = 182,
+  opc_invokespecial = 183,
+  opc_invokestatic = 184,
+  opc_invokeinterface = 185,
+  opc_xxxunusedxxx = 186,
+  opc_new = 187,
+  opc_newarray = 188,
+  opc_anewarray = 189,
+  opc_arraylength = 190,
+  opc_athrow = 191,
+  opc_checkcast = 192,
+  opc_instanceof = 193,
+  opc_monitorenter = 194,
+  opc_monitorexit = 195,
+  opc_wide = 196,
+  opc_multianewarray = 197,
+  opc_ifnull = 198,
+  opc_ifnonnull = 199,
+  opc_goto_w = 200,
+  opc_jsr_w = 201,
+  opc_breakpoint = 202,
+  opc_ldc_quick = 203,
+  opc_ldc_w_quick = 204,
+  opc_ldc2_w_quick = 205,
+  opc_getfield_quick = 206,
+  opc_putfield_quick = 207,
+  opc_getfield2_quick = 208,
+  opc_putfield2_quick = 209,
+  opc_getstatic_quick = 210,
+  opc_putstatic_quick = 211,
+  opc_getstatic2_quick = 212,
+  opc_putstatic2_quick = 213,
+  opc_invokevirtual_quick = 214,
+  opc_invokenonvirtual_quick = 215,
+  opc_invokesuper_quick = 216,
+  opc_invokestatic_quick = 217,
+  opc_invokeinterface_quick = 218,
+  opc_invokevirtualobject_quick = 219,
+  opc_invokeignored_quick = 220,
+  opc_new_quick = 221,
+  opc_anewarray_quick = 222,
+  opc_multianewarray_quick = 223,
+  opc_checkcast_quick = 224,
+  opc_instanceof_quick = 225,
+  opc_invokevirtual_quick_w = 226,
+  opc_getfield_quick_w = 227,
+  opc_putfield_quick_w = 228,
+  opc_nonnull_quick = 229,
+  opc_first_unused_index = 230,
+  opc_software = 254,
+  opc_hardware = 255
+} opcode_type;
diff --git a/MPC.3.5.LINUX/preverifier/opcodes.in_out b/MPC.3.5.LINUX/preverifier/opcodes.in_out
new file mode 100644 (file)
index 0000000..d898616
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * Copyright 1995-2002 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+char * const opcode_in_out[][2] = {
+   {"", ""},           /* nop */
+   {"", "A"},          /* aconst_null */
+   {"", "I"},          /* iconst_m1 */
+   {"", "I"},          /* iconst_0 */
+   {"", "I"},          /* iconst_1 */
+   {"", "I"},          /* iconst_2 */
+   {"", "I"},          /* iconst_3 */
+   {"", "I"},          /* iconst_4 */
+   {"", "I"},          /* iconst_5 */
+   {"", "L"},          /* lconst_0 */
+   {"", "L"},          /* lconst_1 */
+   {"", "F"},          /* fconst_0 */
+   {"", "F"},          /* fconst_1 */
+   {"", "F"},          /* fconst_2 */
+   {"", "D"},          /* dconst_0 */
+   {"", "D"},          /* dconst_1 */
+   {"", "I"},          /* bipush */
+   {"", "I"},          /* sipush */
+   {"", "?"},          /* ldc */
+   {"", "?"},          /* ldc_w */
+   {"", "?"},          /* ldc2_w */
+   {"", "I"},          /* iload */
+   {"", "L"},          /* lload */
+   {"", "F"},          /* fload */
+   {"", "D"},          /* dload */
+   {"", "A"},          /* aload */
+   {"", "I"},          /* iload_0 */
+   {"", "I"},          /* iload_1 */
+   {"", "I"},          /* iload_2 */
+   {"", "I"},          /* iload_3 */
+   {"", "L"},          /* lload_0 */
+   {"", "L"},          /* lload_1 */
+   {"", "L"},          /* lload_2 */
+   {"", "L"},          /* lload_3 */
+   {"", "F"},          /* fload_0 */
+   {"", "F"},          /* fload_1 */
+   {"", "F"},          /* fload_2 */
+   {"", "F"},          /* fload_3 */
+   {"", "D"},          /* dload_0 */
+   {"", "D"},          /* dload_1 */
+   {"", "D"},          /* dload_2 */
+   {"", "D"},          /* dload_3 */
+   {"", "A"},          /* aload_0 */
+   {"", "A"},          /* aload_1 */
+   {"", "A"},          /* aload_2 */
+   {"", "A"},          /* aload_3 */
+   {"[I]I", "I"},              /* iaload */
+   {"[L]I", "L"},              /* laload */
+   {"[F]I", "F"},              /* faload */
+   {"[D]I", "D"},              /* daload */
+   {"[A]I", "A"},              /* aaload */
+   {"[b]I", "I"},              /* baload */
+   {"[C]I", "I"},              /* caload */
+   {"[S]I", "I"},              /* saload */
+   {"I", ""},          /* istore */
+   {"L", ""},          /* lstore */
+   {"F", ""},          /* fstore */
+   {"D", ""},          /* dstore */
+   {"A", ""},          /* astore */
+   {"I", ""},          /* istore_0 */
+   {"I", ""},          /* istore_1 */
+   {"I", ""},          /* istore_2 */
+   {"I", ""},          /* istore_3 */
+   {"L", ""},          /* lstore_0 */
+   {"L", ""},          /* lstore_1 */
+   {"L", ""},          /* lstore_2 */
+   {"L", ""},          /* lstore_3 */
+   {"F", ""},          /* fstore_0 */
+   {"F", ""},          /* fstore_1 */
+   {"F", ""},          /* fstore_2 */
+   {"F", ""},          /* fstore_3 */
+   {"D", ""},          /* dstore_0 */
+   {"D", ""},          /* dstore_1 */
+   {"D", ""},          /* dstore_2 */
+   {"D", ""},          /* dstore_3 */
+   {"A", ""},          /* astore_0 */
+   {"A", ""},          /* astore_1 */
+   {"A", ""},          /* astore_2 */
+   {"A", ""},          /* astore_3 */
+   {"[I]II", ""},              /* iastore */
+   {"[L]IL", ""},              /* lastore */
+   {"[F]IF", ""},              /* fastore */
+   {"[D]ID", ""},              /* dastore */
+   {"[A]IA", ""},              /* aastore */
+   {"[b]II", ""},              /* bastore */
+   {"[C]II", ""},              /* castore */
+   {"[S]II", ""},              /* sastore */
+   {"1", ""},          /* pop */
+   {"2+1", ""},                /* pop2 */
+   {"1", "11"},                /* dup */
+   {"21", "121"},              /* dup_x1 */
+   {"3+21", "1321"},           /* dup_x2 */
+   {"2+1", "2121"},            /* dup2 */
+   {"32+1", "21321"},          /* dup2_x1 */
+   {"4+32+1", "214321"},               /* dup2_x2 */
+   {"21", "12"},               /* swap */
+   {"II", "I"},                /* iadd */
+   {"LL", "L"},                /* ladd */
+   {"FF", "F"},                /* fadd */
+   {"DD", "D"},                /* dadd */
+   {"II", "I"},                /* isub */
+   {"LL", "L"},                /* lsub */
+   {"FF", "F"},                /* fsub */
+   {"DD", "D"},                /* dsub */
+   {"II", "I"},                /* imul */
+   {"LL", "L"},                /* lmul */
+   {"FF", "F"},                /* fmul */
+   {"DD", "D"},                /* dmul */
+   {"II", "I"},                /* idiv */
+   {"LL", "L"},                /* ldiv */
+   {"FF", "F"},                /* fdiv */
+   {"DD", "D"},                /* ddiv */
+   {"II", "I"},                /* irem */
+   {"LL", "L"},                /* lrem */
+   {"FF", "F"},                /* frem */
+   {"DD", "D"},                /* drem */
+   {"I", "I"},                 /* ineg */
+   {"L", "L"},                 /* lneg */
+   {"F", "F"},                 /* fneg */
+   {"D", "D"},                 /* dneg */
+   {"II", "I"},                /* ishl */
+   {"LI", "L"},                /* lshl */
+   {"II", "I"},                /* ishr */
+   {"LI", "L"},                /* lshr */
+   {"II", "I"},                /* iushr */
+   {"LI", "L"},                /* lushr */
+   {"II", "I"},                /* iand */
+   {"LL", "L"},                /* land */
+   {"II", "I"},                /* ior */
+   {"LL", "L"},                /* lor */
+   {"II", "I"},                /* ixor */
+   {"LL", "L"},                /* lxor */
+   {"", ""},           /* iinc */
+   {"I", "L"},                 /* i2l */
+   {"I", "F"},                 /* i2f */
+   {"I", "D"},                 /* i2d */
+   {"L", "I"},                 /* l2i */
+   {"L", "F"},                 /* l2f */
+   {"L", "D"},                 /* l2d */
+   {"F", "I"},                 /* f2i */
+   {"F", "L"},                 /* f2l */
+   {"F", "D"},                 /* f2d */
+   {"D", "I"},                 /* d2i */
+   {"D", "L"},                 /* d2l */
+   {"D", "F"},                 /* d2f */
+   {"I", "I"},                 /* i2b */
+   {"I", "I"},                 /* i2c */
+   {"I", "I"},                 /* i2s */
+   {"LL", "I"},                /* lcmp */
+   {"FF", "I"},                /* fcmpl */
+   {"FF", "I"},                /* fcmpg */
+   {"DD", "I"},                /* dcmpl */
+   {"DD", "I"},                /* dcmpg */
+   {"I", ""},          /* ifeq */
+   {"I", ""},          /* ifne */
+   {"I", ""},          /* iflt */
+   {"I", ""},          /* ifge */
+   {"I", ""},          /* ifgt */
+   {"I", ""},          /* ifle */
+   {"II", ""},                 /* if_icmpeq */
+   {"II", ""},                 /* if_icmpne */
+   {"II", ""},                 /* if_icmplt */
+   {"II", ""},                 /* if_icmpge */
+   {"II", ""},                 /* if_icmpgt */
+   {"II", ""},                 /* if_icmple */
+   {"AA", ""},                 /* if_acmpeq */
+   {"AA", ""},                 /* if_acmpne */
+   {"", ""},           /* goto */
+   {"", "R"},          /* jsr */
+   {"", ""},           /* ret */
+   {"I", ""},          /* tableswitch */
+   {"I", ""},          /* lookupswitch */
+   {"I", ""},          /* ireturn */
+   {"L", ""},          /* lreturn */
+   {"F", ""},          /* freturn */
+   {"D", ""},          /* dreturn */
+   {"A", ""},          /* areturn */
+   {"", ""},           /* return */
+   {"", "?"},          /* getstatic */
+   {"?", ""},          /* putstatic */
+   {"A", "?"},                 /* getfield */
+   {"?", ""},          /* putfield */
+   {"?", "?"},                 /* invokevirtual */
+   {"?", "?"},                 /* invokespecial */
+   {"?", "?"},                 /* invokestatic */
+   {"?", "?"},                 /* invokeinterface */
+   {"?", "?"},                 /* xxxunusedxxx */
+   {"", "A"},          /* new */
+   {"I", "A"},                 /* newarray */
+   {"I", "A"},                 /* anewarray */
+   {"[?]", "I"},               /* arraylength */
+   {"O", ""},          /* athrow */
+   {"A", "A"},                 /* checkcast */
+   {"A", "I"},                 /* instanceof */
+   {"A", ""},          /* monitorenter */
+   {"A", ""},          /* monitorexit */
+   {"", ""},           /* wide */
+   {"?", "A"},                 /* multianewarray */
+   {"A", ""},          /* ifnull */
+   {"A", ""},          /* ifnonnull */
+   {"", ""},           /* goto_w */
+   {"", "R"},          /* jsr_w */
+   {"", ""},           /* breakpoint */
+   {"", "?"},          /* ldc_quick */
+   {"", "?"},          /* ldc_w_quick */
+   {"", "?"},          /* ldc2_w_quick */
+   {"A", "?"},                 /* getfield_quick */
+   {"?", ""},          /* putfield_quick */
+   {"A", "?"},                 /* getfield2_quick */
+   {"?", ""},          /* putfield2_quick */
+   {"", "?"},          /* getstatic_quick */
+   {"?", ""},          /* putstatic_quick */
+   {"", "?"},          /* getstatic2_quick */
+   {"?", "_"},                 /* putstatic2_quick */
+   {"?", "?"},                 /* invokevirtual_quick */
+   {"?", "?"},                 /* invokenonvirtual_quick */
+   {"?", "?"},                 /* invokesuper_quick */
+   {"?", "?"},                 /* invokestatic_quick */
+   {"?", "?"},                 /* invokeinterface_quick */
+   {"?", "?"},                 /* invokevirtualobject_quick */
+   {"?", "?"},                 /* invokeignored_quick */
+   {"", "A"},          /* new_quick */
+   {"I", "A"},                 /* anewarray_quick */
+   {"?", "A"},                 /* multianewarray_quick */
+   {"A", "A"},                 /* checkcast_quick */
+   {"A", "I"},                 /* instanceof_quick */
+   {"?", "?"},                 /* invokevirtual_quick_w */
+   {"A", "?"},                 /* getfield_quick_w */
+   {"?", ""},          /* putfield_quick_w */
+   {"A", ""},          /* nonnull_quick */
+};
diff --git a/MPC.3.5.LINUX/preverifier/opcodes.init b/MPC.3.5.LINUX/preverifier/opcodes.init
new file mode 100644 (file)
index 0000000..2e58ccf
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ * Copyright 1995-2002 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+char * const opnames[256] = {
+   "nop",
+   "aconst_null",
+   "iconst_m1",
+   "iconst_0",
+   "iconst_1",
+   "iconst_2",
+   "iconst_3",
+   "iconst_4",
+   "iconst_5",
+   "lconst_0",
+   "lconst_1",
+   "fconst_0",
+   "fconst_1",
+   "fconst_2",
+   "dconst_0",
+   "dconst_1",
+   "bipush",
+   "sipush",
+   "ldc",
+   "ldc_w",
+   "ldc2_w",
+   "iload",
+   "lload",
+   "fload",
+   "dload",
+   "aload",
+   "iload_0",
+   "iload_1",
+   "iload_2",
+   "iload_3",
+   "lload_0",
+   "lload_1",
+   "lload_2",
+   "lload_3",
+   "fload_0",
+   "fload_1",
+   "fload_2",
+   "fload_3",
+   "dload_0",
+   "dload_1",
+   "dload_2",
+   "dload_3",
+   "aload_0",
+   "aload_1",
+   "aload_2",
+   "aload_3",
+   "iaload",
+   "laload",
+   "faload",
+   "daload",
+   "aaload",
+   "baload",
+   "caload",
+   "saload",
+   "istore",
+   "lstore",
+   "fstore",
+   "dstore",
+   "astore",
+   "istore_0",
+   "istore_1",
+   "istore_2",
+   "istore_3",
+   "lstore_0",
+   "lstore_1",
+   "lstore_2",
+   "lstore_3",
+   "fstore_0",
+   "fstore_1",
+   "fstore_2",
+   "fstore_3",
+   "dstore_0",
+   "dstore_1",
+   "dstore_2",
+   "dstore_3",
+   "astore_0",
+   "astore_1",
+   "astore_2",
+   "astore_3",
+   "iastore",
+   "lastore",
+   "fastore",
+   "dastore",
+   "aastore",
+   "bastore",
+   "castore",
+   "sastore",
+   "pop",
+   "pop2",
+   "dup",
+   "dup_x1",
+   "dup_x2",
+   "dup2",
+   "dup2_x1",
+   "dup2_x2",
+   "swap",
+   "iadd",
+   "ladd",
+   "fadd",
+   "dadd",
+   "isub",
+   "lsub",
+   "fsub",
+   "dsub",
+   "imul",
+   "lmul",
+   "fmul",
+   "dmul",
+   "idiv",
+   "ldiv",
+   "fdiv",
+   "ddiv",
+   "irem",
+   "lrem",
+   "frem",
+   "drem",
+   "ineg",
+   "lneg",
+   "fneg",
+   "dneg",
+   "ishl",
+   "lshl",
+   "ishr",
+   "lshr",
+   "iushr",
+   "lushr",
+   "iand",
+   "land",
+   "ior",
+   "lor",
+   "ixor",
+   "lxor",
+   "iinc",
+   "i2l",
+   "i2f",
+   "i2d",
+   "l2i",
+   "l2f",
+   "l2d",
+   "f2i",
+   "f2l",
+   "f2d",
+   "d2i",
+   "d2l",
+   "d2f",
+   "i2b",
+   "i2c",
+   "i2s",
+   "lcmp",
+   "fcmpl",
+   "fcmpg",
+   "dcmpl",
+   "dcmpg",
+   "ifeq",
+   "ifne",
+   "iflt",
+   "ifge",
+   "ifgt",
+   "ifle",
+   "if_icmpeq",
+   "if_icmpne",
+   "if_icmplt",
+   "if_icmpge",
+   "if_icmpgt",
+   "if_icmple",
+   "if_acmpeq",
+   "if_acmpne",
+   "goto",
+   "jsr",
+   "ret",
+   "tableswitch",
+   "lookupswitch",
+   "ireturn",
+   "lreturn",
+   "freturn",
+   "dreturn",
+   "areturn",
+   "return",
+   "getstatic",
+   "putstatic",
+   "getfield",
+   "putfield",
+   "invokevirtual",
+   "invokespecial",
+   "invokestatic",
+   "invokeinterface",
+   "xxxunusedxxx",
+   "new",
+   "newarray",
+   "anewarray",
+   "arraylength",
+   "athrow",
+   "checkcast",
+   "instanceof",
+   "monitorenter",
+   "monitorexit",
+   "wide",
+   "multianewarray",
+   "ifnull",
+   "ifnonnull",
+   "goto_w",
+   "jsr_w",
+   "breakpoint",
+   "ldc_quick",
+   "ldc_w_quick",
+   "ldc2_w_quick",
+   "getfield_quick",
+   "putfield_quick",
+   "getfield2_quick",
+   "putfield2_quick",
+   "getstatic_quick",
+   "putstatic_quick",
+   "getstatic2_quick",
+   "putstatic2_quick",
+   "invokevirtual_quick",
+   "invokenonvirtual_quick",
+   "invokesuper_quick",
+   "invokestatic_quick",
+   "invokeinterface_quick",
+   "invokevirtualobject_quick",
+   "invokeignored_quick",
+   "new_quick",
+   "anewarray_quick",
+   "multianewarray_quick",
+   "checkcast_quick",
+   "instanceof_quick",
+   "invokevirtual_quick_w",
+   "getfield_quick_w",
+   "putfield_quick_w",
+   "nonnull_quick",
+   "??",
+   "??",
+   "??",
+   "??",
+   "??",
+   "??",
+   "??",
+   "??",
+   "??",
+   "??",
+   "??",
+   "??",
+   "??",
+   "??",
+   "??",
+   "??",
+   "??",
+   "??",
+   "??",
+   "??",
+   "??",
+   "??",
+   "??",
+   "??",
+   "software",
+   "hardware",
+};
diff --git a/MPC.3.5.LINUX/preverifier/opcodes.length b/MPC.3.5.LINUX/preverifier/opcodes.length
new file mode 100644 (file)
index 0000000..1d741e6
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ * Copyright 1995-2002 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+const short opcode_length[256] = {
+   1,          /* nop */
+   1,          /* aconst_null */
+   1,          /* iconst_m1 */
+   1,          /* iconst_0 */
+   1,          /* iconst_1 */
+   1,          /* iconst_2 */
+   1,          /* iconst_3 */
+   1,          /* iconst_4 */
+   1,          /* iconst_5 */
+   1,          /* lconst_0 */
+   1,          /* lconst_1 */
+   1,          /* fconst_0 */
+   1,          /* fconst_1 */
+   1,          /* fconst_2 */
+   1,          /* dconst_0 */
+   1,          /* dconst_1 */
+   2,          /* bipush */
+   3,          /* sipush */
+   2,          /* ldc */
+   3,          /* ldc_w */
+   3,          /* ldc2_w */
+   2,          /* iload */
+   2,          /* lload */
+   2,          /* fload */
+   2,          /* dload */
+   2,          /* aload */
+   1,          /* iload_0 */
+   1,          /* iload_1 */
+   1,          /* iload_2 */
+   1,          /* iload_3 */
+   1,          /* lload_0 */
+   1,          /* lload_1 */
+   1,          /* lload_2 */
+   1,          /* lload_3 */
+   1,          /* fload_0 */
+   1,          /* fload_1 */
+   1,          /* fload_2 */
+   1,          /* fload_3 */
+   1,          /* dload_0 */
+   1,          /* dload_1 */
+   1,          /* dload_2 */
+   1,          /* dload_3 */
+   1,          /* aload_0 */
+   1,          /* aload_1 */
+   1,          /* aload_2 */
+   1,          /* aload_3 */
+   1,          /* iaload */
+   1,          /* laload */
+   1,          /* faload */
+   1,          /* daload */
+   1,          /* aaload */
+   1,          /* baload */
+   1,          /* caload */
+   1,          /* saload */
+   2,          /* istore */
+   2,          /* lstore */
+   2,          /* fstore */
+   2,          /* dstore */
+   2,          /* astore */
+   1,          /* istore_0 */
+   1,          /* istore_1 */
+   1,          /* istore_2 */
+   1,          /* istore_3 */
+   1,          /* lstore_0 */
+   1,          /* lstore_1 */
+   1,          /* lstore_2 */
+   1,          /* lstore_3 */
+   1,          /* fstore_0 */
+   1,          /* fstore_1 */
+   1,          /* fstore_2 */
+   1,          /* fstore_3 */
+   1,          /* dstore_0 */
+   1,          /* dstore_1 */
+   1,          /* dstore_2 */
+   1,          /* dstore_3 */
+   1,          /* astore_0 */
+   1,          /* astore_1 */
+   1,          /* astore_2 */
+   1,          /* astore_3 */
+   1,          /* iastore */
+   1,          /* lastore */
+   1,          /* fastore */
+   1,          /* dastore */
+   1,          /* aastore */
+   1,          /* bastore */
+   1,          /* castore */
+   1,          /* sastore */
+   1,          /* pop */
+   1,          /* pop2 */
+   1,          /* dup */
+   1,          /* dup_x1 */
+   1,          /* dup_x2 */
+   1,          /* dup2 */
+   1,          /* dup2_x1 */
+   1,          /* dup2_x2 */
+   1,          /* swap */
+   1,          /* iadd */
+   1,          /* ladd */
+   1,          /* fadd */
+   1,          /* dadd */
+   1,          /* isub */
+   1,          /* lsub */
+   1,          /* fsub */
+   1,          /* dsub */
+   1,          /* imul */
+   1,          /* lmul */
+   1,          /* fmul */
+   1,          /* dmul */
+   1,          /* idiv */
+   1,          /* ldiv */
+   1,          /* fdiv */
+   1,          /* ddiv */
+   1,          /* irem */
+   1,          /* lrem */
+   1,          /* frem */
+   1,          /* drem */
+   1,          /* ineg */
+   1,          /* lneg */
+   1,          /* fneg */
+   1,          /* dneg */
+   1,          /* ishl */
+   1,          /* lshl */
+   1,          /* ishr */
+   1,          /* lshr */
+   1,          /* iushr */
+   1,          /* lushr */
+   1,          /* iand */
+   1,          /* land */
+   1,          /* ior */
+   1,          /* lor */
+   1,          /* ixor */
+   1,          /* lxor */
+   3,          /* iinc */
+   1,          /* i2l */
+   1,          /* i2f */
+   1,          /* i2d */
+   1,          /* l2i */
+   1,          /* l2f */
+   1,          /* l2d */
+   1,          /* f2i */
+   1,          /* f2l */
+   1,          /* f2d */
+   1,          /* d2i */
+   1,          /* d2l */
+   1,          /* d2f */
+   1,          /* i2b */
+   1,          /* i2c */
+   1,          /* i2s */
+   1,          /* lcmp */
+   1,          /* fcmpl */
+   1,          /* fcmpg */
+   1,          /* dcmpl */
+   1,          /* dcmpg */
+   3,          /* ifeq */
+   3,          /* ifne */
+   3,          /* iflt */
+   3,          /* ifge */
+   3,          /* ifgt */
+   3,          /* ifle */
+   3,          /* if_icmpeq */
+   3,          /* if_icmpne */
+   3,          /* if_icmplt */
+   3,          /* if_icmpge */
+   3,          /* if_icmpgt */
+   3,          /* if_icmple */
+   3,          /* if_acmpeq */
+   3,          /* if_acmpne */
+   3,          /* goto */
+   3,          /* jsr */
+   2,          /* ret */
+   99,         /* tableswitch */
+   99,         /* lookupswitch */
+   1,          /* ireturn */
+   1,          /* lreturn */
+   1,          /* freturn */
+   1,          /* dreturn */
+   1,          /* areturn */
+   1,          /* return */
+   3,          /* getstatic */
+   3,          /* putstatic */
+   3,          /* getfield */
+   3,          /* putfield */
+   3,          /* invokevirtual */
+   3,          /* invokespecial */
+   3,          /* invokestatic */
+   5,          /* invokeinterface */
+   0,          /* xxxunusedxxx */
+   3,          /* new */
+   2,          /* newarray */
+   3,          /* anewarray */
+   1,          /* arraylength */
+   1,          /* athrow */
+   3,          /* checkcast */
+   3,          /* instanceof */
+   1,          /* monitorenter */
+   1,          /* monitorexit */
+   0,          /* wide */
+   4,          /* multianewarray */
+   3,          /* ifnull */
+   3,          /* ifnonnull */
+   5,          /* goto_w */
+   5,          /* jsr_w */
+   1,          /* breakpoint */
+   2,          /* ldc_quick */
+   3,          /* ldc_w_quick */
+   3,          /* ldc2_w_quick */
+   3,          /* getfield_quick */
+   3,          /* putfield_quick */
+   3,          /* getfield2_quick */
+   3,          /* putfield2_quick */
+   3,          /* getstatic_quick */
+   3,          /* putstatic_quick */
+   3,          /* getstatic2_quick */
+   3,          /* putstatic2_quick */
+   3,          /* invokevirtual_quick */
+   3,          /* invokenonvirtual_quick */
+   3,          /* invokesuper_quick */
+   3,          /* invokestatic_quick */
+   5,          /* invokeinterface_quick */
+   3,          /* invokevirtualobject_quick */
+   3,          /* invokeignored_quick */
+   3,          /* new_quick */
+   3,          /* anewarray_quick */
+   4,          /* multianewarray_quick */
+   3,          /* checkcast_quick */
+   3,          /* instanceof_quick */
+   3,          /* invokevirtual_quick_w */
+   3,          /* getfield_quick_w */
+   3,          /* putfield_quick_w */
+   1,          /* nonnull_quick */
+   -1,
+   -1,
+   -1,
+   -1,
+   -1,
+   -1,
+   -1,
+   -1,
+   -1,
+   -1,
+   -1,
+   -1,
+   -1,
+   -1,
+   -1,
+   -1,
+   -1,
+   -1,
+   -1,
+   -1,
+   -1,
+   -1,
+   -1,
+   -1,
+   -1,
+   -1,
+};
diff --git a/MPC.3.5.LINUX/preverifier/path.h b/MPC.3.5.LINUX/preverifier/path.h
new file mode 100644 (file)
index 0000000..d4624ad
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * @(#)path.h  1.6 02/09/27
+ *
+ * Copyright 1995-1998 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ * 
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+#ifndef        _PATH_H_
+#define        _PATH_H_
+
+#include <sys/stat.h>
+#include "path_md.h"
+
+typedef struct {
+    struct {
+        unsigned long locpos;
+       unsigned long cenpos;
+    } jar;
+    char type;
+    char name[1];
+} zip_t; 
+
+/*
+ * Class path element, which is either a directory or zip file.
+ */
+typedef struct {
+    enum { CPE_DIR, CPE_ZIP } type;
+    union {
+       zip_t *zip;
+       char *dir;
+    } u;
+} cpe_t;
+
+cpe_t **sysGetClassPath(void);
+void pushDirectoryOntoClassPath(char* directory);
+void pushJarFileOntoClassPath(zip_t *zip);
+void popClassPath(void);
+
+bool_t 
+findJARDirectories(zip_t *entry, struct stat *statbuf);
+
+#endif /* !_PATH_H_ */
diff --git a/MPC.3.5.LINUX/preverifier/path_md.h b/MPC.3.5.LINUX/preverifier/path_md.h
new file mode 100644 (file)
index 0000000..f7553d6
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * @(#)path_md.h       1.4 02/09/27
+ *
+ * Copyright 1995-1998 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+#ifndef _PATH_MD_H_
+#define _PATH_MD_H_
+
+#define        DIR_SEPARATOR           '/'
+
+#ifdef UNIX
+#define        LOCAL_DIR_SEPARATOR             '/'
+#define PATH_SEPARATOR          ':'
+
+#include <dirent.h>
+#endif
+#ifdef WIN32
+
+#define        LOCAL_DIR_SEPARATOR             '\\'
+#define PATH_SEPARATOR          ';'
+
+#include <direct.h>
+struct dirent {
+    char d_name[1024];
+};
+
+typedef struct {
+    struct dirent dirent;
+    char *path;
+    HANDLE handle;
+    WIN32_FIND_DATA find_data;
+} DIR;
+
+DIR *opendir(const char *dirname);
+struct dirent *readdir(DIR *dirp);
+int closedir(DIR *dirp);
+
+#endif
+
+#endif /* !_PATH_MD_H_ */
diff --git a/MPC.3.5.LINUX/preverifier/signature.h b/MPC.3.5.LINUX/preverifier/signature.h
new file mode 100644 (file)
index 0000000..94afc71
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * @(#)signature.h     1.2 02/09/27
+ *
+ * Copyright 1995-1998 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ * 
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+/*
+ * The keyletters used in type signatures
+ */
+
+#ifndef _SIGNATURE_H_
+#define _SIGNATURE_H_
+
+#define SIGNATURE_ANY          'A'
+#define SIGNATURE_ARRAY                '['
+#define SIGNATURE_BYTE         'B'
+#define SIGNATURE_CHAR         'C'
+#define SIGNATURE_CLASS                'L'
+#define SIGNATURE_ENDCLASS     ';'
+#define SIGNATURE_ENUM         'E'
+#define SIGNATURE_FLOAT                'F'
+#define SIGNATURE_DOUBLE        'D'
+#define SIGNATURE_FUNC         '('
+#define SIGNATURE_ENDFUNC      ')'
+#define SIGNATURE_INT          'I'
+#define SIGNATURE_LONG         'J'
+#define SIGNATURE_SHORT                'S'
+#define SIGNATURE_VOID         'V'
+#define SIGNATURE_BOOLEAN      'Z'
+
+#define SIGNATURE_ANY_STRING           "A"
+#define SIGNATURE_ARRAY_STRING         "["
+#define SIGNATURE_BYTE_STRING          "B"
+#define SIGNATURE_CHAR_STRING          "C"
+#define SIGNATURE_CLASS_STRING         "L"
+#define SIGNATURE_ENDCLASS_STRING      ";"
+#define SIGNATURE_ENUM_STRING          "E"
+#define SIGNATURE_FLOAT_STRING         "F"
+#define SIGNATURE_DOUBLE_STRING        "D"
+#define SIGNATURE_FUNC_STRING          "("
+#define SIGNATURE_ENDFUNC_STRING       ")"
+#define SIGNATURE_INT_STRING           "I"
+#define SIGNATURE_LONG_STRING          "J"
+#define SIGNATURE_SHORT_STRING         "S"
+#define SIGNATURE_VOID_STRING          "V"
+#define SIGNATURE_BOOLEAN_STRING       "Z"
+
+
+
+#endif /* !_SIGNATURE_H_ */
diff --git a/MPC.3.5.LINUX/preverifier/stubs.c b/MPC.3.5.LINUX/preverifier/stubs.c
new file mode 100644 (file)
index 0000000..09c15fb
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * @(#)stubs.c 1.6 02/09/27
+ *
+ * Copyright 1995-1998 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ * 
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+/*=========================================================================
+ * SYSTEM:    Verifier
+ * SUBSYSTEM: Stubs.
+ * FILE:      stubs.c
+ * OVERVIEW:  Miscellaneous functions used during class loading, etc.
+ *
+ * AUTHOR:    Sheng Liang, Sun Microsystems, Inc.
+ *            Edited by Tasneem Sayeed, Sun Microsystems
+ *=======================================================================*/
+
+/*=========================================================================
+ * Include files
+ *=======================================================================*/
+
+#include "oobj.h"
+#include "sys_api.h"
+
+void
+SignalError(struct execenv * ee, char *ename, char *DetailMessage)
+{
+       printCurrentClassName();
+    jio_fprintf(stderr, "%s", ename);
+       if (DetailMessage) {
+               jio_fprintf(stderr, ": %s\n", DetailMessage);
+       } else {
+               jio_fprintf(stderr, "\n");
+       }
+    exit(1);
+}
+
+bool_t
+VerifyClassAccess(ClassClass *current_class, ClassClass *new_class, 
+                 bool_t classloader_only) 
+{
+    return TRUE;
+}
+
+/* This is called by FindClassFromClass when a class name is being requested
+ * by another class that was loaded via a classloader.  For javah, we don't
+ * really care.
+ */
+
+ClassClass *
+ClassLoaderFindClass(struct execenv *ee, 
+                    struct Hjava_lang_ClassLoader *loader, 
+                    char *name, bool_t resolve)
+{ 
+    return NULL;
+}
+
+/* Get the execution environment
+ */
+ExecEnv *
+EE() {
+    static struct execenv lee;
+    return &lee;
+}
+
+bool_t RunStaticInitializers(ClassClass *cb)
+{
+    return TRUE;
+}
+
+void InitializeInvoker(ClassClass *cb)
+{
+}
+
+int verifyclasses = VERIFY_ALL;
+long nbinclasses, sizebinclasses;
+ClassClass **binclasses;
+bool_t verbose;
+struct StrIDhash *nameTypeHash;
+struct StrIDhash *stringHash;
+
+void *allocClassClass()
+{
+    ClassClass *cb = sysCalloc(1, sizeof(ClassClass));
+    Classjava_lang_Class *ucb = sysCalloc(1, sizeof(Classjava_lang_Class));
+    
+    cb->obj = ucb;
+    ucb->HandleToSelf = cb;
+    return cb;
+}
+
+void DumpThreads() {}
diff --git a/MPC.3.5.LINUX/preverifier/sys_api.h b/MPC.3.5.LINUX/preverifier/sys_api.h
new file mode 100644 (file)
index 0000000..539f197
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * @(#)sys_api.h       1.6 02/09/27
+ *
+ * Copyright 1995-1999 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+/*
+ * System or Host dependent API.  This defines the "porting layer" for
+ * POSIX.1 compliant operating systems.
+ */
+
+#ifndef _SYS_API_H_
+#define _SYS_API_H_
+
+/*
+ * typedefs_md.h includes basic types for this platform;
+ * any macros for HPI functions have been moved to "sysmacros_md.h"
+ */
+#include "typedefs.h"
+
+/*
+ * Miscellaneous system utility APIs that fall outside the POSIX.1
+ * spec.
+ *
+ * Until POSIX (P1003.1a) formerly P.4 is standard, we'll use our
+ * time struct definitions found in timeval.h.
+ */
+long   sysGetMilliTicks(void);
+long    sysTime(long *);
+int64_t sysTimeMillis(void);
+
+#include <time.h>
+struct tm * sysLocaltime(time_t *, struct tm*);
+struct tm * sysGmtime(time_t *, struct tm*);
+void        sysStrftime(char *, int, char *, struct tm *);
+time_t      sysMktime(struct tm*);
+
+/*
+ * System API for general allocations
+ */
+void * sysMalloc(size_t);
+void * sysRealloc(void*, size_t);
+void   sysFree(void*);
+void * sysCalloc(size_t, size_t);
+#ifdef PAGED_HEAPS
+void *  sysAllocBlock(size_t, void**);
+void    sysFreeBlock(void *);
+#endif /* PAGED_HEAPS */
+
+/*
+ * System API for dynamic linking libraries into the interpreter
+ */
+char *  sysInitializeLinker(void);
+int     sysAddDLSegment(char *);
+void    sysSaveLDPath(char *);
+long    sysDynamicLink(char *);
+void   sysBuildLibName(char *, int, char *, char *);
+int     sysBuildFunName(char *, int, void *, int);
+long *  sysInvokeNative(void *, void *, long *, char *, int, void *);
+
+/*
+ * System API for invoking the interpreter from native applications
+ */
+void    sysGetDefaultJavaVMInitArgs(void *);
+int     sysInitializeJavaVM(void *, void *);
+int     sysFinalizeJavaVM(void *);
+void    sysAttachThreadLock();
+void    sysAttachThreadUnlock();
+
+/*
+ * System API for threads
+ */
+typedef struct  sys_thread sys_thread_t;
+typedef struct  sys_mon sys_mon_t;
+typedef void *  stackp_t;
+
+int    sysThreadBootstrap(sys_thread_t **, void *);
+void   sysThreadInitializeSystemThreads(void);
+
+#ifdef UNIX
+int    sysThreadCreate(long, uint flags, void *(*)(void *),
+                       sys_thread_t **, void *);
+#else
+int    sysThreadCreate(long, uint_t flags, void *(*)(void *),
+                       sys_thread_t **, void *);
+#endif
+
+void   sysThreadExit(void);
+sys_thread_t * sysThreadSelf(void);
+void    sysThreadYield(void);
+int     sysThreadVMSuspend(sys_thread_t *, sys_thread_t *);
+void    sysThreadVMSuspendMe(void);
+int     sysThreadVMUnsuspend(sys_thread_t *);
+int    sysThreadSuspend(sys_thread_t *);
+int    sysThreadResume(sys_thread_t *);
+int    sysThreadSetPriority(sys_thread_t *, int);
+int    sysThreadGetPriority(sys_thread_t *, int *);
+void *  sysThreadStackPointer(sys_thread_t *);
+stackp_t sysThreadStackBase(sys_thread_t *);
+void    sysThreadSetStackBase(sys_thread_t *, stackp_t);
+int    sysThreadSingle(void);
+void   sysThreadMulti(void);
+int     sysThreadEnumerateOver(int (*)(sys_thread_t *, void *), void *);
+void   sysThreadInit(sys_thread_t *, stackp_t);
+void *  sysThreadGetBackPtr(sys_thread_t *);
+int     sysThreadCheckStack(void);
+int     sysInterruptsPending(void);
+void   sysThreadPostException(sys_thread_t *, void *);
+void   sysThreadDumpInfo(sys_thread_t *);
+void    sysThreadInterrupt(sys_thread_t *);
+int     sysThreadIsInterrupted(sys_thread_t *, long);
+int     sysThreadAlloc(sys_thread_t **, stackp_t, void *);
+int     sysThreadFree(sys_thread_t *);
+
+/*
+ * System API for monitors
+ */
+int     sysMonitorSizeof(void);
+int     sysMonitorInit(sys_mon_t *);
+int     sysMonitorDestroy(sys_mon_t *);
+int     sysMonitorEnter(sys_mon_t *);
+bool_t  sysMonitorEntered(sys_mon_t *);
+int     sysMonitorExit(sys_mon_t *);
+int     sysMonitorNotify(sys_mon_t *);
+int     sysMonitorNotifyAll(sys_mon_t *);
+int    sysMonitorWait(sys_mon_t *, int, bool_t);
+void    sysMonitorDumpInfo(sys_mon_t *);
+bool_t  sysMonitorInUse(sys_mon_t *);
+
+#define SYS_OK         0
+#define SYS_ERR               -1
+#define SYS_INTRPT     -2    /* Operation was interrupted */
+#define SYS_TIMEOUT    -3    /* A timer ran out */
+#define SYS_NOMEM      -5    /* Ran out of memory */
+#define SYS_NORESOURCE -6    /* Ran out of some system resource */
+
+/*
+ * Symbolic constant to be used when waiting indefinitely on a condition
+ * variable
+ */
+#define SYS_TIMEOUT_INFINITY -1
+
+/*
+ * System API for raw memory allocation
+ */
+void *  sysMapMem(long, long *);
+void *  sysUnmapMem(void *, long, long *);
+void *  sysCommitMem(void *, long, long *);
+void *  sysDecommitMem(void *, long, long *);
+void *  sysUncommitMem(void *, long, long *);
+
+/*
+ * System API for termination
+ */
+void   sysExit(int);
+int    sysAtexit(void (*func)(void));
+void   sysAbort(void);
+
+/*
+ * System API for files
+ */
+extern int sysIsAbsolute(const char* path);
+extern int sysAccess(const char* pFile, int perm);
+
+extern int sysStat(const char *path, struct stat *sbuf);
+extern int sysFStat(int fd, struct stat * sbuf);
+
+extern int sysOpen(const char *name, int openMode, int filePerm);
+extern int sysClose(int fd);
+
+extern long sysSeek(int fd, long offset, int whence);
+extern int sysAvailable(int fd, long* bytes);
+extern size_t sysRead(int fd, void *buf, unsigned int nBytes);
+extern size_t sysWrite(int fd, const void *buf, unsigned int nBytes);
+
+extern int sysRename(const char* srcName, const char* dstName);
+extern int sysUnlink(const char* file);
+
+extern int sysMkdir(const char* path, int mode);
+extern int sysRmdir(const char* path);
+extern int sysCanonicalPath(char *path, char *result, int result_len);
+
+/*
+ * API support needed for various multiprocessor related synchronization
+ * primitives.  Systems that don't use real threads can just define
+ * these to be 0 in their sysmacros_md.h.
+ */
+
+int sysIsMP();
+void sysMemoryFlush();
+void sysStoreBarrier();
+
+/*
+ * Include platform specific macros to override these
+ */
+#include "sysmacros_md.h"
+
+#endif /* !_SYS_API_H_ */
diff --git a/MPC.3.5.LINUX/preverifier/sys_support.c b/MPC.3.5.LINUX/preverifier/sys_support.c
new file mode 100644 (file)
index 0000000..f8a3ab7
--- /dev/null
@@ -0,0 +1,475 @@
+/*
+ * @(#)sys_support.c   1.7 01/01/18
+ *
+ * Copyright 1995-1999 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ * 
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+/*=========================================================================
+ * SYSTEM:    Verifier 
+ * SUBSYSTEM: System support functions 
+ * FILE:      sys_support.c
+ * OVERVIEW:  Routines for system support functions. The routines
+ *            are for retrieving system class path and for certain 
+ *            Windows specific file parsing functions.
+ *
+ * AUTHOR:    Sheng Liang, Sun Microsystems, Inc.
+ *            Modifications for JAR support and comments,
+ *            Tasneem Sayeed, Sun Microsystems, Inc.
+ *=======================================================================*/
+
+/*=========================================================================
+ * Include files
+ *=======================================================================*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+//#include <errno.h>
+
+#include "oobj.h"
+#include "jar.h"
+#include "typedefs.h"
+#include "sys_api.h"
+#include "path.h"
+
+/*=========================================================================
+ * Globals and extern declarations
+ *=======================================================================*/
+
+static cpe_t **saved_classpath;
+static cpe_t **saved_classpath_end;
+
+extern zip_t * getZipEntry(char *zipFile, int len);
+
+/*=========================================================================
+ * FUNCTION:      sysGetClassPath 
+ * OVERVIEW:      Returns the system class path using the getenv() system
+ *                call for retrieving the CLASSPATH environment. 
+ * INTERFACE:
+ *   parameters:  none 
+ *
+ *   returns:     Pointer to cpe_t struct ptr (see path.h) 
+ *=======================================================================*/
+cpe_t **
+sysGetClassPath(void)
+{
+    struct stat sbuf;
+    int length;
+    zip_t *zipEntry;
+    bool_t includedDot = FALSE;
+
+    if (saved_classpath == 0) {
+        char *cps, *s;
+        int ncpe = 1;
+        cpe_t **cpp;
+        if ((cps = getenv("CLASSPATH")) == 0) {
+            cps = ".";
+        }
+        if ((cps = strdup(cps)) == 0) {
+            return 0;
+        }
+        for (s = cps; *s != '\0'; s++) {
+            if (*s == PATH_SEPARATOR) {
+                ncpe++;
+            }
+        }
+        /* We add 2 since we automatically append "." to the list, and we
+         * need a NULL element at the end.
+         * We add an extra 10 to allow pushing and popping of the classpath.
+         * Generally, we'll need two, at most, but we can afford to be 
+         * a little extravagant.
+         */
+        cpp = saved_classpath = sysMalloc((ncpe + 2 + 10) * sizeof(cpe_t *));
+        if (cpp == 0) {
+            return 0;
+        }
+        while (cps && *cps) {
+            char *path = cps;
+            cpe_t *cpe;
+            if ((cps = strchr(cps, PATH_SEPARATOR)) != 0) {
+                *cps++ = '\0';
+            }
+            if (*path == '\0') {
+                path = ".";
+            }
+            cpe = sysMalloc(sizeof(cpe_t));
+            if (cpe == 0) {
+                return 0;
+            }
+            length = strlen(path);
+            if (JAR_DEBUG && verbose) {
+                jio_fprintf(stderr, "SysGetClassPath: Length : %d\n", length); 
+                jio_fprintf(stderr, "SysGetClasspath: Path : %s\n", path);
+            }
+            if (stat(path, &sbuf) < 0) {
+                /* we don't have to do anything */
+            } else if (sbuf.st_mode & S_IFDIR) {
+                /* this is a directory */
+                cpe->type = CPE_DIR;
+                cpe->u.dir = path;
+                if (strcmp(path, ".") == 0) { 
+                    includedDot = TRUE;
+                }
+
+                /* restore only for a valid directory */
+                *cpp++ = cpe;
+                
+                if (JAR_DEBUG && verbose)
+                    jio_fprintf(stderr, "SysGetClassPath: Found directory [%s]\n", path);
+                
+            } else if (isJARfile (path, length)) { 
+                /* this looks like a JAR file */
+                /* initialize the zip structure */
+               
+                if (JAR_DEBUG && verbose)
+                    jio_fprintf(stderr, "SysGetClassPath: Found .JAR file [%s]\n", path);
+                
+                /* Create the zip entry for searching the JAR
+                 * directories. If the zip entry is NULL, it 
+                 * would indicate that we ran out of memory
+                 * and would have exited already.
+                 */
+                zipEntry = getZipEntry(path, length); 
+                       
+                /* search for the JAR directories */
+                if (findJARDirectories(zipEntry, &sbuf)) {
+                    /* this is a JAR file - initialize the cpe */
+                    
+                    if (JAR_DEBUG && verbose)
+                        jio_fprintf(stderr, "SysGetClassPath: JAR directories OK in [%s]\n", zipEntry->name);
+                    
+                    zipEntry->type = 'j';
+                    cpe->type = CPE_ZIP;
+                    cpe->u.zip = zipEntry; 
+                    /* restore entry only for a valid JAR */
+                    *cpp++ = cpe;
+                }
+            }
+        }
+        if (!includedDot) { 
+            cpe_t *cpe = sysMalloc(sizeof(cpe_t));
+            cpe->type = CPE_DIR;
+            cpe->u.dir = ".";
+            *cpp++ = cpe;
+        }
+        *cpp = 0;
+        saved_classpath_end = cpp;
+    }
+    
+    return saved_classpath;
+}
+
+
+/* Puts this directory at the beginning of the class path */
+
+void
+pushDirectoryOntoClassPath(char* directory)
+{ 
+    cpe_t **ptr;
+
+    cpe_t *cpe = sysMalloc(sizeof(cpe_t));
+    cpe->type = CPE_DIR;
+    cpe->u.dir = directory;
+
+    sysGetClassPath();          /* just in case not done yet */
+
+    /* Note that saved_classpath_end points to the NULL at the end. */
+    saved_classpath_end++;
+    for (ptr = saved_classpath_end; ptr > saved_classpath; ptr--) { 
+        ptr[0] = ptr[-1];
+    }
+    ptr[0] = cpe;
+}
+
+
+/* Puts this jar file at the beginning of the class path */
+
+void
+pushJarFileOntoClassPath(zip_t *zipEntry)
+{
+    cpe_t **ptr;
+
+    cpe_t *cpe = sysMalloc(sizeof(cpe_t));
+    cpe->type = CPE_ZIP;
+    cpe->u.zip = zipEntry; 
+
+    sysGetClassPath();          /* just in case not done yet */
+
+    /* Note that saved_classpath_end points to the NULL at the end. */
+    saved_classpath_end++;
+    for (ptr = saved_classpath_end; ptr > saved_classpath; ptr--) { 
+        ptr[0] = ptr[-1];
+    }
+    ptr[0] = cpe;
+}
+    
+
+/* Pop the first element off the class path */
+void
+popClassPath()
+{ 
+    cpe_t **ptr;
+
+    sysFree(*saved_classpath);
+
+    --saved_classpath_end;
+    for (ptr = saved_classpath; ptr <= saved_classpath_end; ptr++) { 
+        /* This copies all of the elements, including the NULL at the end */
+        ptr[0] = ptr[1];
+    }
+}
+
+
+/*=========================================================================
+ * Win32 file parsing functions 
+ *=======================================================================*/
+
+#ifdef WIN32
+
+#undef DEBUG_PATH              /* Define this to debug path code */
+
+#define isfilesep(c) ((c) == '/' || (c) == '\\')
+#define islb(c)      (IsDBCSLeadByte((BYTE)(c)))
+
+
+/*=========================================================================
+ * FUNCTION:      sysNativePath 
+ * OVERVIEW:      Converts a path name to native format. On win32, this 
+ *                involves forcing all separators to be '\\' rather than '/'
+ *                (both are legal inputs, but Win95 sometimes rejects '/')
+ *                and removing redundant separators. The input path is assumed
+ *                to have been converted into the character encoding used by 
+ *                the local system. Because this might be a double-byte 
+ *                encoding, care is taken to treat double-byte lead characters
+ *                correctly. 
+ *               
+ * INTERFACE:
+ *   parameters:  char *path 
+ *
+ *   returns:     char * 
+ *=======================================================================*/
+char *
+sysNativePath(char *path)
+{
+    char *src = path, *dst = path;
+    char *colon = NULL;                /* If a drive specifier is found, this will
+                                  point to the colon following the drive
+                                  letter */
+
+    /* Assumption: '/', '\\', ':', and drive letters are never lead bytes */
+    sysAssert(!islb('/') && !islb('\\') && !islb(':'));
+
+    /* Check for leading separators */
+    while (isfilesep(*src)) src++;
+    if (!islb(*src) && src[1] == ':') {
+       /* Remove leading separators if followed by drive specifier.  This
+          hack is necessary to support file URLs containing drive
+          specifiers (e.g., "file://c:/path").  As a side effect,
+          "/c:/path" can be used as an alternative to "c:/path". */
+       *dst++ = *src++;
+       colon = dst;
+       *dst++ = ':'; src++;
+    } else {
+       src = path;
+       if (isfilesep(src[0]) && isfilesep(src[1])) {
+           /* UNC pathname: Retain first separator; leave src pointed at
+              second separator so that further separators will be collapsed
+              into the second separator.  The result will be a pathname
+              beginning with "\\\\" followed (most likely) by a host name. */
+           src = dst = path + 1;
+           path[0] = '\\';     /* Force first separator to '\\' */
+       }
+    }
+
+    /* Remove redundant separators from remainder of path, forcing all
+       separators to be '\\' rather than '/' */
+    while (*src != '\0') {
+       if (isfilesep(*src)) {
+           *dst++ = '\\'; src++;
+           while (isfilesep(*src)) src++;
+           if (*src == '\0') { /* Check for trailing separator */
+               if (colon == dst - 2) break;                      /* "z:\\" */
+               if (dst == path + 1) break;                       /* "\\" */
+               if (dst == path + 2 && isfilesep(path[0])) {
+                   /* "\\\\" is not collapsed to "\\" because "\\\\" marks the
+                      beginning of a UNC pathname.  Even though it is not, by
+                      itself, a valid UNC pathname, we leave it as is in order
+                      to be consistent with sysCanonicalPath() (below) as well
+                      as the win32 APIs, which treat this case as an invalid
+                      UNC pathname rather than as an alias for the root
+                      directory of the current drive. */
+                   break;
+               }
+               dst--;          /* Path does not denote a root directory, so
+                                  remove trailing separator */
+               break;
+           }
+       } else {
+           if (islb(*src)) {   /* Copy a double-byte character */
+               *dst++ = *src++;
+               if (*src) {
+                   *dst++ = *src++;
+               }
+           } else {            /* Copy a single-byte character */
+               *dst++ = *src++;
+           }
+       }
+    }
+
+    *dst = '\0';
+#ifdef DEBUG_PATH
+    jio_fprintf(stderr, "sysNativePath: %s\n", path);
+#endif /* DEBUG_PATH */
+    return path;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      opendir
+ * OVERVIEW:      open directory given dir pointer. 
+ *                
+ * INTERFACE:
+ *   parameters:  const char *dirarg
+ *
+ *   returns:     Pointer to DIR structure 
+ *=======================================================================*/
+DIR *
+opendir(const char *dirarg)
+{
+    DIR *dirp = (DIR *)sysMalloc(sizeof(DIR));
+    unsigned long fattr;
+    char alt_dirname[4] = { 0, 0, 0, 0 };
+       char dirname_buf[1024];
+       char *dirname = dirname_buf;
+
+    if (dirp == 0) {
+//     errno = ENOMEM;
+       return 0;
+    }
+
+       strcpy(dirname, dirarg);
+       sysNativePath(dirname);
+
+    /*
+     * Win32 accepts "\" in its POSIX stat(), but refuses to treat it
+     * as a directory in FindFirstFile().  We detect this case here and
+     * prepend the current drive name.
+     */
+    if (dirname[1] == '\0' && dirname[0] == '\\') {
+       alt_dirname[0] = _getdrive() + 'A' - 1;
+       alt_dirname[1] = ':';
+       alt_dirname[2] = '\\';
+       alt_dirname[3] = '\0';
+       dirname = alt_dirname;
+    }
+
+    dirp->path = (char *)sysMalloc(strlen(dirname) + 5);
+    if (dirp->path == 0) {
+       sysFree(dirp);
+//     errno = ENOMEM;
+       return 0;
+    }
+    strcpy(dirp->path, dirname);
+
+    fattr = GetFileAttributes(dirp->path);
+    if (fattr == 0xffffffff) {
+       sysFree(dirp->path);
+       sysFree(dirp);
+//     errno = ENOENT;
+       return 0;
+    } else if ((fattr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
+       sysFree(dirp->path);
+       sysFree(dirp);
+//     errno = ENOTDIR;
+       return 0;
+    }
+
+    /* Append "*.*", or possibly "\\*.*", to path */
+    if (dirp->path[1] == ':'
+       && (dirp->path[2] == '\0'
+           || (dirp->path[2] == '\\' && dirp->path[3] == '\0'))) {
+       /* No '\\' needed for cases like "Z:" or "Z:\" */
+       strcat(dirp->path, "*.*");
+    } else {
+       strcat(dirp->path, "\\*.*");
+    }
+
+    dirp->handle = FindFirstFile(dirp->path, &dirp->find_data);
+    if (dirp->handle == INVALID_HANDLE_VALUE) {
+        if (GetLastError() != ERROR_FILE_NOT_FOUND) {
+           sysFree(dirp->path);
+           sysFree(dirp);
+//         errno = EACCES;
+           return 0;
+       }
+    }
+    return dirp;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      readdir 
+ * OVERVIEW:      read directory given pointer to DIR structure. 
+ *                
+ * INTERFACE:
+ *   parameters:  DIR *dirp
+ *
+ *   returns:     Pointer to dirent structure. 
+ *=======================================================================*/
+struct dirent *
+readdir(DIR *dirp)
+{
+    if (dirp->handle == INVALID_HANDLE_VALUE) {
+       return 0;
+    }
+
+    strcpy(dirp->dirent.d_name, dirp->find_data.cFileName);
+
+    if (!FindNextFile(dirp->handle, &dirp->find_data)) {
+       if (GetLastError() == ERROR_INVALID_HANDLE) {
+//         errno = EBADF;
+           return 0;
+       }
+       FindClose(dirp->handle);
+       dirp->handle = INVALID_HANDLE_VALUE;
+    }
+
+    return &dirp->dirent;
+}
+
+
+/*=========================================================================
+ * FUNCTION:      closedir
+ * OVERVIEW:      close directory given pointer to DIR structure. 
+ *                Returns non-zero status if the close fails.
+ *                
+ * INTERFACE:
+ *   parameters:  DIR: *dirp
+ *
+ *   returns:     int: status 
+ *=======================================================================*/
+int
+closedir(DIR *dirp)
+{
+    if (dirp->handle != INVALID_HANDLE_VALUE) {
+       if (!FindClose(dirp->handle)) {
+//         errno = EBADF;
+           return -1;
+       }
+       dirp->handle = INVALID_HANDLE_VALUE;
+    }
+    sysFree(dirp->path);
+    sysFree(dirp);
+    return 0;
+}
+
+#endif
diff --git a/MPC.3.5.LINUX/preverifier/sysmacros_md.h b/MPC.3.5.LINUX/preverifier/sysmacros_md.h
new file mode 100644 (file)
index 0000000..0f02961
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * @(#)sysmacros_md.h  1.5 02/09/27
+ *
+ * Copyright 1995-1998 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYSMACROS_MD_H_
+#define _SYSMACROS_MD_H_
+
+/*
+ * Because these are used directly as function ptrs, just redefine the name
+ */
+#define sysMalloc      malloc
+#define sysFree                free
+#define sysCalloc      calloc
+#define sysRealloc     realloc
+
+/* A macro for sneaking into a sys_mon_t to get the owner sys_thread_t */
+#define sysMonitorOwner(mid)   ((mid)->monitor_owner)
+
+#ifdef DEBUG
+extern void DumpThreads(void);
+void panic (const char *, ...);
+#define sysAssert(expression) {                \
+    if (!(expression)) {               \
+       DumpThreads();                  \
+       panic("\"%s\", line %d: assertion failure\n", __FILE__, __LINE__); \
+    }                                  \
+}
+#else
+#define sysAssert(expression)
+#endif
+
+/*
+ * Case insensitive compare of ASCII strings
+ */
+#define sysStricmp(a, b)               strcasecmp(a, b)
+
+/*
+ * File system macros
+ */
+#ifdef UNIX
+#define sysOpen(_path, _oflag, _mode)  open(_path, _oflag, _mode)
+#define sysNativePath(path)            (path)
+#endif
+#ifdef WIN32
+#include <io.h>
+#define sysOpen(_path, _oflag, _mode)  open(_path, _oflag | O_BINARY, _mode)
+char *sysNativePath(char *);
+#endif
+#define sysRead(_fd, _buf, _n)         read(_fd, _buf, _n)
+#define sysWrite(_fd, _buf, _n)                write(_fd, _buf, _n)
+#define sysClose(_fd)                  close(_fd)
+#define sysAccess(_path, _mode)                access(_path, _mode)
+#define sysStat(_path, _buf)           stat(_path, _buf)
+#define sysMkdir(_path, _mode)         mkdir(_path, _mode)
+#define sysUnlink(_path)               unlink(_path)
+#define sysIsAbsolute(_path)           (*(_path) == '/')
+#define sysCloseDir(_dir)              closedir(_dir)
+#define sysOpenDir(_path)              opendir(_path)
+#define sysRmdir(_dir)                  remove(_dir)
+#define sysSeek(fd, offset, whence)    lseek(fd, offset, whence)
+#define sysRename(s, d)                        rename(s, d)
+
+#endif /*_SYSMACROS_MD_H_*/
diff --git a/MPC.3.5.LINUX/preverifier/tree.h b/MPC.3.5.LINUX/preverifier/tree.h
new file mode 100644 (file)
index 0000000..dca770f
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * @(#)tree.h  1.3 02/09/27
+ *
+ * Copyright 1995-1998 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ * 
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Definitions having to do with the program tree
+ */
+
+#ifndef _TREE_H_
+#define _TREE_H_
+
+#include "oobj.h"      /* for the definition of unicode */
+#include "typecodes.h"
+
+extern int   SkipSourceChecks;
+extern char *progname;
+extern ClassClass **binclasses;
+extern long nbinclasses, sizebinclasses;
+
+/* User specifiable attributes */
+#define ACC_PUBLIC            0x0001    /* visible to everyone */
+#define ACC_PRIVATE           0x0002   /* visible only to the defining class */
+#define ACC_PROTECTED         0x0004    /* visible to subclasses */
+#define ACC_STATIC            0x0008    /* instance variable is static */
+#define ACC_FINAL             0x0010    /* no further subclassing, overriding */
+#define ACC_SYNCHRONIZED      0x0020    /* wrap method call in monitor lock */
+#define ACC_SUPER             0x0020    /* funky handling of invokespecial */
+#define ACC_THREADSAFE        0x0040    /* can cache in registers */
+#define ACC_TRANSIENT         0x0080    /* not persistant */
+#define ACC_NATIVE            0x0100    /* implemented in C */
+#define ACC_INTERFACE         0x0200    /* class is an interface */
+#define ACC_ABSTRACT         0x0400    /* no definition provided */
+#define ACC_XXUNUSED1         0x0800    /*  */
+
+#define ACC_WRITTEN_FLAGS     0x0FFF    /* flags actually put in .class file */
+
+/* Other attributes */
+#define ACC_VALKNOWN          0x1000    /* constant with known value */
+#define ACC_DOCED             0x2000    /* documentation generated */
+#define ACC_MACHINE_COMPILED  0x4000    /* compiled to machine code */
+#define ACC_XXUNUSED3         0x8000    /*  */
+
+#define IsPrivate(access) (((access) & ACC_PRIVATE) != 0)
+#define IsPublic(access)  (((access) & ACC_PUBLIC) != 0)
+#define IsProtected(access)  (((access) & ACC_PROTECTED) != 0)
+
+char *addstr(char *s, char *buf, char *limit, char term);
+char *addhex(long n, char *buf, char *limit);
+char *adddec(long n, char *buf, char *limit);
+
+#ifdef TRIMMED
+# undef DEBUG
+# undef STATS
+# define NOLOG
+#endif
+
+
+#endif /* !_TREE_H_ */
diff --git a/MPC.3.5.LINUX/preverifier/typecodes.h b/MPC.3.5.LINUX/preverifier/typecodes.h
new file mode 100644 (file)
index 0000000..8e4b4e3
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * @(#)typecodes.h     1.2 02/09/27
+ *
+ * Copyright 1995-1998 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ * 
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Type codes  6/12/91
+
+       This typecode system allows us to represent the type
+       of scalars in a uniform way. For instance, all integer types
+       have some bits in common, and are distinguished by a built-in
+       size field. Types without multiple sizes don't have a size field.
+
+       Scalars may only have sizes which are powers of 2. The size
+       field holds the log-based-2 of the object's size.
+
+       All run-time types can be encoded in 4 bits. There are more
+       compile- time types. These fit in 5 bits.
+       Schematically, we have:
+               +----+----+----+----+----+
+               | c  |    t    |    s    |
+               +----+----+----+----+----+
+
+               Encoding is:
+                  c   t  s     type
+               -------------------------
+                  0  00 00     unassigned
+                  0  00 01     array
+                  0  00 10     class
+                  0  00 11     proxy    (OBSOLETE)
+                  0  01 00     boolean (1 byte)
+                  0  01 01     char    (2 bytes)
+                  0  01 1s     float (single=1; double=2)
+                  0  1u xx     integer (byte=0; short=1; int=2; long=3;
+                                        u=1 => unsigned)
+
+                       For runtime types, the size of an object
+                       is 1<<(t&3)
+
+                  1  00 00     typedef (compiler only)
+                  1  00 01     void    (compiler only)
+                  1  00 10     func    (compiler only)
+                  1  00 11     unknown (compiler only)
+                  1  01 00     error   (compiler only)
+
+       Char and Boolean are not int's because they need a different signature,
+       so have to be distinguishable, even at runtime. We allow arrays
+       of objects, arrays(?), booleans, char, integers, and floats.
+       Note that the low-order two bits of all these gives the log of
+       the size, except for arrays, of course.
+
+       I would prefer not to have unsigned int in the language, but
+       don't want to make that decision at this level. We could come up
+       with a better encoding of boolean and char if there were no
+       unsigned.
+
+       The compile-only type values that could be confused with the 
+       integer and float scalar types must not ever be used. Value 0 must
+       not be assigned a runtime type, as this is used for some sleazy
+       trickery in punning types and pointer. In fact, we even have a name
+       for it.
+*/
+
+/* If you change these typecodes, you'll have to fix the arrayinfo table
+   in gc.c and the {in,}direct_{load,store}_ops tables in
+   compiler/tree2code.c */
+
+#ifndef _TYPECODES_H_
+#define _TYPECODES_H_
+
+#define T_NORMAL_OBJECT        0
+#define T_XXUNUSEDXX1   1      /* Used to be T_ARRAY */
+#define T_CLASS                2
+#define T_BOOLEAN      4
+#define T_CHAR         5
+
+#define T_FLOATING     4       /* add log2 size to get correct code:
+                                       float has code 6,
+                                       double has code 7 */
+#define T_INTEGER      010
+#define T_UINTEGER     014
+
+#define        T_MAXNUMERIC    020
+
+#define        T_XXUNUSEDXX2   020
+#define        T_VOID          021
+#define        T_FUNC          022
+#define        T_UNKNOWN       023
+#define        T_ERROR         024
+
+/* for type construction */
+#define T_TMASK        034
+#define T_LMASK 003
+#define T_LSIZE 2
+#define T_MKTYPE( t, l )  ( ( (t)&T_TMASK ) | ( (l)&T_LMASK) )
+
+/* for type deconstruction */
+       /*
+        * Because we promise always to let ints and compile-only types be 
+        * distinguished by the "t" and "s" bits above, we can simplify
+        * some of our predicates by masking out the "c" bit when testing
+        * for integers. Thus the T_TS_MASK...
+        */
+#define T_TS_MASK 034
+#define T_ISINTEGER(t)  ( ((t)&030) == T_INTEGER  )
+#define T_ISFLOATING(t) ( ((t)&036) == T_FLOAT )
+#define T_ISNUMERIC(t)  ( (t) >= T_CHAR && (t) < T_MAXNUMERIC )
+#define T_SIZEFIELD(t) ((t)&T_LMASK)
+#define T_ELEMENT_SIZE(t) (1<<T_SIZEFIELD(t))  /* only for some!! */
+
+#define T_IS_BIG_TYPE(t) ((t == T_DOUBLE) || (t == T_LONG))
+#define T_TYPE_WORDS(t) (T_IS_BIG_TYPE(t) ? 2 : 1)
+
+/* nick-names for the usual scalar types */
+#define T_FLOAT  T_MKTYPE(T_FLOATING,2)
+#define T_DOUBLE T_MKTYPE(T_FLOATING,3)
+#define T_BYTE  T_MKTYPE(T_INTEGER,0)
+#define T_SHORT         T_MKTYPE(T_INTEGER,1)
+#define T_INT   T_MKTYPE(T_INTEGER,2)
+#define T_LONG  T_MKTYPE(T_INTEGER,3)
+
+#ifdef NO_LONGER_USED
+/* We no longer support these types */
+#define T_UBYTE         T_MKTYPE(T_UINTEGER,0)
+#define T_USHORT T_MKTYPE(T_UINTEGER,1)
+#define T_UINT  T_MKTYPE(T_UINTEGER,2)
+#define T_ULONG         T_MKTYPE(T_UINTEGER,3)
+
+#endif
+
+/* only a slight exaggeration */
+#define N_TYPECODES    (1<<6)
+#define        N_TYPEMASK      (N_TYPECODES-1)
+
+#endif /* !_TYPECODES_H_ */
diff --git a/MPC.3.5.LINUX/preverifier/typedefs.h b/MPC.3.5.LINUX/preverifier/typedefs.h
new file mode 100644 (file)
index 0000000..e9c5de9
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * @(#)typedefs.h      1.4 02/09/27
+ *
+ * Copyright 1995-1998 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ * 
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+#ifndef        _TYPEDEFS_H_
+#define        _TYPEDEFS_H_
+
+#include "typedefs_md.h"       /* for int64_t */
+
+/*
+ * Macros to deal with the JavaVM's stack alignment. Many machines
+ * require doublewords to be double aligned.  This union is used by
+ * code in math.h as a more portable way do alignment on machines
+ * that require it.  This union and the macros that use it came from
+ * Netscape.
+ */
+
+typedef union Java8Str {
+    int32_t x[2];
+    double d;
+    int64_t l;
+    void *p;
+} Java8;
+
+
+#ifdef HAVE_ALIGNED_LONGLONGS
+#define GET_INT64(_t,_addr) ( ((_t).x[0] = ((int32_t*)(_addr))[0]), \
+                              ((_t).x[1] = ((int32_t*)(_addr))[1]), \
+                              (_t).l )
+#define SET_INT64(_t, _addr, _v) ( (_t).l = (_v),                    \
+                                   ((int32_t*)(_addr))[0] = (_t).x[0], \
+                                   ((int32_t*)(_addr))[1] = (_t).x[1] )
+#else
+#define GET_INT64(_t,_addr) (*(int64_t*)(_addr))
+#define SET_INT64(_t, _addr, _v) (*(int64_t*)(_addr) = (_v))
+#endif
+
+/* If double's must be aligned on doubleword boundaries then define this */
+#ifdef HAVE_ALIGNED_DOUBLES
+#define GET_DOUBLE(_t,_addr) ( ((_t).x[0] = ((int32_t*)(_addr))[0]), \
+                               ((_t).x[1] = ((int32_t*)(_addr))[1]), \
+                               (_t).d )
+#define SET_DOUBLE(_t, _addr, _v) ( (_t).d = (_v),                    \
+                                    ((int32_t*)(_addr))[0] = (_t).x[0], \
+                                    ((int32_t*)(_addr))[1] = (_t).x[1] )
+#else
+#define GET_DOUBLE(_t,_addr) (*(double*)(_addr))
+#define SET_DOUBLE(_t, _addr, _v) (*(double*)(_addr) = (_v))
+#endif
+
+/* If pointers are 64bits then define this */
+#ifdef HAVE_64BIT_POINTERS
+#define GET_HANDLE(_t,_addr) ( ((_t).x[0] = ((int32_t*)(_addr))[0]), \
+                               ((_t).x[1] = ((int32_t*)(_addr))[1]), \
+                               (_t).p )
+#define SET_HANDLE(_t, _addr, _v) ( (_t).p = (_v),                    \
+                                    ((int32_t*)(_addr))[0] = (_t).x[0], \
+                                    ((int32_t*)(_addr))[1] = (_t).x[1] )
+#else
+#define GET_HANDLE(_t,_addr) (*(JHandle*)(_addr))
+#define SET_HANDLE(_t, _addr, _v) (*(JHandle*)(_addr) = (_v))
+#endif
+
+#undef TRUE
+#undef FALSE
+
+typedef enum {
+    FALSE = 0,
+    TRUE = 1
+} bool_t;
+
+#endif /* !_TYPEDEFS_H_ */
diff --git a/MPC.3.5.LINUX/preverifier/typedefs_md.h b/MPC.3.5.LINUX/preverifier/typedefs_md.h
new file mode 100644 (file)
index 0000000..a8ec6d7
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * @(#)typedefs_md.h   1.2 00/05/31
+ *
+ * Copyright 1995-1998 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+#ifndef _TYPES_MD_H_
+#define _TYPES_MD_H_
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef SOLARIS2
+/* don't redefine typedef's on Solaris 2.6 or Later */
+
+#if !defined(_ILP32) && !defined(_LP64)
+
+#ifndef        _UINT64_T
+#define        _UINT64_T
+typedef unsigned long long uint64_t;
+#define _UINT32_T
+typedef unsigned long uint32_t;
+#endif
+
+#ifndef        _INT64_T
+#define        _INT64_T
+typedef long long int64_t;
+#define _INT32_T
+typedef long int32_t;
+#endif
+
+#endif /* !defined(_ILP32) && !defined(_LP64) */
+#endif /* SOLARIS2 */
+
+#ifdef LINUX
+#ifndef       _UINT64_T
+#define       _UINT64_T
+typedef unsigned long long uint64_t;
+#define _UINT32_T
+typedef unsigned long uint32_t;
+#endif
+#endif /* LINUX */
+
+#ifdef WIN32
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+typedef long int32_t;
+typedef unsigned long uint32_t;
+typedef unsigned int uint_t;
+#endif
+
+/* use these macros when the compiler supports the long long type */
+
+#define ll_high(a)     ((long)((a)>>32))
+#define ll_low(a)      ((long)(a))
+#define int2ll(a)      ((int64_t)(a))
+#define ll2int(a)      ((int)(a))
+#define ll_add(a, b)   ((a) + (b))
+#define ll_and(a, b)   ((a) & (b))
+#define ll_div(a, b)   ((a) / (b))
+#define ll_mul(a, b)   ((a) * (b))
+#define ll_neg(a)      (-(a))
+#define ll_not(a)      (~(a))
+#define ll_or(a, b)    ((a) | (b))
+#define ll_shl(a, n)   ((a) << (n))
+#define ll_shr(a, n)   ((a) >> (n))
+#define ll_sub(a, b)   ((a) - (b))
+#define ll_ushr(a, n)  ((unsigned long long)(a) >> (n))
+#define ll_xor(a, b)   ((a) ^ (b))
+#define uint2ll(a)     ((uint64_t)(unsigned long)(a))
+#define ll_rem(a,b)    ((a) % (b))
+
+#define INT_OP(x,op,y)  ((x) op (y))
+#define NAN_CHECK(l,r,x) x
+#define IS_NAN(x) isnand(x)
+
+
+/* On Intel these conversions have to be method calls and not typecasts.
+   See the win32 typedefs_md.h file */
+#if defined(i386) || defined (__i386)
+
+extern int32_t float2l(float f);
+extern int32_t double2l(double d);
+extern int64_t float2ll(float f);
+extern int64_t double2ll(double d);
+
+#else /* not i386 */
+
+#define float2l(f)     (f)
+#define double2l(f)    (f)
+#define float2ll(f)    ((int64_t) (f))
+#define double2ll(f)   ((int64_t) (f))
+
+#endif /* i386 */
+
+
+#define ll2float(a)    ((float) (a))
+#define ll2double(a)   ((double) (a))
+
+/* comparison operators */
+#define ll_ltz(ll)     ((ll)<0)
+#define ll_gez(ll)     ((ll)>=0)
+#define ll_eqz(a)      ((a) == 0)
+#define ll_eq(a, b)    ((a) == (b))
+#define ll_ne(a,b)     ((a) != (b))
+#define ll_ge(a,b)     ((a) >= (b))
+#define ll_le(a,b)     ((a) <= (b))
+#define ll_lt(a,b)     ((a) < (b))
+#define ll_gt(a,b)     ((a) > (b))
+
+#define ll_zero_const  ((int64_t) 0)
+#define ll_one_const   ((int64_t) 1)
+
+extern void ll2str(int64_t a, char *s, char *limit);
+
+#ifdef ppc
+#define HAVE_ALIGNED_DOUBLES
+#define HAVE_ALIGNED_LONGLONGS
+#endif
+
+#ifdef SOLARIS2
+#include <sys/byteorder.h>
+#endif
+
+#ifdef LINUX
+#include <asm/byteorder.h>
+#endif
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#endif /* !_TYPES_MD_H_ */
diff --git a/MPC.3.5.LINUX/preverifier/utf.c b/MPC.3.5.LINUX/preverifier/utf.c
new file mode 100644 (file)
index 0000000..3f1eb20
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * @(#)utf.c   1.5 02/09/27
+ *
+ * Copyright 1995-1998 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ * 
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+/*=========================================================================
+ * SYSTEM:    Verifier
+ * SUBSYSTEM: Unicode translators.
+ * FILE:      utf.c
+ * OVERVIEW:  Routines for Unicode -> UTF and UTF -> unicode translators.
+ *       
+ * This file implements the unicode -> UTF and UTF -> unicode translators
+ * needed by the various parts of the compiler and interpreter.
+ *
+ * UTF strings are streams of bytes, in which unicode characters are encoded
+ * as follows:
+ *       Unicode                  UTF
+ *       00000000 0jklmnop       0jklmnop 
+ *       00000fgh ijklmnop       110fghij 10klmnop
+ *       abcdefgh ijklmnop       1110abcd 10efghij 10klmnop
+ *
+ * unicode bytes with 7 or fewer significant bits MUST be converted using the
+ * first format.  bytes with 11 or fewer bits MUST be converted using the
+ * second format.
+ *
+ * In JAVA/JAVAC, we deviate slightly from the above.  
+ *    1) The null unicode character is represented using the 2-byte format
+ *    2)  All UTF strings are null-terminated.
+ * In this way, we do not need to separately maintain a length field for the
+ * UTF string.
+ *
+ * Given a unicode string and its length, convert it to a utf string.  But 
+ * the result into the given buffer, whose length is buflength.  The utf
+ * string should include a null terminator.
+ *
+ * If both buffer and buflength are 0, then malloc an appropriately sized
+ * buffer for the result.
+ *
+ * AUTHOR:    Sheng Liang, Sun Microsystems, Inc.
+ *            Edited by Tasneem Sayeed, Sun Microsystems
+ *=======================================================================*/
+
+/*=========================================================================
+ * Include files
+ *=======================================================================*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "oobj.h"
+#include "utf.h"
+#include "sys_api.h"
+
+char *unicode2utf(unicode *unistring, int length, char *buffer, int buflength)
+{
+    int i;
+    unicode *uniptr;
+    char *bufptr;
+    unsigned bufleft;
+
+    if ((buffer == 0) && (buflength == 0)) {
+       buflength = unicode2utfstrlen(unistring, length);
+       if ((buffer = (char *) sysMalloc(buflength)) == 0) 
+           return 0;
+    }
+
+    bufleft = buflength - 1; /* take note of null now! */
+
+    for(i = length, uniptr = unistring, bufptr = buffer; --i >= 0; uniptr++) {
+       unicode ch = *uniptr;
+       if ((ch != 0) && (ch <=0x7f)) {
+           if ((int)(--bufleft) < 0)   /* no space for character */
+               break;
+           *bufptr++ = (char)ch;
+       } else if (ch <= 0x7FF) { 
+           /* 11 bits or less. */
+           unsigned char high_five = ch >> 6;
+           unsigned char low_six = ch & 0x3F;
+           if ((int)(bufleft -= 2) < 0) /* no space for character */
+               break;
+           *bufptr++ = high_five | 0xC0; /* 110xxxxx */
+           *bufptr++ = low_six | 0x80;   /* 10xxxxxx */
+       } else {
+           /* possibly full 16 bits. */
+           char high_four = ch >> 12;
+           char mid_six = (ch >> 6) & 0x3F;
+           char low_six = ch & 0x3f;
+           if ((int)(bufleft -= 3) < 0) /* no space for character */
+               break;
+           *bufptr++ = high_four | 0xE0; /* 1110xxxx */
+           *bufptr++ = mid_six | 0x80;   /* 10xxxxxx */
+           *bufptr++ = low_six | 0x80;   /* 10xxxxxx*/
+       }
+    }
+    *bufptr = 0;
+    return buffer;
+}
+
+/* Return the number of characters that would be needed to hold the unicode
+ * string in utf.  This INCLUDES the NULL!
+ */
+int unicode2utfstrlen(unicode *unistring, int unilength)
+{
+    int result_length = 1;
+    
+    for (; unilength > 0; unistring++, unilength--) {
+       unicode ch = *unistring;
+       if ((ch != 0) && (ch <= 0x7f)) /* 1 byte */
+           result_length++;
+       else if (ch <= 0x7FF)
+           result_length += 2; /* 2 byte character */
+       else 
+           result_length += 3; /* 3 byte character */
+    }
+    return result_length;
+}
+
+/* Give the number of unicode characters in a utf string */
+int utfstrlen(char *utfstring) 
+{
+    int length;
+    for (length = 0; *utfstring != 0; length++) 
+        next_utf2unicode(&utfstring);
+    return length;
+}
+
+/* Convert a utfstring to unicode in the buffer provided.  Put at most
+ * max_length characters into the buffer.  Whether or not we actually overflow
+ * the space, indicate the actual unicode length.
+ *
+ * Whether or not we overflow the space, return the actual number of
+ * characters that we used.
+ */
+
+void
+utf2unicode(char *utfstring, unicode *unistring, 
+           int max_length, int *lengthp)
+{
+    int length_remaining = max_length;
+    
+    while (length_remaining > 0 && *utfstring != 0) {
+       *unistring++ = next_utf2unicode(&utfstring);
+       length_remaining--;
+    }
+
+    if (length_remaining == 0) {
+       *lengthp = max_length + utfstrlen(utfstring);
+    } else {
+       *lengthp = max_length - length_remaining;
+    }
+}
+
+bool_t is_simple_utf(char *utfstring) 
+{
+    unsigned char *ptr;
+    for (ptr = (unsigned char *)utfstring; *ptr != 0; ptr++) {
+       if (*ptr > 0x80) return FALSE;
+    }
+    return TRUE;
+}
+
+
+unicode next_utf2unicode(char **utfstring_ptr) {
+    unsigned char *ptr = (unsigned char *)(*utfstring_ptr);
+    unsigned char ch, ch2, ch3;
+    int length = 1;            /* default length */
+    unicode result = 0x80;     /* default bad result; */
+    switch ((ch = ptr[0]) >> 4) {
+        default:
+           result = ch;
+           break;
+
+       case 0x8: case 0x9: case 0xA: case 0xB: case 0xF:
+           /* Shouldn't happen. */
+           break;
+
+       case 0xC: case 0xD:     
+           /* 110xxxxx  10xxxxxx */
+           if (((ch2 = ptr[1]) & 0xC0) == 0x80) {
+               unsigned char high_five = ch & 0x1F;
+               unsigned char low_six = ch2 & 0x3F;
+               result = (high_five << 6) + low_six;
+               length = 2;
+           } 
+           break;
+
+       case 0xE:
+           /* 1110xxxx 10xxxxxx 10xxxxxx */
+           if (((ch2 = ptr[1]) & 0xC0) == 0x80) {
+               if (((ch3 = ptr[2]) & 0xC0) == 0x80) {
+                   unsigned char high_four = ch & 0x0f;
+                   unsigned char mid_six = ch2 & 0x3f;
+                   unsigned char low_six = ch3 & 0x3f;
+                   result = (((high_four << 6) + mid_six) << 6) + low_six;
+                   length = 3;
+               } else {
+                   length = 2;
+               }
+           }
+           break;
+       } /* end of switch */
+
+    *utfstring_ptr = (char *)(ptr + length);
+    return result;
+}
diff --git a/MPC.3.5.LINUX/preverifier/utf.h b/MPC.3.5.LINUX/preverifier/utf.h
new file mode 100644 (file)
index 0000000..b5a3cd2
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * @(#)utf.h   1.2 02/09/27
+ *
+ * Copyright 1995-1998 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ * 
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Prototypes for the various UTF support functions.
+ */
+
+#ifndef _UTF_H_
+#define _UTF_H_
+
+char *unicode2utf(unicode *unistring, int length, char *buffer, int buflength);
+int unicode2utfstrlen(unicode *unistring, int unilength);
+int utfstrlen(char *utfstring);
+void utf2unicode(char *utfstring, unicode *unistring, 
+               int max_length, int *lengthp);
+bool_t is_simple_utf(char *utfstring);
+
+unicode next_utf2unicode(char **utfstring);
+
+#endif /* !_UTF_H_ */ 
diff --git a/MPC.3.5.LINUX/preverifier/util.c b/MPC.3.5.LINUX/preverifier/util.c
new file mode 100644 (file)
index 0000000..07b1db0
--- /dev/null
@@ -0,0 +1,745 @@
+/*
+ * @(#)util.c  1.7 02/09/27
+ *
+ * Copyright 1995-1999 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ * 
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ * Use is subject to license terms.
+ */
+
+/*=========================================================================
+ * SYSTEM:    Verifier
+ * SUBSYSTEM: Utility functions.
+ * FILE:      util.c
+ * OVERVIEW:  Utility routines needed by both the compiler and the interpreter.
+ *
+ * AUTHOR:    Sheng Liang, Sun Microsystems, Inc.
+ *            Edited by Tasneem Sayeed, Sun Microsystems
+ *=======================================================================*/
+
+/*=========================================================================
+ * Include files
+ *=======================================================================*/
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stddef.h>
+
+#include "oobj.h"
+#include "utf.h"
+#include "sys_api.h"
+#include "path.h"       /* DIR_SEPARATOR */
+
+/*=========================================================================
+ * Globals and extern declarations
+ *=======================================================================*/
+
+extern struct StrIDhash *nameTypeHash;
+extern struct StrIDhash *stringHash;
+
+unicode *
+str2unicode(char *str, unicode *ustr, long len)
+{
+    unicode *dst = ustr;
+
+    memset((char *) dst, 0, len * sizeof(*dst));
+    while (*str && --len >= 0)
+       *ustr++ = 0xff & *str++;
+    return dst;
+}
+
+void
+unicode2str(unicode *src, char *dst, long len)
+{
+    while (--len >= 0)
+       *dst++ = (char)(*src++);
+    *dst = '\0';
+}
+
+
+int
+jio_printf (const char *format, ...)
+{
+    int len;
+
+    va_list args;
+    va_start(args, format);
+    len = jio_vfprintf(stdout, format, args);
+    va_end(args);
+
+    return len;
+}
+
+int
+jio_fprintf (FILE *handle, const char *format, ...)
+{
+    int len;
+
+    va_list args;
+    va_start(args, format);
+    len = jio_vfprintf(handle, format, args);
+    va_end(args);
+
+    return len;
+}
+
+int
+jio_vfprintf (FILE *handle, const char *format, va_list args)
+{
+  return vfprintf(handle, format, args);
+}
+
+
+/*
+ * Print s null terminated C-style character string.
+ */
+void
+prints(char *s)
+{
+    jio_fprintf(stdout, "%s", s);
+}
+
+#undef  HTSIZE                 /* Avoid conflict on PC */
+#define HTSIZE 2003            /* Default size -- must be prime */
+#define HTOVERFLOWPOINT(h)     (h->size * 4 / 5)
+
+/*
+ * We store most of the result of the hash in hash_bits to quickly
+ * reject impossible matches because strcmp() is fairly expensive,
+ * especially when many strings will have common prefixes.
+ */
+typedef struct {
+    char *hash;                        /* the string for this entry */
+    unsigned is_malloced :  1; /* 1 if hash was malloced */
+    unsigned hash_bits   : 31; /* low 31 bits of the hash */
+} StrIDhashSlot;
+
+typedef void (*hash_fn)(const char *s, unsigned *h1, unsigned *h2);
+
+typedef struct StrIDhash {
+    int size;                  /* number of entries */
+    hash_fn hash;              /* hash function for this table */
+    struct StrIDhash *next;    /* next bucket */
+    short used;                        /* number of full entries */
+    short baseid;              /* ID for item in slot[0] */
+    void **params;             /* param table, if needed */
+    StrIDhashSlot slot[1];     /* expanded to be number of slots */
+} StrIDhash;
+
+/* Hash a string into a primary and secondary hash value */
+static void
+default_hash(const char *s, unsigned *h1, unsigned *h2)
+{
+    int i;
+    unsigned raw_hash;
+    for (raw_hash = 0; (i = *s) != '\0'; ++s) 
+
+       raw_hash = raw_hash * 37 + i;
+    *h1 = raw_hash;
+    *h2 = (raw_hash & 7) + 1; /* between 1 and 8 */
+}
+
+/* Create a hash table of the specified size */
+static StrIDhash *
+createHash(int entries)
+{
+    StrIDhash *h;
+    int size = offsetof(struct StrIDhash, slot) +  (entries * sizeof(h->slot));
+    h = (StrIDhash *)sysCalloc(1, size); 
+    if (h != NULL) { 
+       h->size = entries;
+       h->hash = default_hash; /* only custom tables get something else */
+       h->next = NULL;
+    }
+    return h;
+}
+
+/*
+ * Given a string, return a unique 16 bit id number.  
+ * If param isn't null, we also set up an array of void * for holding info
+ *     about each object.  The address of this void * is stored into param
+ * If CopyNeeded is true, then the name argument "s" must be dup'ed, since
+ * the current item is allocated on the stack.
+ *
+ * Note about returning 0 in the case of out of memory errors: 0 is *not*
+ * a valid ID!  The out of memory error should be thrown by the calling code.
+ */
+unsigned short
+Str2ID(StrIDhash **hash_ptr, register char *s, void ***param,
+             int CopyNeeded)
+{
+    /*
+     * The database is a hash table.  When the hash table overflows, a new
+     * hashtable is created chained onto the previous one.  This is done so
+     * that we can use the hashtable slot index as the ID, without worrying
+     * about having the IDs change when the hashtable grows.
+     */
+    StrIDhash *h = *hash_ptr;
+    long i;
+    unsigned primary_hash;
+    unsigned secondary_hash;
+    unsigned hash_bits;
+    hash_fn current_hash_func = NULL;
+
+    if (h == NULL) 
+       goto not_found;
+
+    /* Create the hash values */
+    current_hash_func = h->hash;
+    current_hash_func(s, &primary_hash, &secondary_hash);
+    hash_bits = primary_hash & ((1u << 31) - 1);
+
+    for (;;) {
+       char *s2;
+       int bucketSize = h->size;
+       
+       /* See if the new hash table has a different hash function */
+       if (h->hash != current_hash_func) {
+           current_hash_func = h->hash;
+           current_hash_func(s, &primary_hash, &secondary_hash);
+           hash_bits = primary_hash & ((1u << 31) - 1);
+       }
+       i = primary_hash % bucketSize;
+       
+       while ((s2 = h->slot[i].hash) != NULL) {
+           if (h->slot[i].hash_bits == hash_bits && strcmp(s2, s) == 0)
+               goto found_it;
+           if ((i -= secondary_hash) < 0)
+               i += bucketSize;
+       }
+       /* Not found in this table.  Try the next table. */
+       if (h->next == NULL)
+           break;
+       h = h->next;
+    }
+    
+not_found:
+    /* Either the hash table is empty, or the item isn't yet found. */
+    if (h == NULL || (h->used >= HTOVERFLOWPOINT(h))) {
+       /* Need to create a new bucket */
+       StrIDhash *next;
+        if (h && h->baseid > 30000 && *hash_ptr != stringHash) {
+           panic("16-bit string hash table overflow");
+       }
+       next = createHash(HTSIZE);
+       if (next == NULL) {
+           /* Calling code should signal OutOfMemoryError */
+           return 0;
+       }
+       if (h == NULL) { 
+           /* Create a new table */
+           *hash_ptr = h = next; 
+           h->baseid = 1;  /* guarantee that no ID is 0 */
+       } else { 
+           next->baseid = h->baseid + h->size;
+           h->next = next;
+           h = next;
+       }
+       if (h->hash != current_hash_func) {
+           current_hash_func = h->hash;
+           current_hash_func(s, &primary_hash, &secondary_hash);
+           hash_bits = primary_hash & ((1u << 31) - 1);
+       }
+       i = primary_hash % h->size;
+    }
+    if (CopyNeeded) {
+       char *d = strdup(s);
+       if (d == NULL) {
+           /* Calling code should signal OutOfMemoryError */
+            return 0;
+       }
+       s = d;
+       h->slot[i].is_malloced = 1;
+    } 
+    h->slot[i].hash = s;
+    h->slot[i].hash_bits = hash_bits;
+    h->used++;
+
+found_it:
+    /* We have found or created slot "i" in hash bucket "h" */
+    if (param != NULL) { 
+       if (h->params == NULL) { 
+           h->params = sysCalloc(h->size, sizeof(void *));
+           if (h->params == NULL) {
+               /* Calling code should signal OutOfMemoryError */
+               return 0;
+           }
+       }
+       *param = &(h->params[i]);
+    }
+    return (unsigned short)(h->baseid + i);
+}
+
+/* Free an StrIDhash table and all the entries in it */
+void Str2IDFree(StrIDhash **hash_ptr)
+{
+    StrIDhash *hash = *hash_ptr;
+
+    while (hash != NULL) {
+       StrIDhash *next = hash->next;
+       StrIDhashSlot *ptr, *endPtr;
+       for (ptr = &hash->slot[0], endPtr = ptr + hash->size; 
+                 ptr < endPtr; ptr++) { 
+           if (ptr->is_malloced) 
+               sysFree(ptr->hash);
+       }
+       if (hash->params != NULL) 
+           sysFree(hash->params);
+       sysFree(hash);
+       hash = next;
+    }
+    *hash_ptr = 0;
+}
+
+/*
+ * Call the callback function on every entry in the table.  This
+ * should only be invoked holding the string hash table lock.
+ */
+void Str2IDCallback(StrIDhash **hash_ptr, void (*callback)(char *, void *))
+{
+    StrIDhash *hash, *next;
+    int i;
+
+    hash = *hash_ptr;
+    while (hash) {
+       void **params = hash->params;
+       next = hash->next;
+       for (i = 0; i < hash->size; i++) {
+           if (hash->slot[i].hash != 0) { 
+               callback(hash->slot[i].hash, params ? params[i] : NULL);
+           }
+       }
+       hash = next;
+    }
+}
+
+/*
+ * Returns NULL in the case of an error.
+ */
+char *
+ID2Str(StrIDhash *h, unsigned short ID, void ***param)
+{
+    int entry;
+
+    while ((long)(ID - h->baseid) >= h->size) {
+       h = h->next;
+    }
+    entry = ID - h->baseid;
+    if (param != NULL) { 
+       if (h->params == NULL) {
+           h->params = (void **)sysCalloc(h->size, sizeof(*param));
+           if (h->params == NULL) {
+               /* Calling code should signal OutOfMemoryError */
+               return NULL;
+           }
+       }
+       *param = &h->params[entry];
+    } 
+    return h->slot[entry].hash;
+}
+
+char *
+addstr(char *s, char *buf, char *limit, char term)
+{
+    char c;
+    while ((c = *s) && c != term && buf < limit) {
+       *buf++ = c;
+       s++;
+    }
+    return buf;
+}
+
+char *
+unicode2rd(unicode *s, long len)
+{       /* unicode string to readable C string */
+#define CSTRLEN 40
+    static char buf[CSTRLEN+1];
+    char *dp = buf;
+    int c;
+    if (s == 0)
+       return "NULL";
+    *dp++ = '"';
+    while (--len>=0 && (c = *s++) != 0 && dp < buf + sizeof buf - 10)
+       if (040 <= c && c < 0177)
+           *dp++ = c;
+       else
+           switch (c) {
+           case '\n':
+               *dp++ = '\\';
+               *dp++ = 'n';
+               break;
+           case '\t':
+               *dp++ = '\\';
+               *dp++ = 't';
+               break;
+           case '\r':
+               *dp++ = '\\';
+               *dp++ = 'r';
+               break;
+           case '\b':
+               *dp++ = '\\';
+               *dp++ = 'b';
+               break;
+           case '\f':
+               *dp++ = '\\';
+               *dp++ = 'f';
+               break;
+           default:
+               /* Should not be possible to overflow, truncate if so */
+               (void) jio_snprintf(dp, CSTRLEN+1 - (dp - buf), "\\%X", c);
+               dp += strlen(dp);
+               break;
+           }
+    *dp++ = '"';
+    if (len >= 0 && c != 0)
+       *dp++ = '.', *dp++ = '.', *dp++ = '.';
+    *dp++ = 0;
+    return buf;
+}
+
+/*
+ * WARNING: out_of_memory() aborts the runtime!  It should not be used
+ * except in the case of out of memory situations that are clearly not
+ * survivable, like running out of memory before the runtime is initialized.
+ * If the runtime has finished initializing and you run out of memory, you
+ * should throw an OutOfMemoryError instead.
+ */
+void
+out_of_memory()
+{
+       jio_fprintf(stderr, "**Out of memory, exiting**\n");
+       exit(1);
+}
+
+void
+panic(const char *format, ...)
+{
+    va_list ap;
+    char buf[256];
+
+       printCurrentClassName();
+    va_start(ap, format);
+    
+    /* If buffer overflow, quietly truncate */
+    (void) jio_vsnprintf(buf, sizeof(buf), format, ap);
+
+    jio_fprintf(stdout, "\nERROR: %s\n", buf);
+
+    exit(1);
+}
+
+char *
+classname2string(char *src, char *dst, int size) {
+    char *buf = dst;
+    for (; (--size > 0) && (*src != '\0') ; src++, dst++) {
+       if (*src == '/') {
+           *dst = '.';
+       }  else {
+           *dst = *src;
+       }
+    }
+    *dst = '\0';
+    return buf;
+}
+
+typedef struct InstanceData {
+    char *buffer;
+    char *end;
+} InstanceData;
+
+#define ERROR_RETVAL -1
+#undef  SUCCESS
+#define SUCCESS 0
+#undef  CheckRet
+#define CheckRet(x) { if ((x) == ERROR_RETVAL) return ERROR_RETVAL; }
+
+static int 
+put_char(InstanceData *this, int c)
+{
+    if (iscntrl(0xff & c) && c != '\n' && c != '\t') {
+        c = '@' + (c & 0x1F);
+        if (this->buffer >= this->end) {
+            return ERROR_RETVAL;
+        }
+        *this->buffer++ = '^';
+    }
+    if (this->buffer >= this->end) {
+        return ERROR_RETVAL;
+    }
+    *this->buffer++ = c;
+    return SUCCESS;
+}
+
+static int
+format_string(InstanceData *this, char *str, int left_justify, int min_width,
+              int precision)
+{
+    int pad_length;
+    char *p;
+
+    if (str == 0) {
+       return ERROR_RETVAL;
+    }
+
+    if ((int)strlen(str) < precision) {
+        pad_length = min_width - strlen(str);
+    } else {
+        pad_length = min_width - precision;
+    }
+    if (pad_length < 0)
+        pad_length = 0;
+    if (left_justify) {
+        while (pad_length > 0) {
+            CheckRet(put_char(this, ' '));
+            --pad_length;
+        }
+    }
+
+    for (p = str; *p != '\0' && --precision >= 0; p++) {
+        CheckRet(put_char(this, *p));
+    }
+
+    if (!left_justify) {
+        while (pad_length > 0) {
+            CheckRet(put_char(this, ' '));
+            --pad_length;
+        }
+    }
+    return SUCCESS;
+}
+
+#define MAX_DIGITS 32
+
+static int
+format_number(InstanceData *this, long value, int format_type, int left_justify,
+              int min_width, int precision, bool_t zero_pad)
+{
+    int sign_value = 0;
+    unsigned long uvalue;
+    char convert[MAX_DIGITS+1];
+    int place = 0;
+    int pad_length = 0;
+    static char digits[] = "0123456789abcdef";
+    int base = 0;
+    bool_t caps = FALSE;
+    bool_t add_sign = FALSE;
+
+    switch (format_type) {
+      case 'o': case 'O':
+          base = 8;
+          break;
+      case 'd': case 'D':
+          add_sign = TRUE; /* fall through */
+      case 'u': case 'U':
+          base = 10;
+          break;
+      case 'X':
+          caps = TRUE; /* fall through */
+      case 'x':
+          base = 16;
+          break;
+    }
+    sysAssert(base > 0 && base <= 16);
+
+    uvalue = value;
+    if (add_sign) {
+        if (value < 0) {
+            sign_value = '-';
+            uvalue = -value;
+        }
+    }
+
+    do {
+        convert[place] = digits[uvalue % (unsigned)base];
+        if (caps) {
+            convert[place] = toupper(convert[place]);
+        }
+        place++;
+        uvalue = (uvalue / (unsigned)base);
+        if (place > MAX_DIGITS) {
+            return ERROR_RETVAL;
+        }
+    } while(uvalue);
+    convert[place] = 0;
+
+    pad_length = min_width - place;
+    if (pad_length < 0) {
+        pad_length = 0;
+    }
+    if (left_justify) {
+        if (zero_pad && pad_length > 0) {
+            if (sign_value) {
+                CheckRet(put_char(this, sign_value));
+                --pad_length;
+                sign_value = 0;
+            }
+            while (pad_length > 0) {
+                CheckRet(put_char(this, '0'));
+                --pad_length;
+            }
+        } else {
+            while (pad_length > 0) {
+                CheckRet(put_char(this, ' '));
+                --pad_length;
+            }
+        }
+    }
+    if (sign_value) {
+        CheckRet(put_char(this, sign_value));
+    }
+
+    while (place > 0 && --precision >= 0) {
+        CheckRet(put_char(this, convert[--place]));
+    }
+
+    if (!left_justify) {
+        while (pad_length > 0) {
+            CheckRet(put_char(this, ' '));
+            --pad_length;
+        }
+    }
+    return SUCCESS;
+}
+
+int
+jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args)
+{
+    char *strvalue;
+    long value;
+    InstanceData this;
+    bool_t left_justify, zero_pad, long_flag, add_sign, fPrecision;
+    int min_width, precision, ch;
+
+    if (str == NULL) {
+       return ERROR_RETVAL;
+    }
+    str[0] = '\0';
+
+    this.buffer = str;
+    this.end = str + count - 1;
+    *this.end = '\0';          /* ensure null-termination in case of failure */
+
+    while ((ch = *fmt++) != 0) {
+        if (ch == '%') {
+            zero_pad = long_flag = add_sign = fPrecision = FALSE;
+            left_justify = TRUE;
+            min_width = 0;
+            precision = this.end - this.buffer;
+        next_char:
+            ch = *fmt++;
+            switch (ch) {
+              case 0:
+                  return ERROR_RETVAL;
+              case '-':
+                  left_justify = FALSE;
+                  goto next_char;
+              case '0': /* set zero padding if min_width not set */
+                  if (min_width == 0)
+                      zero_pad = TRUE;
+              case '1': case '2': case '3':
+              case '4': case '5': case '6':
+              case '7': case '8': case '9':
+                  if (fPrecision == TRUE) {
+                      precision = precision * 10 + (ch - '0');
+                  } else {
+                      min_width = min_width * 10 + (ch - '0');
+                  }
+                  goto next_char;
+              case '.':
+                  fPrecision = TRUE;
+                  precision = 0;
+                  goto next_char;
+              case 'l':
+                  long_flag = TRUE;
+                  goto next_char;
+              case 's':
+                  strvalue = va_arg(args, char *);
+                  CheckRet(format_string(&this, strvalue, left_justify,
+                                         min_width, precision));
+                  break;
+              case 'c':
+                  ch = va_arg(args, int);
+                  CheckRet(put_char(&this, ch));
+                  break;
+              case '%':
+                  CheckRet(put_char(&this, '%'));
+                  break;
+              case 'd': case 'D':
+              case 'u': case 'U':
+              case 'o': case 'O':
+              case 'x': case 'X':
+                  value = long_flag ? va_arg(args, long) : va_arg(args, int);
+                  CheckRet(format_number(&this, value, ch, left_justify,
+                                         min_width, precision, zero_pad));
+                  break;
+              default:
+                  return ERROR_RETVAL;
+            }
+        } else {
+            CheckRet(put_char(&this, ch));
+        }
+    }
+    *this.buffer = '\0';
+    return strlen(str);
+}
+
+int 
+jio_snprintf(char *str, size_t count, const char *fmt, ...)
+{
+    va_list args;
+    int len;
+
+    va_start(args, fmt);
+    len = jio_vsnprintf(str, count, fmt, args);
+    va_end(args);
+    return len;
+}
+
+/* Return true if the two classes are in the same class package */
+
+bool_t
+IsSameClassPackage(ClassClass *class1, ClassClass *class2) 
+{
+    if (cbLoader(class1) != cbLoader(class2)) 
+       return FALSE;
+    else {
+       char *name1 = cbName(class1);
+       char *name2 = cbName(class2);
+       char *last_slash1 = strrchr(name1, DIR_SEPARATOR);
+       char *last_slash2 = strrchr(name2, DIR_SEPARATOR);
+       if ((last_slash1 == NULL) || (last_slash2 == NULL)) {
+           /* One of the two doesn't have a package.  Only return true
+            * if the other one also doesn't have a package. */
+           return (last_slash1 == last_slash2); 
+       } else {
+           int length1, length2;
+           if (*name1 == SIGNATURE_ARRAY) { 
+               do name1++; while (*name1 == SIGNATURE_ARRAY);
+               if (*name1 != SIGNATURE_CLASS) { 
+                   /* Something is terribly wrong.  Shouldn't be here */
+                   return FALSE;
+               }
+               name1++;
+           }
+           if (*name2 == SIGNATURE_ARRAY) { 
+               do name2++; while (*name2 == SIGNATURE_ARRAY);
+               if (*name2 != SIGNATURE_CLASS) { 
+                   /* Something is terribly wrong.  Shouldn't be here */
+                   return FALSE;
+               }
+               name2++;
+           }
+           length1 = last_slash1 - name1;
+           length2 = last_slash2 - name2;
+           return ((length1 == length2) 
+                   && (strncmp(name1, name2, length1) == 0));
+       }
+    }
+}
diff --git a/MPC.3.5.LINUX/readme.txt b/MPC.3.5.LINUX/readme.txt
new file mode 100644 (file)
index 0000000..7d88d1a
--- /dev/null
@@ -0,0 +1,10 @@
+This is the official MIDletPascal 3.5 compiler source code.
+
+To read the enhancements, adjustments, modifications and bugfixes that I made check the header comments of the main/main.c file.
+
+To get it working use Code::Blocks 8.02 (http://www.codeblocks.org/) and GCC.
+
+Enjoy,
+
+Javier Santo Domingo
+02.february.2013
diff --git a/MPC.3.5.LINUX/structures/block.c b/MPC.3.5.LINUX/structures/block.c
new file mode 100644 (file)
index 0000000..cb7b9d4
--- /dev/null
@@ -0,0 +1,3040 @@
+/********************************************************************
+
+       block.h - structures and functions used to hold program
+       block descriptions
+
+  Niksa Orlic, 2004-04-29
+
+********************************************************************/
+
+
+#include "../util/strings.h"
+#include "../util/error.h"
+//#include "../util/message.h"
+#include "../classgen/bytecode.h"
+#include "type_list.h"
+#include "string_list.h"
+#include "type.h"
+#include "identifier.h"
+#include "name_table.h"
+#include "unit.h"
+#include "block.h"
+#include "../classgen/preverify.h"
+
+#include "../util/memory.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "../classgen/constant_pool.h"
+#include "../classgen/classgen.h"
+
+extern int linenum;
+extern int new_linenum;
+extern block* root_block;
+extern char *global_library_directory;
+extern char *project_library_directory;
+
+extern char *user_libraries;
+extern char **units;
+
+extern int detect_units_only;
+
+extern constant_pool *constants;
+extern int constant_pool_size;
+
+extern int usesFloat;
+extern int usesRecordStore;
+extern int usesHttp;
+
+extern int canvasType;
+
+extern int mathType;
+
+extern int compiling_unit;
+extern string* str_program_name;
+
+extern char* output_path;
+
+#pragma warning (disable:4305)
+#pragma warning (disable:4761)
+
+/*
+       Create an empty block
+*/
+block* block_create(block *parent_block, string *block_name)
+{
+       block *new_block;
+       new_block = (block*) mem_alloc(sizeof(block));
+
+       new_block->names = name_table_create();
+       new_block->parent_block = parent_block;
+       new_block->block_name = block_name; /* do not copy the name, just point to it */
+
+       new_block->next_variable_index = 0;
+       new_block->next_parameter_index = 0;
+
+       new_block->code = bytecode_create();
+
+       new_block->children_count = 0;
+
+       return new_block;
+}
+
+
+/*
+       Delete a block
+*/
+void block_destroy(block *item)
+{
+       int i;
+       name_table_destroy(item->names);
+       bytecode_destroy(item->code);
+
+       /* delete all of its children */
+       for(i=0; i<item->children_count; i++)
+       {
+               block_destroy(item->children[i]);
+       }
+
+       if (item->children_count > 0)
+       {
+               mem_free(item->children);
+       }
+
+       /* do not delete the item->block_name */
+       mem_free(item);
+}
+
+
+/*
+       Check if a given name is legal name for a
+       new identifier in a block.
+*/
+int block_check_name(block *item, char *cstr)
+{
+       int return_value = 1;
+
+       string *name;
+       identifier *descriptor;
+       name = string_from_cstr(cstr);
+
+       descriptor = name_table_find(item->names, name);
+
+       if (descriptor != NULL)
+       {
+               if (((descriptor->identifier_class == procedure_name)
+                           || (descriptor->identifier_class == function_name))
+                       && (descriptor->forward_declaration == 1))
+                       return_value = 1;
+               else
+                       return_value = 0;
+       }
+
+       /* check the root block's types - those types are protected */
+       if (return_value == 1)
+       {
+               while (item->parent_block != NULL)
+                       item = item->parent_block;
+
+               descriptor = name_table_find(item->names, name);
+
+               if ((descriptor != NULL) && (descriptor->identifier_class == type_name))
+                       return_value = 0;
+       }
+
+       string_destroy(name);
+
+       return return_value;
+}
+
+/*
+       Adds a single real constant into the block
+*/
+void add_real_constant(block *item, float value, char *cstr_name)
+{
+       string *name;
+       identifier *descriptor;
+
+       name = string_from_cstr(cstr_name);
+       descriptor = identifier_create();
+       descriptor->identifier_class = constant_name;
+       descriptor->constant_type = type_create();
+       descriptor->constant_type->type_class = real_type;
+       descriptor->constant_real_value = value;
+       name_table_insert(item->names, name, descriptor);
+}
+
+
+/*
+       Adds a single integer constant into the block
+*/
+void add_integer_constant(block *item, long int value, char *cstr_name)
+{
+       string *name;
+       identifier *descriptor;
+
+       name = string_from_cstr(cstr_name);
+       descriptor = identifier_create();
+       descriptor->identifier_class = constant_name;
+       descriptor->constant_type = type_create();
+       descriptor->constant_type->type_class = integer_type;
+       descriptor->constant_int_value = value;
+       name_table_insert(item->names, name, descriptor);
+}
+
+
+/*
+       Adds a single character constant into the block
+*/
+void add_char_constant(block *item, char value, char *cstr_name)
+{
+       string *name;
+       identifier *descriptor;
+
+       name = string_from_cstr(cstr_name);
+       descriptor = identifier_create();
+       descriptor->identifier_class = constant_name;
+       descriptor->constant_type = type_create();
+       descriptor->constant_type->type_class = char_type;
+       descriptor->constant_int_value = value;
+       name_table_insert(item->names, name, descriptor);
+}
+
+
+/*
+       Adds a single boolean constant into the block
+*/
+void add_boolean_constant(block *item, char value, char *cstr_name)
+{
+       string *name;
+       identifier *descriptor;
+
+       name = string_from_cstr(cstr_name);
+       descriptor = identifier_create();
+       descriptor->identifier_class = constant_name;
+       descriptor->constant_type = type_create();
+       descriptor->constant_type->type_class = boolean_type;
+       descriptor->constant_int_value = value;
+       name_table_insert(item->names, name, descriptor);
+}
+
+
+/*
+       Adds a single string constant into the block
+*/
+void add_string_constant(block *item, string *value, char *cstr_name)
+{
+       string *name;
+       identifier *descriptor;
+
+       name = string_from_cstr(cstr_name);
+       descriptor = identifier_create();
+       descriptor->identifier_class = constant_name;
+       descriptor->constant_type = type_create();
+       descriptor->constant_type->type_class = string_type;
+       descriptor->constant_string_value = string_duplicate(value);
+       name_table_insert(item->names, name, descriptor);
+}
+
+
+/*
+       Adds variables into a block. The variable names are
+       located inside a string list, and a type for all
+       the variables is described in var_type parameter.
+*/
+void add_variables(block *item, string_list *identifier_list, type *var_type)
+{
+       string_list *it;
+       identifier *descriptor;
+       identifier *block_identifier;
+
+       it = identifier_list;
+
+       if (it->data == NULL)
+       {
+               type_destroy(var_type);
+               return;
+       }
+
+       if(item->parent_block != root_block)
+       {
+               block_identifier = name_table_find(item->parent_block->names, item->block_name);
+               if (block_identifier->variables == NULL)
+                       block_identifier->variables = type_list_create();
+       }
+       else
+               block_identifier = NULL;
+
+       while (it != NULL)
+       {
+        // j-a-s-d: consecutive variable name collision fix
+        if (!block_check_name(item, it->data->cstr))
+        {
+            add_error_message(400, it->data->cstr, "");
+        }
+               descriptor = identifier_create();
+               descriptor->identifier_class = variable_name;
+               descriptor->variable_type = type_duplicate(var_type);
+               descriptor->variable_index = item->next_variable_index;
+               descriptor->belongs_to_program_block = (item->parent_block == root_block);
+               name_table_insert(item->names, string_duplicate(it->data), descriptor);
+
+               if (compiling_unit == 0)
+                       initialize_variable(item, descriptor, it->data->cstr, 1, "M");
+               else
+                       initialize_variable(item, descriptor, it->data->cstr, 1, string_get_cstr(str_program_name));
+
+               if (block_identifier != NULL)
+                       type_list_append(block_identifier->variables, descriptor->variable_type);
+
+               item->next_variable_index ++;
+
+               it = it->next;
+       }
+
+}
+
+/*
+       Add a type into block. The name and type_type
+       are NOT copied.
+*/
+void add_type(block *item, string *name, type *type_type)
+{
+       identifier *descriptor;
+
+       descriptor = identifier_create();
+       descriptor->identifier_class = type_name;
+       descriptor->defined_type = type_type;
+       name_table_insert(item->names, name, descriptor);
+}
+
+
+/*
+       Adds a procedure declaration into the block
+*/
+void add_procedure(block *item, string *name, type_list *parameters,
+                                  int forward_declaration, int linenum)
+{
+       identifier *descriptor;
+
+       descriptor = name_table_find(item->names, name);
+
+       if (descriptor != NULL)
+       {
+               if ((forward_declaration != -1)
+                       && (descriptor->forward_declaration != -1))
+                       check_forward_declaration(descriptor, parameters,
+                               forward_declaration, NULL);
+
+               if ((descriptor->forward_declaration == -1)
+                       || (forward_declaration != -1))
+                       descriptor->forward_declaration = forward_declaration;
+       }
+       else
+       {
+               descriptor = identifier_create();
+               descriptor->identifier_class = procedure_name;
+               descriptor->parameters = parameters;
+               descriptor->forward_declaration = forward_declaration;
+               descriptor->subprogram_linenum = linenum;
+               name_table_insert(item->names, name, descriptor);
+       }
+}
+
+
+/*
+       Adds a function declaration into the block
+*/
+void add_function(block *item, string *name, type_list *parameters,
+                                 type *return_type, int forward_declaration, int linenum)
+{
+       identifier *descriptor;
+
+       descriptor = name_table_find(item->names, name);
+
+       if (descriptor != NULL)
+       {
+               if ((forward_declaration != -1)
+                       && (descriptor->forward_declaration != -1))
+                       check_forward_declaration(descriptor, parameters,
+                               forward_declaration, return_type);
+
+               if ((descriptor->forward_declaration == -1)
+                       || (forward_declaration != -1))
+               descriptor->forward_declaration = forward_declaration;
+       }
+       else
+       {
+               descriptor = identifier_create();
+               descriptor->identifier_class = function_name;
+               descriptor->parameters = parameters;
+               descriptor->return_type = return_type;
+               descriptor->forward_declaration = forward_declaration;
+               descriptor->subprogram_linenum = linenum;
+               name_table_insert(item->names, name, descriptor);
+       }
+}
+
+
+/*
+       Loads (inserts) an external library into the project - load the class file and
+       enumerate all static functions.
+*/
+void load_extern_library(string* library_name)
+{
+       FILE *library_file = NULL;
+       FILE *symbol_file = NULL;
+       string *global_library_path;
+       string *project_library_path;
+       unit *library_unit;
+       identifier  *unit_identifier;
+
+       lowercase(library_name->cstr);
+
+       /* create the full path to the library file */
+       /* global library directory */
+       global_library_path = string_from_cstr(global_library_directory);
+       #ifdef WIN32
+       string_append(global_library_path, string_from_cstr("\\Lib_"));
+       #endif
+       #ifdef UNIX
+       string_append(global_library_path, string_from_cstr("/Lib_"));
+       #endif
+       string_append(global_library_path, library_name);
+       string_append(global_library_path, string_from_cstr(".class"));
+       /* project library directory */
+       project_library_path = string_from_cstr(project_library_directory);
+       #ifdef WIN32
+       string_append(project_library_path, string_from_cstr("\\Lib_"));
+       #endif
+       #ifdef UNIX
+       string_append(project_library_path, string_from_cstr("/Lib_"));
+       #endif
+       string_append(project_library_path, library_name);
+       string_append(project_library_path, string_from_cstr(".class"));
+
+       if (name_table_find(root_block->names, library_name) != NULL)
+       {
+               add_error_message(450, string_get_cstr(library_name), "");
+               fclose(library_file);
+               goto lel_finally;
+       }
+
+       /* create a new unit object */
+       library_unit = unit_create(string_duplicate(library_name));
+       unit_identifier = identifier_create();
+       unit_identifier->identifier_class = unit_name;
+       unit_identifier->unit_block = library_unit;
+       name_table_insert(root_block->names, string_duplicate(library_name), unit_identifier);
+
+       /* try open the library file from the libraries directories */
+       library_file = fopen(project_library_path->cstr, "rb");
+       if (library_file == NULL)
+       {
+        library_file = fopen(global_library_path->cstr, "rb");
+       }
+       if (library_file == NULL)
+       {
+               /* if this fails, try to open an unit file */
+               char *filename = (char*)malloc(strlen(output_path) + string_length(library_name) + 10);
+
+        #ifdef WIN32
+               sprintf(filename, "%s\\%s.bsf", output_path, string_get_cstr(library_name));
+               #endif
+               #ifdef UNIX
+               sprintf(filename, "%s/%s.bsf", output_path, string_get_cstr(library_name));
+               #endif
+
+               symbol_file = fopen(filename, "rb");
+
+               free(filename);
+
+               if (symbol_file == NULL)
+               {
+                   // j-a-s-d: if unit is not found it must stop only if compiling
+                       if (!detect_units_only)
+                       {
+                               add_error_message(448, library_name->cstr, "");
+                goto lel_finally;
+                       }
+
+               }
+
+               if (detect_units_only)
+            requires(0, library_name->cstr);
+       } else {
+               if (!detect_units_only)
+            requires(1, library_name->cstr);
+       }
+
+       /* read the library file */
+       if (library_file)
+       {
+               library_unit->is_library = 1;
+               if (detect_units_only == 0)
+                       read_library_file(library_file, library_unit);
+               fclose(library_file);
+       }
+
+       if (symbol_file)
+       {
+               library_unit->is_library = 0;
+               if (detect_units_only == 0)
+                       read_symbol_file(symbol_file, library_unit);
+               fclose(symbol_file);
+       }
+
+       unit_identifier->identifier_class = unit_name;
+       unit_identifier->unit_block = library_unit;
+
+       name_table_insert(root_block->names, library_name , unit_identifier);
+
+       if (library_file)
+       {
+               if (user_libraries == NULL)
+               {
+                       user_libraries = malloc(library_name->length+1);
+                       strcpy(user_libraries, library_name->cstr);
+               }
+               else
+               {
+                       int len = strlen(user_libraries);
+                       user_libraries = realloc(user_libraries, len + 3 + library_name->length);
+                       user_libraries[strlen(user_libraries)] = ' ';
+                       strcpy(user_libraries + len + 1, library_name->cstr);
+               }
+       }
+
+       if (symbol_file)
+       {
+save_unit_name:
+               if (*units == NULL)
+               {
+                       *units = malloc(library_name->length+1);
+                       strcpy(*units, library_name->cstr);
+               }
+               else
+               {
+                       int len = strlen(*units);
+                       *units = realloc(*units, len + 3 + library_name->length);
+                       (*units)[len] = ' ';
+                       strcpy(*units + len + 1, library_name->cstr);
+               }
+       }
+
+
+lel_finally:
+       string_destroy(library_name);
+       string_destroy(project_library_path);
+       string_destroy(global_library_path);
+}
+
+
+/*
+       Reads the library file.
+*/
+void read_library_file(FILE* library_file, unit* library_unit)
+{
+       int constant_pool_count;
+       struct constant_pool_struct *constant_pool;
+       int access_flags, this_class, super_class;
+       int interface_count, field_count, methods_count;
+       int i, j;
+
+       /* read and check magic number */
+       if ((fgetc(library_file) != 0xca)
+               || (fgetc(library_file) != 0xfe)
+               || (fgetc(library_file) != 0xba)
+               || (fgetc(library_file) != 0xbe)
+               )
+       {
+               add_error_message(449, "", "");
+               fclose(library_file);
+               die(6);
+               return;
+       }
+
+       /* skip major and minor count */
+       read_long_int(library_file);
+
+       /* read the number of constant pool entries */
+       constant_pool_count = read_short_int(library_file);
+
+       /* allocate and read the constant pool */
+       constant_pool = mem_alloc(sizeof(struct constant_pool_struct) * constant_pool_count);
+
+       for (i = 1; i<constant_pool_count; i++)
+       {
+               int tag;
+
+               tag = fgetc(library_file);
+               constant_pool[i].tag = tag;
+               constant_pool[i].data = NULL;
+
+               switch (tag)
+               {
+               case  7: /* ClassInfo */
+               case 8: /* StringInfo */
+                       constant_pool[i].param1 = read_short_int(library_file);
+                       break;
+               case 9: /* Fieldref */
+               case 10: /* Methodref */
+               case 11: /* Instanceref*/
+               case 12: /* NameAndType */
+                       constant_pool[i].param1 = read_short_int(library_file);
+                       constant_pool[i].param2 = read_short_int(library_file);
+                       break;
+               case 3: /* Integer */
+               case 4: /* Float */
+                       constant_pool[i].param1 = read_long_int(library_file);
+                       break;
+               case 5: /* Long */
+               case 6: /* double */
+                       constant_pool[i].param1 = read_long_int(library_file);
+                       constant_pool[i].param2 = read_long_int(library_file);
+                       break;
+
+               case 1: /* Utf8 */
+                       constant_pool[i].data_len = read_short_int(library_file);
+                       constant_pool[i].data = mem_alloc(sizeof(char) * constant_pool[i].data_len);
+                       fread(constant_pool[i].data, 1, constant_pool[i].data_len, library_file);
+                       break;
+
+               default:
+                       add_error_message(449, "", "");
+                       goto rlf_finally;
+               }
+       }
+
+       access_flags = read_short_int(library_file);
+       this_class= read_short_int(library_file);
+       super_class = read_short_int(library_file);
+
+       /* TODO:: check that this class has the proper name, no package etc. */
+       /* check access flags */
+       if ((access_flags & 0x0200) // ACC_INTERFACE
+               || (access_flags & 0x0400)) // ACC_ABSTRACT
+       {
+               add_error_message(451, "", "");
+       }
+
+       /* TODO:: are there some limitations on super class? */
+
+       /* skip over the implemented interfaces */
+       interface_count = read_short_int(library_file);
+       for(i=0; i<interface_count; i++)
+       {
+               read_short_int(library_file);
+       }
+
+       /* skip over the fields */
+       field_count = read_short_int(library_file);
+       for(i=0; i<field_count; i++)
+       {
+               int attributes_count;
+               read_short_int(library_file);
+               read_short_int(library_file);
+               read_short_int(library_file);
+               attributes_count = read_short_int(library_file);
+               for(j=0; j<attributes_count; j++)
+               {
+                       int length;
+                       read_short_int(library_file);
+                       length = read_long_int(library_file);
+                       fseek(library_file, length, SEEK_CUR);
+               }
+       }
+
+       /* read the methods and add them into the program scope */
+       methods_count = read_short_int(library_file);
+
+       for (i = 0; i<methods_count; i++)
+       {
+               short int method_access_flags;
+               short int method_name_index;
+               short int method_descriptor_index;
+               short int attributes_count;
+
+               method_access_flags = read_short_int(library_file);
+               method_name_index = read_short_int(library_file);
+               method_descriptor_index = read_short_int(library_file);
+
+               /* read the method's attributes */
+               attributes_count = read_short_int(library_file);
+
+               /* if the method is declared as 'public static' consider
+               adding it into the unit interface */
+               if(method_access_flags == 0x0009)
+               {
+                       char *descriptor;
+                       int parsing_return_type = 0;
+                       identifier *method;
+                       string *method_name;
+                       int j;
+
+                       method = identifier_create();
+                       method->forward_declaration = 0;
+                       method->standard_function = 0;
+                       method->parameters = type_list_create();
+
+                       /* check that method parameters and return value are OK */
+                       descriptor = constant_pool[method_descriptor_index].data;
+
+                       for(j = 1; j<constant_pool[method_descriptor_index].data_len; j++)
+                       {
+                               if (descriptor[j] == ')')
+                               {
+                                       parsing_return_type = 1;
+                               }
+                               else
+                               if ((descriptor[j] == 'L') && (strncmp(descriptor+j, "Ljava/lang/String;", 18) == 0))
+                               {
+                                       type* new_type = type_create();
+                                       new_type->type_class = string_type;
+
+                                       if (!parsing_return_type)
+                                               type_list_append(method->parameters, new_type);
+                                       else
+                                       {
+                                               method->return_type = new_type;
+                                               method->identifier_class = function_name;
+                                       }
+                                       j += 17;
+                               }
+                               else
+                               if ((descriptor[j] == 'L') && (strncmp(descriptor+j, "Ljavax/microedition/lcdui/Image;", 32) == 0))
+                               {
+                                       type* new_type = type_create();
+                                       new_type->type_class = image_type;
+
+                                       if (!parsing_return_type)
+                                               type_list_append(method->parameters, new_type);
+                                       else
+                                       {
+                                               method->return_type = new_type;
+                                               method->identifier_class = function_name;
+                                       }
+                                       j += 31;
+                               }
+                               else
+                               if ((descriptor[j] == 'L') && (strncmp(descriptor+j, "Ljavax/microedition/lcdui/Command;", 34) == 0))
+                               {
+                                       type* new_type = type_create();
+                                       new_type->type_class = command_type;
+
+                                       if (!parsing_return_type)
+                                               type_list_append(method->parameters, new_type);
+                                       else
+                                       {
+                                               method->return_type = new_type;
+                                               method->identifier_class = function_name;
+                                       }
+                                       j += 33;
+                               }
+                               else
+                               if ((descriptor[j] == 'L') && (strncmp(descriptor+j, "Ljava/io/InputStream;", 21) == 0))
+                               {
+                                       type* new_type = type_create();
+                                       new_type->type_class = stream_type;
+
+                                       if (!parsing_return_type)
+                                               type_list_append(method->parameters, new_type);
+                                       else
+                                       {
+                                               method->return_type = new_type;
+                                               method->identifier_class = function_name;
+                                       }
+                                       j += 20;
+                               }
+                               else
+                               if ((descriptor[j] == 'L') && (strncmp(descriptor+j, "Ljavax/microedition/rms/RecordStore;", 36) == 0))
+                               {
+                                       type* new_type = type_create();
+                                       new_type->type_class = record_store_type;
+
+                                       if (!parsing_return_type)
+                                               type_list_append(method->parameters, new_type);
+                                       else
+                                       {
+                                               method->return_type = new_type;
+                                               method->identifier_class = function_name;
+                                       }
+                                       j += 35;
+                               }
+                               else
+                               if (descriptor[j] == 'I')
+                               {
+                                       type* new_type = type_create();
+                                       new_type->type_class = integer_type;
+                                       if (!parsing_return_type)
+                                               type_list_append(method->parameters, new_type);
+                                       else
+                                       {
+                                               method->return_type = new_type;
+                                               method->identifier_class = function_name;
+                                       }
+                               }
+                               else
+                               if ((descriptor[j] == 'V') && (parsing_return_type))
+                               {
+                                       method->identifier_class = procedure_name;
+                               }
+                               else
+                               {
+                                       add_error_message(452, "", "");
+                                       break;
+                               }
+                       }
+
+                       method->unit_function = 1;
+                       method->container_unit = library_unit;
+                       method_name = string_create();
+                       method_name->length = constant_pool[method_name_index].data_len;
+                       method_name->cstr = malloc(method_name->length + 1);
+                       strcpy(method_name->cstr, constant_pool[method_name_index].data);
+                       method_name->cstr[method_name->length] = '\0';
+                       name_table_insert(library_unit->names, method_name, method);
+               }
+
+               /* skip over all attributes */
+               for (j=0; j<attributes_count; j++)
+               {
+                       long int length;
+                       int name = read_short_int(library_file);
+                       length = read_long_int(library_file);
+                       fseek(library_file, length, SEEK_CUR);
+               }
+       }
+
+
+
+rlf_finally:
+       /* free the constant pool from the memory */
+       for (i = 1; i<constant_pool_count; i++)
+       {
+               if (constant_pool[i].data != NULL)
+                       mem_free(constant_pool[i].data);
+       }
+
+       mem_free(constant_pool);
+
+}
+
+void read_symbol_file(FILE *symbol_file, struct unit_struct* library_unit)
+{
+       char tag;
+
+       while(fread(&tag, 1, 1, symbol_file) == 1)
+       {
+               switch(tag)
+               {
+               case 1:
+                       { /* constant */
+                               identifier *constant;
+                               string* name;
+                               char type;
+
+                               constant = identifier_create();
+                               constant->identifier_class = constant_name;
+                               constant->unit_function = 1;
+                               constant->container_unit = library_unit;
+
+                               name = bsf_read_STRING(symbol_file);
+                               fread(&type, 1, 1, symbol_file);
+
+                               constant->constant_type = type_create();
+
+                               switch (type)
+                               {
+                               case 1:
+                                       constant->constant_type->type_class = integer_type;
+                                       fread(&constant->constant_int_value, sizeof(int), 1, symbol_file);
+                                       break;
+                               case 2:
+                                       constant->constant_type->type_class = real_type;
+                                       fread(&constant->constant_real_value, sizeof(float), 1, symbol_file);
+                                       break;
+                               case 3:
+                                       constant->constant_type->type_class = boolean_type;
+                                       fread(&constant->constant_int_value, sizeof(char), 1, symbol_file);
+                                       break;
+                               case 4:
+                                       constant->constant_type->type_class = char_type;
+                                       fread(&constant->constant_int_value, sizeof(char), 1, symbol_file);
+                                       break;
+                               case 5:
+                                       constant->constant_type->type_class = string_type;
+                                       constant->constant_string_value = bsf_read_STRING(symbol_file);
+                                       break;
+                               }
+
+                               name_table_insert(library_unit->names, name, constant);
+                       }
+                       break;
+
+               case 2:
+                       {
+                               string *var_name;
+                               type  *var_type;
+                               identifier *variable = identifier_create();
+
+                               variable->identifier_class = variable_name;
+
+                               var_name = bsf_read_STRING(symbol_file);
+                               var_type = bsf_read_TYPE(symbol_file);
+
+                               variable->variable_type = var_type;
+                               variable->unit_function = 1;
+                               variable->container_unit = library_unit;
+
+                               name_table_insert(library_unit->names, var_name, variable);
+                       }
+                       break;
+
+               case 3:
+                       {
+                               string *name;
+                               identifier *type_identifier = identifier_create();
+
+                               type_identifier->identifier_class = type_name;
+
+                               name = bsf_read_STRING(symbol_file);
+                               type_identifier->defined_type = bsf_read_TYPE(symbol_file);
+                               type_identifier->unit_function = 1;
+                               type_identifier->container_unit = library_unit;
+
+                               name_table_insert(library_unit->names, name, type_identifier);
+                       }
+                       break;
+
+               case 4:
+                       {
+                               string *name;
+                               char params;
+                               identifier* procedure = identifier_create();
+
+                               procedure->forward_declaration = 0;
+                               procedure->standard_function = 0;
+                               procedure->identifier_class = procedure_name;
+                               procedure->unit_function = 1;
+                               procedure->container_unit = library_unit;
+                               procedure->subprogram_linenum = 1;
+
+                               procedure->parameters = type_list_create();
+
+                               name = bsf_read_STRING(symbol_file);
+                               fread(&params, 1, 1, symbol_file);
+
+                               while (params > 0)
+                               {
+                                       type_list_append(procedure->parameters, bsf_read_TYPE(symbol_file));
+                                       params --;
+                               }
+
+                               name_table_insert(library_unit->names, name, procedure);
+                       }
+                       break;
+
+               case 5:
+                       {
+                               string *name;
+                               char params;
+                               identifier* function = identifier_create();
+
+                               function->forward_declaration = 0;
+                               function->standard_function = 0;
+                               function->identifier_class = function_name;
+                               function->unit_function = 1;
+                               function->container_unit = library_unit;
+                               function->subprogram_linenum = 1;
+
+                               function->parameters = type_list_create();
+
+                               name = bsf_read_STRING(symbol_file);
+                               function->return_type = bsf_read_TYPE(symbol_file);
+                               fread(&params, 1, 1, symbol_file);
+
+                               while (params > 0)
+                               {
+                                       type_list_append(function->parameters, bsf_read_TYPE(symbol_file));
+                                       params --;
+                               }
+
+                               name_table_insert(library_unit->names, name, function);
+                       }
+                       break;
+               }
+       }
+}
+
+
+/*
+       Adds parameters names into block.
+*/
+void add_parameters(block *item, string_list *parameters_list,
+                                       type *parameters_type, int is_parameter_variable)
+{
+       string_list *it;
+       identifier *descriptor;
+
+       it = parameters_list;
+
+       if (it->data == NULL)
+       {
+               type_destroy(parameters_type);
+               return;
+       }
+
+       while (it != NULL)
+       {
+               descriptor = identifier_create();
+               descriptor->identifier_class = parameter_name;
+               descriptor->parameter_index = item->next_parameter_index;
+               item-> next_parameter_index ++;
+               descriptor->parameter_type = type_duplicate(parameters_type);
+               descriptor->is_parameter_variable = is_parameter_variable;
+               name_table_insert(item->names, string_duplicate(it->data), descriptor);
+
+               it = it->next;
+       }
+
+       item->next_variable_index = item->next_parameter_index;
+
+       type_destroy(parameters_type);
+}
+
+
+/*
+       Checks if a forward declaration corresponds to a real
+       function definition.
+
+    The identifier 'declaration' is a function or a
+       procedure that is forward.
+*/
+void check_forward_declaration(identifier *declaration,
+                                                          type_list *parameters,
+                                                          int forward_declaration,
+                                                          type *return_type)
+{
+       int different_parameter;
+
+       if ((declaration->identifier_class != procedure_name)
+               && (declaration->identifier_class != function_name))
+       {
+               return;
+       }
+
+       if (forward_declaration)
+       {
+               add_error_message(401, "", "");
+               return;
+       }
+
+       if ((return_type == NULL) /* it is a procedure */
+               && (declaration->identifier_class == function_name))
+               add_error_message(402, "function", "");
+
+       if ((return_type != NULL) /* it is a function*/
+               && (declaration->identifier_class == procedure_name))
+               add_error_message(402, "procedure", "");
+
+       different_parameter = type_list_different_parameter(
+                               parameters, declaration->parameters);
+
+       if (different_parameter == -1)
+               add_error_message(403, "", "");
+
+       if (different_parameter > 0)
+       {
+               char number[8];
+
+               sprintf(number, "%d", different_parameter);
+               add_error_message(404, number, "");
+       }
+
+       if (return_type != NULL)
+       {
+               if ((declaration->identifier_class != function_name) || (!type_equal(return_type, declaration->return_type)))
+                       add_error_message(405, "", "");
+       }
+}
+
+
+/*
+       Checks if there is any identifier contained in the current block that is
+       forward function or procedure delcaration. If there is, report an error.
+*/
+void check_unmatched_forward_declarations(block *current_block, name_table *node)
+{
+       int i;
+       identifier *declaration;
+
+       if ((node == NULL) || (node->descriptor == NULL))
+               return;
+
+       declaration = node->descriptor;
+
+       if (
+               ((declaration->identifier_class == procedure_name) ||
+                 (declaration->identifier_class == function_name))
+               && (declaration->forward_declaration == 1)
+               )
+       {
+               new_linenum=declaration->subprogram_linenum;
+               add_error_message(441, "", "");
+       }
+
+       check_unmatched_forward_declarations(current_block, node->left_child);
+       check_unmatched_forward_declarations(current_block, node->right_child);
+
+}
+
+
+/*
+       Uses a given name to access all the defined types.
+       Return a found type, or an error type if no type
+       was found.
+*/
+type *type_from_name(block *current_block, char *cstr)
+{
+       type *found_type;
+       string *name;
+       identifier *declaration;
+
+
+       found_type = type_create();
+       found_type->type_class = error_type;
+
+       name = string_from_cstr(cstr);
+
+       while (current_block != NULL)
+       {
+               declaration = name_table_find(current_block->names, name);
+
+               if (declaration != NULL)
+               {
+                       if (declaration->identifier_class == type_name)
+                       {
+                               type_destroy(found_type);
+                               found_type = type_duplicate(declaration->defined_type);
+                       }
+
+                       break;
+               }
+
+               current_block = current_block->parent_block;
+       }
+
+       string_destroy(name);
+       return found_type;
+}
+
+
+/*
+       Retuns the type of the constant given by its name,
+       or return error_type if cstr is not a constant name.
+*/
+type *get_constant_type(block *current_block, char *cstr)
+{
+       type *found_type;
+       string *name;
+       identifier *declaration;
+
+       found_type = type_create();
+       found_type->type_class = error_type;
+
+       name = string_from_cstr(cstr);
+
+       while (current_block != NULL)
+       {
+               declaration = name_table_find(current_block->names, name);
+
+               if (declaration != NULL)
+               {
+                       if (declaration->identifier_class == constant_name)
+                       {
+                               type_destroy(found_type);
+                               found_type = type_duplicate(declaration->constant_type);
+                       }
+
+                       break;
+               }
+
+               current_block = current_block->parent_block;
+       }
+
+       string_destroy(name);
+       return found_type;
+}
+
+
+/*
+       Return a copy of an identifier associated with a
+       constant of a given name, or a none identifier
+       if identifier is not a constant or not found.
+*/
+identifier *get_constant_identifier(block *current_block, char *cstr)
+{
+       string *name;
+       identifier *found_constant = NULL;
+       identifier *declaration;
+
+       name = string_from_cstr(cstr);
+
+       while (current_block != NULL)
+       {
+               declaration = name_table_find(current_block->names, name);
+
+               if (declaration != NULL)
+               {
+                       if (declaration->identifier_class == constant_name)
+                               found_constant = identifier_duplicate(declaration);
+
+                       break;
+               }
+
+               current_block = current_block->parent_block;
+       }
+
+       string_destroy(name);
+
+       if (found_constant == NULL)
+               found_constant = identifier_create();
+
+       return found_constant;
+}
+
+
+/*
+       Return an identifier from a given name
+*/
+identifier *get_identifier(block *current_block, char *cstr)
+{
+       string *name;
+       identifier *found_identifier = NULL;
+       identifier *declaration;
+       name_table *name_table_it;
+
+       name = string_from_cstr(cstr);
+
+       while (current_block != NULL)
+       {
+               declaration = name_table_find(current_block->names, name);
+
+               if (declaration != NULL)
+               {
+                       found_identifier = identifier_duplicate(declaration);
+
+                       if (current_block->parent_block == root_block)
+                               found_identifier->belongs_to_program_block = 1;
+                       else
+                               found_identifier->belongs_to_program_block = 0;
+
+                       break;
+               }
+
+               current_block = current_block->parent_block;
+       }
+
+       string_destroy(name);
+
+       if (found_identifier != NULL)
+               return found_identifier;
+
+       /*
+               Search all units for a given identifier. If the same identifier is found
+               in more then one unit, output ambiguity error.
+       */
+       if (root_block->names->name != NULL)
+       {
+               name_table_it = root_block->names;
+
+               while (name_table_it != NULL)
+               {
+                       identifier *descriptor = name_table_it->descriptor;
+
+                       if (descriptor->identifier_class == unit_name)
+                       {
+                               /*
+                                       Search inside the unit for the given name
+                               */
+                               name_table *unit_table_it = descriptor->unit_block->names;
+
+                               if (unit_table_it->name != NULL)
+                               {
+                                       while (unit_table_it != NULL)
+                                       {
+                                               if(STRING_COMPARE(string_get_cstr(unit_table_it->name),
+                                                                     cstr) == 0)
+                                               {
+                                                       if (found_identifier == NULL)
+                                                               found_identifier = identifier_duplicate(unit_table_it->descriptor);
+                                                       else
+                                                       {
+                                                               add_error_message(459, cstr, "");
+                                                               found_identifier = NULL;
+                                                               goto unit_search_done;
+                                                       }
+                                               }
+
+
+                                               unit_table_it = unit_table_it->next;
+                                       }
+                               }
+                       }
+
+                       name_table_it = name_table_it->next;
+               }
+       }
+
+unit_search_done:
+
+       if (found_identifier == NULL)
+       {
+               found_identifier = identifier_create();
+               found_identifier->belongs_to_program_block = 0;
+       }
+
+       return found_identifier;
+}
+
+
+/*
+       Returns the type of a variable given by its name.
+       Return an error type if no variable was found.
+*/
+type *get_variable_type(block *current_block, char *cstr)
+{
+       type *found_type;
+       string *name;
+       identifier *declaration;
+
+       found_type = type_create();
+       found_type->type_class = error_type;
+
+       name = string_from_cstr(cstr);
+
+       while (current_block != NULL)
+       {
+               declaration = name_table_find(current_block->names, name);
+
+               if (declaration != NULL)
+               {
+                       if (declaration->identifier_class == variable_name)
+                               found_type = type_duplicate(declaration->variable_type);
+
+                       break;
+               }
+
+               current_block = current_block->parent_block;
+       }
+
+       string_destroy(name);
+       return found_type;
+}
+
+/*
+       Create the bytecode to initialize the new variable.
+*/
+void initialize_variable(block *item, identifier *variable, char *name, int is_static, char *class_name)
+{
+       int storeIntoField = 0;
+
+       /* if the variable belongs to the program block */
+       if (variable->belongs_to_program_block)
+       {
+               storeIntoField = 1;
+       }
+
+       switch(variable->variable_type->type_class)
+       {
+       case integer_type:
+       case char_type:
+       case boolean_type:
+               {
+                       bytecode_append(item->code, iconst_0$);
+
+                       if (!storeIntoField)
+                       {
+                               switch(variable->variable_index)
+                               {
+                               case 0:
+                                       bytecode_append(item->code, istore_0$);
+                                       break;
+                               case 1:
+                                       bytecode_append(item->code, istore_1$);
+                                       break;
+                               case 2:
+                                       bytecode_append(item->code, istore_2$);
+                                       break;
+                               case 3:
+                                       bytecode_append(item->code, istore_3$);
+                                       break;
+                               default:
+                                       bytecode_append(item->code, istore$);
+                                       bytecode_append(item->code, (char)variable->variable_index);
+                                       break;
+                               }
+                       }
+               }
+               break; // case integer_type
+
+       case real_type:
+               {
+                       if (mathType == 1)
+                       {
+                               bytecode_append(item->code, iconst_0$);
+
+                               if (!storeIntoField)
+                               {
+                                       switch(variable->variable_index)
+                                       {
+                                       case 0:
+                                               bytecode_append(item->code, istore_0$);
+                                               break;
+                                       case 1:
+                                               bytecode_append(item->code, istore_1$);
+                                               break;
+                                       case 2:
+                                               bytecode_append(item->code, istore_2$);
+                                               break;
+                                       case 3:
+                                               bytecode_append(item->code, istore_3$);
+                                               break;
+                                       default:
+                                               bytecode_append(item->code, istore$);
+                                               bytecode_append(item->code, (char)variable->variable_index);
+                                               break;
+                                       }
+                               }
+                       }
+                       else
+                       {
+                               int method_index;
+                               int class_index;
+
+                               usesFloat = 1;
+
+                               class_index = cp_add_class("Real");
+                               method_index = cp_add_methodref("Real", "<init>", "()V");
+
+                               bytecode_append(item->code, new$);
+                               bytecode_append_short_int(item->code, (short)class_index);
+                               bytecode_append(item->code, dup$);
+                               bytecode_append(item->code, invokespecial$);
+                               bytecode_append_short_int(item->code, (short)method_index);
+
+                               if (!storeIntoField)
+                               {
+                                       switch(variable->variable_index)
+                                       {
+                                       case 0:
+                                               bytecode_append(item->code, astore_0$);
+                                               break;
+                                       case 1:
+                                               bytecode_append(item->code, astore_1$);
+                                               break;
+                                       case 2:
+                                               bytecode_append(item->code, astore_2$);
+                                               break;
+                                       case 3:
+                                               bytecode_append(item->code, astore_3$);
+                                               break;
+                                       default:
+                                               bytecode_append(item->code, astore$);
+                                               bytecode_append(item->code, variable->variable_index);
+                                               break;
+                                       }
+                               }
+                       }
+               }
+               break;
+
+
+       case string_type:
+               {
+                       int method_index;
+                       int class_index;
+
+                       class_index = cp_add_class("java/lang/String");
+                       method_index = cp_add_methodref("java/lang/String", "<init>", "()V");
+
+                       bytecode_append(item->code, new$);
+                       bytecode_append_short_int(item->code, (short)class_index);
+                       bytecode_append(item->code, dup$);
+                       bytecode_append(item->code, invokespecial$);
+                       bytecode_append_short_int(item->code, (short)method_index);
+
+                       if (!storeIntoField)
+                       {
+                               switch(variable->variable_index)
+                               {
+                               case 0:
+                                       bytecode_append(item->code, astore_0$);
+                                       break;
+                               case 1:
+                                       bytecode_append(item->code, astore_1$);
+                                       break;
+                               case 2:
+                                       bytecode_append(item->code, astore_2$);
+                                       break;
+                               case 3:
+                                       bytecode_append(item->code, astore_3$);
+                                       break;
+                               default:
+                                       bytecode_append(item->code, astore$);
+                                       bytecode_append(item->code, variable->variable_index);
+                                       break;
+                               }
+                       }
+               }
+               break;
+
+       case image_type:
+               {
+                       int method_index = cp_add_methodref("javax/microedition/lcdui/Image", "createImage", "(II)Ljavax/microedition/lcdui/Image;");
+
+                       bytecode_append(item->code, iconst_1$);
+                       bytecode_append(item->code, iconst_1$);
+                       bytecode_append(item->code, invokestatic$);
+                       bytecode_append_short_int(item->code, method_index);
+
+                       if (!storeIntoField)
+                       {
+                               switch(variable->variable_index)
+                               {
+                               case 0:
+                                       bytecode_append(item->code, astore_0$);
+                                       break;
+                               case 1:
+                                       bytecode_append(item->code, astore_1$);
+                                       break;
+                               case 2:
+                                       bytecode_append(item->code, astore_2$);
+                                       break;
+                               case 3:
+                                       bytecode_append(item->code, astore_3$);
+                                       break;
+                               default:
+                                       bytecode_append(item->code, astore$);
+                                       bytecode_append(item->code, (char)variable->variable_index);
+                                       break;
+                               }
+                       }
+               }
+               break; // case image_type
+
+
+               case stream_type:
+               {
+                       bytecode_append(item->code, aconst_null$);
+
+                       if (!storeIntoField)
+                       {
+                               switch(variable->variable_index)
+                               {
+                               case 0:
+                                       bytecode_append(item->code, astore_0$);
+                                       break;
+                               case 1:
+                                       bytecode_append(item->code, astore_1$);
+                                       break;
+                               case 2:
+                                       bytecode_append(item->code, astore_2$);
+                                       break;
+                               case 3:
+                                       bytecode_append(item->code, astore_3$);
+                                       break;
+                               default:
+                                       bytecode_append(item->code, astore$);
+                                       bytecode_append(item->code, (char)variable->variable_index);
+                                       break;
+                               }
+                       }
+               }
+               break; // case stream_type
+
+       case command_type:
+               {
+                       int method_index = cp_add_methodref("javax/microedition/lcdui/Command", "<init>", "(Ljava/lang/String;II)V");
+
+                       bytecode_append(item->code, new$);
+                       bytecode_append_short_int(item->code, cp_add_class("javax/microedition/lcdui/Command"));
+                       bytecode_append(item->code, dup$);
+
+                       bytecode_append(item->code, new$);
+                       bytecode_append_short_int(item->code, cp_add_class("java/lang/String"));
+                       bytecode_append(item->code, dup$);
+                       bytecode_append(item->code, invokespecial$);
+                       bytecode_append_short_int(item->code, cp_add_methodref("java/lang/String", "<init>", "()V"));
+
+                       bytecode_append(item->code, iconst_1$);
+                       bytecode_append(item->code, iconst_1$);
+                       bytecode_append(item->code, invokespecial$);
+                       bytecode_append_short_int(item->code, method_index);
+
+                       if (!storeIntoField)
+                       {
+                               switch(variable->variable_index)
+                               {
+                               case 0:
+                                       bytecode_append(item->code, astore_0$);
+                                       break;
+                               case 1:
+                                       bytecode_append(item->code, astore_1$);
+                                       break;
+                               case 2:
+                                       bytecode_append(item->code, astore_2$);
+                                       break;
+                               case 3:
+                                       bytecode_append(item->code, astore_3$);
+                                       break;
+                               default:
+                                       bytecode_append(item->code, astore$);
+                                       bytecode_append(item->code, (char)variable->variable_index);
+                                       break;
+                               }
+                       }
+               }
+               break; // case command_type
+
+               case http_type:
+               {
+                       int method_index = cp_add_methodref("H", "<init>", "()V");
+                       usesHttp = 1;
+
+                       bytecode_append(item->code, new$);
+                       bytecode_append_short_int(item->code, cp_add_class("H"));
+                       bytecode_append(item->code, dup$);
+
+                       bytecode_append(item->code, invokespecial$);
+                       bytecode_append_short_int(item->code, method_index);
+
+                       if (!storeIntoField)
+                       {
+                               switch(variable->variable_index)
+                               {
+                               case 0:
+                                       bytecode_append(item->code, astore_0$);
+                                       break;
+                               case 1:
+                                       bytecode_append(item->code, astore_1$);
+                                       break;
+                               case 2:
+                                       bytecode_append(item->code, astore_2$);
+                                       break;
+                               case 3:
+                                       bytecode_append(item->code, astore_3$);
+                                       break;
+                               default:
+                                       bytecode_append(item->code, astore$);
+                                       bytecode_append(item->code, (char)variable->variable_index);
+                                       break;
+                               }
+                       }
+               }
+               break; // case http_type
+
+       case record_store_type:
+               {
+                       usesRecordStore = 1;
+                       /* no initialization needeed */
+               }
+               break;
+
+       case array_type:
+               {
+                       int count = 0;
+                       type_list *it = variable->variable_type->dimensions_list;
+                       char *descriptor;
+                       descriptor = (char*) mem_alloc(1024);
+                       if (descriptor == NULL)
+                               die(1);
+
+                       get_field_descriptor(variable->variable_type, descriptor);
+
+                       /* put dimensions on to the stack */
+                       while (it != NULL)
+                       {
+                               if (it->data != NULL)
+                               {
+                                       int size;
+                                       size = it->data->last_element - it->data->first_element + 1;
+
+                                       if (size <= 0) {
+                                               add_error_message(437, "", "");
+                                       } else if (size <= 127) {
+                                               bytecode_append(item->code, bipush$);
+                                               bytecode_append(item->code, (char)size);
+                                       } else if (size <= 32767) {
+                                               bytecode_append(item->code, sipush$);
+                                               bytecode_append_short_int(item->code, (short)size);
+                                       } else {
+                                               add_error_message(438, "", "");
+                                       }
+                               }
+                               it = it->next;
+
+                               count ++;
+                       }
+
+                       bytecode_append(item->code, multianewarray$);
+                       bytecode_append_short_int(item->code, cp_add_class(descriptor));
+                       bytecode_append(item->code, (char)count);
+
+                       // NEW:
+                       create_put_variable_bytecode(variable, item->code, name, storeIntoField);
+
+                       if((variable->variable_type->element_type->type_class == record_type)
+                               || (variable->variable_type->element_type->type_class == string_type)
+                               || ((variable->variable_type->element_type->type_class == real_type) && (mathType != 1))
+                               || (variable->variable_type->element_type->type_class == image_type)
+                               || (variable->variable_type->element_type->type_class == command_type))
+                       {
+                               /* initialize the fields */
+                               unsigned short int c = 0;
+                               char descriptor[128];
+                               unsigned short int num;
+                               int *offsets;
+                               int *dimensions_sizes; // j-a-s-d: OOB in initialization of complex-type multidimensional arrays bug fix
+                               type_list *it = variable->variable_type->dimensions_list;
+
+                               while (it != NULL)
+                               {
+                                       it = it->next;
+                                       c ++;
+                               }
+
+                               if (variable->variable_type->element_type->type_class == real_type)
+                                       usesFloat = 1;
+
+                               offsets = (int*) mem_alloc(c * sizeof(int));
+                               dimensions_sizes = (int*) mem_alloc(c * sizeof(int)); // j-a-s-d: OOB in initialization of complex-type multidimensional arrays bug fix
+                               num = c;
+
+                               /* reset */
+                               it = variable->variable_type->dimensions_list;
+                               c = 0;
+                               while (it != NULL)
+                               {
+                                       if (it->data != NULL)
+                                       {
+                                               bytecode_append(item->code, getstatic$);
+                                               bytecode_append_short_int(item->code, cp_add_fieldref("M", "IC", "[I"));
+                                               bytecode_append(item->code, sipush$);
+                                               bytecode_append_short_int(item->code, c);
+                                               bytecode_append(item->code, iconst_0$);
+                                               bytecode_append(item->code, iastore$);
+
+                                               offsets[c] = item->code->bytecode_pos;
+                                               dimensions_sizes[c] = it->data->last_element-it->data->first_element; // j-a-s-d: OOB in initialization of complex-type multidimensional arrays bug fix
+                                       }
+                                       c++;
+                                       it = it->next;
+                               }
+
+                               /* load */
+                               for(c=0; c<num; c++)
+                               {
+                                       if ((c < (num-1)) || (c == 0))
+                                       {
+                                               // OLD: bytecode_append(item->code, dup$);
+                                               // NEW:
+                                               create_variable_bytecode(variable, item->code, name, storeIntoField);
+                                       }
+                                       bytecode_append(item->code, getstatic$);
+                                       bytecode_append_short_int(item->code, cp_add_fieldref("M", "IC", "[I"));
+                                       bytecode_append(item->code, sipush$);
+                                       bytecode_append_short_int(item->code, c);
+                                       bytecode_append(item->code, iaload$);
+                                       if (c < (num-1))
+                                               bytecode_append(item->code, aaload$);
+                               }
+
+                               /* new */
+                               get_field_descriptor(variable->variable_type->element_type, descriptor);
+                               descriptor[strlen(descriptor)-1] = '\0';
+
+                               if (variable->variable_type->element_type->type_class == image_type)
+                               {
+                                       bytecode_append(item->code, iconst_1$);
+                                       bytecode_append(item->code, iconst_1$);
+                                       bytecode_append(item->code, invokestatic$);
+                                       bytecode_append_short_int(item->code, cp_add_methodref("javax/microedition/lcdui/Image", "createImage", "(II)Ljavax/microedition/lcdui/Image;"));
+                               }
+                               else if (variable->variable_type->element_type->type_class == command_type)
+                               {
+                                       int method_index = cp_add_methodref("javax/microedition/lcdui/Command", "<init>", "(Ljava/lang/String;II)V");
+
+                                       bytecode_append(item->code, new$);
+                                       bytecode_append_short_int(item->code, cp_add_class("javax/microedition/lcdui/Command"));
+                                       bytecode_append(item->code, dup$);
+
+                                       bytecode_append(item->code, new$);
+                                       bytecode_append_short_int(item->code, cp_add_class("java/lang/String"));
+                                       bytecode_append(item->code, dup$);
+                                       bytecode_append(item->code, invokespecial$);
+                                       bytecode_append_short_int(item->code, cp_add_methodref("java/lang/String", "<init>", "()V"));
+
+                                       bytecode_append(item->code, iconst_1$);
+                                       bytecode_append(item->code, iconst_1$);
+                                       bytecode_append(item->code, invokespecial$);
+                                       bytecode_append_short_int(item->code, method_index);
+                               }
+                               else
+                               {
+                                       bytecode_append(item->code, new$);
+                                       bytecode_append_short_int(item->code, cp_add_class(descriptor+1));
+                                       bytecode_append(item->code, dup$);
+                                       bytecode_append(item->code, invokespecial$);
+                                       bytecode_append_short_int(item->code, cp_add_methodref(descriptor+1, "<init>", "()V"));
+                               }
+
+                               bytecode_append(item->code, aastore$);
+
+                               /* jump back */
+                               it = variable->variable_type->dimensions_list;
+                               c = num-1;
+                               while (it != NULL)
+                               {
+                                       if (it->data != NULL)
+                                       {
+                                               short int offset;
+                                               bytecode_append(item->code, getstatic$);
+                                               bytecode_append_short_int(item->code, cp_add_fieldref("M", "IC", "[I"));
+                                               bytecode_append(item->code, dup$);
+                                               bytecode_append(item->code, sipush$);
+                                               bytecode_append_short_int(item->code, c);
+                                               bytecode_append(item->code, iaload$);
+                                               bytecode_append(item->code, iconst_1$);
+                                               bytecode_append(item->code, iadd$);
+                                               bytecode_append(item->code, sipush$);
+                                               bytecode_append_short_int(item->code, c);
+                                               bytecode_append(item->code, swap$);
+                                               bytecode_append(item->code, iastore$);
+                                               /* the value is increased by one */
+
+                                               bytecode_append(item->code, getstatic$);
+                                               bytecode_append_short_int(item->code, cp_add_fieldref("M", "IC", "[I"));
+                                               bytecode_append(item->code, sipush$);
+                                               bytecode_append_short_int(item->code, c);
+                                               bytecode_append(item->code, iaload$);
+                                               bytecode_append(item->code, sipush$);
+                                               bytecode_append_short_int(item->code,
+                                                       //it->data->last_element-it->data->first_element);
+                                                       dimensions_sizes[c]); // j-a-s-d: OOB in initialization of complex-type multidimensional arrays bug fix
+                                               bytecode_append(item->code, if_icmple$);
+                                               offset = offsets[c] - item->code->bytecode_pos + 1;
+                                               bytecode_append_short_int(item->code, offset);
+                                       }
+                                       c--;
+                                       it = it->next;
+                               }
+
+                               mem_free(offsets);
+                       }
+
+               /*OLD:  if (!storeIntoField)
+                       {
+                               switch(variable->variable_index)
+                               {
+                               case 0:
+                                       bytecode_append(item->code, astore_0$);
+                                       break;
+                               case 1:
+                                       bytecode_append(item->code, astore_1$);
+                                       break;
+                               case 2:
+                                       bytecode_append(item->code, astore_2$);
+                                       break;
+                               case 3:
+                                       bytecode_append(item->code, astore_3$);
+                                       break;
+                               default:
+                                       bytecode_append(item->code, astore$);
+                                       bytecode_append(item->code, (char)variable->variable_index);
+                                       break;
+                               }
+                       } */
+
+                       mem_free(descriptor);
+
+                       break;
+               } // case array_type
+
+       case record_type:
+               {
+                       char *descriptor;
+                       descriptor = (char*) mem_alloc(1024);
+
+                       if(descriptor == NULL)
+                               die(1);
+
+                       get_field_descriptor(variable->variable_type, descriptor);
+
+                       descriptor[strlen(descriptor) - 1] = '\0';
+
+                       bytecode_append(item->code, new$);
+                       bytecode_append_short_int(item->code, cp_add_class(descriptor + 1));
+                       bytecode_append(item->code, dup$);
+                       bytecode_append(item->code, invokespecial$);
+                       bytecode_append_short_int(item->code, cp_add_methodref(descriptor + 1, "<init>", "()V"));
+
+                       mem_free(descriptor);
+
+                       if (!storeIntoField)
+                       {
+                               switch(variable->variable_index)
+                               {
+                               case 0:
+                                       bytecode_append(item->code, astore_0$);
+                                       break;
+                               case 1:
+                                       bytecode_append(item->code, astore_1$);
+                                       break;
+                               case 2:
+                                       bytecode_append(item->code, astore_2$);
+                                       break;
+                               case 3:
+                                       bytecode_append(item->code, astore_3$);
+                                       break;
+                               default:
+                                       bytecode_append(item->code, astore$);
+                                       bytecode_append(item->code, (char)variable->variable_index);
+                                       break;
+                               }
+                       }
+               }
+               break;
+
+       case error_type:
+               break;
+
+       default:
+               {
+                       die(14);
+               }
+       }
+
+
+       /* create the bytecode for storing data into the field */
+       if ((storeIntoField)
+               && (variable->variable_type->type_class != record_store_type)
+               && (variable->variable_type->type_class != array_type)) /* array initialization stores the variable */
+       {
+               int field_index;
+               char descriptor[512];
+               get_field_descriptor(variable->variable_type, descriptor);
+
+               if (name == NULL)
+                       die(23);
+
+               lowercase(name);
+               field_index = cp_add_fieldref(class_name, name, descriptor);
+
+               if (is_static)
+                       bytecode_append(item->code, putstatic$);
+               else
+                       bytecode_append(item->code, putfield$);
+               bytecode_append_short_int(item->code, (short)field_index);
+       }
+}
+
+
+void transform_break_stmts(bytecode *code, int start_offset, int end_offset, int jump_pos)
+{
+       int jump_offset;
+       int pos = start_offset;
+
+       while (pos < end_offset)
+       {
+               if (((unsigned char)(code->bytecode[pos]) == (unsigned char)break_stmt$)
+                       && ((pos + 2) < end_offset))
+               {
+                       if ((code->bytecode[pos+1] == 0)
+                               && (code->bytecode[pos+2] == 0))
+                       {
+                               jump_offset = jump_pos - pos;
+                               code->bytecode[pos] = goto$;
+                               code->bytecode[pos+1] = (jump_offset) >> 8;
+                               code->bytecode[pos+2] = jump_offset;
+                       }
+               }
+
+               pos ++;
+       }
+}
+
+
+/*
+       Writes the class file based on the information provided in the
+       root block.
+*/
+void create_class_file(block *program_block, FILE *fp)
+{
+       int this_class_index;
+       int super_class_index;
+       int i;
+
+       /*** Insert the additional data into the constant pool ***/
+       if (compiling_unit == 0)
+       {
+               this_class_index = cp_add_class("M");
+               switch (canvasType)
+               {
+               case NORMAL:
+                       super_class_index = cp_add_class("javax/microedition/lcdui/Canvas");
+                       break;
+               case FULL_NOKIA:
+                       super_class_index = cp_add_class("com/nokia/mid/ui/FullCanvas");
+                       break;
+               case FULL_MIDP20:
+                       super_class_index = cp_add_class("javax/microedition/lcdui/game/GameCanvas");
+                       break;
+               }
+       }
+       else
+       {
+               this_class_index = cp_add_class(string_get_cstr(str_program_name));
+               super_class_index = cp_add_class("java/lang/Object");
+       }
+
+
+       /* Insert the data needed by the methods into the constant pool */
+       write_method(program_block, NULL);
+       for(i=0; i<program_block->children_count; i++)
+       {
+               write_method(program_block->children[i], NULL);
+       }
+       write_block_fields(program_block->names, NULL);
+
+       if (compiling_unit == 0)
+       {
+               write_constructor(NULL);
+               write_paint_method(NULL);
+               write_run_method(NULL);
+               write_keypressed_method(NULL);
+               write_keyreleased_method(NULL);
+       }
+
+       /* add data to constant poll that is later needed */
+       cp_add_utf8("I");
+       cp_add_utf8("T");
+       cp_add_utf8("G");
+       cp_add_utf8("KC");
+       cp_add_utf8("KP");
+       cp_add_utf8("IC");
+       cp_add_utf8("[I");
+       cp_add_utf8("Ljavax/microedition/lcdui/Image;");
+       cp_add_utf8("LM;");
+       cp_add_class("M");
+       cp_add_utf8("Ljavax/microedition/lcdui/Graphics;");
+       cp_add_class("java/lang/Runnable");
+       cp_add_utf8("StackMap");
+
+       /*** Write data to the file ***/
+
+       /* write the header */
+       create_class_file_header(fp);
+
+       /* write constant pool */
+       write_constant_pool(fp);
+
+       /* write the access flags, set to ACC_PUBLIC and ACC_SUPER */
+       write_short_int(fp, 0x0021);
+
+       /* write the index to constat pool with this class description */
+       write_short_int(fp, (short)this_class_index);
+
+       /* write the index to constant pool with the super class description */
+       write_short_int(fp, (short)super_class_index);
+
+       if (compiling_unit == 0)
+       {
+               /* we have 1 interface */
+               write_short_int(fp, 1);
+
+               write_short_int(fp, cp_add_class("java/lang/Runnable"));
+       }
+       else
+       {
+               /* unit has 0 interfaces */
+               write_short_int(fp, 0);
+       }
+
+       /* write the fields (global variables in pascal) */
+       if (compiling_unit == 0)
+       {
+               write_short_int(fp, (short)(program_block->next_variable_index + 7));
+
+               /* write the RNG field */
+               {
+                       /* access flags: ACC_PUBLIC and ACC_STATIC */
+                       write_short_int(fp, 0x0001 | 0x0008);
+
+                       /* write the name index */
+                       write_short_int(fp, cp_add_utf8("RNG"));
+
+                       /* write the descriptor index */
+                       write_short_int(fp, cp_add_utf8("Ljava/util/Random;"));
+
+                       /* write 0 attributes */
+                       write_short_int(fp, 0);
+               }
+
+               /* write the image (I) field */
+               {
+                       /* access flags: ACC_PUBLIC and ACC_STATIC */
+                       write_short_int(fp, 0x0001 | 0x0008);
+
+                       /* write the name index */
+                       write_short_int(fp, cp_add_utf8("I"));
+
+                       /* write the descriptor index */
+                       write_short_int(fp, cp_add_utf8("Ljavax/microedition/lcdui/Image;"));
+
+                       /* write 0 attributes */
+                       write_short_int(fp, 0);
+               }
+
+               /* write the this (T) field */
+               {
+                       /* access flags: ACC_PUBLIC and ACC_STATIC */
+                       write_short_int(fp, 0x0001 | 0x0008);
+
+                       /* write the name index */
+                       write_short_int(fp, cp_add_utf8("T"));
+
+                       /* write the descriptor index */
+                       write_short_int(fp, cp_add_utf8("LM;"));
+
+                       /* write 0 attributes */
+                       write_short_int(fp, 0);
+               }
+
+
+               /* write the graphics (G) field */
+               {
+                       /* access flags: ACC_PUBLIC and ACC_STATIC */
+                       write_short_int(fp, 0x0001 | 0x0008);
+
+                       /* write the name index */
+                       write_short_int(fp, cp_add_utf8("G"));
+
+                       /* write the descriptor index */
+                       write_short_int(fp, cp_add_utf8("Ljavax/microedition/lcdui/Graphics;"));
+
+                       /* write 0 attributes */
+                       write_short_int(fp, 0);
+               }
+
+               /* write the key clicked (KC) field */
+               {
+                       /* access flags: ACC_PUBLIC and ACC_STATIC */
+                       write_short_int(fp, 0x0001 | 0x0008);
+
+                       /* write the name index */
+                       write_short_int(fp, cp_add_utf8("KC"));
+
+                       /* write the descriptor index */
+                       write_short_int(fp, cp_add_utf8("I"));
+
+                       /* write 0 attributes */
+                       write_short_int(fp, 0);
+               }
+
+               /* write the key pressed (KP) field */
+               {
+                       /* access flags: ACC_PUBLIC and ACC_STATIC */
+                       write_short_int(fp, 0x0001 | 0x0008);
+
+                       /* write the name index */
+                       write_short_int(fp, cp_add_utf8("KP"));
+
+                       /* write the descriptor index */
+                       write_short_int(fp, cp_add_utf8("I"));
+
+                       /* write 0 attributes */
+                       write_short_int(fp, 0);
+               }
+
+               /* write the INDEX COUNTER (IC) field */
+               {
+                       /* access flags: ACC_PUBLIC and ACC_STATIC */
+                       write_short_int(fp, 0x0001 | 0x0008);
+
+                       /* write the name index */
+                       write_short_int(fp, cp_add_utf8("IC"));
+
+                       /* write the descriptor index */
+                       write_short_int(fp, cp_add_utf8("[I"));
+
+                       /* write 0 attributes */
+                       write_short_int(fp, 0);
+               }
+       }
+       else
+       {
+               write_short_int(fp, (short)(program_block->next_variable_index));
+       }
+
+       write_block_fields(program_block->names, fp);
+
+
+       /* write the methods */
+       if (compiling_unit == 0)
+       {
+               /* write the methods count */
+               write_short_int(fp, (short)(program_block->children_count + 6));
+
+               /* write the constructor */
+               write_constructor(fp);
+
+               /* write the paint method */
+               write_paint_method(fp);
+
+               /* write the run method */
+               write_run_method(fp);
+
+               /* write the key pressed and key released methods */
+               write_keypressed_method(fp);
+               write_keyreleased_method(fp);
+       }
+       else
+       {
+               write_short_int(fp, (short)(program_block->children_count + 1));
+       }
+
+       /* write all other methods */
+       for(i=0; i<program_block->children_count; i++)
+       {
+               write_method(program_block->children[i], fp);
+       }
+
+       /* write the main (R) method - <clinit> for interfaces */
+       write_method(program_block, fp);
+
+
+       /* we have no attributes */
+       write_short_int(fp, 0);
+
+
+       // TODO: deallocate constant pool
+}
+
+
+/*
+       Writes the method to the file, if fp is NULL only add needeed
+       data to the constant pool
+*/
+void write_method(block *current_block, FILE *fp)
+{
+       identifier *block_identifier = NULL;
+       stack_map_list *map_list;
+       int code_attribute_length, code_attribute_length_offset;
+       int stack_map_attribute_offset;
+       int stack_map_size;
+       int stack_map_entries;
+       int tmp_offset;
+
+       /* write access flags, ACC_PUBLIC and ACC_STATIC */
+       write_short_int(fp, 0x0001 | 0x0008);
+
+       if(current_block->parent_block == root_block)
+       {
+               /*** it is the main block ***/
+
+               /* write name index */
+               if (compiling_unit == 0)
+                       write_short_int(fp, cp_add_utf8("R"));
+               else
+                       write_short_int(fp, cp_add_utf8("<clinit>"));
+
+               /* write the descriptor */
+               write_short_int(fp, cp_add_utf8("()V"));
+       }
+       else
+       {
+               char *descriptor;
+               int pos = 1;
+               type_list *it;
+
+               descriptor = (char*) mem_alloc(5*1024);
+
+               if (descriptor == NULL)
+                       die(1);
+
+               descriptor[0] = '(';
+
+               /*** procedure or function ***/
+
+               /* write name index */
+               lowercase(current_block->block_name->cstr);
+               write_short_int(fp, cp_add_utf8(current_block->block_name->cstr));
+
+               /* write the descriptor */
+               block_identifier = name_table_find(current_block->parent_block->names, current_block->block_name);
+
+               if ((block_identifier == NULL)
+                       || (block_identifier->identifier_class != function_name
+                       && block_identifier->identifier_class != procedure_name))
+               {
+                       mem_free(descriptor);
+                       die(17);
+               }
+
+               it = block_identifier->parameters;
+
+               while(it != NULL)
+               {
+                       if (it->data == NULL)
+                               break;
+
+                       get_field_descriptor(it->data, descriptor + pos);
+                       pos = strlen(descriptor);
+                       it = it->next;
+               }
+
+               descriptor[pos] = ')';
+               pos ++;
+               descriptor[pos] = '\0';
+
+               if (block_identifier->identifier_class == procedure_name)
+                       strcat(descriptor, "V");
+               else
+                       get_field_descriptor(block_identifier->return_type, descriptor + pos);
+
+               write_short_int(fp, cp_add_utf8(descriptor));
+
+               mem_free(descriptor);
+       }
+
+//PREVERIFY    map_list = preverify_bytecode(current_block->code, block_identifier);
+               map_list = NULL;
+
+
+       /* write the code */
+       write_short_int(fp, 2); /* attribute count */
+
+       write_short_int(fp, cp_add_utf8("Code"));
+       if (fp != NULL)
+               code_attribute_length_offset = ftell(fp);
+       write_long_int(fp, current_block->code->bytecode_pos + 12); /* update the size later when we know it */
+       code_attribute_length = current_block->code->bytecode_pos + 12;
+
+       write_short_int(fp, 32); /* max stack */
+
+       if (current_block->parent_block == root_block)
+               write_short_int(fp, 0); /* max locals for program block */
+       else
+               write_short_int(fp, current_block->next_variable_index + 2); /* max locals */
+
+       write_long_int(fp, current_block->code->bytecode_pos); /* code length */
+
+       if(fp != NULL)
+               fwrite(current_block->code->bytecode, current_block->code->bytecode_pos, 1, fp);
+
+       write_short_int(fp, 0);
+       if (map_list != NULL)
+       {
+               write_short_int(fp, 1); /* The Code has one attribute (The StackMap attribute) */
+
+               write_short_int(fp, cp_add_utf8("StackMap"));
+               if (fp != NULL)
+                       stack_map_attribute_offset = ftell(fp);
+               write_long_int(fp, 0); /* attribute length */
+               write_short_int(fp, 0); /* number of entries; these two fields will be filled in later */
+
+               stack_map_size = 2;
+               stack_map_entries = 0;
+
+               do
+               {
+                       int i;
+                       stack_map *map = stack_map_list_get(&map_list);
+
+                       if (map != NULL)
+                               write_short_int(fp, (short)(map->bytecode_offset));
+                       stack_map_size += 2;
+
+                       /* write the locals */
+                       if (current_block->parent_block == root_block)
+                       {
+                               write_short_int(fp, 0);
+                               stack_map_size += 2;
+                       }
+                       else
+                       {
+                               identifier *block_identifier;
+
+                               /* write the StackMap for locals */
+                               block_identifier = name_table_find(current_block->parent_block->names, current_block->block_name);
+
+                               write_short_int(fp, (short)current_block->next_variable_index);
+                               stack_map_size += 2;
+
+                               write_locals_stackmap(fp, block_identifier, &stack_map_size);
+                       }
+
+                       if (map == NULL)
+                               break;
+
+                       /* write the stack items */
+                       write_short_int(fp, (short)map->number_of_items);
+                       stack_map_size += 2;
+                       for(i=0; i<map->number_of_items; i++)
+                       {
+                               if (fp != NULL)
+                               {
+                                       fwrite(&(map->stack[i]->item_type), 1, 1, fp);
+                               }
+
+                               if ((map->stack[i]->item_type == ITEM_Object)
+                                       || (map->stack[i]->item_type == ITEM_NewObject))
+                               {
+                                       write_short_int(fp, map->stack[i]->additional_data);
+                                       stack_map_size += 2;
+                               }
+
+                               stack_map_size ++;
+                       }
+
+                       stack_map_destroy(map);
+
+                       stack_map_entries ++;
+
+               } while (map_list != NULL);
+
+               /* write the stack map size and the number of entries and
+               the code attribute length */
+               if (fp != NULL)
+               {
+                       tmp_offset = ftell(fp);
+                       fseek(fp, stack_map_attribute_offset, SEEK_SET);
+                       write_long_int(fp, stack_map_size); /* attribute length */
+                       write_short_int(fp, (short)stack_map_entries); /* number of entries */
+
+                       fseek(fp, code_attribute_length_offset, SEEK_SET);
+                       write_long_int(fp, code_attribute_length + 6 + stack_map_size);
+
+                       fseek(fp, tmp_offset, SEEK_SET);
+               }
+       }
+       else
+       {
+               write_short_int(fp, 0);
+       }
+
+       /* write the Exceptions attribute */
+       write_short_int(fp, cp_add_utf8("Exceptions"));
+
+       write_long_int(fp, 4);
+
+       write_short_int(fp, 1);
+       write_short_int(fp, cp_add_class("java/lang/Exception"));
+
+}
+
+
+/*
+       Creates the code for the following method:
+
+       public void paint(Graphics g)
+       {
+               g.drawImage(IMG, 0, 0, Graphics.TOP|Graphics.LEFT);
+       }
+*/
+void write_paint_method(FILE *fp)
+{
+       bytecode *code = bytecode_create();
+       if (code == NULL)
+               die(1);
+
+       /* create the code */
+
+       /* PUSH param_1 */
+       bytecode_append(code, aload_1$);
+
+       /* PUSH (I) */
+       bytecode_append(code, getstatic$);
+       bytecode_append_short_int(code, cp_add_fieldref("M", "I", "Ljavax/microedition/lcdui/Image;"));
+
+       /* PUSH 0; PUSH 0*/
+       bytecode_append(code, iconst_0$);
+       bytecode_append(code, iconst_0$);
+
+       /* PUSH Graphics.LEFT|Graphics.TOP */
+       bytecode_append(code, bipush$);
+       bytecode_append(code, 20);
+
+       /* invoke drawImage(Image, int, int, int) */
+       bytecode_append(code, invokevirtual$);
+       bytecode_append_short_int(code,
+               cp_add_methodref("javax/microedition/lcdui/Graphics", "drawImage", "(Ljavax/microedition/lcdui/Image;III)V"));
+
+       bytecode_append(code, return$);
+
+       /* write the method headers */
+
+       /* write access flags, ACC_PUBLIC  */
+       write_short_int(fp, 0x0001);
+
+       /* write method name */
+       write_short_int(fp, cp_add_utf8("paint"));
+
+       /* write method descriptor */
+       write_short_int(fp, cp_add_utf8("(Ljavax/microedition/lcdui/Graphics;)V"));
+
+       /* write 1 attribute */
+       write_short_int(fp, 1);
+
+       /* write the Code attribute */
+       write_short_int(fp, cp_add_utf8("Code"));
+       write_long_int(fp, code->bytecode_pos + 12);
+
+       /* write the max stack */
+       write_short_int(fp, 10);
+
+       /* max locals for program block */
+       write_short_int(fp, 2);
+
+
+       /* code length */
+       write_long_int(fp, code->bytecode_pos);
+
+       /* write the code itself */
+       if (fp != NULL)
+               fwrite(code->bytecode, 1, code->bytecode_pos, fp);
+
+       bytecode_destroy(code);
+
+       write_short_int(fp, 0);
+       write_short_int(fp, 0);
+}
+
+/*
+       Creates the code for the following method:
+
+       public void run()
+       {
+               R();
+       }
+*/
+void write_run_method(FILE *fp)
+{
+       char tag;
+
+       bytecode *code = bytecode_create();
+       if (code == NULL)
+               die(1);
+
+       /* create the code */
+       bytecode_append(code, invokestatic$);
+       bytecode_append_short_int(code, cp_add_methodref("M", "R", "()V"));
+
+       bytecode_append(code, goto$);
+       bytecode_append_short_int(code, 4);
+
+       bytecode_append(code, pop$);    /* the exception handler */
+
+       bytecode_append(code, return$);
+
+       /* write the method headers */
+
+       /* write access flags, ACC_PUBLIC  */
+       write_short_int(fp, 0x0001);
+
+       /* write method name */
+       write_short_int(fp, cp_add_utf8("run"));
+
+       /* write method descriptor */
+       write_short_int(fp, cp_add_utf8("()V"));
+
+       /* write 1 attribute */
+       write_short_int(fp, 1);
+
+       /* write the Code attribute */
+       write_short_int(fp, cp_add_utf8("Code"));
+       write_long_int(fp, code->bytecode_pos + 20 + 38); /* 38 = stackmap size */
+
+       /* write the max stack */
+       write_short_int(fp, 2);
+
+       /* max locals for program block */
+       write_short_int(fp, 1);
+
+       /* code length */
+       write_long_int(fp, code->bytecode_pos);
+
+       /* write the code itself */
+       if (fp != NULL)
+               fwrite(code->bytecode, 1, code->bytecode_pos, fp);
+
+       bytecode_destroy(code);
+
+       /* write exception table length*/
+       write_short_int(fp, 1);
+
+       /* write the exception table */
+       write_short_int(fp, 0);
+       write_short_int(fp, 3);
+       write_short_int(fp, 6);
+       write_short_int(fp, cp_add_class("java/lang/Exception"));
+
+
+       /* StackMap attribute */
+       write_short_int(fp, 1);
+
+               write_short_int(fp, cp_add_utf8("StackMap"));
+               write_long_int(fp, 32);
+
+               /* 2 frames*/
+               write_short_int(fp, 3);
+
+               /* write the frame 0 */
+                       write_short_int(fp, 0);
+
+                       /* write the locals */
+                       write_short_int(fp, 1);
+                       tag = 7;
+                       if (fp != NULL)
+                               fwrite(&tag, 1, 1, fp);
+                       write_short_int(fp, cp_add_class("M"));
+
+
+                       /* 0 stack entries */
+                       write_short_int(fp, 0);
+
+               /* write the frame 1 */
+                       write_short_int(fp, 6);
+
+                       /* write the locals*/
+                       write_short_int(fp, 1);
+                       tag = 7;
+                       if (fp != NULL)
+                               fwrite(&tag, 1, 1, fp);
+                       write_short_int(fp, cp_add_class("M"));
+
+                       /* 1 stack entry */
+                       write_short_int(fp, 1);
+                       tag = 7;
+                       if (fp != NULL)
+                               fwrite(&tag, 1, 1, fp);
+                       write_short_int(fp, cp_add_class("java/lang/Exception"));
+
+
+               /* write the frame 2 */
+                       write_short_int(fp, 7);
+
+                       /* write the locals */
+                       write_short_int(fp, 1);
+                       tag = 7;
+                       if (fp != NULL)
+                               fwrite(&tag, 1, 1, fp);
+                       write_short_int(fp, cp_add_class("M"));
+
+                       /* 0 stack entries */
+                       write_short_int(fp, 0);
+
+}
+
+
+/*
+       Creates the code for the following methods:
+
+       public void keyPressed(int keyCode)
+       {
+               KC = keyCode;
+               KP = keyCode;
+       }
+
+    public void keyReleased(int keyCode)
+       {
+               KP = 0;
+       }
+*/
+void write_keypressed_method(FILE *fp)
+{
+       bytecode *code = bytecode_create();
+       if (code == NULL)
+               die(1);
+
+       /* create the code */
+       bytecode_append(code, iload_1$);
+       bytecode_append(code, dup$);
+       bytecode_append(code, putstatic$);
+       bytecode_append_short_int(code, cp_add_fieldref("M", "KC", "I"));
+       bytecode_append(code, putstatic$);
+       bytecode_append_short_int(code, cp_add_fieldref("M", "KP", "I"));
+
+       bytecode_append(code, return$);
+
+       /* write the method headers */
+
+       /* write access flags, ACC_PUBLIC  */
+       write_short_int(fp, 0x0001);
+
+       /* write method name */
+       write_short_int(fp, cp_add_utf8("keyPressed"));
+
+       /* write method descriptor */
+       write_short_int(fp, cp_add_utf8("(I)V"));
+
+       /* write 1 attribute */
+       write_short_int(fp, 1);
+
+       /* write the Code attribute */
+       write_short_int(fp, cp_add_utf8("Code"));
+       write_long_int(fp, code->bytecode_pos + 12);
+
+       /* write the max stack */
+       write_short_int(fp, 2);
+
+       /* max locals for program block */
+       write_short_int(fp, 2);
+
+
+       /* code length */
+       write_long_int(fp, code->bytecode_pos);
+
+       /* write the code itself */
+       if (fp != NULL)
+               fwrite(code->bytecode, 1, code->bytecode_pos, fp);
+
+       bytecode_destroy(code);
+
+       write_short_int(fp, 0);
+       write_short_int(fp, 0);
+}
+void write_keyreleased_method(FILE *fp)
+{
+       bytecode *code = bytecode_create();
+       if (code == NULL)
+               die(1);
+
+       /* create the code */
+       bytecode_append(code, iconst_0$);
+       bytecode_append(code, putstatic$);
+       bytecode_append_short_int(code, cp_add_fieldref("M", "KP", "I"));
+
+       bytecode_append(code, return$);
+
+       /* write the method headers */
+
+       /* write access flags, ACC_PUBLIC  */
+       write_short_int(fp, 0x0001);
+
+       /* write method name */
+       write_short_int(fp, cp_add_utf8("keyReleased"));
+
+       /* write method descriptor */
+       write_short_int(fp, cp_add_utf8("(I)V"));
+
+       /* write 1 attribute */
+       write_short_int(fp, 1);
+
+       /* write the Code attribute */
+       write_short_int(fp, cp_add_utf8("Code"));
+       write_long_int(fp, code->bytecode_pos + 12);
+
+       /* write the max stack */
+       write_short_int(fp, 2);
+
+       /* max locals for program block */
+       write_short_int(fp, 2);
+
+
+       /* code length */
+       write_long_int(fp, code->bytecode_pos);
+
+       /* write the code itself */
+       if (fp != NULL)
+               fwrite(code->bytecode, 1, code->bytecode_pos, fp);
+
+       bytecode_destroy(code);
+
+       write_short_int(fp, 0);
+       write_short_int(fp, 0);
+}
+
+
+/*
+       Creates the code for the class constructor.
+*/
+void write_constructor(FILE *fp)
+{
+       bytecode *code = bytecode_create();
+       if (code == NULL)
+               die(1);
+
+       /* create the code */
+       switch (canvasType)
+       {
+       case NORMAL:
+               bytecode_append(code, aload_0$);
+       bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Canvas", "<init>", "()V"));
+               break;
+       case FULL_NOKIA:
+               bytecode_append(code, aload_0$);
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, cp_add_methodref("com/nokia/mid/ui/FullCanvas", "<init>", "()V"));
+               break;
+       case FULL_MIDP20:
+               bytecode_append(code, aload_0$);
+               bytecode_append(code, iconst_0$);
+               bytecode_append(code, invokespecial$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/game/GameCanvas", "<init>", "(Z)V"));
+
+               bytecode_append(code, aload_0$);
+               bytecode_append(code, iconst_1$);
+               bytecode_append(code, invokevirtual$);
+               bytecode_append_short_int(code, cp_add_methodref("javax/microedition/lcdui/Canvas", "setFullScreenMode", "(Z)V"));
+               break;
+       }
+
+       bytecode_append(code, return$);
+
+       /* write the method headers */
+
+       /* write access flags, ACC_PUBLIC  */
+       write_short_int(fp, 0x0001);
+
+       /* write method name */
+       write_short_int(fp, cp_add_utf8("<init>"));
+
+       /* write method descriptor */
+       write_short_int(fp, cp_add_utf8("()V"));
+
+       /* write 1 attribute */
+       write_short_int(fp, 1);
+
+       /* write the Code attribute */
+       write_short_int(fp, cp_add_utf8("Code"));
+       write_long_int(fp, code->bytecode_pos + 12);
+
+       /* write the max stack */
+       write_short_int(fp, 10);
+
+       /* max locals for program block */
+       write_short_int(fp, 2);
+
+
+       /* code length */
+       write_long_int(fp, code->bytecode_pos);
+
+       /* write the code itself */
+       if (fp != NULL)
+               fwrite(code->bytecode, 1, code->bytecode_pos, fp);
+
+       bytecode_destroy(code);
+
+       write_short_int(fp, 0);
+       write_short_int(fp, 0);
+
+}
+
+
+/*
+       Write the variables from the block as fields into the
+       given class file. If fp==NULL only add constants into
+       the constant pool.
+*/
+void write_block_fields(name_table *names, FILE *fp)
+{
+       char descriptor[128];
+
+       if ((names->descriptor != NULL)
+               && (names->descriptor->identifier_class == variable_name))
+       {
+               /* access flags: ACC_PUBLIC and ACC_STATIC */
+               write_short_int(fp, 0x0001 | 0x0008);
+
+               /* write the name index */
+               lowercase(names->name->cstr);
+               write_short_int(fp, cp_add_utf8(names->name->cstr));
+
+               /* write the descriptor index */
+               get_field_descriptor(names->descriptor->variable_type, descriptor);
+               write_short_int(fp, cp_add_utf8(descriptor));
+
+               /* write 0 attributes */
+               write_short_int(fp, 0);
+       }
+
+       /* write the left child */
+       if ((names->descriptor != NULL)
+               && (names->left_child != NULL))
+       {
+               write_block_fields(names->left_child, fp);
+       }
+
+       /* write the right child */
+       if ((names->descriptor != NULL)
+               && (names->right_child != NULL))
+       {
+               write_block_fields(names->right_child, fp);
+       }
+}
+
+
+void write_locals_stackmap(FILE *fp, identifier *block_identifier, int *stack_map_size)
+{
+       type_list *it = block_identifier->parameters;
+       write_stackmap(fp, it, stack_map_size);
+
+       /* for functions, add the return value */
+       if (block_identifier->identifier_class == function_name)
+       {
+               it = type_list_create();
+               type_list_append(it, block_identifier->return_type);
+               write_stackmap(fp, it, stack_map_size);
+               type_list_destroy(it);
+       }
+
+       it = block_identifier->variables;
+       write_stackmap(fp, it, stack_map_size);
+}
+
+void write_stackmap(FILE *fp, type_list *it, int *stack_map_size)
+{
+
+       while (it != NULL)
+       {
+               char c;
+
+               if (it->data != NULL)
+               {
+                       switch(it->data->type_class)
+                       {
+                       case integer_type:
+                       case char_type:
+                       case boolean_type:
+                               c = 1;
+                               if (fp != NULL)
+                                       fwrite(&c, 1, 1, fp);
+                               (*stack_map_size) ++;
+                               break;
+
+                       case real_type:
+                               {
+                                       if (mathType == 1)
+                                       {
+                                               c = 1;
+                                               if (fp != NULL)
+                                                       fwrite(&c, 1, 1, fp);
+                                               (*stack_map_size) ++;
+                                       }
+                                       else
+                                       {
+                                               c = 7;
+                                               if (fp != NULL)
+                                                       fwrite(&c, 1, 1, fp);
+                                               write_short_int(fp, cp_add_class("Real"));
+                                               (*stack_map_size) += 3;
+                                       }
+                               }
+                               break;
+
+                       case string_type:
+                               c = 7;
+                               if (fp != NULL)
+                                       fwrite(&c, 1, 1, fp);
+                               write_short_int(fp, cp_add_class("java/lang/String"));
+                               (*stack_map_size) += 3;
+                               break;
+
+                       case image_type:
+                               c = 7;
+                               if (fp != NULL)
+                                       fwrite(&c, 1, 1, fp);
+                               write_short_int(fp, cp_add_class("javax/microedition/lcdui/Image"));
+                               (*stack_map_size) += 3;
+                               break;
+
+                       case command_type:
+                               c = 7;
+                               if (fp != NULL)
+                                       fwrite(&c, 1, 1, fp);
+                               write_short_int(fp, cp_add_class("javax/microedition/lcdui/Command"));
+                               (*stack_map_size) += 3;
+                               break;
+
+
+                       case stream_type:
+                               c = 7;
+                               if (fp != NULL)
+                                       fwrite(&c, 1, 1, fp);
+                               write_short_int(fp, cp_add_class("java/io/InputStream"));
+                               (*stack_map_size) += 3;
+                               break;
+
+                       case record_store_type:
+                               c = 7;
+                               if (fp != NULL)
+                                       fwrite(&c, 1, 1, fp);
+                               write_short_int(fp, cp_add_class("javax/microedition/rms/RecordStore"));
+                               (*stack_map_size) += 3;
+                               break;
+
+                       case http_type:
+                               c = 7;
+                               if (fp != NULL)
+                                       fwrite(&c, 1, 1, fp);
+                               write_short_int(fp, cp_add_class("H"));
+                               (*stack_map_size) += 3;
+                               break;
+
+                       case alert_type:
+                               c = 7;
+                               if (fp != NULL)
+                                       fwrite(&c, 1, 1, fp);
+                               write_short_int(fp, cp_add_class("Ljavax/microedition/lcdui/AlertType;"));
+                               (*stack_map_size) += 3;
+                               break;
+
+                       case array_type:
+                               {
+                                       char descriptor[512];
+                                       char element_type[128];
+                                       int i, len;
+
+                                       get_field_descriptor(it->data->element_type, element_type);
+
+                                       len = type_list_length(it->data->dimensions_list);
+                                       for(i=0; i < len; i++)
+                                       {
+                                               descriptor[i] = '[';
+                                       }
+
+                                       descriptor[len] = '\0';
+
+                                       sprintf(descriptor + len, "%s", element_type);
+
+                                       c = 7;
+                                       if (fp != NULL)
+                                               fwrite(&c, 1, 1, fp);
+                                       write_short_int(fp, cp_add_class(descriptor));
+                                       (*stack_map_size) += 3;
+                               }
+                               break;
+
+                       case record_type:
+                               {
+                                       char descriptor[16];
+                                       c = 7;
+                                       if (fp != NULL)
+                                               fwrite(&c, 1, 1, fp);
+                                       sprintf(descriptor, "R_%d", it->data->unique_record_ID);
+                                       write_short_int(fp, cp_add_class(descriptor));
+                                       (*stack_map_size) += 3;
+                               }
+                               break;
+                       }
+               }
+
+               it = it->next;
+       }
+}
diff --git a/MPC.3.5.LINUX/structures/block.h b/MPC.3.5.LINUX/structures/block.h
new file mode 100644 (file)
index 0000000..0d9acbb
--- /dev/null
@@ -0,0 +1,90 @@
+/********************************************************************
+       
+       block.h - structures and functions used to hold program
+       block descriptions
+
+  Niksa Orlic, 2004-04-23
+
+********************************************************************/
+
+#include <stdio.h>
+
+/*
+       The structure to hold description for
+       one block;
+*/
+struct block_struct
+{
+       struct block_struct *parent_block;
+
+       name_table *names;
+
+       string *block_name;
+
+       int next_variable_index;
+       int next_parameter_index;
+
+       bytecode *code;
+
+       struct block_struct **children;
+       int children_count;
+};
+
+typedef struct block_struct block;
+
+/* canvas types */
+#define NORMAL         0
+#define FULL_MIDP20 1
+#define FULL_NOKIA     2
+
+
+block* block_create(block*, string*);
+void block_destroy(block*);
+
+int block_check_name(block*, char*);
+
+void add_real_constant(block*, float, char*);
+void add_integer_constant(block*, long int, char*);
+void add_char_constant(block*, char, char*);
+void add_boolean_constant(block*, char, char*);
+void add_string_constant(block*, string*, char*);
+
+void add_variables(block*, string_list*, type*);
+
+void add_type(block*, string*, type*);
+
+void add_procedure(block*, string*, type_list*, int, int);
+void add_function(block*, string*, type_list*,type*, int, int);
+
+void load_extern_library(string*);
+void read_library_file(FILE*, struct unit_struct*);
+void read_symbol_file(FILE*, struct unit_struct*);
+
+void add_parameters(block*, string_list*, type*, int);
+
+void check_forward_declaration(identifier*, type_list*,
+                                                          int, type*);
+void check_unmatched_forward_declarations(block*, name_table*);
+
+void transform_break_stmts(bytecode*, int, int, int);
+
+type *type_from_name(block*, char*);
+type *get_constant_type(block*, char*);
+type *get_variable_type(block*, char*);
+identifier *get_constant_identifier(block*, char*);
+identifier *get_identifier(block*, char*);
+
+void initialize_variable(block*, identifier*, char*, int, char*);
+
+void create_class_file(block *root_block, FILE *fp);
+void write_method(block *current_block, FILE *fp);
+void write_block_fields(name_table *, FILE*);
+
+void write_paint_method(FILE *fp);
+void write_constructor(FILE *fp);
+void write_run_method(FILE *fp);
+void write_keypressed_method(FILE *fp);
+void write_keyreleased_method(FILE *fp);
+
+void write_locals_stackmap(FILE *fp, identifier *block_identifier, int* stack_map_size);
+void write_stackmap(FILE *fp, type_list *it, int *stack_map_size);
diff --git a/MPC.3.5.LINUX/structures/identifier.c b/MPC.3.5.LINUX/structures/identifier.c
new file mode 100644 (file)
index 0000000..6485b35
--- /dev/null
@@ -0,0 +1,506 @@
+/********************************************************************
+
+       identifier.c - handling identifier descriptions
+
+  Niksa Orlic, 2004-04-28
+
+********************************************************************/
+
+#include "../util/strings.h"
+#include "../util/error.h"
+//#include "../util/message.h"
+#include "type_list.h"
+#include "string_list.h"
+#include "type.h"
+#include "identifier.h"
+#include "name_table.h"
+#include "../classgen/bytecode.h"
+#include "block.h"
+#include "unit.h"
+#include "../util/memory.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+extern FILE* symbols_file;
+
+/*
+       Creates an empty identifier
+*/
+
+identifier *identifier_create()
+{
+       identifier *new_identifier;
+       new_identifier = (identifier*) mem_alloc(sizeof(identifier));
+
+       if (new_identifier == NULL)
+               die(1);
+
+       new_identifier->identifier_class = none;
+
+       new_identifier->standard_function = 0;
+
+       new_identifier->variables = NULL;
+
+       new_identifier->forward_declaration = 0;
+
+       new_identifier->unit_block = NULL;
+
+       new_identifier->unit_function = 0;
+       new_identifier->container_unit = NULL;
+
+       return new_identifier;
+}
+
+
+/*
+       Deletes an identifier
+*/
+void identifier_destroy(identifier *item)
+{
+       switch (item->identifier_class)
+       {
+       case constant_name:
+               {
+                       if (item->constant_type->type_class == string_type)
+                               string_destroy(item->constant_string_value);
+                       type_destroy(item->constant_type);
+                       break;
+               }
+
+       case variable_name:
+               {
+                       if (item->variable_type != NULL)
+                               type_destroy(item->variable_type);
+                       break;
+               }
+
+       case type_name:
+               {
+                       type_destroy(item->defined_type);
+                       break;
+               }
+
+       case procedure_name:
+               {
+                       type_list_destroy(item->parameters);
+                       if (item->variables != NULL)
+                               type_list_destroy(item->variables);
+                       break;
+               }
+
+       case function_name:
+               {
+                       type_destroy(item->return_type);
+                       type_list_destroy(item->parameters);
+                       if (item->variables != NULL)
+                               type_list_destroy(item->variables);
+                       break;
+               }
+
+       case parameter_name:
+               {
+                       type_destroy(item->parameter_type);
+                       break;
+               }
+
+       case unit_name:
+               {
+                       unit_destroy(item->unit_block);
+                       break;
+               }
+       }
+
+       mem_free(item);
+}
+
+/*
+       Create a copy of a given identifier
+*/
+identifier *identifier_duplicate(identifier *item)
+{
+       identifier *new_identifier;
+       new_identifier = (identifier*) mem_alloc(sizeof(identifier));
+
+       if (new_identifier == NULL)
+               die(1);
+
+       new_identifier->identifier_class = item->identifier_class;
+       new_identifier->unit_function = item->unit_function;
+
+       switch(new_identifier->identifier_class)
+       {
+       case constant_name:
+               {
+                       new_identifier->constant_type = type_duplicate(item->constant_type);
+                       switch(item->constant_type->type_class)
+                       {
+                       case integer_type:
+                               {
+                                       new_identifier->constant_int_value = item->constant_int_value;
+                                       break;
+                               }
+                       case char_type:
+                               {
+                                       new_identifier->constant_int_value = item->constant_int_value;
+                                       break;
+                               }
+                       case string_type:
+                               {
+                                       new_identifier->constant_string_value = string_duplicate(item->constant_string_value);
+                                       break;
+                               }
+                       case boolean_type:
+                               {
+                                       new_identifier->constant_int_value = item->constant_int_value;
+                                       break;
+                               }
+                       case real_type:
+                               {
+                                       new_identifier->constant_real_value = item->constant_real_value;
+                                       break;
+                               }
+                       case command_type:
+                       case record_store_type:
+                       case http_type:
+                       case image_type:
+                       case stream_type:
+                       case alert_type:
+                               {
+                                       break;
+                               }
+                       default:
+                               {
+                                       die(11);
+                               }
+                       }
+                       break;
+               }
+
+       case variable_name:
+               {
+                       new_identifier->variable_type = type_duplicate(item->variable_type);
+                       new_identifier->variable_index = item->variable_index;
+                       break;
+               }
+
+       case type_name:
+               {
+                       new_identifier->defined_type = type_duplicate(item->defined_type);
+                       break;
+               }
+
+       case procedure_name:
+               {
+                       new_identifier->parameters = type_list_duplicate(item->parameters);
+                       new_identifier->forward_declaration = item->forward_declaration;
+                       new_identifier->standard_function = item->standard_function;
+                       new_identifier->variables = type_list_duplicate(item->variables);
+                       if (item->container_unit != NULL)
+                               new_identifier->container_unit = unit_duplicate(item->container_unit);
+                       else
+                               new_identifier->container_unit = NULL;
+                       break;
+               }
+
+       case function_name:
+               {
+                       new_identifier->parameters = type_list_duplicate(item->parameters);
+                       new_identifier->return_type = type_duplicate(item->return_type);
+                       new_identifier->forward_declaration = item->forward_declaration;
+                       new_identifier->standard_function = item->standard_function;
+                       new_identifier->variables = type_list_duplicate(item->variables);
+                       break;
+               }
+
+       case parameter_name:
+               {
+                       new_identifier->parameter_type = type_duplicate(item->parameter_type);
+                       new_identifier->is_parameter_variable = item->is_parameter_variable;
+                       new_identifier->parameter_index = item->parameter_index;
+                       break;
+               }
+
+       case unit_name:
+               {
+                       new_identifier->unit_block = unit_duplicate(item->unit_block);
+                       break;
+               }
+
+       }
+
+       if (item->container_unit != NULL)
+               new_identifier->container_unit = unit_duplicate(item->container_unit);
+       else
+               new_identifier->container_unit = NULL;
+
+       if (item->unit_block != NULL)
+               new_identifier->unit_block = unit_duplicate(item->unit_block);
+       else
+               new_identifier->unit_block = NULL;
+
+       return new_identifier;
+}
+
+void bsf_write_integer_constant(long int value, char* name)
+{
+       char tag = 1;
+       char type = 1;
+       fwrite(&tag, 1, 1, symbols_file);
+       bsf_write_STRING(name);
+       fwrite(&type, 1, 1, symbols_file);
+       fwrite(&value, sizeof(long int), 1, symbols_file);
+}
+
+void bsf_write_real_constant(float value, char* name)
+{
+       char tag = 1;
+       char type = 2;
+       fwrite(&tag, 1, 1, symbols_file);
+       bsf_write_STRING(name);
+       fwrite(&type, 1, 1, symbols_file);
+       fwrite(&value, sizeof(float), 1, symbols_file);
+}
+
+void bsf_write_boolean_constant(char value, char* name)
+{
+       char tag = 1;
+       char type = 3;
+       fwrite(&tag, 1, 1, symbols_file);
+       bsf_write_STRING(name);
+       fwrite(&type, 1, 1, symbols_file);
+       fwrite(&value, sizeof(char), 1, symbols_file);
+}
+
+void bsf_write_char_constant(char value, char* name)
+{
+       char tag = 1;
+       char type = 4;
+       fwrite(&tag, 1, 1, symbols_file);
+       bsf_write_STRING(name);
+       fwrite(&type, 1, 1, symbols_file);
+       fwrite(&value, sizeof(char), 1, symbols_file);
+}
+
+void bsf_write_string_constant(string* value, char* name)
+{
+       char tag = 1;
+       char type = 5;
+       fwrite(&tag, 1, 1, symbols_file);
+       bsf_write_STRING(name);
+       fwrite(&type, 1, 1, symbols_file);
+
+       bsf_write_STRING(string_get_cstr(value));
+}
+
+void bsf_write_variables(string_list* names, type* var_type)
+{
+       string_list *it = names;
+
+       while ((it != NULL) && (it->data != NULL))
+       {
+               char tag = 2;
+               fwrite(&tag, 1, 1, symbols_file);
+               bsf_write_STRING(string_get_cstr(it->data));
+               bsf_write_TYPE(var_type);
+               it = it->next;
+       }
+}
+
+void bsf_write_type(string* type_name, type* type_type)
+{
+       char tag = 3;
+       fwrite(&tag, 1, 1, symbols_file);
+       bsf_write_STRING(string_get_cstr(type_name));
+       bsf_write_TYPE(type_type);
+}
+
+void bsf_write_procedure(string* name, type_list* parameters)
+{
+       type_list *it;
+       char params_count = 0;
+
+       char tag = 4;
+       fwrite(&tag, 1, 1, symbols_file);
+       bsf_write_STRING(string_get_cstr(name));
+
+       params_count = type_list_length(parameters);
+       fwrite(&params_count, 1, 1, symbols_file);
+
+       it = parameters;
+
+       while ((it != NULL) && (it->data != NULL))
+       {
+               bsf_write_TYPE(it->data);
+               it = it->next;
+       }
+}
+
+void bsf_write_function(string* name, type_list* parameters, type* return_type)
+{
+       type_list *it;
+       char params_count = 0;
+
+       char tag = 5;
+       fwrite(&tag, 1, 1, symbols_file);
+       bsf_write_STRING(string_get_cstr(name));
+
+       bsf_write_TYPE(return_type);
+
+       params_count = type_list_length(parameters);
+       fwrite(&params_count, 1, 1, symbols_file);
+
+       it = parameters;
+
+       while ((it != NULL) && (it->data != NULL))
+       {
+               bsf_write_TYPE(it->data);
+               it = it->next;
+       }
+}
+
+void bsf_write_STRING(char* value)
+{
+       char len = strlen(value);
+       lowercase(value);
+       fwrite(&len, 1, 1, symbols_file);
+       fwrite(value, 1, len, symbols_file);
+}
+
+string* bsf_read_STRING(FILE* file)
+{
+       char length;
+       char *buffer;
+       string* string_value;
+
+       fread(&length, 1, 1, file);
+       buffer = (char*) malloc(length + 5);
+       fread(buffer, 1, length, file);
+       buffer[length] = '\0';
+       string_value = string_from_cstr(buffer);
+       free(buffer);
+
+       return string_value;
+}
+
+void bsf_write_TYPE(type* type_desc)
+{
+       // j-a-s-d
+       #ifdef __GNUC__
+       fwrite((char *)&type_desc->type_class, 1, 1, symbols_file);
+       #else
+       fwrite(&(char)type_desc->type_class, 1, 1, symbols_file);
+       #endif
+
+       if (type_desc->type_class == array_type)
+       {
+               char dimensions;
+               type_list *it;
+
+               bsf_write_TYPE(type_desc->element_type);
+
+               dimensions = type_list_length(type_desc->dimensions_list);
+               fwrite(&dimensions, 1, 1, symbols_file);
+
+               it = type_desc->dimensions_list;
+
+               while ((it != NULL) && (it->data != NULL))
+               {
+                       bsf_write_TYPE(it->data);
+                       it = it->next;
+               }
+       }
+
+       if (type_desc->type_class == record_type)
+       {
+               char elements;
+               string_list *name_it;
+               type_list *type_it;
+
+               elements = string_list_length(type_desc->elements_name_list);
+               fwrite(&elements, 1, 1, symbols_file);
+
+               name_it = type_desc->elements_name_list;
+               type_it = type_desc->elements_type_list;
+
+               while ((name_it != NULL) && (name_it->data != NULL))
+               {
+                       bsf_write_STRING(string_get_cstr(name_it->data));
+                       bsf_write_TYPE(type_it->data);
+
+                       name_it = name_it->next;
+                       type_it = type_it->next;
+               }
+
+               fwrite(&type_desc->unique_record_ID, 4, 1, symbols_file);
+       }
+
+       if (type_desc->type_class == interval_type)
+       {
+        // j-a-s-d
+        #ifdef __GNUC__
+        fwrite((char *)&type_desc->interval_base_type, 1, 1, symbols_file);
+        #else
+        fwrite(&(char)type_desc->interval_base_type, 1, 1, symbols_file);
+        #endif
+               fwrite(&type_desc->first_element, 4, 1, symbols_file);
+               fwrite(&type_desc->last_element, 4, 1, symbols_file);
+       }
+}
+
+type* bsf_read_TYPE(FILE* symbol_file)
+{
+       char type_class;
+
+       type* result_type = type_create();
+
+       fread(&type_class, 1, 1, symbol_file);
+       result_type->type_class = (enum en_type_class)type_class;
+
+       if (result_type->type_class == array_type)
+       {
+               char dimensions;
+
+               result_type->element_type = bsf_read_TYPE(symbol_file);
+               fread(&dimensions, 1, 1, symbol_file);
+
+               result_type->dimensions_list = type_list_create();
+
+               while (dimensions > 0)
+               {
+                       type_list_append(result_type->dimensions_list, bsf_read_TYPE(symbol_file));
+                       dimensions --;
+               }
+       }
+
+       if (result_type->type_class == record_type)
+       {
+               char elements;
+               fread(&elements, 1, 1, symbol_file);
+
+               result_type->elements_name_list = string_list_create();
+               result_type->elements_type_list = type_list_create();
+
+               while (elements > 0)
+               {
+                       string_list_append(result_type->elements_name_list, bsf_read_STRING(symbol_file));
+                       type_list_append(result_type->elements_type_list, bsf_read_TYPE(symbol_file));
+                       elements --;
+               }
+
+               fread(&result_type->unique_record_ID, sizeof(int), 1, symbol_file);
+       }
+
+       if (result_type->type_class == interval_type)
+       {
+               char base_type_class;
+               fread(&base_type_class, 1, 1, symbol_file);
+
+               result_type->interval_base_type = (enum en_type_class)base_type_class;
+
+               fread(&result_type->first_element, sizeof(long int), 1, symbol_file);
+               fread(&result_type->last_element, sizeof(long int), 1, symbol_file);
+       }
+
+       return result_type;
+}
diff --git a/MPC.3.5.LINUX/structures/identifier.h b/MPC.3.5.LINUX/structures/identifier.h
new file mode 100644 (file)
index 0000000..ce04ad4
--- /dev/null
@@ -0,0 +1,169 @@
+/********************************************************************
+       
+       identifier.h - structures used to hold identifier descriptions
+
+  Niksa Orlic, 2004-04-28
+
+********************************************************************/
+
+/*
+  When an unit compiles, it exports public symbols into
+
+  unit_name.bsf (binary symbol file)
+
+  The bsf file contains an array of symbol entries.
+
+  Symbols are divided into the following categories:
+
+  Constant
+  ---------
+  1 byte identifier: set to 1 to indicate that it is an constant
+  STRING - symbol name
+  1 byte to indicate the constant type, (1-integer, 2-real, 3-boolean, 4-char, 5-string)
+  value: if a constant is integer or float, this is 4-byte field
+         if a constant is string, then a STRING entry follows
+                if a constant is a boolean or a char, 1 byte follows
+
+  Variable
+  --------
+  1 byte indentifier: set to 2 for variable
+  STRING - symbol name
+  TYPE - variable type
+
+  Type
+  ----
+  1 byte identifier: set to 3 for type definition
+  STRING - symbol name
+  TYPE - the type description
+
+  Procedure
+  ---------
+  1 byte identifier: set to 4 for procedures
+  STRING - name
+  1 byte - the number of parameters (n)
+  TYPE[n] - parameters type
+
+  Function
+  --------
+  1 byte identifier: set to 5 for functions
+  STRING - name
+  TYPE - return type
+  1 byte - number of parameters
+  TYPE[n] - parameter types
+
+  
+       Special fields used are:
+
+  STRING
+  ------
+  1 byte containing the string length (n)
+  n bytes with the string data (NOT zero terminated)
+
+  TYPE
+  ----
+  1 byte : type class, a value from en_type_class enumeration
+  
+     if a type is an array: TYPE element_type
+                               1 byte dimensions num
+                                                       TYPE[n] dimension interval types
+
+     if a type is a record: 1 byte number of elements
+                               {STRING, TYPE} [n] for each element there is a pair name/type describing the member
+                                                       4 bytes record ID
+
+     if a type is an interval: 1 byte interval base type (from the en_type_class)
+                                  4 bytes: starting value
+                                                          4 bytes: ending value
+
+*/
+
+#include <stdio.h>
+
+/*
+       The possible identifier classes
+*/
+enum en_identifier_class
+{
+       none,
+       program_name,
+       constant_name,
+       variable_name,
+       type_name,
+       procedure_name,
+       function_name,
+       parameter_name,
+       unit_name
+};
+
+
+/*
+       The structure used to hold the description of
+       a single identifier
+*/
+struct identifier_descriptor_struct
+{
+       enum en_identifier_class identifier_class;
+
+       /* for constants */
+       type *constant_type;
+       int constant_int_value;
+       float constant_real_value;
+       string *constant_string_value;
+
+       /* for variables */
+       type *variable_type;
+       int variable_index; 
+
+       /* for types */
+       type *defined_type;
+
+       /* for procedures and functions */
+       type *return_type; 
+       type_list *parameters;  /* the list of formal parameters to the function, each one is identifier_descriptor */
+       type_list *variables;   /* the list of names of variables */
+       int forward_declaration;
+       int standard_function;
+       int subprogram_linenum; /* the number of the first line of the subprogram */
+       int unit_function; /* used by all items that are defined inside an unit , 1 says that the item is inside a unit */
+       struct unit_struct *container_unit;
+
+       /* for parameters */
+       type *parameter_type;
+       short int is_parameter_variable;
+       int parameter_index;
+
+       /* for units */
+       struct unit_struct *unit_block;
+
+       /* this field is set in get_identifier function and is true
+       if this struct describes identifier directly located inside
+       the program block*/
+       int belongs_to_program_block;
+};
+
+
+typedef struct identifier_descriptor_struct identifier;
+
+identifier *identifier_create();
+void identifier_destroy(identifier*);
+identifier *identifier_duplicate(identifier*);
+
+struct type_struct;
+struct string_list_struct;
+struct string_struct;
+
+void bsf_write_integer_constant(long int value, char* name);
+void bsf_write_real_constant(float value, char* name);
+void bsf_write_boolean_constant(char value, char* name);
+void bsf_write_char_constant(char value, char* name);
+void bsf_write_string_constant(string* value, char* name);
+void bsf_write_variables(struct string_list_struct* names, struct type_struct* var_type);
+void bsf_write_type(string* type_name, struct type_struct* type_type);
+void bsf_write_procedure(string* name, type_list* parameters);
+void bsf_write_function(string* name, type_list* parameters, type* return_type);
+void bsf_write_STRING(char* value);
+void bsf_write_TYPE(type* type_desc);
+
+struct string_struct* bsf_read_STRING(FILE*);
+struct type_struct* bsf_read_TYPE(FILE*);
+
diff --git a/MPC.3.5.LINUX/structures/name_table.c b/MPC.3.5.LINUX/structures/name_table.c
new file mode 100644 (file)
index 0000000..b7cd2e8
--- /dev/null
@@ -0,0 +1,213 @@
+/********************************************************************
+       
+       name-table.c - the functions used for name table handling. The
+       name table is a binary tree. The node's left child has the name
+       alphabetically before the name in the node, and the right child
+       has the name which is alphabetically after the name in the node.
+
+  Niksa Orlic, 2004-04-25
+
+********************************************************************/
+
+#include "../util/strings.h"
+#include "../util/error.h"
+//#include "../util/message.h"
+#include "type_list.h"
+#include "string_list.h"
+#include "type.h"
+#include "identifier.h"
+#include "name_table.h"
+#include "../classgen/bytecode.h"
+#include "block.h"
+#include "unit.h"
+#include "../util/memory.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+
+/*
+       Create an empty name table.
+*/
+name_table *name_table_create()
+{
+       name_table *new_item;
+       new_item = (name_table*) mem_alloc(sizeof(name_table));
+
+       if (new_item == NULL)
+               die(1);
+
+       new_item->left_child = NULL;
+       new_item->right_child = NULL;
+       new_item->name = NULL;
+       new_item->descriptor = NULL;
+       
+       new_item->last = new_item;
+       new_item->next = NULL;
+
+       return new_item;
+}
+
+
+/*
+       Destroy an allocated name table and free all memory.
+*/
+void name_table_destroy(name_table *item)
+{
+       if (item == NULL)
+               return;
+
+       if (item->name != NULL)
+               string_destroy(item->name);
+
+       if (item->descriptor != NULL)
+               identifier_destroy(item->descriptor);
+
+       if (item->left_child != NULL)
+               name_table_destroy(item->left_child);
+
+       if (item->right_child != NULL)
+               name_table_destroy(item->right_child);
+}
+
+/*
+name_table *name_table_duplicate(name_table *item)
+{
+       name_table *new_item = mem_alloc(sizeof(name_table));
+
+       new_item->descriptor = identifier_duplicate(item->descriptor);
+       new_item->name = string_duplicate(item->name);
+
+       if (item->left_child != NULL)
+               new_item->left_child = name_table_duplicate(item->left_child);
+       else
+               new_item->left_child = NULL;
+
+       if (item->right_child != NULL)
+               new_item->right_child = name_table_duplicate(item->right_child);
+       else
+               new_item->right_child = NULL;
+
+       return new_item;
+}*/
+
+
+/*
+       Inserts an entry into the name table. The string and the descriptor are
+       not copied, only pointers to the string and descriptor are copied.
+*/
+void name_table_insert(name_table *root, string *name, 
+                                          identifier *descriptor)
+{
+       int string_compare;
+       name_table *item, *new_item;
+
+       if (root == NULL)
+               return;
+
+       if (root->name == NULL)
+       {
+               /* the root item is empty, insert the value
+                  into the root item */
+
+               root->name = name;
+               root->descriptor = descriptor;
+               return;
+       }
+
+
+       /* go through the tree to the first free element */
+       item = root;
+
+       do
+       {
+               string_compare = STRING_COMPARE(string_get_cstr(name), string_get_cstr(item->name));
+
+               if (string_compare == 0)
+               {
+                       /* an error occured, just return */
+                       return;
+               }
+
+               if (string_compare < 0)
+               {
+                       if (item->left_child == NULL)
+                               break;
+
+                       item = item->left_child;
+               }
+
+               if (string_compare > 0)
+               {
+                       if (item->right_child == NULL)
+                               break;
+
+                       item = item->right_child;
+               }
+       } while (1); /* until the break is called */
+
+       new_item = name_table_create();
+       new_item->name = name;
+       new_item->descriptor = descriptor;
+       new_item->next = NULL;
+
+       root->last->next = new_item;
+       root->last = new_item;
+
+       if (string_compare < 0)
+               item->left_child = new_item;
+
+       if (string_compare > 0)
+               item->right_child = new_item;
+
+}
+
+
+/*
+       Searches name table for an element with a given name.
+       Return the identifier descriptor if found or NULL if
+       not found.
+*/
+identifier* name_table_find(name_table *item, string *name)
+{
+       int string_compare;
+
+       while ((item != NULL) && (item->name != NULL))
+       {
+               string_compare = STRING_COMPARE(string_get_cstr(name), string_get_cstr(item->name));
+
+               if (string_compare == 0)
+                       return item->descriptor;
+
+               if (string_compare < 0)
+                       item = item->left_child;
+
+               if (string_compare > 0)
+                       item = item->right_child;
+
+       }
+
+       return NULL;
+}
+
+identifier *name_table_find_cstr(name_table *item, char *name)
+{
+       int string_compare;
+
+       while ((item != NULL) && (item->name != NULL))
+       {
+               string_compare = STRING_COMPARE(name, string_get_cstr(item->name));
+
+               if (string_compare == 0)
+                       return item->descriptor;
+
+               if (string_compare < 0)
+                       item = item->left_child;
+
+               if (string_compare > 0)
+                       item = item->right_child;
+
+       }
+
+       return NULL;
+}
\ No newline at end of file
diff --git a/MPC.3.5.LINUX/structures/name_table.h b/MPC.3.5.LINUX/structures/name_table.h
new file mode 100644 (file)
index 0000000..fc0216c
--- /dev/null
@@ -0,0 +1,40 @@
+/********************************************************************
+
+       name_table.h - structures and function prototypes for handling
+       names
+
+  Niksa Orlic, 2004-04-28
+
+********************************************************************/
+
+struct name_table_struct
+{
+       string *name;
+       struct name_table_struct *left_child;
+       struct name_table_struct *right_child;
+
+       struct name_table_struct *last; // used only in the first item
+       struct name_table_struct *next;
+
+       identifier *descriptor;
+};
+
+typedef struct name_table_struct name_table;
+
+
+name_table *name_table_create();
+//name_table *name_table_duplicate(name_table*);
+void name_table_destroy(name_table *item);
+void name_table_insert(name_table *root, string *name,
+                                          identifier *descriptor);
+identifier* name_table_find(name_table *item, string *name);
+identifier *name_table_find_cstr(name_table *item, char *name);
+
+/*
+       Define the case insensitive string-compare routine.
+
+  _stricmp on MSVC
+  strcasecmp on gcc (I think)
+*/
+//#define STRING_COMPARE _stricmp
+#define STRING_COMPARE strcasecmp
diff --git a/MPC.3.5.LINUX/structures/string_list.c b/MPC.3.5.LINUX/structures/string_list.c
new file mode 100644 (file)
index 0000000..a8f1453
--- /dev/null
@@ -0,0 +1,128 @@
+/********************************************************************
+       
+       string_list.c - function for handling string lists
+
+  Niksa Orlic, 2004-04-28
+
+********************************************************************/
+
+#include "../util/strings.h"
+#include "../util/error.h"
+//#include "../util/message.h"
+#include "string_list.h"
+
+
+#include <string.h>
+#include <stdlib.h>
+
+/*
+       Create a new empty list
+*/
+string_list *string_list_create()
+{
+       string_list *new_list = (string_list*) mem_alloc(sizeof(string_list));
+
+       if (new_list == NULL)
+               die(1);
+
+       new_list->data = NULL;
+       new_list->next = NULL;
+
+       return new_list;
+}
+
+
+/*
+       Delete the list and the data in the list
+*/
+void string_list_destroy(string_list* item)
+{
+       string_list *it, *next;
+
+       it = item;
+       while (it != NULL)
+       {
+               next = it->next;
+
+               if (it->data != NULL)
+                       string_destroy(it->data);
+
+               mem_free (it);
+
+               it = next;
+       }
+}
+
+/*
+       Creates a copy of the list, the data
+       values are also copied
+*/
+string_list *string_list_duplicate(string_list *item)
+{
+       string_list *new_list;
+
+       new_list = string_list_create();
+
+       if (item->data == NULL)
+               return new_list;
+
+       do
+       {
+               if(item->data == NULL)
+                       break;
+
+               string_list_append(new_list, string_duplicate(item->data));
+               item = item->next;
+       } while (item != NULL);
+
+       return new_list;
+}
+
+
+/*
+       Add an element into the list, the data is 
+       copied.
+*/
+void string_list_append(string_list *item, string *data)
+{
+       string_list *new_element;
+       
+       if (item->data == NULL)
+               item->data = string_duplicate(data);
+       else
+       {
+               new_element = (string_list*) mem_alloc(sizeof(string_list));
+
+               if (new_element == NULL)
+                       die(1);
+
+               new_element->data = string_duplicate(data);
+               new_element->next = NULL;
+
+               /* move to the end of the list */
+               while (item->next != NULL)
+                       item = item->next;
+
+               item->next = new_element;
+       }
+}
+
+
+/*
+       Returns the number of elements in the list
+*/
+int string_list_length(string_list *item)
+{
+       int counter = 0;
+
+       if (item->data == NULL)
+               return counter;
+
+       do
+       {
+               item = item->next;
+               counter ++;
+       } while (item != NULL);
+
+       return counter;
+}
diff --git a/MPC.3.5.LINUX/structures/string_list.h b/MPC.3.5.LINUX/structures/string_list.h
new file mode 100644 (file)
index 0000000..d735e73
--- /dev/null
@@ -0,0 +1,22 @@
+/********************************************************************
+       
+       string_list.h - list of strings
+
+  Niksa Orlic, 2004-04-29
+
+********************************************************************/
+
+struct string_list_struct
+{
+       struct string_list_struct *next;
+       string *data;
+};
+
+typedef struct string_list_struct string_list;
+
+string_list *string_list_create();
+void string_list_destroy(string_list*);
+
+string_list *string_list_duplicate(string_list*);
+void string_list_append(string_list*, string*);
+int string_list_length(string_list*);
diff --git a/MPC.3.5.LINUX/structures/type.c b/MPC.3.5.LINUX/structures/type.c
new file mode 100644 (file)
index 0000000..4974774
--- /dev/null
@@ -0,0 +1,329 @@
+/********************************************************************
+       
+       type.c - function for handling types in pascal
+
+  Niksa Orlic, 2004-04-28
+
+********************************************************************/
+
+#include "../util/strings.h"
+#include "../util/error.h"
+//#include "../util/message.h"
+#include "type_list.h"
+#include "string_list.h"
+#include "type.h"
+#include "identifier.h"
+#include "name_table.h"
+#include "../classgen/bytecode.h"
+#include "block.h"
+#include "../util/memory.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+extern int linenum;
+
+/*
+       Create an empty type
+*/
+type* type_create()
+{
+       type *new_type;
+       new_type = (type*) mem_alloc(sizeof(type));
+
+       if (new_type == NULL)
+               die(1);
+
+       new_type->type_class = void_type;
+
+       return new_type;
+}
+
+
+/*
+       Deletes a type
+*/
+void type_destroy(type *item)
+{
+       if (item == NULL)
+               return;
+
+       switch(item->type_class)
+       {
+       case array_type:
+               {
+                       type_list_destroy(item->dimensions_list);
+                       type_destroy(item->element_type);
+                       break;
+               }
+
+       case record_type:
+               {
+                       type_list_destroy(item->elements_type_list);
+                       string_list_destroy(item->elements_name_list);
+                       break;
+               }
+       }
+
+       mem_free(item);
+}
+
+
+/*
+       Create a copy of a type
+*/
+type* type_duplicate(type *item)
+{
+       type *new_item;
+       new_item = (type*) mem_alloc(sizeof(type));
+
+       if (new_item == NULL)
+               die(1);
+
+       memcpy(new_item, item, sizeof(type));
+
+       if (new_item->type_class == array_type)
+       {
+               new_item->dimensions_list = type_list_duplicate(item->dimensions_list);
+               new_item->element_type = type_duplicate(item->element_type);
+       }
+
+       if (new_item->type_class == record_type)
+       {
+               new_item->elements_type_list = type_list_duplicate(item->elements_type_list);
+               new_item->elements_name_list = string_list_duplicate(item->elements_name_list);
+               new_item->unique_record_ID = item->unique_record_ID;
+       }
+
+       return new_item;
+}
+
+
+/*
+       Return a nonzero value if both types are equal.
+*/
+int type_equal(type *type1, type *type2)
+{
+       if (type1 == type2)
+               return 1;
+
+       if ((type1 == NULL) || (type2 == NULL))
+               return 0;
+
+       if (type1->type_class != type2->type_class)
+               return 0;
+
+       switch (type1->type_class)
+       {
+       case array_type:
+               {
+                       if (!type_equal(type1->element_type, type2->element_type))
+                               return 0;
+
+                       if (type_list_different_parameter(type1->dimensions_list,
+                                                       type2->dimensions_list) != 0)
+                               return 0;
+
+                       break;
+               }
+
+       case record_type:
+               {
+                       return (type1->unique_record_ID == type2->unique_record_ID);
+
+                       break;
+               }
+
+       case interval_type:
+               {
+                       if (type1->interval_base_type != type2->interval_base_type)
+                               return 0;
+
+                       if (type1->first_element != type2->first_element)
+                               return 0;
+
+                       if (type1->last_element != type2->last_element)
+                               return 0;
+
+                       break;
+               }
+       }
+
+       return 1;
+}
+
+/*
+       Return 0 if types are not equal; 1 if the types
+       are exactly the same, 2 if type1 is real and type2 int
+       or 3 if type2 is real and type1 int
+
+       Also, char can be casted into string
+*/
+int type_equal_cast(type *type1, type* type2)
+{
+       if (type_equal(type1, type2))
+               return 1;
+
+       if ((type1->type_class == real_type)
+               && (type2->type_class == integer_type))
+               return 2;
+
+       if ((type1->type_class == integer_type)
+               && (type2->type_class == real_type))
+               return 3;
+
+       if ((type1->type_class == string_type)
+               && (type2->type_class == char_type))
+               return 2;
+
+       if ((type1->type_class == char_type)
+               && (type2->type_class == string_type))
+               return 3;
+
+       return 0;
+}
+
+
+/*
+       Returns a name for any basic type, string 'unknown type' otherwise
+*/
+string *type_get_name(type *basic_type)
+{
+       switch(basic_type->type_class)
+       {
+       case integer_type:
+               return string_from_cstr("integer");
+
+       case real_type:
+               return string_from_cstr("real");
+
+       case boolean_type:
+               return string_from_cstr("boolean");
+
+       case char_type:
+               return string_from_cstr("char");
+
+       case image_type:
+               return string_from_cstr("image");
+
+       case command_type:
+               return string_from_cstr("command");
+
+       case stream_type:
+               return string_from_cstr("stream");
+
+       case string_type:
+               return string_from_cstr("string");
+
+       case array_type:
+               return string_from_cstr("array");
+
+       case record_type:
+               return string_from_cstr("record");
+
+       case record_store_type:
+               return string_from_cstr("recordStore");
+
+       case http_type:
+               return string_from_cstr("http");
+
+       case alert_type:
+               return string_from_cstr("alert type");
+
+       case interval_type:
+               return string_from_cstr("interval");
+
+       default:
+               return string_from_cstr("unknown type");
+       }
+
+       return NULL;
+}
+
+
+/*
+       Check if any name from element_names already exists in
+       item->elements_name_list
+*/
+void type_record_check_duplicate_names(type *item, string_list *element_names)
+{
+       string_list *item_list;
+
+       while (element_names != NULL)
+       {
+               if (element_names->data != NULL)
+               {
+                       item_list = item->elements_name_list;
+
+                       while (item_list != NULL)
+                       {
+                               if (item_list->data != NULL)
+                               {
+                                       if (STRING_COMPARE(string_get_cstr(item_list->data), 
+                                                string_get_cstr(element_names->data)) == 0)
+                                       {
+                                               add_error_message(418, string_get_cstr(item_list->data), "");
+                                       }
+                               }
+                       
+                               item_list = item_list->next;
+                       }
+               }
+       
+               element_names = element_names->next;
+       }
+}
+
+
+/*
+       Add elements into a record type
+*/
+void type_add_record(type *item, string_list *element_names, type *element_type)
+{
+       /* check for duplicate names in the names */
+       type_record_check_duplicate_names(item, element_names);
+
+       while (element_names != NULL)
+       {
+               if (element_names->data != NULL)
+               {
+                       string_list_append(item->elements_name_list, element_names->data);
+                       type_list_append(item->elements_type_list, element_type);
+               }
+       
+               element_names = element_names->next;
+       }
+}
+
+
+/*
+       Returns the type of an element of a given record type identified
+       by a given name. In case of an error, NULL is returned.
+*/
+type* type_find_record_element(type *record, char *cstr)
+{
+       string_list *names;
+       type_list *types;
+
+       if (record->type_class != record_type)
+               return NULL;
+
+       names = record->elements_name_list;
+       types = record->elements_type_list;
+
+       while (names != NULL)
+       {
+               if (names->data != NULL)
+               {
+                       if(STRING_COMPARE(cstr, string_get_cstr(names->data)) == 0)
+                       {
+                               return type_duplicate(types->data);
+                       }
+               }
+       
+               names = names->next;
+               types = types->next;
+       }
+
+       return NULL;
+}
\ No newline at end of file
diff --git a/MPC.3.5.LINUX/structures/type.h b/MPC.3.5.LINUX/structures/type.h
new file mode 100644 (file)
index 0000000..0ec2852
--- /dev/null
@@ -0,0 +1,74 @@
+/********************************************************************
+       
+       type.h - structures used to hold descriptions of pascal types
+
+  Niksa Orlic, 2004-04-28
+
+********************************************************************/
+
+
+/*
+       The possible type classes
+*/
+enum en_type_class
+{ 
+       error_type, /* used to detect errors */
+       void_type,
+       integer_type,
+       real_type,
+       char_type,
+       boolean_type,
+       string_type,
+       array_type,
+       record_type,
+       interval_type,
+       image_type,
+       command_type,
+       stream_type,
+       record_store_type,
+       http_type,
+       alert_type /* this is only an internal type, the user cannot declare variables to be alert_type */
+       
+       /* add our own types */
+} en_type_class;
+
+/*
+       The structure to hold description for a single
+       type.
+*/
+struct type_struct
+{
+       enum en_type_class type_class;
+
+       /* for array types */
+       struct type_struct* element_type; /* the type of array elements */
+       type_list *dimensions_list; /* the type for each dimension */
+
+       /* for record type */
+       string_list *elements_name_list; /* the elements in record, their names */
+       type_list *elements_type_list; /* the elements in record, their types */
+       int unique_record_ID; /* the name that identifies the record */
+
+       /* for interval type */
+       enum en_type_class interval_base_type;
+       long int first_element;
+       long int last_element;
+};
+
+typedef struct type_struct type;
+
+
+type* type_create();
+void type_destroy(type*);
+
+type* type_duplicate(type*);
+
+int type_equal(type*, type*);
+int type_equal_cast(type*, type*);
+
+string *type_get_name(type*);
+
+void type_record_check_duplicate_names(type*, string_list*);
+void type_add_record(type*, string_list*, type*);
+
+type *type_find_record_element(type*, char*);
\ No newline at end of file
diff --git a/MPC.3.5.LINUX/structures/type_list.c b/MPC.3.5.LINUX/structures/type_list.c
new file mode 100644 (file)
index 0000000..4ef2c75
--- /dev/null
@@ -0,0 +1,236 @@
+/********************************************************************
+       
+       type_list.c - function for handling type lists
+
+  Niksa Orlic, 2004-04-28
+
+********************************************************************/
+
+#include "../util/strings.h"
+#include "../util/error.h"
+//#include "../util/message.h"
+#include "type_list.h"
+#include "string_list.h"
+#include "type.h"
+#include "identifier.h"
+#include "name_table.h"
+#include "../classgen/bytecode.h"
+#include "block.h"
+#include "../util/memory.h"
+
+#include <stdlib.h>
+
+/*
+       Create a new empty list
+*/
+type_list *type_list_create()
+{
+       type_list *new_list = (type_list*) mem_alloc(sizeof(type_list));
+
+       if (new_list == NULL)
+               die(1);
+
+       new_list->data = NULL;
+       new_list->next = NULL;
+
+       return new_list;
+}
+
+
+/*
+       Delete the list with all associated data
+*/
+void type_list_destroy(type_list* item)
+{
+       type_list *it, *next;
+       it = item;
+
+       while (it != NULL)
+       {       
+               next = it->next;
+       
+               if (it->data != NULL)
+                       mem_free(it->data);
+
+               mem_free (it);
+
+               it = next;              
+       }
+
+}
+
+/*
+       Creates a copy of the list, the data
+       values are also copied
+*/
+type_list *type_list_duplicate(type_list *item)
+{
+       type_list *new_list;
+
+       if (item == NULL)
+               return NULL;
+
+       new_list = type_list_create();
+
+       if ((item == NULL) ||(item->data == NULL))
+               return new_list;
+
+       do
+       {
+               type_list_append(new_list, item->data);
+               item = item->next;
+       } while (item != NULL);
+
+       return new_list;
+}
+
+
+/*
+       Add an element into the list, the data is 
+       copied.
+*/
+void type_list_append(type_list *item, struct type_struct *data)
+{
+       type_list *new_element;
+       
+       if (item->data == NULL)
+               item->data = type_duplicate(data);
+       else
+       {
+               new_element = (type_list*) mem_alloc(sizeof(type_list));
+
+               if (new_element == NULL)
+                       die(1);
+
+               new_element->data = type_duplicate(data);
+               new_element->next = NULL;
+
+               /* move to the end of the list */
+               while (item->next != NULL)
+                       item = item->next;
+
+               item->next = new_element;
+       }
+}
+
+
+/*
+       Returns the number of elements in the list
+*/
+int type_list_length(type_list *item)
+{
+       int counter = 0;
+
+       if (item->data == NULL)
+               return counter;
+
+       do
+       {
+               item = item->next;
+               counter ++;
+       } while (item != NULL);
+
+       return counter;
+}
+
+
+/*
+       Returns the index (starting with one) of the first
+       item in the list1 different than the parameetr in the list2,
+       0 if the lists are equal, or -1 if the list1 is shorter than
+       the list2 and all elements in the list1 correspond to the first
+       n elements in the list2.
+*/
+int type_list_different_parameter(type_list *list1, type_list *list2)
+{
+       int counter = 1;
+
+       while (list1 != NULL)
+       {
+               if ((list2 == NULL) 
+                       || (list1->data == NULL)
+                       || (list2->data == NULL)
+                       || (!type_equal(list1->data, list2->data)))
+               {
+                       if ((list2 != NULL)
+                               && (list1->data == NULL)
+                               && (list2->data == NULL))
+                               return 0;
+
+                       return counter;
+               }
+
+               counter ++;
+               list1 = list1->next;
+               list2 = list2->next;
+       }
+       
+       if (list2 != NULL)
+               return -1;
+
+       return 0;
+}
+
+/*
+       Same as the previous function, except that if the list1 element
+       can be casted into list2 element, it is OK !!!
+*/
+int type_list_different_parameter_cast(type_list *list1, type_list *list2)
+{
+       int counter = 1;
+
+       while (list1 != NULL)
+       {
+               if ((list2 == NULL) 
+                       || (list1->data == NULL)
+                       || (list2->data == NULL)
+                       || (type_equal_cast(list1->data, list2->data) == 0)
+                       || (type_equal_cast(list1->data, list2->data) == 2))
+               {
+                       if ((list2 != NULL)
+                               && (list1->data == NULL)
+                               && (list2->data == NULL))
+                               return 0;
+
+                       return counter;
+               }
+
+               counter ++;
+               list1 = list1->next;
+               list2 = list2->next;
+       }
+       
+       if (list2 != NULL)
+               return -1;
+
+       return 0;
+}
+
+/*
+       Same as the above, but compares interval base types against the types; 
+       this is used when checking array dimensions
+*/
+int type_list_different_parameter_array(type_list *real_types, type_list *interval_types)
+{
+       int counter = 1;
+
+       while (real_types != NULL)
+       {
+               if ((interval_types == NULL) 
+                       || (real_types->data == NULL)
+                       || (interval_types->data == NULL)
+                       || (real_types->data->type_class != interval_types->data->interval_base_type))
+               {
+                       return counter;
+               }
+
+               counter ++;
+               real_types = real_types->next;
+               interval_types = interval_types->next;
+       }
+       
+       if (interval_types != NULL)
+               return -1;
+
+       return 0;
+}
diff --git a/MPC.3.5.LINUX/structures/type_list.h b/MPC.3.5.LINUX/structures/type_list.h
new file mode 100644 (file)
index 0000000..1c97655
--- /dev/null
@@ -0,0 +1,28 @@
+/********************************************************************
+       
+       type_list.h - functions to work with typelists
+
+  Niksa Orlic, 2004-04-28
+
+********************************************************************/
+
+
+
+struct type_list_struct
+{
+       struct type_list_struct *next;
+       struct type_struct *data;
+};
+
+typedef struct type_list_struct type_list;
+
+type_list *type_list_create();
+void type_list_destroy(type_list*);
+
+type_list *type_list_duplicate(type_list*);
+void type_list_append(type_list*, struct type_struct*);
+int type_list_length(type_list*);
+
+int type_list_different_parameter(type_list*, type_list*);
+int type_list_different_parameter_array(type_list*, type_list*);
+int type_list_different_parameter_cast(type_list*, type_list*);
diff --git a/MPC.3.5.LINUX/structures/unit.c b/MPC.3.5.LINUX/structures/unit.c
new file mode 100644 (file)
index 0000000..f09ce5e
--- /dev/null
@@ -0,0 +1,75 @@
+/********************************************************************
+       
+       block.h - structures and functions used to hold program
+       block descriptions
+
+  Niksa Orlic, 2005-03-30
+
+********************************************************************/
+
+#include "../util/strings.h"
+#include "../util/error.h"
+//#include "../util/message.h"
+#include "../classgen/bytecode.h"
+#include "type_list.h"
+#include "string_list.h"
+#include "type.h"
+#include "identifier.h"
+#include "name_table.h"
+#include "block.h"
+#include "unit.h"
+#include "../classgen/preverify.h"
+
+#include "../util/memory.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "../classgen/constant_pool.h"
+#include "../classgen/classgen.h"
+
+
+/*
+       Create an empty unit from the given name.
+*/
+unit* unit_create(string *unit_name)
+{
+       unit *new_unit;
+       new_unit = (unit*)mem_alloc(sizeof(unit));
+
+       if (new_unit == NULL)
+               return NULL;
+
+       new_unit->unit_name = unit_name;
+       new_unit->names = name_table_create();
+       new_unit->is_library = 0;
+
+       return new_unit;
+}
+
+/*
+       Destroy a unit.
+*/
+void unit_destroy(unit *old_unit)
+{
+       string_destroy(old_unit->unit_name);
+
+       mem_free(old_unit);
+}
+
+
+/*
+       Duplicate a unit.
+*/
+unit* unit_duplicate(unit *item)
+{
+       unit *new_item;
+       new_item = (unit*) mem_alloc(sizeof(unit));
+
+       new_item->names = item->names;
+       new_item->unit_name = string_duplicate(item->unit_name);
+       new_item->is_library = item->is_library;
+
+       return new_item;
+}
\ No newline at end of file
diff --git a/MPC.3.5.LINUX/structures/unit.h b/MPC.3.5.LINUX/structures/unit.h
new file mode 100644 (file)
index 0000000..156840c
--- /dev/null
@@ -0,0 +1,21 @@
+/********************************************************************
+       
+       unit.h - structures and functions used to hold unit
+       descriptions
+
+  Niksa Orlic, 2005-03-30
+
+********************************************************************/
+
+struct unit_struct
+{
+       name_table *names;
+       string *unit_name;
+       int is_library;  /* set to 1 if it is an external library, or 0 if it is a plain unit */
+};
+
+typedef struct unit_struct unit;
+
+unit* unit_create(string*);
+void unit_destroy(unit*);
+unit* unit_duplicate(unit*);
\ No newline at end of file
diff --git a/MPC.3.5.LINUX/util/error.c b/MPC.3.5.LINUX/util/error.c
new file mode 100644 (file)
index 0000000..64d101b
--- /dev/null
@@ -0,0 +1,203 @@
+/********************************************************************
+
+       error.c - implementation of error-handling routines
+
+  Niksa Orlic, 2004-04-19
+
+********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+extern char msgstr[1024];
+extern char *source_file_name;
+extern int linenum;
+
+char locbuf[1024];
+short int error_count = 0;
+long int last_error_linenum = -1;
+int new_linenum = 0;
+short int warning_count = 0;
+
+
+char *msg(int i){
+       switch(i)
+       {
+       // General messages
+       case 1: return "Out of memory";
+       case 2: return "Too many errors";
+       case 3: return "Cannot create record file";
+       case 4: return "Cannot create class file";
+       case 5: return "Cannot open source file";
+       case 6: return "Serious error occured, stopping compilation";
+       case 7: return "Cannot create binary symbol file";
+       case 10: return "Internal error #010";
+       case 11: return "Internal error #011";
+       case 12: return "Internal error #012";
+       case 13: return "Internal error #013";
+       case 14: return "Internal error #014";
+       case 15: return "Internal error #015";
+       case 16: return "Internal error #016";
+       case 17: return "Internal error #017";
+       case 18: return "Internal error #018";
+       case 19: return "Internal error #019";
+       case 20: return "Internal error #020";
+       case 21: return "Internal error #021";
+       case 22: return "Internal error #022";
+       case 23: return "Internal error #023";
+       case 24: return "Internal error #024";
+       case 25: return "Internal error #025";
+       case 26: return "Internal error #026 memory";
+       // Scanner errors
+       case 100: return "unknown character \'%s\', ignored";
+       case 101: return "newline in string constant";
+       case 102: return "error in preprocessor statement";
+       // Parser errors
+       case 200: return "character \'%s\' expected, \'%s\' found";
+       case 201: return "unexpected text \'%s\' after program end";
+       case 202: return "identifier (name) expected";
+       case 203: return "keyword \'%s\' expected, \'%s\' found";
+       case 204: return "unexpected token \'%s\'";
+       case 205: return "operator \'=\' expected, \'%s\' found";
+       case 206: return "constant expected";
+       case 207: return "unexpected end of file found";
+       case 208: return "error in parameter list on token \'%s\'";
+       case 209: return "operator \':=\' expected, \'%s\' found";
+       case 210: return "\'packed\' arrays not supported; ordinary array are used";
+       case 211: return "sets are not supported in this version";
+       case 212: return "enumerated types are not supported in this version";
+       case 213: return "operator \'..\' expected, \'%s\' found";
+       case 214: return "keyword \'end\' expected, \'%s\' found";
+       case 215: return "\'with\' is not supported in this version";
+       case 216: return "keyword \'then\' expected, \'%s\' found";
+       case 217: return "constant of type integer or char expected";
+       case 218: return "operator \':=\' expected";
+       case 219: return "\'break\' statemnt found outside of do-while, repeat-until or for loop";
+       case 220: return "compiler does ot support the \'finalization\' part of the unit";
+       case 221: return "procedures and functions may not contain body inside unit interface part";
+       // Semantic errors
+       case 400: return "identifier \'%s\' already defined";
+       case 401: return "method was already declared as forward";
+       case 402: return "a %s with the same name was declared as forward";
+       case 403: return "parameter list is shorter than the list in previous forward declaration";
+       case 404: return "parameter list differs on element %s from the list in previous forward declaration";
+       case 405: return "return type is different than the return type declared in the previous forward declaration";
+       case 406: return "unknown type \'%s\'";
+       case 407: return "%s type expected";
+       case 408: return "integer, char or string type expected";
+       case 409: return "constant of type %s expected, %s found";
+       case 410: return "\'%s\' is not a constant";
+       case 411: return "integer or char type expected";
+       case 412: return "%s type expected, %s type found";
+       case 413: return "wrong type in interval definition";
+       case 414: return "\'%s\' is not a constant";
+       case 415: return "type name or integer/char constant expected, \'%s\' found";
+       case 416: return "error in interval definition";
+       case 417: return "operand is wrong type";
+       case 418: return "name \'%s\' already exists in a record declaration";
+       case 419: return "procedure/function takes 0 arguments, brackets must be left out";
+       case 420: return "procedure/function takes more than 0 arguments, '(' expected";
+       case 421: return "parameter list is too short";
+       case 422: return "error on parameter %s";
+       case 423: return "left and right operands to \':=\' must have the same type";
+       case 424: return "\'.\' operator can only be used on record types";
+       case 425: return "the record does not contain element named \'%s\'";
+       case 426: return "\'[\' operator can only be used on array types";
+       case 427: return "error in array dimensions (array has %s dimensions, %s are specified)";
+       case 428: return "identifier \'%s\' is not procedure, function, variable or unit name";
+       case 429: return "identifier \'%s\' is not constant, function or variable name";
+       case 430: return "only interval types can be used for array indexes";
+       case 431: return "nested functions or procedures are not supported";
+       case 432: return "function \'%s\' cannot be called from here; procedure call or assignement expected";
+       case 433: return "\'run\' is reserved name and cannot be used as a function or procedure name";
+       case 434: return "only string, character, integer or boolean can be appended to string";
+       case 435: return "files are not supported in this version";
+       case 436: return "variable parameters are not supported and are ignored";
+       case 437: return "invalid interval";
+       case 438: return "interval too large";
+       case 439: return "only integer type can be used as string index";
+       case 440: return "variables of interval type are not supported";
+       case 441: return "only forward declaration supplied; the implementation is missing";
+       case 442: return "case statement is not supported in this version";
+       case 443: return "a value cannot be asigned to an array. This is a limitation of MIDletPascal";
+       case 444: return "unknown identifier";
+       case 445: return "name of the procedure/function has already been taken by another identifier";
+       case 446: return "arrays in records (\'%s\') are not implemented. This is a limitation of MIDletPascal";
+       case 447: return "unknown record element \'%s\'";
+       case 448: return "failed to load \'%s\' library/unit";
+       case 449: return "error reading external library file";
+       case 450: return "could not load library/unit \'%s\' because identifier of the same name already exists";
+       case 451: return "serious internal error in library";
+       case 452: return "library/unit contains a method with an incorrect argument type";
+       case 453: return "library/unit does not contain function \'%s\'";
+       case 454: return "unit name must contain at least 2 characters";
+       case 455: return "library/unit does not contain type \'%s\'";
+       case 456: return "iterator used in for-loop must not be defined inside a library/unit";
+       case 457: return "identifier \'%s\' is not a procedure or variable name";
+       case 458: return "identifier \'%s\' is not a function, variable or constant name";
+       case 459: return "identifier \'%s\' found in more units; use syntax 'unit_name'.'identifier' to resolve ambiguity";
+       case 460: return "inlined label \'%d\' (offs:%d) not found";
+       case 461: return "inlined label \'%d\' (offs:%d) already defined";
+       case 462: return "inlined label \'%d\' (offs:%d) tableswitch / loookupswitch";
+       case 463: return "keyword \'%s\' is not allowed here.";
+       case 464: return "use bytecode/end instead of inline() which might be deprecated";
+       }
+}
+
+
+/*
+       Terminate the program and output the error message
+*/
+
+void die(int i)
+{
+       sprintf(msgstr,"Fatal error: %s\n", msg(i));
+       compileMSG();
+       compile_terminate();
+}
+
+
+/*
+       Add an error message, if the total number of errors exceeds 100,
+       die
+*/
+void add_error_message(int num, char *additional_data1, char *additional_data2)
+{
+       if (new_linenum==0)
+               new_linenum=linenum;
+       if (new_linenum != last_error_linenum) {
+           // j-a-s-d
+           if (num < 100)
+            sprintf(locbuf, "[Compiler Error] %s(%d): E%d %s\n", source_file_name, new_linenum, num,  msg(num));
+        else
+            sprintf(locbuf, "[Pascal Error] %s(%d): E%d %s\n", source_file_name, new_linenum, num,  msg(num));
+
+               sprintf(msgstr, locbuf, additional_data1, additional_data2);
+               compileMSG();
+               error_count ++;
+               if (error_count > 100)
+                       die(2);
+               last_error_linenum = new_linenum;
+       }
+       new_linenum=0;
+}
+
+
+/*
+       Add warning message, if the total number of errors exceeds 100,
+       die
+*/
+void add_warning_message(int num, char *additional_data1, char *additional_data2)
+{
+       if (new_linenum==0)
+               new_linenum=linenum;
+       // j-a-s-d
+       sprintf(locbuf, "[Pascal Warning] %s(%d): W%d %s\n", source_file_name, new_linenum, num, msg(num));
+
+       sprintf(msgstr, locbuf, additional_data1, additional_data2);
+       compileMSG();
+       warning_count ++;
+       if (warning_count > 100)
+               die(2);
+       new_linenum=0;
+}
diff --git a/MPC.3.5.LINUX/util/error.h b/MPC.3.5.LINUX/util/error.h
new file mode 100644 (file)
index 0000000..2620e6b
--- /dev/null
@@ -0,0 +1,24 @@
+/********************************************************************
+       
+       error.h - declaration of error-handling routines
+
+  Niksa Orlic, 2004-04-19
+
+********************************************************************/
+
+/*
+       Terminate the program and output the error message
+*/
+void die(int i/*char *message*/);
+
+
+/*
+       Adds an error message
+*/
+char *msg(int i);
+
+void add_error_message(/*char *message, long int linenum,*/ int num,
+                                          char *additional_data1, char *additional_data2);
+
+void add_warning_message(/*char *message, long int linenum,*/ int num,
+                                          char *additional_data1, char *additional_data2);
diff --git a/MPC.3.5.LINUX/util/memory.c b/MPC.3.5.LINUX/util/memory.c
new file mode 100644 (file)
index 0000000..6c233a4
--- /dev/null
@@ -0,0 +1,213 @@
+/********************************************************************
+       
+       memory.c - memory handling routines
+
+  Niksa Orlic, 2005-03-22
+
+********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "memory.h"
+#include "error.h"
+//#include "message.h"
+
+#define SLOWLIST 1
+
+static memory_object* memory_object_list_begin = NULL;
+static memory_object* memory_object_list_end = NULL;
+
+
+/*
+       Initialize the list of memory objects
+*/
+void mem_init()
+{
+       memory_object_list_begin = (memory_object*)malloc(sizeof(memory_object));
+       memory_object_list_begin->next = NULL;
+       memory_object_list_begin->prev = NULL;
+       memory_object_list_begin->data = NULL;
+       memory_object_list_end = memory_object_list_begin;
+}
+
+/*
+       Clean up the list of memory objects
+*/
+void mem_close()
+{
+       memory_object *it = memory_object_list_begin;
+       memory_object *old_object;
+
+       while (it != NULL)
+       {               
+               old_object = it;
+               it = it->next;
+#if SLOWLIST
+               if (old_object->data != NULL)
+                       free(old_object->data);
+               free(old_object);
+#else
+               mem_free(old_object);
+#endif
+       }
+}
+
+/*
+       Allocate the new block of memory and append it into the list
+*/
+void* mem_alloc(size_t s)
+{
+#if SLOWLIST
+       memory_object *wrapper = (memory_object*)malloc(sizeof(memory_object)); 
+#else
+       memory_object *wrapper = (memory_object*)malloc(sizeof(memory_object) + s);
+#endif 
+       if (wrapper == NULL)
+               return NULL;
+
+#if SLOWLIST
+       wrapper->data = malloc(s);
+       if (wrapper->data == NULL)
+               return NULL;
+#else  
+       wrapper->data = (char*)wrapper + sizeof(memory_object);
+#endif
+
+       wrapper->next = NULL;
+       wrapper->prev = memory_object_list_end;
+       memory_object_list_end->next = wrapper;
+       memory_object_list_end = wrapper;
+
+       if (memory_object_list_end == NULL)
+               die(26);
+
+       return wrapper->data;
+}
+
+
+/*
+       Reallocate the new block of memory and append it into the list
+*/
+void* mem_realloc(char* old_block, int s)
+{
+       memory_object *wrapper;
+       memory_object *prev, *next;
+
+       void *new_block;
+
+       prev = next = NULL;
+
+#if SLOWLIST
+       /* find the block */
+       {
+               memory_object *it = memory_object_list_begin;
+
+               while (it != NULL)
+               {
+                       if (it->data == old_block)
+                       {                               
+                               break;
+                       }
+
+                       it = it->next;
+               }
+       
+               it->data = realloc(it->data, s);
+               
+               return it->data;                
+       }
+#else
+       prev = ((memory_object*)(old_block - sizeof(memory_object)))->prev;
+       next = ((memory_object*)(old_block - sizeof(memory_object)))->next;
+
+       new_block = realloc(old_block - sizeof(memory_object), sizeof(memory_object) + s);
+
+       if (new_block == NULL)
+       {
+               mem_free(old_block);
+               return NULL;
+       }
+
+       if ((old_block - sizeof(memory_object)) == new_block)
+               return old_block;
+
+       wrapper = (memory_object*) new_block;
+
+       if (prev != NULL)
+               prev->next = wrapper;
+       wrapper->prev = prev;
+
+       if (next != NULL)
+               next->prev = wrapper;
+       wrapper->next = next;
+
+       mem_free(old_block);
+
+       return wrapper->data;
+#endif
+}
+
+/*
+       Free the block of memory
+*/
+void mem_free(char* old_block)
+{      
+       memory_object *prev, *next;
+
+       prev = next = NULL;
+
+       if (old_block == NULL)
+               return; 
+
+#if SLOWLIST
+       /* find the block */
+       {
+               memory_object *it = memory_object_list_begin;
+
+               while (it != NULL)
+               {
+                       if (it->data == old_block)
+                       {
+                               prev = it->prev;
+                               next = it->next;
+
+                               if (prev == NULL)
+                               {
+                                       int a = 1;
+                               }
+
+                               free(old_block);
+                               free(it);
+
+                               break;
+                       }
+
+                       it = it->next;
+               }
+
+               if (it == NULL)
+                       return;
+       }
+#else
+       prev = ((memory_object*)(old_block - sizeof(memory_object)))->prev;
+       next = ((memory_object*)(old_block - sizeof(memory_object)))->next;
+
+       free(old_block - sizeof(memory_object));
+#endif
+
+       if (prev != NULL)       
+               prev->next = next;
+       
+       if (next != NULL)
+               next->prev = prev;
+
+       if (next == NULL)
+               memory_object_list_end = prev;
+
+       if (memory_object_list_end == NULL)
+       {
+               int a = 1;
+       }
+
+}
\ No newline at end of file
diff --git a/MPC.3.5.LINUX/util/memory.h b/MPC.3.5.LINUX/util/memory.h
new file mode 100644 (file)
index 0000000..5e7552f
--- /dev/null
@@ -0,0 +1,30 @@
+/********************************************************************
+
+       memory.h - memory handling routines
+
+  Niksa Orlic, 2005-03-22
+
+********************************************************************/
+
+struct memory_object_struct
+{
+       struct memory_object_struct *next;
+       struct memory_object_struct *prev;
+       char *data;
+};
+
+typedef struct memory_object_struct memory_object;
+
+void mem_init();
+void mem_close();
+
+void* mem_alloc(size_t);
+
+// j-a-s-d
+#ifdef __GNUC__
+void* mem_realloc(char*, int);
+void mem_free(char*);
+#else
+void* mem_realloc(void*, int);
+void mem_free(void*);
+#endif
diff --git a/MPC.3.5.LINUX/util/strings.c b/MPC.3.5.LINUX/util/strings.c
new file mode 100644 (file)
index 0000000..252cd93
--- /dev/null
@@ -0,0 +1,201 @@
+/********************************************************************
+       
+       strings.c - implementation of a string-handling routines
+
+  Niksa Orlic, 2004-04-19
+
+********************************************************************/
+
+#include "error.h"
+#include "strings.h"
+#include "memory.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+/*
+       Create an empty string
+*/
+string* string_create()
+{
+       string *new_string;
+       new_string = (string*) mem_alloc(sizeof(string));
+
+       if (new_string == NULL)
+               die(1);
+
+       new_string->cstr = (char*) mem_alloc(sizeof(char) * 16);
+
+       if (new_string->cstr == NULL)
+               die(1);
+
+       new_string->cstr[0] = '\0';
+
+       new_string->length = 0;
+       new_string->allocated = 16;
+
+       return new_string;
+}
+
+
+/*
+       Create a copy of the string
+*/
+string* string_duplicate(string *str)
+{
+       string *new_string;
+       new_string = (string*) mem_alloc(sizeof(string));
+
+       if (new_string == NULL)
+               die(1);
+
+       new_string->cstr = (char*) mem_alloc(sizeof(char) * (str->allocated));
+
+       if (new_string->cstr == NULL)
+               die(1);
+
+       memcpy(new_string->cstr, str->cstr, str->length + 1); /* also copy the terminating NULL character */
+
+       new_string->allocated = str->allocated;
+       new_string->length = str->length;
+
+       return new_string;
+}
+
+
+/*
+       Create a string from a C-style string
+*/
+string* string_from_cstr(char *cstr)
+{
+       string *new_string;
+       new_string = (string*) mem_alloc(sizeof(string));
+
+       if (new_string == NULL)
+               die(1);
+
+       new_string->cstr = (char*) mem_alloc((strlen(cstr)+5) * sizeof(char));
+
+       if (new_string->cstr == NULL)
+               die(1);
+
+       strcpy(new_string->cstr, cstr);
+
+       new_string->allocated = strlen(cstr) + 5;
+       new_string->length = strlen(cstr);
+
+       return new_string;
+}
+
+
+/*
+       Free all memory used by the string
+*/
+void string_destroy(string *str)
+{
+       mem_free(str->cstr);
+       mem_free(str);
+}
+
+
+/*
+       Empties the given string        
+*/
+void string_empty(string *str)
+{
+       str->length = 0;
+       str->cstr[0] = '\0';
+}
+
+
+/*
+       Append the second string to the first string
+*/
+void string_append(string *str1, string *str2)
+{
+       if (str1->length + str2->length + 1 >= str1->allocated)
+       {
+               str1->cstr = (char*) mem_realloc(str1->cstr, sizeof(char)*(str1->length + str2->length + 1));
+
+               if (str1->cstr == NULL)
+                       die(1);
+
+               str1->allocated = str1->length + str2->length + 1;
+       }
+
+       memcpy(str1->cstr + str1->length, 
+              str2->cstr,
+                  str2->length);
+       
+       str1->length = str1->length + str2->length;
+       
+       str1->cstr[str1->length] = '\0';
+}
+
+
+/*
+       Append the C-style string to the string
+*/
+void string_append_cstr(string *str1, char *cstr2)
+{
+       short int cstr2_length;
+
+       if (str1 == NULL)
+               str1 = string_create();
+
+       cstr2_length = strlen(cstr2);
+
+       if (str1->length + cstr2_length + 1 >= str1->allocated)
+       {
+               str1->cstr = (char*) mem_realloc(str1->cstr, sizeof(char)*(str1->length + cstr2_length + 1));
+
+               if (str1->cstr == NULL)
+                       die(1);
+
+               str1->allocated = str1->length + cstr2_length + 1;
+       }
+
+       memcpy(str1->cstr + str1->length, 
+              cstr2,
+                  cstr2_length);
+       
+       str1->length = str1->length + cstr2_length;
+       
+       str1->cstr[str1->length] = '\0';
+}
+
+
+/*
+       Get the C-style string from a given string
+*/
+char *string_get_cstr(string *str)
+{
+       return str->cstr;
+}
+
+
+/*
+       Get the string length
+*/
+short int string_length(string *str)
+{
+       return str->length;
+}
+
+/*
+       Translate the string into lowercase
+*/
+void lowercase(char *cstr)
+{
+       int i = 0;
+
+       while (cstr[i] != 0)
+       {
+               if ((cstr[i] >= 'A') && (cstr[i] <= 'Z'))
+               {
+                       cstr[i] = cstr[i] | (char) 0x20;
+               }
+
+               i++;
+       }
+}
\ No newline at end of file
diff --git a/MPC.3.5.LINUX/util/strings.h b/MPC.3.5.LINUX/util/strings.h
new file mode 100644 (file)
index 0000000..d81da14
--- /dev/null
@@ -0,0 +1,76 @@
+/********************************************************************
+       
+       strings.h - declaration of a string-handling routines
+
+  Niksa Orlic, 2004-04-19
+
+********************************************************************/
+
+struct string_struct
+{
+       char *cstr;
+       short int length;
+       short int allocated;
+};
+
+typedef struct string_struct string;
+
+
+/*
+       Create an empty string
+*/
+string* string_create();
+
+
+/*
+       Create a copy of the string
+*/
+string* string_duplicate(string*);
+
+
+/*
+       Create a string from a C-style string
+*/
+string* string_from_cstr(char *cstr);
+
+
+/*
+       Free all memory used by the string
+*/
+void string_destroy(string*);
+
+
+/*
+       Empties the given string        
+*/
+void string_empty(string*);
+
+
+/*
+       Append the second string to the first string
+*/
+void string_append(string*, string*);
+
+
+/*
+       Append the C-style string to the string
+*/
+void string_append_cstr(string*, char*);
+
+
+/*
+       Get the C-style string from a given string
+*/
+char* string_get_cstr(string*);
+
+
+/*
+       Get the string length
+*/
+short int string_length(string*);
+
+
+/*
+       Translates a string into lower case
+*/
+void lowercase(char *);
\ No newline at end of file
diff --git a/MPS.3.1/F.java b/MPS.3.1/F.java
new file mode 100644 (file)
index 0000000..a97edca
--- /dev/null
@@ -0,0 +1,435 @@
+/*
+ * Fixed-point aritmetika za MIDletPascal
+ * */
+
+public class F
+{
+
+    private F()
+    {
+    }
+
+    // fromInt
+    public static int fI(int i)
+    {
+        return i << 12;
+    }
+
+    // fromint
+    public static int fI(int a, int b)
+    {
+       StringBuffer s = new StringBuffer();
+       s.append(a);
+       s.append('.');
+       s.append(b);
+       return fI(s.toString(),10);
+    }
+
+    // fromInt
+    public static int fI(String s, int radix)
+    {
+        int i = 0;
+        if(s.charAt(0) == '-')
+            i = 1;
+        String s1 = "-1";
+        int j = s.indexOf('.');
+        if(j >= 0)
+        {
+            for(s1 = s.substring(j + 1, s.length()); s1.length() < 4; s1 = s1 + "0");
+            if(s1.length() > 4)
+                s1 = s1.substring(0, 4);
+        } else
+        {
+            j = s.length();
+        }
+        int k = Integer.parseInt(s.substring(i, j), radix);
+        int l = Integer.parseInt(s1, radix) + 1;
+        int i1 = (k << 12) + (l << 12) / 10000;
+        if(i == 1)
+            i1 = -i1;
+        return i1;
+    }
+
+    // toString
+    public static String tS(int i)
+    {
+        boolean flag = false;
+        if(i < 0)
+        {
+            flag = true;
+            i = -i;
+        }
+        int j = i >> 12;
+        int k = 10000 * (i & 0xfff) >> 12;
+        String s;
+        for(s = Integer.toString(k); s.length() < 4; s = "0" + s);
+        return (flag ? "-" : "") + Integer.toString(j) + "." + s;
+    }
+
+    // toInt
+    public static int tI(int i)
+    {
+        if(i >= 0)
+            i += 2048;
+        else
+            i -= 2048;
+        return i >> 12;
+    }
+
+    // div
+    public static int D(int i, int j)
+    {
+        boolean flag = false;
+        if(j == 4096)
+            return i;
+        if((j & 0xfff) == 0)
+            return i / (j >> 12);
+        if(i < 0)
+        {
+            i = -i;
+            flag = true;
+        }
+        if(j < 0)
+        {
+            j = -j;
+            if(flag)
+                flag = false;
+            else
+                flag = true;
+        }
+        byte byte0 = 0;
+        if(i > 0x64fff)
+            byte0 = 3;
+        if(i > 0x3e8fff)
+            byte0 = 4;
+        if(i > 0x7dffff)
+            byte0 = 6;
+        if(i > 0x1f4ffff)
+            byte0 = 8;
+        if(i > 0x7dfffff)
+            byte0 = 10;
+        if(byte0 > 0)
+        {
+            int k = 2 << byte0 - 1;
+            i += k;
+            j += k;
+        }
+        int l = (i << 12 - byte0) / (j >> byte0);
+        return flag ? -l : l;
+    }
+
+    // mult
+    public static int M(int i, int j)
+    {
+        boolean flag = false;
+        if((i & 0xfff) == 0)
+            return (i >> 12) * j;
+        if((j & 0xfff) == 0)
+            return i * (j >> 12);
+        if(i < 0 && j > 0 || i > 0 && j < 0)
+            flag = true;
+        if(i < 0)
+            i = -i;
+        if(j < 0)
+            j = -j;
+        byte byte0 = 0;
+        if(i > 0x64fff || j > 0x64fff)
+            byte0 = 2;
+        if(i > 0x3e8fff || j > 0x3e8fff)
+            byte0 = 4;
+        if(i > 0x271ffff || j > 0x271ffff)
+            byte0 = 6;
+        if(byte0 > 0)
+        {
+            int k = 2 << byte0 - 1;
+            i += k;
+            j += k;
+        }
+        int l = (i >> 12) * (j >> 12) << 12;
+        int i1 = (i & 0xfff) * (j & 0xfff) >> 12;
+        i1 += ((i & 0xfffff000) >> byte0) * ((j & 0xfff) >> byte0) >> 12 - (byte0 << 1);
+        l = l + i1 + (((i & 0xfff) >> byte0) * ((j & 0xfffff000) >> byte0) >> 12 - (byte0 << 1));
+        if(l < 0)
+            return 0;
+        else
+            return flag ? -l : l;
+    }
+
+    // abs
+    public static int A(int i)
+    {
+        if(i < 0)
+            return -i;
+        else
+            return i;
+    }
+
+    // sqrt
+    public static int S(int i, int j)
+    {
+        if(i < 0)
+            return 0;
+        if(i == 0)
+            return 0;
+        int k = i + 4096 >> 1;
+        for(int l = 0; l < j; l++)
+            k = k + D(i, k) >> 1;
+
+        if(k < 0)
+            return 0;
+        else
+            return k;
+    }
+
+    // sqrt
+    public static int S(int i)
+    {
+        byte byte0 = 8;
+        if(i > 0x64000)
+            byte0 = 12;
+        if(i > 0x3e8000)
+            byte0 = 16;
+        return S(i, byte0);
+    }
+
+    // sin
+    public static int s(int i)
+    {
+        int j = 0;
+        for(; i < 0; i += 25736);
+        if(i > 25736)
+            i %= 25736;
+        int k = (i * 10) / 714;
+        if(i != 0 && i != 6434 && i != 12868 && i != 19302 && i != 25736)
+            j = (i * 100) / 714 - k * 10;
+        if(k <= 90)
+            return sin_lookup(k, j);
+        if(k <= 180)
+            return sin_lookup(180 - k, j);
+        if(k <= 270)
+            return -sin_lookup(k - 180, j);
+        else
+            return -sin_lookup(360 - k, j);
+    }
+
+    private static int sin_lookup(int i, int j)
+    {
+        if(j > 0 && j < 10 && i < 90)
+            return SIN_TABLE[i] + ((SIN_TABLE[i + 1] - SIN_TABLE[i]) / 10) * j;
+        else
+            return SIN_TABLE[i];
+    }
+
+       // cos
+    public static int C(int i)
+    {
+        return s(i + 6435);
+    }
+
+    public static int tan(int i)
+    {
+        int j = D(s(i), C(i));
+        return j;
+    }
+
+    public static int cot(int i)
+    {
+        int j = D(fI(1), tan(i));
+        return j;
+    }
+
+    // asin
+    public static int AS(int i)
+    {
+        boolean flag = false;
+        if(i < 0)
+            flag = true;
+        if(A(i) > 4096)
+           return 0;
+        i = A(i);
+        int j = 0;
+        int k = SIN_TABLE.length;
+        for(int l = 0; l < SIN_TABLE.length; l++)
+        {
+            int i1 = A(i - SIN_TABLE[l]);
+            if(i1 < k)
+            {
+                k = i1;
+                j = l;
+            }
+        }
+
+        if(flag)
+            return -(j * 72);
+        else
+            return j * 72;
+    }
+
+    // acos
+    public static int AC(int i)
+    {
+        return 6434 - AS(i);
+    }
+
+    // exp
+    public static int e(int i)
+    {
+        int j = A(i) >> 12;
+        if(j > 13)
+            return 0;
+        int ai[] = {
+            4096, 11134, 30266, 0x1415e, 0x36992, 0x9469c, 0x1936dc, 0x448a21, 0xba4f54, 0x1fa7158, 
+            0x560a774, 0xe9e2244, 0x27bc2ca9, 0x6c02d646
+        };
+        int k = ai[j];
+        int l = A(i) & 0xfff;
+        if(l > 0)
+        {
+            int i1 = 0;
+            int j1 = 4096;
+            int k1 = 1;
+            for(int l1 = 0; l1 < 6; l1++)
+            {
+                i1 += j1 / k1;
+                j1 = M(j1, l);
+                k1 *= l1 + 1;
+            }
+
+            k = M(k, i1);
+        }
+        if(i < 0)
+            return D(4096, k);
+        else
+            return k;
+    }
+
+    public static int log(int i)
+    {
+        if(i <= 0)
+            return 0;
+        int j = 0;
+        boolean flag = false;
+        int l;
+        for(l = 0; i > 8192; l++)
+            i >>= 1;
+
+        int i1 = l * 2839;
+        int j1 = 0;
+        i -= 4096;
+        for(int k1 = 1; k1 < 11; k1++)
+        {
+            int k;
+            if(j == 0)
+                k = i;
+            else
+                k = M(j, i);
+            if(k == 0)
+                break;
+            j1 += ((k1 % 2 != 0 ? 1 : -1) * k) / k1;
+            j = k;
+        }
+
+        return i1 + j1;
+    }
+
+    public static int log10(int i)
+    {
+       return D(log(i), log(2));
+    }
+
+    // pow
+    public static int p(int i, int j)
+    {
+        boolean flag = false;
+        int k = 1;
+        if(j < 0)
+        {
+            flag = true;
+            j = -j;
+        }
+        if(A(i) < 4096 && j > 12288)
+        {
+            k = e(M(log(i), j));
+        } else
+        {
+            k = pi(i, j >> 12);
+            if((j & 0xfff) != 0)
+                k = M(k, e(M(log(i), j & 0xfff)));
+        }
+        if(flag)
+            return D(4096, k);
+        else
+            return k;
+    }
+
+    private static int pi(int i, int j)
+    {
+        int k = 4096;
+        if(i == 0)
+            return 0;
+        for(int l = 0; l < j; l++)
+            k = M(k, i);
+
+        if(k < 0)
+            return 0;
+        else
+            return k;
+    }
+
+    // to degrees
+    public static int tD(int i)
+    {
+       return 180*D(i, PI);
+    }
+
+    // to radians
+    public static int tR(int i)
+    {
+       return M(i/180, PI);
+    }
+
+    public static int atan(int i)
+    {
+       return AC(D(fI(1), S(1+M(i, i))));
+    }
+
+    public static int atan2(int y, int x)
+    {
+       int res;
+       if (x == 0)
+       {
+               if (y == 0)
+                       return 0;
+               if (y > 0)
+                       return PI/2;
+               return -PI/2;
+       }
+       
+       if (x>0)
+               return atan(D(y,x));
+
+       res = PI - atan(A(D(y,x)));
+
+       if (y>=0)
+               return res;
+       return -res;
+    }
+
+    public static final int MAX_VALUE = 0x7fffffff;
+    public static final int MIN_VALUE = 0x80000001;
+    public static final int E = 11134;
+    public static final int PI = 12868;
+    private static final int SIN_TABLE[] = {
+        0, 71, 142, 214, 285, 357, 428, 499, 570, 641, 
+        711, 781, 851, 921, 990, 1060, 1128, 1197, 1265, 1333, 
+        1400, 1468, 1534, 1600, 1665, 1730, 1795, 1859, 1922, 1985, 
+        2048, 2109, 2170, 2230, 2290, 2349, 2407, 2464, 2521, 2577, 
+        2632, 2686, 2740, 2793, 2845, 2896, 2946, 2995, 3043, 3091, 
+        3137, 3183, 3227, 3271, 3313, 3355, 3395, 3434, 3473, 3510, 
+        3547, 3582, 3616, 3649, 3681, 3712, 3741, 3770, 3797, 3823, 
+        3849, 3872, 3895, 3917, 3937, 3956, 3974, 3991, 4006, 4020, 
+        4033, 4045, 4056, 4065, 4073, 4080, 4086, 4090, 4093, 4095, 
+        4096
+    };
+
+}
diff --git a/MPS.3.1/FS.java b/MPS.3.1/FS.java
new file mode 100644 (file)
index 0000000..7849d0e
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * This class is used when Forms support is needeed
+ * */
+import javax.microedition.lcdui.*;
+
+public class FS
+{
+       /* add a textfiled into the form */
+       public static int Lj(String label, String text, 
+                       int maxSize, int constraints)
+       {
+               try
+               {
+                       return FW.F.append(new TextField(label, text, maxSize, constraints));
+               }
+               catch (Exception E)
+               {
+                       return -1;
+               }
+       }
+
+       /* add gauge */
+       public static int Lj(String label, int interactive, 
+                       int maxValue, int initialValue)
+       {
+               try
+               {
+                       boolean inter = true;
+                       if (interactive == 0)
+                               inter = false;
+                       // j-a-s-d: avoid AV false alarm
+                       return FW.F.append(new Gauge(label, inter, maxValue, initialValue));
+               }
+               catch (Exception E)
+               {
+                       return -1;
+               }
+       }
+
+       /* add choice group */
+       public static int Lj(String label, int type)
+       {
+               try
+               {
+                       ChoiceGroup cg = new ChoiceGroup(label, type);
+                       return FW.F.append(cg);
+               }
+               catch (Exception E)
+               {
+                       return -1;
+               }
+       }
+
+       /* get int value from gauge */
+       public static int Lja(int itemNum)
+       {
+               try
+               {
+                       Item it = FW.F.get(itemNum);
+                       Gauge g = (Gauge)it;
+                       return g.getValue();                    
+               }
+               catch(Exception e)
+               {
+                       return -1;
+               }
+       }
+
+       /* set value to gauge */
+       public static void Lja(int itemNum, int value)
+       {
+               try
+               {
+                       Item it = FW.F.get(itemNum);
+                       Gauge g = (Gauge)it;
+                       g.setValue(value);
+               }
+               catch(Exception e)
+               {
+                       return;
+               }
+       }
+
+       /* get text from textfield */
+       public static String ja(int itemNum)
+       {
+               try
+               {
+                       Item it = FW.F.get(itemNum);
+                       TextField tf = (TextField)it;
+                       return tf.getString();                  
+               }
+               catch(Exception e)
+               {
+                       return "";
+               }
+       }
+
+       /* set text of field */
+       public static void ja(int itemNum, String text)
+       {
+               try
+               {
+                       Item it = FW.F.get(itemNum);
+                       TextField tf = (TextField)it;
+                       tf.setString(text);
+               }
+               catch(Exception e)
+               {
+                       return;
+               }
+       }
+
+       /* choice group append item (string, null) */
+       public static int I(int itemNum, String text)
+       {
+               try
+               {
+                       ChoiceGroup cg = (ChoiceGroup)FW.F.get(itemNum);
+                       return cg.append(text, null);
+               }
+               catch(Exception e)
+               {
+                       return -1;
+               }
+       }
+
+       /* choice group append item (string, image) */
+       public static int I(int itemNum, String text, Image image)
+       {
+               try
+               {
+                       ChoiceGroup cg = (ChoiceGroup)FW.F.get(itemNum);
+                       return cg.append(text, image);
+               }
+               catch(Exception e)
+               {
+                       return -1;
+               }
+       }
+
+       /* choice is selected item */
+       public static int L(int itemNum, int entryNum)
+       {
+               try
+               {
+                       ChoiceGroup cg = (ChoiceGroup)FW.F.get(itemNum);
+                       if (cg.isSelected(entryNum))
+                                         return -1;
+                       else
+                                         return 0;
+               }
+               catch(Exception e)
+               {
+                       return -1;
+               }
+       }
+       
+       /* choice get selected item */
+       public static int L(int itemNum)
+       {
+               try
+               {
+                       ChoiceGroup cg = (ChoiceGroup)FW.F.get(itemNum);
+                       return cg.getSelectedIndex();
+               }
+               catch(Exception e)
+               {
+                       return -1;
+               }
+       }
+
+       /* formAddDateField */
+       public static int dd(String title, int type)
+       {
+               try
+               {
+                       DateField df = new DateField(title, type);
+                       return FW.F.append(df);
+               }
+               catch (Exception e)
+               {
+                       return -1;
+               }
+       }
+
+       /* formSetDate */
+       public static void dd(int index, int time)
+       {
+               try
+               {
+                       DateField df = (DateField)FW.F.get(index);
+                       df.setDate(new java.util.Date(((long)time) * 1000));
+               }
+               catch (Exception e)
+               {
+                       return;
+               }
+       }
+
+       /* formGetDate*/
+       public static int dd(int index)
+       {
+               try
+               {
+                       DateField df = (DateField)FW.F.get(index);
+                       return (int) (df.getDate().getTime() / 1000);
+               }
+               catch (Exception e)
+               {
+                       return -1;
+               }
+       }
+
+       /* getFormTitle*/
+       public static String gft()
+       {
+               try
+               {
+                       String title = FW.F.getTitle();
+                       if (title == null)
+                               title = "";
+                       return title;
+               }
+               catch (Exception e)
+               {
+                       return "";
+               }
+       }
+};
diff --git a/MPS.3.1/FW.java b/MPS.3.1/FW.java
new file mode 100644 (file)
index 0000000..d302e8b
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * This is the framework file for the MIDLetPascal generated MIDlets
+ * The Pascal code is compiled into java class called M.
+ * */
+import javax.microedition.midlet.*;  
+import javax.microedition.lcdui.*;
+  
+public class FW extends MIDlet implements CommandListener
+{
+       public static   FW fw = null;
+       public M m = null;
+       public boolean threadStarted = false;
+       public Display display;
+       public static int MP; // MidletPaused
+
+       // command & forms support
+       public static Form F;
+       public static Displayable CD;
+       public static Command LC;
+       public static List L;
+       public static Alert A;
+       public static TextBox TB;
+
+       public void startApp()
+       {
+               MP = 0;
+               
+               display = Display.getDisplay(this);
+               
+               fw = this;
+
+               LC = null;
+
+               if (m == null)
+               {
+                       m = new M();
+       
+                       M.T = m;
+                       M.I = Image.createImage(m.getWidth(), m.getHeight());
+                       M.G = M.I.getGraphics();
+                       M.KC = 0;
+                       L = new List("", List.IMPLICIT);
+                       A = new Alert("", "", null, AlertType.INFO);
+                       TB = new TextBox("", "", 2, TextField.ANY);
+                       display.setCurrent(m);
+                       CD = m;
+                       try
+                       {
+                       m.setCommandListener(this);
+                       } catch (Exception e)
+                       { 
+                               // do nothing, this catches the exception for NokiaAPI FullCanvas 
+                       }
+                       F = new Form("");
+                       F.setCommandListener(this);
+               }
+               else
+               {
+                       m.repaint();
+                       m.serviceRepaints();
+               }
+               
+               if (! threadStarted)
+               {
+                        new Thread(m).start();
+                        threadStarted = true;
+               }
+        }
+     
+    public void pauseApp()
+    {      
+         MP = -1;
+    }      
+      
+    
+    public void destroyApp(boolean unconditional)
+    {
+         m = null;
+                       M.I = null;
+                       M.G = null;
+                       CD = null;
+                       TB = null;
+                       F = null;
+                       A = null;
+                       L = null;
+                       fw = null;
+                       LC = null;
+         notifyDestroyed(); 
+    }
+
+       public void commandAction(Command c, Displayable item) {
+               LC = c;
+    }
+
+}     
diff --git a/MPS.3.1/H.java b/MPS.3.1/H.java
new file mode 100644 (file)
index 0000000..8b7b353
--- /dev/null
@@ -0,0 +1,155 @@
+// The HTTP class for the MIDletPascal
+import javax.microedition.io.*;
+import java.io.*;
+
+public class H
+{
+       public HttpConnection c = null;
+       public OutputStream o = null;
+       public InputStream i = null;
+
+       // open a http connection
+       public int L(String url)
+       {
+               try
+               {
+                       c = (HttpConnection)Connector.open(url);
+                       o = c.openOutputStream();
+                       return -1;
+               }
+               catch(Exception e)
+               {
+                       c = null;
+                       return 0;
+               }
+       }
+
+       // return true if the connection is open
+       public int L()
+       {
+               if (c != null)
+                       return -1;
+               return 0;
+       }
+
+       // close the connection
+       public void c()
+       {
+               try
+               {
+                       if (i != null)
+                       {
+                               i.close();
+                               i = null;
+                       }
+                       if (o != null)
+                       {
+                               o.close();
+                               o = null;
+                       }
+                       c.close();
+                       c = null;
+               }
+               catch(Exception e)
+               {
+                       c = null;
+               }
+       }
+
+       // add http header
+       public void L(String header, String value)
+       {
+               try
+               {
+                       c.setRequestProperty(header, value);
+               }
+               catch(Exception e)
+               {}
+       }
+
+       // setRequestMethod :
+       // HEAD, POST, GET bi trebalo rijesiti kao string konstante
+       public void c(String method)
+       {
+               try
+               {
+                       c.setRequestMethod(method);
+               }
+               catch(Exception e)
+               {}
+       }
+
+       // get header field
+       public String i(String header)
+       {
+               try
+               {
+                       String value;
+                       value = c.getHeaderField(header);
+
+                       if (value == null)
+                         value = "";
+
+                       return value;
+               }
+               catch(Exception e)
+               {
+                       return "";
+               }
+       }
+
+       // set message text
+       public int o(String message)
+       {
+               try
+               {
+                       o.write(message.getBytes());
+
+                       return -1;
+               }
+               catch(Exception e)
+               {
+                       o = null;
+                       return 0;
+               }
+       }
+
+       // getresponse code
+       // ovaj takodjer otvara konekciju i ceka dok se ne odgovori
+       public int o()
+       {
+               try
+               {
+                       int code;
+                       code = c.getResponseCode();
+                       i = c.openInputStream();
+                       return code;
+               }
+               catch(Exception e)
+               {
+                       return -1;
+               }
+       }
+
+       // read the input data from the connection
+       public String j()
+       {
+               try
+               {
+                       StringBuffer retval = new StringBuffer();
+                       int c;
+
+                       while ((c=i.read()) != -1)
+                       {
+                               retval.append((char)(char)c);
+                       }
+                       
+                       return retval.toString();
+               }
+               catch(Exception e)
+               {
+                       return "";
+               }
+       }
+
+};
diff --git a/MPS.3.1/P.java b/MPS.3.1/P.java
new file mode 100644 (file)
index 0000000..4c33830
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * The player class used for playing the music.
+ * */
+
+import javax.microedition.media.*;
+
+public class P
+{
+               public static Player p = null;
+
+               /* load music player */
+               public static int a(String resource, String type)
+               {
+                       try
+                       {
+                 if (p != null)
+                         {
+                               p.close();
+                         }
+                               p = Manager.createPlayer(FW.fw.getClass().getResourceAsStream(resource), type);
+                               p.realize();
+                               p.prefetch();
+                       }
+                       catch (Exception e)
+                       {
+                               return 0;
+                       }
+
+                       return -1;
+               }
+
+               /* play */
+               public static int a()
+               {
+                       try
+                       {
+                               if (p == null)
+                                       return 0;
+
+                               p.start();
+                       }
+                       catch (Exception e)
+                       {
+                               return 0;
+                       }
+
+                       return -1;
+               }
+
+               /* stops playing the music */
+               public static void b()
+               {
+                       try
+                       {
+                               if (p != null)
+                               {
+                                       p.stop();
+                               }
+                       }
+                       catch (Exception e)
+                       {}
+               }
+
+               /* set loop count, -1 indefinitely */
+               public static int a(int x)
+               {
+                       try
+                       {
+                               if (p != null)
+                               {
+                                       if (p.getState() == Player.STARTED)
+                                                         return 0;
+                                       p.setLoopCount(x);
+                                       return -1;
+                               }
+                               
+                       } catch (Exception e)
+                       {
+                               return 0;
+                       }
+                       return 0;
+               }
+
+               /* get duration time in milliseconds */
+               public static int c()
+               {
+                       try
+                       {
+                               if (p != null)
+                               {
+                                       return (int)(p.getDuration() / 1000);
+                               }
+                               else return -1;
+                       }
+                       catch (Exception e)
+                       {
+                               return -1;
+                       }
+               }
+               
+}
diff --git a/MPS.3.1/README.txt b/MPS.3.1/README.txt
new file mode 100644 (file)
index 0000000..83d9c74
--- /dev/null
@@ -0,0 +1,9 @@
+For building this stubs, just call the java compiler and then the preverifier in the regular way.
+
+For example, assumbing you have both in the path, the WTK is in C:\WTK25, and that you have a subdirectory called "bin" to hold the preverified class output, for building the SM class you can do:
+
+javac -g:none -classpath c:\WTK25\lib\midpapi10.jar;c:\WTK25\lib\cldcapi10.jar;c:\WTK25\lib\wma11.jar -source 1.3 -target 1.1 SM.java
+preverify1.1 -nofp -nofinalize -nonative -classpath c:\WTK25\lib\midpapi10.jar;c:\WTK25\lib\cldcapi10.jar;c:\WTK25\lib\wma11.jar -d "bin" "SM"
+
+Enjoy,
+Javier Santo Domingo
diff --git a/MPS.3.1/RS.java b/MPS.3.1/RS.java
new file mode 100644 (file)
index 0000000..a87ea9a
--- /dev/null
@@ -0,0 +1,125 @@
+// this is the class to implement record store functionality
+// for MIDletPascal
+import javax.microedition.rms.*;
+
+public class RS
+{
+       // open record store
+       public static RecordStore j(String name) 
+       {
+               try
+               {
+                       return RecordStore.openRecordStore(name, true);
+               }
+               catch(Exception e)
+               {
+                       return null;
+               }
+       }
+
+       
+       // closes record store
+       public static void L(RecordStore rs)
+       {
+               try
+               {
+                       rs.closeRecordStore();
+               }
+               catch(Exception e)
+               {
+               }
+       }
+
+       // deletes a record store
+       public static void L(String name)
+       {
+               try
+               {
+                       RecordStore.deleteRecordStore(name);
+               }
+               catch(Exception e)
+               {
+               }
+       }
+
+       // deletes a record from a record store
+       public static void L(RecordStore rs, int id)
+       {
+               try
+               {
+                       rs.deleteRecord(id);
+               }
+               catch(Exception e)
+               {
+               }
+       }
+
+       // adds a record
+       public static int L(RecordStore rs, String data)
+       {
+               try
+               {
+                       return rs.addRecord(data.getBytes(), 0, data.length());
+               }
+               catch(Exception e)
+               {
+                       return -1;
+               }
+       }
+
+       // sets a data in the entry
+       public static void L(RecordStore rs, String data, int id)
+       {
+         try
+               {
+                 rs.setRecord(id, data.getBytes(), 0, data.getBytes().length);
+               }
+               catch (Exception e)
+               {}
+       }
+
+       // returns the next record ID
+       public static int Lja(RecordStore rs)
+       {
+               try
+               {
+                       return rs.getNextRecordID();
+               }
+               catch (Exception e)
+               {
+                       return -1;
+               }
+       }
+
+       // read the data from the record store
+       public static String j(RecordStore rs, int id)
+       {
+               try
+               {
+                       byte[] res;
+                       res = rs.getRecord(id);
+
+                       if (res == null)
+                               return "";
+
+                       return new String(res);
+               }
+               catch(Exception e)
+               {
+                       return "";
+               }
+       }
+
+       // return the number of records in the record store
+       public static int j(RecordStore rs)
+       {
+               try
+               {
+                       return rs.getNumRecords();
+               }
+               catch(Exception e)
+               {
+                       return 0;
+               }
+       }
+};
diff --git a/MPS.3.1/Real.java b/MPS.3.1/Real.java
new file mode 100644 (file)
index 0000000..c6a131f
--- /dev/null
@@ -0,0 +1,6020 @@
+
+
+
+
+
+
+/**
+ * <b>Java integer implementation of 63-bit precision floating point.</b>
+ * <br><i>Version 1.13</i>
+ *
+ * <p>Copyright 2003-2009 Roar Lauritzsen <roarl@pvv.org>
+ *
+ * <blockquote>
+ *
+ * <p>This library 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 of the License, or (at your option)
+ * any later version.
+ *
+ * <p>This library 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.
+ *
+ * <p>The following link provides a copy of the GNU General Public License:
+ * <br>&nbsp;&nbsp;&nbsp;&nbsp;<a
+ * href="http://www.gnu.org/licenses/gpl.txt">http://www.gnu.org/licenses/gpl.txt</a>
+ * <br>If you are unable to obtain the copy from this address, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA
+ *
+ * </blockquote>
+ *
+ * <p><b>General notes</b>
+ * <ul>
+ *
+ *   <li><code>Real</code> objects are not immutable, like Java
+ *   <code>Double</code> or <code>BigDecimal</code>. This means that you
+ *   should not think of a <code>Real</code> object as a "number", but rather
+ *   as a "register holding a number". This design choice is done to encourage
+ *   object reuse and limit garbage production for more efficient execution on
+ *   e.g. a limited MIDP device. The design choice is reflected in the API,
+ *   where an operation like {@link #add(Real) add} does not return a new
+ *   object containing the result (as with {@link
+ *   java.math.BigDecimal#add(java.math.BigDecimal) BigDecimal}), but rather
+ *   adds the argument to the object itself, and returns nothing.
+ *
+ *   <li>This library implements infinities and NaN (Not-a-Number) following
+ *   the IEEE 754 logic. If an operation produces a result larger (in
+ *   magnitude) than the largest representable number, a value representing
+ *   positive or negative infinity is generated. If an operation produces a
+ *   result smaller than the smallest representable number, a positive or
+ *   negative zero is generated. If an operation is undefined, a NaN value is
+ *   produced. Abnormal numbers are often fine to use in further
+ *   calculations. In most cases where the final result would be meaningful,
+ *   abnormal numbers accomplish this, e.g. atan(1/0)=&pi;/2. In most cases
+ *   where the final result is not meaningful, a NaN will be produced.
+ *   <i>No exception is ever (deliberately) thrown.</i>
+ *
+ *   <li>Error bounds listed under <a href="#method_detail">Method Detail</a>
+ *   are calculated using William Rossi's <a
+ *   href="http://dfp.sourceforge.net/">rossi.dfp.dfp</a> at 40 decimal digits
+ *   accuracy. Error bounds are for "typical arguments" and may increase when
+ *   results approach zero or 
+ *   infinity. The abbreviation {@link Math#ulp(double) ULP} means Unit in the
+ *   Last Place. An error bound of ½ ULP means that the result is correctly
+ *   rounded. The relative execution time listed under each method is the
+ *   average from running on SonyEricsson T610 (R3C), K700i, and Nokia 6230i.
+ *
+ *   <li>The library is not thread-safe. Static <code>Real</code> objects are
+ *   used extensively as temporary values to avoid garbage production and the
+ *   overhead of <code>new</code>. To make the library thread-safe, references
+ *   to all these static objects must be replaced with code that instead
+ *   allocates new <code>Real</code> objects in their place.
+ *
+ *   <li>There is one bug that occurs again and again and is really difficult
+ *   to debug. Although the pre-calculated constants are declared <code>static
+ *   final</code>, Java cannot really protect the contents of the objects in
+ *   the same way as <code>const</code>s are protected in C/C++. Consequently,
+ *   you can accidentally change these values if you send them into a function
+ *   that modifies its arguments. If you were to modify {@link #ONE Real.ONE}
+ *   for instance, many of the succeeding calculations would be wrong because
+ *   the same variable is used extensively in the internal calculations of
+ *   Real.java.
+ *
+ * </ul>
+ */
+public final class Real
+{
+    /**
+     * The mantissa of a <code>Real</code>. <i>To maintain numbers in a
+     * normalized state and to preserve the integrity of abnormal numbers, it
+     * is discouraged to modify the inner representation of a
+     * <code>Real</code> directly.</i>
+     *
+     * <p>The number represented by a <code>Real</code> equals:<br>
+     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-1<sup>sign</sup>&nbsp;·&nbsp;mantissa&nbsp;·&nbsp;2<sup>-62</sup>&nbsp;·&nbsp;2<sup>exponent-0x40000000</sup>
+     *
+     * <p>The normalized mantissa of a finite <code>Real</code> must be
+     * between <code>0x4000000000000000L</code> and
+     * <code>0x7fffffffffffffffL</code>. Using a denormalized
+     * <code>Real</code> in <u>any</u> operation other than {@link
+     * #normalize()} may produce undefined results. The mantissa of zero and
+     * of an infinite value is <code>0x0000000000000000L</code>.
+     *
+     * <p>The mantissa of a NaN is any nonzero value. However, it is
+     * recommended to use the value <code>0x4000000000000000L</code>. Any
+     * other values are reserved for future extensions.
+     */
+    public long mantissa;
+    /**
+     * The exponent of a <code>Real</code>. <i>To maintain numbers in a
+     * normalized state and to preserve the integrity of abnormal numbers, it
+     * is discouraged to modify the inner representation of a
+     * <code>Real</code> directly.</i>
+     *
+     * <p>The exponent of a finite <code>Real</code> must be between
+     * <code>0x00000000</code> and <code>0x7fffffff</code>. The exponent of
+     * zero <code>0x00000000</code>.
+     *
+     * <p>The exponent of an infinite value and of a NaN is any negative
+     * value. However, it is recommended to use the value
+     * <code>0x80000000</code>. Any other values are reserved for future
+     * extensions.
+     */
+    public int exponent;
+    /**
+     * The sign of a <code>Real</code>. <i>To maintain numbers in a normalized
+     * state and to preserve the integrity of abnormal numbers, it is
+     * discouraged to modify the inner representation of a <code>Real</code>
+     * directly.</i>
+     *
+     * <p>The sign of a finite, zero or infinite <code>Real</code> is 0 for
+     * positive values and 1 for negative values. Any other values may produce
+     * undefined results.
+     *
+     * <p>The sign of a NaN is ignored. However, it is recommended to use the
+     * value <code>0</code>. Any other values are reserved for future
+     * extensions.
+     */
+    public byte sign;
+    /**
+     * Set to <code>false</code> during numerical algorithms to favor accuracy
+     * over prettyness. This flag is initially set to <code>true</code>.
+     *
+     * <p>The flag controls the operation of a subtraction of two
+     * almost-identical numbers that differ only in the last three bits of the
+     * mantissa. With this flag enabled, the result of such a subtraction is
+     * rounded down to zero. Probabilistically, this is the correct course of
+     * action in an overwhelmingly large percentage of calculations.
+     * However, certain numerical algorithms such as differentiation depend
+     * on keeping maximum accuracy during subtraction.
+     *
+     * <p>Note, that because of <code>magicRounding</code>,
+     * <code>a.sub(b)</code> may produce zero even though
+     * <code>a.equalTo(b)</code> returns <code>false</code>. This must be
+     * considered e.g. when trying to avoid division by zero.
+     */
+    public static boolean magicRounding = true;
+    /**
+     * A <code>Real</code> constant holding the exact value of 0.  Among other
+     * uses, this value is used as a result when a positive underflow occurs.
+     */
+    public static final Real ZERO = new Real(0,0x00000000,0x0000000000000000L);
+    /**
+     * A <code>Real</code> constant holding the exact value of 1.
+     */
+    public static final Real ONE = new Real(0,0x40000000,0x4000000000000000L);
+    /**
+     * A <code>Real</code> constant holding the exact value of 2.
+     */
+    public static final Real TWO = new Real(0,0x40000001,0x4000000000000000L);
+    /**
+     * A <code>Real</code> constant holding the exact value of 3.
+     */
+    public static final Real THREE= new Real(0,0x40000001,0x6000000000000000L);
+    /**
+     * A <code>Real</code> constant holding the exact value of 5.
+     */
+    public static final Real FIVE = new Real(0,0x40000002,0x5000000000000000L);
+    /**
+     * A <code>Real</code> constant holding the exact value of 10.
+     */
+    public static final Real TEN = new Real(0,0x40000003,0x5000000000000000L);
+    /**
+     * A <code>Real</code> constant holding the exact value of 100.
+     */
+    public static final Real HUNDRED=new Real(0,0x40000006,0x6400000000000000L);
+    /**
+     * A <code>Real</code> constant holding the exact value of 1/2.
+     */
+    public static final Real HALF = new Real(0,0x3fffffff,0x4000000000000000L);
+    /**
+     * A <code>Real</code> constant that is closer than any other to 1/3.
+     */
+    public static final Real THIRD= new Real(0,0x3ffffffe,0x5555555555555555L);
+    /**
+     * A <code>Real</code> constant that is closer than any other to 1/10.
+     */
+    public static final Real TENTH= new Real(0,0x3ffffffc,0x6666666666666666L);
+    /**
+     * A <code>Real</code> constant that is closer than any other to 1/100.
+     */
+    public static final Real PERCENT=new Real(0,0x3ffffff9,0x51eb851eb851eb85L);
+    /**
+     * A <code>Real</code> constant that is closer than any other to the
+     * square root of 2.
+     */
+    public static final Real SQRT2= new Real(0,0x40000000,0x5a827999fcef3242L);
+    /**
+     * A <code>Real</code> constant that is closer than any other to the
+     * square root of 1/2.
+     */
+    public static final Real SQRT1_2=new Real(0,0x3fffffff,0x5a827999fcef3242L);
+    /**
+     * A <code>Real</code> constant that is closer than any other to 2&pi;.
+     */
+    public static final Real PI2 = new Real(0,0x40000002,0x6487ed5110b4611aL);
+    /**
+     * A <code>Real</code> constant that is closer than any other to &pi;, the
+     * ratio of the circumference of a circle to its diameter.
+     */
+    public static final Real PI = new Real(0,0x40000001,0x6487ed5110b4611aL);
+    /**
+     * A <code>Real</code> constant that is closer than any other to &pi;/2.
+     */
+    public static final Real PI_2 = new Real(0,0x40000000,0x6487ed5110b4611aL);
+    /**
+     * A <code>Real</code> constant that is closer than any other to &pi;/4.
+     */
+    public static final Real PI_4 = new Real(0,0x3fffffff,0x6487ed5110b4611aL);
+    /**
+     * A <code>Real</code> constant that is closer than any other to &pi;/8.
+     */
+    public static final Real PI_8 = new Real(0,0x3ffffffe,0x6487ed5110b4611aL);
+    /**
+     * A <code>Real</code> constant that is closer than any other to <i>e</i>,
+     * the base of the natural logarithms.
+     */
+    public static final Real E = new Real(0,0x40000001,0x56fc2a2c515da54dL);
+    /**
+     * A <code>Real</code> constant that is closer than any other to the
+     * natural logarithm of 2.
+     */
+    public static final Real LN2 = new Real(0,0x3fffffff,0x58b90bfbe8e7bcd6L);
+    /**
+     * A <code>Real</code> constant that is closer than any other to the
+     * natural logarithm of 10.
+     */
+    public static final Real LN10 = new Real(0,0x40000001,0x49aec6eed554560bL);
+    /**
+     * A <code>Real</code> constant that is closer than any other to the
+     * base-2 logarithm of <i>e</i>.
+     */
+    public static final Real LOG2E= new Real(0,0x40000000,0x5c551d94ae0bf85eL);
+    /**
+     * A <code>Real</code> constant that is closer than any other to the
+     * base-10 logarithm of <i>e</i>.
+     */
+    public static final Real LOG10E=new Real(0,0x3ffffffe,0x6f2dec549b9438cbL);
+    /**
+     * A <code>Real</code> constant holding the maximum non-infinite positive
+     * number = 4.197e323228496.
+     */
+    public static final Real MAX = new Real(0,0x7fffffff,0x7fffffffffffffffL);
+    /**
+     * A <code>Real</code> constant holding the minimum non-zero positive
+     * number = 2.383e-323228497.
+     */
+    public static final Real MIN = new Real(0,0x00000000,0x4000000000000000L);
+    /**
+     * A <code>Real</code> constant holding the value of NaN (not-a-number).
+     * This value is always used as a result to signal an invalid operation.
+     */
+    public static final Real NAN = new Real(0,0x80000000,0x4000000000000000L);
+    /**
+     * A <code>Real</code> constant holding the value of positive infinity.
+     * This value is always used as a result to signal a positive overflow.
+     */
+    public static final Real INF = new Real(0,0x80000000,0x0000000000000000L);
+    /**
+     * A <code>Real</code> constant holding the value of negative infinity.
+     * This value is always used as a result to signal a negative overflow.
+     */
+    public static final Real INF_N= new Real(1,0x80000000,0x0000000000000000L);
+    /**
+     * A <code>Real</code> constant holding the value of negative zero. This
+     * value is used as a result e.g. when a negative underflow occurs.
+     */
+    public static final Real ZERO_N=new Real(1,0x00000000,0x0000000000000000L);
+    /**
+     * A <code>Real</code> constant holding the exact value of -1.
+     */
+    public static final Real ONE_N= new Real(1,0x40000000,0x4000000000000000L);
+    private static final int clz_magic = 0x7c4acdd;
+    private static final byte[] clz_tab =
+    { 31,22,30,21,18,10,29, 2,20,17,15,13, 9, 6,28, 1,
+      23,19,11, 3,16,14, 7,24,12, 4, 8,25, 5,26,27, 0 };
+    /**
+     * Creates a new <code>Real</code> with a value of zero.
+     */
+    public Real() {
+    }
+    /**
+     * Creates a new <code>Real</code>, assigning the value of another
+     * <code>Real</code>. See {@link #assign(Real)}.
+     *
+     * @param a the <code>Real</code> to assign.
+     */
+    public Real(Real a) {
+        { this.mantissa = a.mantissa; this.exponent = a.exponent; this.sign = a.sign; };
+    }
+    /**
+     * Creates a new <code>Real</code>, assigning the value of an integer. See
+     * {@link #assign(int)}.
+     *
+     * @param a the <code>int</code> to assign.
+     */
+    public Real(int a) {
+        assign(a);
+    }
+    /**
+     * Creates a new <code>Real</code>, assigning the value of a long
+     * integer. See {@link #assign(long)}.
+     *
+     * @param a the <code>long</code> to assign.
+     */
+    public Real(long a) {
+        assign(a);
+    }
+    /**
+     * Creates a new <code>Real</code>, assigning the value encoded in a
+     * <code>String</code> using base-10. See {@link #assign(String)}.
+     *
+     * @param a the <code>String</code> to assign.
+     */
+    public Real(String a) {
+        assign(a,10);
+    }
+    /**
+     * Creates a new <code>Real</code>, assigning the value encoded in a
+     * <code>String</code> using the specified number base. See {@link
+     * #assign(String,int)}.
+     *
+     * @param a the <code>String</code> to assign.
+     * @param base the number base of <code>a</code>. Valid base values are 2,
+     *     8, 10 and 16.
+     */
+    public Real(String a, int base) {
+        assign(a,base);
+    }
+    /**
+     * Creates a new <code>Real</code>, assigning a value by directly setting
+     * the fields of the internal representation. The arguments must represent
+     * a valid, normalized <code>Real</code>. This is the fastest way of
+     * creating a constant value.  See {@link #assign(int,int,long)}.
+     *
+     * @param s {@link #sign} bit, 0 for positive sign, 1 for negative sign
+     * @param e {@link #exponent}
+     * @param m {@link #mantissa}
+     */
+    public Real(int s, int e, long m) {
+        { this.sign=(byte)s; this.exponent=e; this.mantissa=m; };
+    }
+    /**
+     * Creates a new <code>Real</code>, assigning the value previously encoded
+     * into twelve consecutive bytes in a byte array using {@link
+     * #toBytes(byte[],int) toBytes}. See {@link #assign(byte[],int)}.
+     *
+     * @param data byte array to decode into this <code>Real</code>.
+     * @param offset offset to start encoding from. The bytes
+     *     <code>data[offset]...data[offset+11]</code> will be
+     *     read.
+     */
+    public Real(byte [] data, int offset) {
+        assign(data,offset);
+    }
+    /**
+     * Assigns this <code>Real</code> the value of another <code>Real</code>.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = a;</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.3
+     * </td></tr></table>
+     *
+     * @param a the <code>Real</code> to assign.
+     */
+    public void assign(Real a) {
+        if (a == null) {
+            makeZero();
+            return;
+        }
+        sign = a.sign;
+        exponent = a.exponent;
+        mantissa = a.mantissa;
+    }
+    /**
+     * Assigns this <code>Real</code> the value of an integer.
+     * All integer values can be represented without loss of accuracy.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = (double)a;</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.6
+     * </td></tr></table>
+     *
+     * @param a the <code>int</code> to assign.
+     */
+    public void assign(int a) {
+        if (a==0) {
+            makeZero();
+            return;
+        }
+        sign = 0;
+        if (a<0) {
+            sign = 1;
+            a = -a; // Also works for 0x80000000
+        }
+        // Normalize int
+        int t=a; t|=t>>1; t|=t>>2; t|=t>>4; t|=t>>8; t|=t>>16;
+        t = clz_tab[(t*clz_magic)>>>27]-1;
+        exponent = 0x4000001E-t;
+        mantissa = ((long)a)<<(32+t);
+    }
+    /**
+     * Assigns this <code>Real</code> the value of a signed long integer.
+     * All long values can be represented without loss of accuracy.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = (double)a;</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.0
+     * </td></tr></table>
+     *
+     * @param a the <code>long</code> to assign.
+     */
+    public void assign(long a) {
+        sign = 0;
+        if (a<0) {
+            sign = 1;
+            a = -a; // Also works for 0x8000000000000000
+        }
+        exponent = 0x4000003E;
+        mantissa = a;
+        normalize();
+    }
+    /**
+     * Assigns this <code>Real</code> a value encoded in a <code>String</code>
+     * using base-10, as specified in {@link #assign(String,int)}.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *    <code>this = Double.{@link Double#valueOf(String) valueOf}(a);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     ½-1 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     80
+     * </td></tr></table>
+     *
+     * @param a the <code>String</code> to assign.
+     */
+    public void assign(String a) {
+        assign(a,10);
+    }
+    /**
+     * Assigns this <code>Real</code> a value encoded in a <code>String</code>
+     * using the specified number base. The string is parsed as follows:
+     *
+     * <ul>
+     *   <li>If the string is <code>null</code> or an empty string, zero is
+     *       assigned.
+     *   <li>Leading spaces are ignored.
+     *   <li>An optional sign, '+', '-' or '/', where '/' precedes a negative
+     *       two's-complement number, reading: "an infinite number of 1-bits
+     *       preceding the number".
+     *   <li>Optional digits preceding the radix, in the specified base.
+     *       <ul>
+     *           <li>In base-2, allowed digits are '01'.
+     *           <li>In base-8, allowed digits are '01234567'.
+     *           <li>In base-10, allowed digits are '0123456789'.
+     *           <li>In base-16, allowed digits are '0123456789ABCDEF'.
+     </ul>
+     *   <li>An optional radix character, '.' or ','.
+     *   <li>Optional digits following the radix.
+     *   <li>The following spaces are ignored.
+     *   <li>An optional exponent indicator, 'e'. If not base-16, or after a
+     *       space, 'E' is also accepted.
+     *   <li>An optional sign, '+' or '-'.
+     *   <li>Optional exponent digits <i><b>in base-10</b></i>.
+     * </ul>
+     *
+     * <p><i>Valid examples:</i><br>
+     * &nbsp;&nbsp;&nbsp;&nbsp;base-2:  <code>"-.110010101e+5"</code><br>
+     * &nbsp;&nbsp;&nbsp;&nbsp;base-8:  <code>"+5462E-99"</code><br>
+     * &nbsp;&nbsp;&nbsp;&nbsp;base-10: <code>"&nbsp;&nbsp;3,1415927"</code><br>
+     * &nbsp;&nbsp;&nbsp;&nbsp;base-16: <code>"/FFF800C.CCCE e64"</code>
+     *
+     * <p>The number is parsed until the end of the string or an unknown
+     * character is encountered, then silently returns even if the whole
+     * string has not been parsed. Please note that specifying an
+     * excessive number of digits in base-10 may in fact decrease the
+     * accuracy of the result because of the extra multiplications performed.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td>
+     * <td colspan="2">
+     *     <code>this = Double.{@link Double#valueOf(String) valueOf}(a);
+     *           // Works only for base-10</code>
+     * </td></tr><tr><td valign="top" rowspan="2"><i>
+     * Approximate&nbsp;error&nbsp;bound:</i>
+     * </td><td width="1%">base-10</td><td>
+     *     ½-1 ULPs
+     * </td></tr><tr><td>2/8/16</td><td>
+     *     ½ ULPs
+     * </td></tr><tr><td valign="top" rowspan="4"><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;</i>
+     * </td><td width="1%">base-2</td><td>
+     *     54
+     * </td></tr><tr><td>base-8</td><td>
+     *     60
+     * </td></tr><tr><td>base-10</td><td>
+     *     80
+     * </td></tr><tr><td>base-16&nbsp;&nbsp;</td><td>
+     *     60
+     * </td></tr></table>
+     *
+     * @param a the <code>String</code> to assign.
+     * @param base the number base of <code>a</code>. Valid base values are
+     *     2, 8, 10 and 16.
+     */
+    public void assign(String a, int base) {
+        if (a==null || a.length()==0) {
+            assign(ZERO);
+            return;
+        }
+        atof(a,base);
+    }
+    /**
+     * Assigns this <code>Real</code> a value by directly setting the fields
+     * of the internal representation. The arguments must represent a valid,
+     * normalized <code>Real</code>. This is the fastest way of assigning a
+     * constant value.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = (1-2*s) * m *
+     *           Math.{@link Math#pow(double,double)
+     *           pow}(2.0,e-0x400000e3);</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.3
+     * </td></tr></table>
+     *
+     * @param s {@link #sign} bit, 0 for positive sign, 1 for negative sign
+     * @param e {@link #exponent}
+     * @param m {@link #mantissa}
+     */
+    public void assign(int s, int e, long m) {
+        sign = (byte)s;
+        exponent = e;
+        mantissa = m;
+    }
+    /**
+     * Assigns this <code>Real</code> a value previously encoded into into
+     * twelve consecutive bytes in a byte array using {@link
+     * #toBytes(byte[],int) toBytes}.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.2
+     * </td></tr></table>
+     *
+     * @param data byte array to decode into this <code>Real</code>.
+     * @param offset offset to start encoding from. The bytes
+     *     <code>data[offset]...data[offset+11]</code> will be
+     *     read.
+     */
+    public void assign(byte [] data, int offset) {
+        sign = (byte)((data[offset+4]>>7)&1);
+        exponent = (((data[offset ]&0xff)<<24)+
+                    ((data[offset +1]&0xff)<<16)+
+                    ((data[offset +2]&0xff)<<8)+
+                    ((data[offset +3]&0xff)));
+        mantissa = (((long)(data[offset+ 4]&0x7f)<<56)+
+                    ((long)(data[offset+ 5]&0xff)<<48)+
+                    ((long)(data[offset+ 6]&0xff)<<40)+
+                    ((long)(data[offset+ 7]&0xff)<<32)+
+                    ((long)(data[offset+ 8]&0xff)<<24)+
+                    ((long)(data[offset+ 9]&0xff)<<16)+
+                    ((long)(data[offset+10]&0xff)<< 8)+
+                    ( (data[offset+11]&0xff)));
+    }
+    /**
+     * Encodes an accurate representation of this <code>Real</code> value into
+     * twelve consecutive bytes in a byte array. Can be decoded using {@link
+     * #assign(byte[],int)}.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.2
+     * </td></tr></table>
+     *
+     * @param data byte array to save this <code>Real</code> in.
+     * @param offset offset to start encoding to. The bytes
+     *     <code>data[offset]...data[offset+11]</code> will be
+     *     written.
+     */
+    public void toBytes(byte [] data, int offset) {
+        data[offset ] = (byte)(exponent>>24);
+        data[offset+ 1] = (byte)(exponent>>16);
+        data[offset+ 2] = (byte)(exponent>>8);
+        data[offset+ 3] = (byte)(exponent);
+        data[offset+ 4] = (byte)((sign<<7)+(mantissa>>56));
+        data[offset+ 5] = (byte)(mantissa>>48);
+        data[offset+ 6] = (byte)(mantissa>>40);
+        data[offset+ 7] = (byte)(mantissa>>32);
+        data[offset+ 8] = (byte)(mantissa>>24);
+        data[offset+ 9] = (byte)(mantissa>>16);
+        data[offset+10] = (byte)(mantissa>>8);
+        data[offset+11] = (byte)(mantissa);
+    }
+    /**
+     * Assigns this <code>Real</code> the value corresponding to a given bit
+     * representation. The argument is considered to be a representation of a
+     * floating-point value according to the IEEE 754 floating-point "single
+     * format" bit layout.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>float</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Float.{@link Float#intBitsToFloat(int)
+     *           intBitsToFloat}(bits);</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.6
+     * </td></tr></table>
+     *
+     * @param bits a <code>float</code> value encoded in an <code>int</code>.
+     */
+    public void assignFloatBits(int bits) {
+        sign = (byte)(bits>>>31);
+        exponent = (bits>>23)&0xff;
+        mantissa = (long)(bits&0x007fffff)<<39;
+        if (exponent == 0 && mantissa == 0)
+            return; // Valid zero
+        if (exponent == 0 && mantissa != 0) {
+            // Degenerate small float
+            exponent = 0x40000000-126;
+            normalize();
+            return;
+        }
+        if (exponent <= 254) {
+            // Normal IEEE 754 float
+            exponent += 0x40000000-127;
+            mantissa |= 1L<<62;
+            return;
+        }
+        if (mantissa == 0)
+            makeInfinity(sign);
+        else
+            makeNan();
+    }
+    /**
+     * Assigns this <code>Real</code> the value corresponding to a given bit
+     * representation. The argument is considered to be a representation of a
+     * floating-point value according to the IEEE 754 floating-point "double
+     * format" bit layout.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Double.{@link Double#longBitsToDouble(long)
+     *           longBitsToDouble}(bits);</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.6
+     * </td></tr></table>
+     *
+     * @param bits a <code>double</code> value encoded in a <code>long</code>.
+     */
+    public void assignDoubleBits(long bits) {
+        sign = (byte)((bits>>63)&1);
+        exponent = (int)((bits>>52)&0x7ff);
+        mantissa = (bits&0x000fffffffffffffL)<<10;
+        if (exponent == 0 && mantissa == 0)
+            return; // Valid zero
+        if (exponent == 0 && mantissa != 0) {
+            // Degenerate small float
+            exponent = 0x40000000-1022;
+            normalize();
+            return;
+        }
+        if (exponent <= 2046) {
+            // Normal IEEE 754 float
+            exponent += 0x40000000-1023;
+            mantissa |= 1L<<62;
+            return;
+        }
+        if (mantissa == 0)
+            makeInfinity(sign);
+        else
+            makeNan();
+    }
+    /**
+     * Returns a representation of this <code>Real</code> according to the
+     * IEEE 754 floating-point "single format" bit layout.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>float</code><i>&nbsp;code:</i></td><td>
+     *     <code>Float.{@link Float#floatToIntBits(float)
+     *           floatToIntBits}(this)</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.7
+     * </td></tr></table>
+     *
+     * @return the bits that represent the floating-point number.
+     */
+    public int toFloatBits() {
+        if ((this.exponent < 0 && this.mantissa != 0))
+            return 0x7fffffff; // nan
+        int e = exponent-0x40000000+127;
+        long m = mantissa;
+        // Round properly!
+        m += 1L<<38;
+        if (m<0) {
+            m >>>= 1;
+            e++;
+            if (exponent < 0) // Overflow
+                return (sign<<31)|0x7f800000; // inf
+        }
+        if ((this.exponent < 0 && this.mantissa == 0) || e > 254)
+            return (sign<<31)|0x7f800000; // inf
+        if ((this.exponent == 0 && this.mantissa == 0) || e < -22)
+            return (sign<<31); // zero
+        if (e <= 0) // Degenerate small float
+            return (sign<<31)|((int)(m>>>(40-e))&0x007fffff);
+        // Normal IEEE 754 float
+        return (sign<<31)|(e<<23)|((int)(m>>>39)&0x007fffff);
+    }
+    /**
+     * Returns a representation of this <code>Real</code> according to the
+     * IEEE 754 floating-point "double format" bit layout.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>Double.{@link Double#doubleToLongBits(double)
+     *           doubleToLongBits}(this)</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.7
+     * </td></tr></table>
+     *
+     * @return the bits that represent the floating-point number.
+     */
+    public long toDoubleBits() {
+        if ((this.exponent < 0 && this.mantissa != 0))
+            return 0x7fffffffffffffffL; // nan
+        int e = exponent-0x40000000+1023;
+        long m = mantissa;
+        // Round properly!
+        m += 1L<<9;
+        if (m<0) {
+            m >>>= 1;
+            e++;
+            if (exponent < 0)
+                return ((long)sign<<63)|0x7ff0000000000000L; // inf
+        }
+        if ((this.exponent < 0 && this.mantissa == 0) || e > 2046)
+            return ((long)sign<<63)|0x7ff0000000000000L; // inf
+        if ((this.exponent == 0 && this.mantissa == 0) || e < -51)
+            return ((long)sign<<63); // zero
+        if (e <= 0) // Degenerate small double
+            return ((long)sign<<63)|((m>>>(11-e))&0x000fffffffffffffL);
+        // Normal IEEE 754 double
+        return ((long)sign<<63)|((long)e<<52)|((m>>>10)&0x000fffffffffffffL);
+    }
+    /**
+     * Makes this <code>Real</code> the value of positive zero.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = 0;</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.2
+     * </td></tr></table>
+     */
+    public void makeZero() {
+        sign = 0;
+        mantissa = 0;
+        exponent = 0;
+    }
+    /**
+     * Makes this <code>Real</code> the value of zero with the specified sign.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = 0.0 * (1-2*s);</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.2
+     * </td></tr></table>
+     *
+     * @param s sign bit, 0 to make a positive zero, 1 to make a negative zero
+     */
+    public void makeZero(int s) {
+        sign = (byte)s;
+        mantissa = 0;
+        exponent = 0;
+    }
+    /**
+     * Makes this <code>Real</code> the value of infinity with the specified
+     * sign.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *   <code>this = Double.{@link Double#POSITIVE_INFINITY POSITIVE_INFINITY}
+     *           * (1-2*s);</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.3
+     * </td></tr></table>
+     *
+     * @param s sign bit, 0 to make positive infinity, 1 to make negative
+     * infinity
+     */
+    public void makeInfinity(int s) {
+        sign = (byte)s;
+        mantissa = 0;
+        exponent = 0x80000000;
+    }
+    /**
+     * Makes this <code>Real</code> the value of Not-a-Number (NaN).
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Double.{@link Double#NaN NaN};</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.3
+     * </td></tr></table>
+     */
+    public void makeNan() {
+        sign = 0;
+        mantissa = 0x4000000000000000L;
+        exponent = 0x80000000;
+    }
+    /**
+     * Returns <code>true</code> if the value of this <code>Real</code> is
+     * zero, <code>false</code> otherwise.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>(this == 0)</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.3
+     * </td></tr></table>
+     *
+     * @return <code>true</code> if the value represented by this object is
+     *     zero, <code>false</code> otherwise.
+     */
+    public boolean isZero() {
+        return (exponent == 0 && mantissa == 0);
+    }
+    /**
+     * Returns <code>true</code> if the value of this <code>Real</code> is
+     * infinite, <code>false</code> otherwise.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *   <code>Double.{@link Double#isInfinite(double) isInfinite}(this)</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.3
+     * </td></tr></table>
+     *
+     * @return <code>true</code> if the value represented by this object is
+     *     infinite, <code>false</code> if it is finite or NaN.
+     */
+    public boolean isInfinity() {
+        return (exponent < 0 && mantissa == 0);
+    }
+    /**
+     * Returns <code>true</code> if the value of this <code>Real</code> is
+     * Not-a-Number (NaN), <code>false</code> otherwise.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>Double.{@link Double#isNaN(double) isNaN}(this)</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.3
+     * </td></tr></table>
+     *
+     * @return <code>true</code> if the value represented by this object is
+     *     NaN, <code>false</code> otherwise.
+     */
+    public boolean isNan() {
+        return (exponent < 0 && mantissa != 0);
+    }
+    /**
+     * Returns <code>true</code> if the value of this <code>Real</code> is
+     * finite, <code>false</code> otherwise.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>(!Double.{@link Double#isNaN(double) isNaN}(this) &&
+     *            !Double.{@link Double#isInfinite(double)
+     *            isInfinite}(this))</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.3
+     * </td></tr></table>
+     *
+     * @return <code>true</code> if the value represented by this object is
+     *     finite, <code>false</code> if it is infinite or NaN.
+     */
+    public boolean isFinite() {
+        // That is, non-infinite and non-nan
+        return (exponent >= 0);
+    }
+    /**
+     * Returns <code>true</code> if the value of this <code>Real</code> is
+     * finite and nonzero, <code>false</code> otherwise.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *  <code>(!Double.{@link Double#isNaN(double) isNaN}(this) &&
+     *         !Double.{@link Double#isInfinite(double) isInfinite}(this) &&
+     *         (this!=0))</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.3
+     * </td></tr></table>
+     *
+     * @return <code>true</code> if the value represented by this object is
+     *     finite and nonzero, <code>false</code> if it is infinite, NaN or
+     *     zero.
+     */
+    public boolean isFiniteNonZero() {
+        // That is, non-infinite and non-nan and non-zero
+        return (exponent >= 0 && mantissa != 0);
+    }
+    /**
+     * Returns <code>true</code> if the value of this <code>Real</code> is
+     * negative, <code>false</code> otherwise.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>(this < 0)</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.3
+     * </td></tr></table>
+     *
+     * @return <code>true</code> if the value represented by this object
+     *     is negative, <code>false</code> if it is positive or NaN.
+     */
+    public boolean isNegative() {
+        return sign!=0;
+    }
+    /**
+     * Calculates the absolute value.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#abs(double) abs}(this);</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.2
+     * </td></tr></table>
+     */
+    public void abs() {
+        sign = 0;
+    }
+    /**
+     * Negates this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = -this;</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.2
+     * </td></tr></table>
+     */
+    public void neg() {
+        if (!(this.exponent < 0 && this.mantissa != 0))
+            sign ^= 1;
+    }
+    /**
+     * Copies the sign from <code>a</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#abs(double)
+     *           abs}(this)*Math.{@link Math#signum(double) signum}(a);</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.2
+     * </td></tr></table>
+     *
+     * @param a the <code>Real</code> to copy the sign from.
+     */
+    public void copysign(Real a) {
+        if ((this.exponent < 0 && this.mantissa != 0) || (a.exponent < 0 && a.mantissa != 0)) {
+            makeNan();
+            return;
+        }
+        sign = a.sign;
+    }
+    /**
+     * Readjusts the mantissa of this <code>Real</code>. The exponent is
+     * adjusted accordingly. This is necessary when the mantissa has been
+     * {@link #mantissa modified directly} for some purpose and may be
+     * denormalized. The normalized mantissa of a finite <code>Real</code>
+     * must have bit 63 cleared and bit 62 set. Using a denormalized
+     * <code>Real</code> in <u>any</u> other operation may produce undefined
+     * results.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Error&nbsp;bound:</i></td><td>
+     *     ½ ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.7
+     * </td></tr></table>
+     */
+    public void normalize() {
+        if ((this.exponent >= 0)) {
+            if (mantissa > 0)
+            {
+                int clz = 0;
+                int t = (int)(mantissa>>>32);
+                if (t == 0) { clz = 32; t = (int)mantissa; }
+                t|=t>>1; t|=t>>2; t|=t>>4; t|=t>>8; t|=t>>16;
+                clz += clz_tab[(t*clz_magic)>>>27]-1;
+                mantissa <<= clz;
+                exponent -= clz;
+                if (exponent < 0) // Underflow
+                    makeZero(sign);
+            }
+            else if (mantissa < 0)
+            {
+                mantissa = (mantissa+1)>>>1;
+                exponent ++;
+                if (mantissa == 0) { // Ooops, it was 0xffffffffffffffffL
+                    mantissa = 0x4000000000000000L;
+                    exponent ++;
+                }
+                if (exponent < 0) // Overflow
+                    makeInfinity(sign);
+            }
+            else // mantissa == 0
+            {
+                exponent = 0;
+            }
+        }
+    }
+    /**
+     * Readjusts the mantissa of a <code>Real</code> with extended
+     * precision. The exponent is adjusted accordingly. This is necessary when
+     * the mantissa has been {@link #mantissa modified directly} for some
+     * purpose and may be denormalized. The normalized mantissa of a finite
+     * <code>Real</code> must have bit 63 cleared and bit 62 set. Using a
+     * denormalized <code>Real</code> in <u>any</u> other operation may
+     * produce undefined results.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     2<sup>-64</sup> ULPs (i.e. of a normal precision <code>Real</code>)
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.7
+     * </td></tr></table>
+     *
+     * @param extra the extra 64 bits of mantissa of this extended precision
+     *     <code>Real</code>.
+     * @return the extra 64 bits of mantissa of the resulting extended
+     *     precision <code>Real</code>.
+     */
+    public long normalize128(long extra) {
+        if (!(this.exponent >= 0))
+            return 0;
+        if (mantissa == 0) {
+            if (extra == 0) {
+                exponent = 0;
+                return 0;
+            }
+            mantissa = extra;
+            extra = 0;
+            exponent -= 64;
+            if (exponent < 0) { // Underflow
+                makeZero(sign);
+                return 0;
+            }
+        }
+        if (mantissa < 0) {
+            extra = (mantissa<<63)+(extra>>>1);
+            mantissa >>>= 1;
+            exponent ++;
+            if (exponent < 0) { // Overflow
+                makeInfinity(sign);
+                return 0;
+            }
+            return extra;
+        }
+        int clz = 0;
+        int t = (int)(mantissa>>>32);
+        if (t == 0) { clz = 32; t = (int)mantissa; }
+        t|=t>>1; t|=t>>2; t|=t>>4; t|=t>>8; t|=t>>16;
+        clz += clz_tab[(t*clz_magic)>>>27]-1;
+        if (clz == 0)
+            return extra;
+        mantissa = (mantissa<<clz)+(extra>>>(64-clz));
+        extra <<= clz;
+        exponent -= clz;
+        if (exponent < 0) { // Underflow
+            makeZero(sign);
+            return 0;
+        }
+        return extra;
+    }
+    /**
+     * Rounds an extended precision <code>Real</code> to the nearest
+     * <code>Real</code> of normal precision. Replaces the contents of this
+     * <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Error&nbsp;bound:</i></td><td>
+     *     ½ ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.0
+     * </td></tr></table>
+     *
+     * @param extra the extra 64 bits of mantissa of this extended precision
+     *     <code>Real</code>.
+     */
+    public void roundFrom128(long extra) {
+        mantissa += (extra>>63)&1;
+        normalize();
+    }
+    /**
+     * Returns <code>true</code> if this Java object is the same
+     * object as <code>a</code>. Since a <code>Real</code> should be
+     * thought of as a "register holding a number", this method compares the
+     * object references, not the contents of the two objects.
+     * This is very different from {@link #equalTo(Real)}.
+     *
+     * @param a the object to compare to this.
+     * @return <code>true</code> if this object is the same as <code>a</code>.
+     */
+    public boolean equals(Object a) {
+        return this==a;
+    }
+    private int compare(Real a) {
+        // Compare of normal floats, zeros, but not nan or equal-signed inf
+        if ((this.exponent == 0 && this.mantissa == 0) && (a.exponent == 0 && a.mantissa == 0))
+            return 0;
+        if (sign != a.sign)
+            return a.sign-sign;
+        int s = (this.sign==0) ? 1 : -1;
+        if ((this.exponent < 0 && this.mantissa == 0))
+            return s;
+        if ((a.exponent < 0 && a.mantissa == 0))
+            return -s;
+        if (exponent != a.exponent)
+            return exponent<a.exponent ? -s : s;
+        if (mantissa != a.mantissa)
+            return mantissa<a.mantissa ? -s : s;
+        return 0;
+    }
+    private boolean invalidCompare(Real a) {
+        return ((this.exponent < 0 && this.mantissa != 0) || (a.exponent < 0 && a.mantissa != 0) ||
+                ((this.exponent < 0 && this.mantissa == 0) && (a.exponent < 0 && a.mantissa == 0) && sign == a.sign));
+    }
+    /**
+     * Returns <code>true</code> if this <code>Real</code> is equal to
+     * <code>a</code>.
+     * If the numbers are incomparable, i.e. the values are infinities of
+     * the same sign or any of them is NaN, <code>false</code> is always
+     * returned. This method must not be confused with {@link #equals(Object)}.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>(this == a)</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.0
+     * </td></tr></table>
+     *
+     * @param a the <code>Real</code> to compare to this.
+     * @return <code>true</code> if the value represented by this object is
+     *     equal to the value represented by <code>a</code>. <code>false</code>
+     *     otherwise, or if the numbers are incomparable.
+     */
+    public boolean equalTo(Real a) {
+        if (invalidCompare(a))
+            return false;
+        return compare(a) == 0;
+    }
+    /**
+     * Returns <code>true</code> if this <code>Real</code> is equal to
+     * the integer <code>a</code>.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>(this == a)</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.7
+     * </td></tr></table>
+     *
+     * @param a the <code>int</code> to compare to this.
+     * @return <code>true</code> if the value represented by this object is
+     *     equal to the integer <code>a</code>. <code>false</code>
+     *     otherwise.
+     */
+    public boolean equalTo(int a) {
+        tmp0.assign(a);
+        return equalTo(tmp0);
+    }
+    /**
+     * Returns <code>true</code> if this <code>Real</code> is not equal to
+     * <code>a</code>.
+     * If the numbers are incomparable, i.e. the values are infinities of
+     * the same sign or any of them is NaN, <code>false</code> is always
+     * returned.
+     * This distinguishes <code>notEqualTo(a)</code> from the expression
+     * <code>!equalTo(a)</code>.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>(this != a)</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.0
+     * </td></tr></table>
+     *
+     * @param a the <code>Real</code> to compare to this.
+     * @return <code>true</code> if the value represented by this object is not
+     *     equal to the value represented by <code>a</code>. <code>false</code>
+     *     otherwise, or if the numbers are incomparable.
+     */
+    public boolean notEqualTo(Real a) {
+        if (invalidCompare(a))
+            return false;
+        return compare(a) != 0;
+    }
+    /**
+     * Returns <code>true</code> if this <code>Real</code> is not equal to
+     * the integer <code>a</code>.
+     * If this <code>Real</code> is NaN, <code>false</code> is always
+     * returned.
+     * This distinguishes <code>notEqualTo(a)</code> from the expression
+     * <code>!equalTo(a)</code>.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>(this != a)</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.7
+     * </td></tr></table>
+     *
+     * @param a the <code>int</code> to compare to this.
+     * @return <code>true</code> if the value represented by this object is not
+     *     equal to the integer <code>a</code>. <code>false</code>
+     *     otherwise, or if this <code>Real</code> is NaN.
+     */
+    public boolean notEqualTo(int a) {
+        tmp0.assign(a);
+        return notEqualTo(tmp0);
+    }
+    /**
+     * Returns <code>true</code> if this <code>Real</code> is less than
+     * <code>a</code>.
+     * If the numbers are incomparable, i.e. the values are infinities of
+     * the same sign or any of them is NaN, <code>false</code> is always
+     * returned.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>(this &lt; a)</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.0
+     * </td></tr></table>
+     *
+     * @param a the <code>Real</code> to compare to this.
+     * @return <code>true</code> if the value represented by this object is
+     *     less than the value represented by <code>a</code>.
+     *     <code>false</code> otherwise, or if the numbers are incomparable.
+     */
+    public boolean lessThan(Real a) {
+        if (invalidCompare(a))
+            return false;
+        return compare(a) < 0;
+    }
+    /**
+     * Returns <code>true</code> if this <code>Real</code> is less than
+     * the integer <code>a</code>.
+     * If this <code>Real</code> is NaN, <code>false</code> is always
+     * returned.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>(this &lt; a)</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.7
+     * </td></tr></table>
+     *
+     * @param a the <code>int</code> to compare to this.
+     * @return <code>true</code> if the value represented by this object is
+     *     less than the integer <code>a</code>. <code>false</code> otherwise,
+     *     or if this <code>Real</code> is NaN.
+     */
+    public boolean lessThan(int a) {
+        tmp0.assign(a);
+        return lessThan(tmp0);
+    }
+    /**
+     * Returns <code>true</code> if this <code>Real</code> is less than or
+     * equal to <code>a</code>.
+     * If the numbers are incomparable, i.e. the values are infinities of
+     * the same sign or any of them is NaN, <code>false</code> is always
+     * returned.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>(this &lt;= a)</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.0
+     * </td></tr></table>
+     *
+     * @param a the <code>Real</code> to compare to this.
+     * @return <code>true</code> if the value represented by this object is
+     *     less than or equal to the value represented by <code>a</code>.
+     *     <code>false</code> otherwise, or if the numbers are incomparable.
+     */
+    public boolean lessEqual(Real a) {
+        if (invalidCompare(a))
+            return false;
+        return compare(a) <= 0;
+    }
+    /**
+     * Returns <code>true</code> if this <code>Real</code> is less than or
+     * equal to the integer <code>a</code>.
+     * If this <code>Real</code> is NaN, <code>false</code> is always
+     * returned.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>(this &lt;= a)</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.7
+     * </td></tr></table>
+     *
+     * @param a the <code>int</code> to compare to this.
+     * @return <code>true</code> if the value represented by this object is
+     *     less than or equal to the integer <code>a</code>. <code>false</code>
+     *     otherwise, or if this <code>Real</code> is NaN.
+     */
+    public boolean lessEqual(int a) {
+        tmp0.assign(a);
+        return lessEqual(tmp0);
+    }
+    /**
+     * Returns <code>true</code> if this <code>Real</code> is greater than
+     * <code>a</code>.
+     * If the numbers are incomparable, i.e. the values are infinities of
+     * the same sign or any of them is NaN, <code>false</code> is always
+     * returned.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>(this &gt; a)</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.0
+     * </td></tr></table>
+     *
+     * @param a the <code>Real</code> to compare to this.
+     * @return <code>true</code> if the value represented by this object is
+     *     greater than the value represented by <code>a</code>.
+     *     <code>false</code> otherwise, or if the numbers are incomparable.
+     */
+    public boolean greaterThan(Real a) {
+        if (invalidCompare(a))
+            return false;
+        return compare(a) > 0;
+    }
+    /**
+     * Returns <code>true</code> if this <code>Real</code> is greater than
+     * the integer <code>a</code>.
+     * If this <code>Real</code> is NaN, <code>false</code> is always
+     * returned.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>(this &gt; a)</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.7
+     * </td></tr></table>
+     *
+     * @param a the <code>int</code> to compare to this.
+     * @return <code>true</code> if the value represented by this object is
+     *     greater than the integer <code>a</code>.
+     *     <code>false</code> otherwise, or if this <code>Real</code> is NaN.
+     */
+    public boolean greaterThan(int a) {
+        tmp0.assign(a);
+        return greaterThan(tmp0);
+    }
+    /**
+     * Returns <code>true</code> if this <code>Real</code> is greater than
+     * or equal to <code>a</code>.
+     * If the numbers are incomparable, i.e. the values are infinities of
+     * the same sign or any of them is NaN, <code>false</code> is always
+     * returned.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>(this &gt;= a)</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.0
+     * </td></tr></table>
+     *
+     * @param a the <code>Real</code> to compare to this.
+     * @return <code>true</code> if the value represented by this object is
+     *     greater than or equal to the value represented by <code>a</code>.
+     *     <code>false</code> otherwise, or if the numbers are incomparable.
+     */
+    public boolean greaterEqual(Real a) {
+        if (invalidCompare(a))
+            return false;
+        return compare(a) >= 0;
+    }
+    /**
+     * Returns <code>true</code> if this <code>Real</code> is greater than
+     * or equal to the integer <code>a</code>.
+     * If this <code>Real</code> is NaN, <code>false</code> is always
+     * returned.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>(this &gt;= a)</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.7
+     * </td></tr></table>
+     *
+     * @param a the <code>int</code> to compare to this.
+     * @return <code>true</code> if the value represented by this object is
+     *     greater than or equal to the integer <code>a</code>.
+     *     <code>false</code> otherwise, or if this <code>Real</code> is NaN.
+     */
+    public boolean greaterEqual(int a) {
+        tmp0.assign(a);
+        return greaterEqual(tmp0);
+    }
+    /**
+     * Returns <code>true</code> if the absolute value of this
+     * <code>Real</code> is less than the absolute value of
+     * <code>a</code>.
+     * If the numbers are incomparable, i.e. the values are both infinite
+     * or any of them is NaN, <code>false</code> is always returned.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>(Math.{@link Math#abs(double) abs}(this) &lt;
+     *           Math.{@link Math#abs(double) abs}(a))</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.5
+     * </td></tr></table>
+     *
+     * @param a the <code>Real</code> to compare to this.
+     * @return <code>true</code> if the absolute of the value represented by
+     *     this object is less  than the absolute of the value represented by
+     *     <code>a</code>.
+     *     <code>false</code> otherwise, or if the numbers are incomparable.
+     */
+    public boolean absLessThan(Real a) {
+        if ((this.exponent < 0 && this.mantissa != 0) || (a.exponent < 0 && a.mantissa != 0) || (this.exponent < 0 && this.mantissa == 0))
+            return false;
+        if ((a.exponent < 0 && a.mantissa == 0))
+            return true;
+        if (exponent != a.exponent)
+            return exponent<a.exponent;
+        return mantissa<a.mantissa;
+    }
+    /**
+     * Multiplies this <code>Real</code> by 2 to the power of <code>n</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     * This operation is faster than normal multiplication since it only
+     * involves adding to the exponent.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *    <code>this *= Math.{@link Math#pow(double,double) pow}(2.0,n);</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.3
+     * </td></tr></table>
+     *
+     * @param n the integer argument.
+     */
+    public void scalbn(int n) {
+        if (!(this.exponent >= 0 && this.mantissa != 0))
+            return;
+        exponent += n;
+        if (exponent < 0) {
+            if (n<0)
+                makeZero(sign); // Underflow
+            else
+                makeInfinity(sign); // Overflow
+        }
+    }
+    /**
+     * Calculates the next representable neighbour of this <code>Real</code>
+     * in the direction towards <code>a</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     * If the two values are equal, nothing happens.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this += Math.{@link Math#ulp(double) ulp}(this)*Math.{@link
+     *           Math#signum(double) signum}(a-this);</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.8
+     * </td></tr></table>
+     *
+     * @param a the <code>Real</code> argument.
+     */
+    public void nextafter(Real a) {
+        if ((this.exponent < 0 && this.mantissa != 0) || (a.exponent < 0 && a.mantissa != 0)) {
+            makeNan();
+            return;
+        }
+        if ((this.exponent < 0 && this.mantissa == 0) && (a.exponent < 0 && a.mantissa == 0) && sign == a.sign)
+            return;
+        int dir = -compare(a);
+        if (dir == 0)
+            return;
+        if ((this.exponent == 0 && this.mantissa == 0)) {
+            { this.mantissa = MIN.mantissa; this.exponent = MIN.exponent; this.sign = MIN.sign; };
+            sign = (byte)(dir<0 ? 1 : 0);
+            return;
+        }
+        if ((this.exponent < 0 && this.mantissa == 0)) {
+            { this.mantissa = MAX.mantissa; this.exponent = MAX.exponent; this.sign = MAX.sign; };
+            sign = (byte)(dir<0 ? 0 : 1);
+            return;
+        }
+        if ((this.sign==0) ^ dir<0) {
+            mantissa ++;
+        } else {
+            if (mantissa == 0x4000000000000000L) {
+                mantissa <<= 1;
+                exponent--;
+            }
+            mantissa --;
+        }
+        normalize();
+    }
+    /**
+     * Calculates the largest (closest to positive infinity)
+     * <code>Real</code> value that is less than or equal to this
+     * <code>Real</code> and is equal to a mathematical integer.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#floor(double) floor}(this);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.5
+     * </td></tr></table>
+     */
+    public void floor() {
+        if (!(this.exponent >= 0 && this.mantissa != 0))
+            return;
+        if (exponent < 0x40000000) {
+            if ((this.sign==0))
+                makeZero(sign);
+            else {
+                exponent = ONE.exponent;
+                mantissa = ONE.mantissa;
+                // sign unchanged!
+            }
+            return;
+        }
+        int shift = 0x4000003e-exponent;
+        if (shift <= 0)
+            return;
+        if ((this.sign!=0))
+            mantissa += ((1L<<shift)-1);
+        mantissa &= ~((1L<<shift)-1);
+        if ((this.sign!=0))
+            normalize();
+    }
+    /**
+     * Calculates the smallest (closest to negative infinity)
+     * <code>Real</code> value that is greater than or equal to this
+     * <code>Real</code> and is equal to a mathematical integer.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#ceil(double) ceil}(this);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.8
+     * </td></tr></table>
+     */
+    public void ceil() {
+        neg();
+        floor();
+        neg();
+    }
+    /**
+     * Rounds this <code>Real</code> value to the closest value that is equal
+     * to a mathematical integer. If two <code>Real</code> values that are
+     * mathematical integers are equally close, the result is the integer
+     * value with the largest magnitude (positive or negative).  Replaces the
+     * contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#rint(double) rint}(this);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.3
+     * </td></tr></table>
+     */
+    public void round() {
+        if (!(this.exponent >= 0 && this.mantissa != 0))
+            return;
+        if (exponent < 0x3fffffff) {
+            makeZero(sign);
+            return;
+        }
+        int shift = 0x4000003e-exponent;
+        if (shift <= 0)
+            return;
+        mantissa += 1L<<(shift-1); // Bla-bla, this works almost
+        mantissa &= ~((1L<<shift)-1);
+        normalize();
+    }
+    /**
+     * Truncates this <code>Real</code> value to the closest value towards
+     * zero that is equal to a mathematical integer.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = (double)((long)this);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.2
+     * </td></tr></table>
+     */
+    public void trunc() {
+        if (!(this.exponent >= 0 && this.mantissa != 0))
+            return;
+        if (exponent < 0x40000000) {
+            makeZero(sign);
+            return;
+        }
+        int shift = 0x4000003e-exponent;
+        if (shift <= 0)
+            return;
+        mantissa &= ~((1L<<shift)-1);
+        normalize();
+    }
+    /**
+     * Calculates the fractional part of this <code>Real</code> by subtracting
+     * the closest value towards zero that is equal to a mathematical integer.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this -= (double)((long)this);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.2
+     * </td></tr></table>
+     */
+    public void frac() {
+        if (!(this.exponent >= 0 && this.mantissa != 0) || exponent < 0x40000000)
+            return;
+        int shift = 0x4000003e-exponent;
+        if (shift <= 0) {
+            makeZero(sign);
+            return;
+        }
+        mantissa &= ((1L<<shift)-1);
+        normalize();
+    }
+    /**
+     * Converts this <code>Real</code> value to the closest <code>int</code>
+     * value towards zero.
+     *
+     * <p>If the value of this <code>Real</code> is too large, {@link
+     * Integer#MAX_VALUE} is returned. However, if the value of this
+     * <code>Real</code> is too small, <code>-Integer.MAX_VALUE</code> is
+     * returned, not {@link Integer#MIN_VALUE}. This is done to ensure that
+     * the sign will be correct if you calculate
+     * <code>-this.toInteger()</code>. A NaN is converted to 0.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>(int)this</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.6
+     * </td></tr></table>
+     *
+     * @return an <code>int</code> representation of this <code>Real</code>.
+     */
+    public int toInteger() {
+        if ((this.exponent == 0 && this.mantissa == 0) || (this.exponent < 0 && this.mantissa != 0))
+            return 0;
+        if ((this.exponent < 0 && this.mantissa == 0)) {
+            return ((this.sign==0)) ? 0x7fffffff : 0x80000001;
+            // 0x80000001, so that you can take -x.toInteger()
+        }
+        if (exponent < 0x40000000)
+            return 0;
+        int shift = 0x4000003e-exponent;
+        if (shift < 32) {
+            return ((this.sign==0)) ? 0x7fffffff : 0x80000001;
+            // 0x80000001, so that you can take -x.toInteger()
+        }
+        return (this.sign==0) ?
+            (int)(mantissa>>>shift) : -(int)(mantissa>>>shift);
+    }
+    /**
+     * Converts this <code>Real</code> value to the closest <code>long</code>
+     * value towards zero.
+     *
+     * <p>If the value of this <code>Real</code> is too large, {@link
+     * Long#MAX_VALUE} is returned. However, if the value of this
+     * <code>Real</code> is too small, <code>-Long.MAX_VALUE</code> is
+     * returned, not {@link Long#MIN_VALUE}. This is done to ensure that the
+     * sign will be correct if you calculate <code>-this.toLong()</code>.
+     * A NaN is converted to 0.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>(long)this</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.5
+     * </td></tr></table>
+     *
+     * @return a <code>long</code> representation of this <code>Real</code>.
+     */
+    public long toLong() {
+        if ((this.exponent == 0 && this.mantissa == 0) || (this.exponent < 0 && this.mantissa != 0))
+            return 0;
+        if ((this.exponent < 0 && this.mantissa == 0)) {
+            return ((this.sign==0))? 0x7fffffffffffffffL:0x8000000000000001L;
+            // 0x8000000000000001L, so that you can take -x.toLong()
+        }
+        if (exponent < 0x40000000)
+            return 0;
+        int shift = 0x4000003e-exponent;
+        if (shift < 0) {
+            return ((this.sign==0))? 0x7fffffffffffffffL:0x8000000000000001L;
+            // 0x8000000000000001L, so that you can take -x.toLong()
+        }
+        return (this.sign==0) ? (mantissa>>>shift) : -(mantissa>>>shift);
+    }
+    /**
+     * Returns <code>true</code> if the value of this <code>Real</code>
+     * represents a mathematical integer. If the value is too large to
+     * determine if it is an integer, <code>true</code> is returned.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>(this == (long)this)</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.6
+     * </td></tr></table>
+     *
+     * @return <code>true</code> if the value represented by this object
+     *     represents a mathematical integer, <code>false</code> otherwise.
+     */
+    public boolean isIntegral() {
+        if ((this.exponent < 0 && this.mantissa != 0))
+            return false;
+        if ((this.exponent == 0 && this.mantissa == 0) || (this.exponent < 0 && this.mantissa == 0))
+            return true;
+        if (exponent < 0x40000000)
+            return false;
+        int shift = 0x4000003e-exponent;
+        if (shift <= 0)
+            return true;
+        return (mantissa&((1L<<shift)-1)) == 0;
+    }
+    /**
+     * Returns <code>true</code> if the mathematical integer represented
+     * by this <code>Real</code> is odd. You <u>must</u> first determine
+     * that the value is actually an integer using {@link
+     * #isIntegral()}. If the value is too large to determine if the
+     * integer is odd, <code>false</code> is returned.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>((((long)this)&1) == 1)</code>
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.6
+     * </td></tr></table>
+     *
+     * @return <code>true</code> if the mathematical integer represented by
+     *     this <code>Real</code> is odd, <code>false</code> otherwise.
+     */
+    public boolean isOdd() {
+        if (!(this.exponent >= 0 && this.mantissa != 0) ||
+            exponent < 0x40000000 || exponent > 0x4000003e)
+            return false;
+        int shift = 0x4000003e-exponent;
+        return ((mantissa>>>shift)&1) != 0;
+    }
+    /**
+     * Exchanges the contents of this <code>Real</code> and <code>a</code>.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>tmp=this; this=a; a=tmp;</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     0.5
+     * </td></tr></table>
+     *
+     * @param a the <code>Real</code> to exchange with this.
+     */
+    public void swap(Real a) {
+        long tmpMantissa=mantissa; mantissa=a.mantissa; a.mantissa=tmpMantissa;
+        int tmpExponent=exponent; exponent=a.exponent; a.exponent=tmpExponent;
+        byte tmpSign =sign; sign =a.sign; a.sign =tmpSign;
+    }
+    // Temporary values used by functions (to avoid "new" inside functions)
+    private static Real tmp0 = new Real(); // tmp for basic functions
+    private static Real recipTmp = new Real();
+    private static Real recipTmp2 = new Real();
+    private static Real sqrtTmp = new Real();
+    private static Real expTmp = new Real();
+    private static Real expTmp2 = new Real();
+    private static Real expTmp3 = new Real();
+    private static Real tmp1 = new Real();
+    private static Real tmp2 = new Real();
+    private static Real tmp3 = new Real();
+    private static Real tmp4 = new Real();
+    private static Real tmp5 = new Real();
+    /**
+     * Calculates the sum of this <code>Real</code> and <code>a</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this += a;</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     ½ ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     «« 1.0 »»
+     * </td></tr></table>
+     *
+     * @param a the <code>Real</code> to add to this.
+     */
+    public void add(Real a) {
+        if ((this.exponent < 0 && this.mantissa != 0) || (a.exponent < 0 && a.mantissa != 0)) {
+            makeNan();
+            return;
+        }
+        if ((this.exponent < 0 && this.mantissa == 0) || (a.exponent < 0 && a.mantissa == 0)) {
+            if ((this.exponent < 0 && this.mantissa == 0) && (a.exponent < 0 && a.mantissa == 0) && sign != a.sign)
+                makeNan();
+            else
+                makeInfinity((this.exponent < 0 && this.mantissa == 0) ? sign : a.sign);
+            return;
+        }
+        if ((this.exponent == 0 && this.mantissa == 0) || (a.exponent == 0 && a.mantissa == 0)) {
+            if ((this.exponent == 0 && this.mantissa == 0))
+                { this.mantissa = a.mantissa; this.exponent = a.exponent; this.sign = a.sign; };
+            if ((this.exponent == 0 && this.mantissa == 0))
+                sign=0;
+            return;
+        }
+        byte s;
+        int e;
+        long m;
+        if (exponent > a.exponent ||
+            (exponent == a.exponent && mantissa>=a.mantissa))
+        {
+            s = a.sign;
+            e = a.exponent;
+            m = a.mantissa;
+        } else {
+            s = sign;
+            e = exponent;
+            m = mantissa;
+            sign = a.sign;
+            exponent = a.exponent;
+            mantissa = a.mantissa;
+        }
+        int shift = exponent-e;
+        if (shift>=64)
+            return;
+        if (sign == s) {
+            mantissa += m>>>shift;
+            if (mantissa >= 0 && shift>0 && ((m>>>(shift-1))&1) != 0)
+                mantissa ++; // We don't need normalization, so round now
+            if (mantissa < 0) {
+                // Simplified normalize()
+                mantissa = (mantissa+1)>>>1;
+                exponent ++;
+                if (exponent < 0) { // Overflow
+                    makeInfinity(sign);
+                    return;
+                }
+            }
+        } else {
+            if (shift>0) {
+                // Shift mantissa up to increase accuracy
+                mantissa <<= 1;
+                exponent --;
+                shift --;
+            }
+            m = -m;
+            mantissa += m>>shift;
+            if (mantissa >= 0 && shift>0 && ((m>>>(shift-1))&1) != 0)
+                mantissa ++; // We don't need to shift down, so round now
+            if (mantissa < 0) {
+                // Simplified normalize()
+                mantissa = (mantissa+1)>>>1;
+                exponent ++; // Can't overflow
+            } else if (shift==0) {
+                // Operands have equal exponents => many bits may be cancelled
+                // Magic rounding: if result of subtract leaves only a few bits
+                // standing, the result should most likely be 0...
+                if (magicRounding && mantissa > 0 && mantissa <= 7) {
+                    // If arguments were integers <= 2^63-1, then don't
+                    // do the magic rounding anyway.
+                    // This is a bit "post mortem" investigation but it happens
+                    // so seldom that it's no problem to spend the extra time.
+                    m = -m;
+                    if (exponent == 0x4000003c || exponent == 0x4000003d ||
+                        (exponent == 0x4000003e && mantissa+m > 0)) {
+                        long mask = (1<<(0x4000003e-exponent))-1;
+                        if ((mantissa & mask) != 0 || (m & mask) != 0)
+                            mantissa = 0;
+                    } else
+                        mantissa = 0;
+                }
+                normalize();
+            } // else... if (shift>=1 && mantissa>=0) it should be a-ok
+        }
+        if ((this.exponent == 0 && this.mantissa == 0))
+            sign=0;
+    }
+    /**
+     * Calculates the sum of this <code>Real</code> and the integer
+     * <code>a</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this += a;</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     ½ ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.8
+     * </td></tr></table>
+     *
+     * @param a the <code>int</code> to add to this.
+     */
+    public void add(int a) {
+        tmp0.assign(a);
+        add(tmp0);
+    }
+    /**
+     * Calculates the sum of this <code>Real</code> and <code>a</code> with
+     * extended precision.  Replaces the contents of this <code>Real</code>
+     * with the result.  Returns the extra mantissa of the extended precision
+     * result.
+     *
+     * <p>An extra 64 bits of mantissa is added to both arguments for extended
+     * precision. If any of the arguments are not of extended precision, use
+     * <code>0</code> for the extra mantissa.
+     *
+     * <p>Extended prevision can be useful in many situations. For instance,
+     * when accumulating a lot of very small values it is advantageous for the
+     * accumulator to have extended precision. To convert the extended
+     * precision value back to a normal <code>Real</code> for further
+     * processing, use {@link #roundFrom128(long)}.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this += a;</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     2<sup>-62</sup> ULPs (i.e. of a normal precision <code>Real</code>)
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     2.0
+     * </td></tr></table>
+     *
+     * @param extra the extra 64 bits of mantissa of this extended precision
+     *     <code>Real</code>.
+     * @param a the <code>Real</code> to add to this.
+     * @param aExtra the extra 64 bits of mantissa of the extended precision
+     *     value <code>a</code>.
+     * @return the extra 64 bits of mantissa of the resulting extended
+     *     precision <code>Real</code>.
+     */
+    public long add128(long extra, Real a, long aExtra) {
+        if ((this.exponent < 0 && this.mantissa != 0) || (a.exponent < 0 && a.mantissa != 0)) {
+            makeNan();
+            return 0;
+        }
+        if ((this.exponent < 0 && this.mantissa == 0) || (a.exponent < 0 && a.mantissa == 0)) {
+            if ((this.exponent < 0 && this.mantissa == 0) && (a.exponent < 0 && a.mantissa == 0) && sign != a.sign)
+                makeNan();
+            else
+                makeInfinity((this.exponent < 0 && this.mantissa == 0) ? sign : a.sign);
+            return 0;
+        }
+        if ((this.exponent == 0 && this.mantissa == 0) || (a.exponent == 0 && a.mantissa == 0)) {
+            if ((this.exponent == 0 && this.mantissa == 0)) {
+                { this.mantissa = a.mantissa; this.exponent = a.exponent; this.sign = a.sign; };
+                extra = aExtra;
+            }
+            if ((this.exponent == 0 && this.mantissa == 0))
+                sign=0;
+            return extra;
+        }
+        byte s;
+        int e;
+        long m;
+        long x;
+        if (exponent > a.exponent ||
+            (exponent == a.exponent && mantissa>a.mantissa) ||
+            (exponent == a.exponent && mantissa==a.mantissa &&
+             (extra>>>1)>=(aExtra>>>1)))
+        {
+            s = a.sign;
+            e = a.exponent;
+            m = a.mantissa;
+            x = aExtra;
+        } else {
+            s = sign;
+            e = exponent;
+            m = mantissa;
+            x = extra;
+            sign = a.sign;
+            exponent = a.exponent;
+            mantissa = a.mantissa;
+            extra = aExtra;
+        }
+        int shift = exponent-e;
+        if (shift>=127)
+            return extra;
+        if (shift>=64) {
+            x = m>>>(shift-64);
+            m = 0;
+        } else if (shift>0) {
+            x = (x>>>shift)+(m<<(64-shift));
+            m >>>= shift;
+        }
+        extra >>>= 1;
+        x >>>= 1;
+        if (sign == s) {
+            extra += x;
+            mantissa += (extra>>63)&1;
+            mantissa += m;
+        } else {
+            extra -= x;
+            mantissa -= (extra>>63)&1;
+            mantissa -= m;
+            // Magic rounding: if result of subtract leaves only a few bits
+            // standing, the result should most likely be 0...
+            if (mantissa == 0 && extra > 0 && extra <= 0x1f)
+                extra = 0;
+        }
+        extra <<= 1;
+        extra = normalize128(extra);
+        if ((this.exponent == 0 && this.mantissa == 0))
+            sign=0;
+        return extra;
+    }
+    /**
+     * Calculates the difference between this <code>Real</code> and
+     * <code>a</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p>(To achieve extended precision subtraction, it is enough to call
+     * <code>a.{@link #neg() neg}()</code> before calling <code>{@link
+     * #add128(long,Real,long) add128}(extra,a,aExtra)</code>, since only
+     * the sign bit of <code>a</code> need to be changed.)
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this -= a;</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     ½ ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     2.0
+     * </td></tr></table>
+     *
+     * @param a the <code>Real</code> to subtract from this.
+     */
+    public void sub(Real a) {
+        tmp0.mantissa = a.mantissa;
+        tmp0.exponent = a.exponent;
+        tmp0.sign = (byte)(a.sign^1);
+        add(tmp0);
+    }
+    /**
+     * Calculates the difference between this <code>Real</code> and the
+     * integer <code>a</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this -= a;</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     ½ ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     2.4
+     * </td></tr></table>
+     *
+     * @param a the <code>int</code> to subtract from this.
+     */
+    public void sub(int a) {
+        tmp0.assign(a);
+        sub(tmp0);
+    }
+    /**
+     * Calculates the product of this <code>Real</code> and <code>a</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this *= a;</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     ½ ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.3
+     * </td></tr></table>
+     *
+     * @param a the <code>Real</code> to multiply to this.
+     */
+    public void mul(Real a) {
+        if ((this.exponent < 0 && this.mantissa != 0) || (a.exponent < 0 && a.mantissa != 0)) {
+            makeNan();
+            return;
+        }
+        sign ^= a.sign;
+        if ((this.exponent == 0 && this.mantissa == 0) || (a.exponent == 0 && a.mantissa == 0)) {
+            if ((this.exponent < 0 && this.mantissa == 0) || (a.exponent < 0 && a.mantissa == 0))
+                makeNan();
+            else
+                makeZero(sign);
+            return;
+        }
+        if ((this.exponent < 0 && this.mantissa == 0) || (a.exponent < 0 && a.mantissa == 0)) {
+            makeInfinity(sign);
+            return;
+        }
+        long a0 = mantissa & 0x7fffffff;
+        long a1 = mantissa >>> 31;
+        long b0 = a.mantissa & 0x7fffffff;
+        long b1 = a.mantissa >>> 31;
+        mantissa = a1*b1;
+        // If we're going to need normalization, we don't want to round twice
+        int round = (mantissa<0) ? 0 : 0x40000000;
+        mantissa += ((a0*b1 + a1*b0 + ((a0*b0)>>>31) + round)>>>31);
+        int aExp = a.exponent;
+        exponent += aExp-0x40000000;
+        if (exponent < 0) {
+            if (exponent == -1 && aExp < 0x40000000 && mantissa < 0) {
+                // Not underflow after all, it will be corrected in the
+                // normalization below
+            } else {
+                if (aExp < 0x40000000)
+                    makeZero(sign); // Underflow
+                else
+                    makeInfinity(sign); // Overflow
+                return;
+            }
+        }
+        // Simplified normalize()
+        if (mantissa < 0) {
+            mantissa = (mantissa+1)>>>1;
+            exponent ++;
+            if (exponent < 0) // Overflow
+                makeInfinity(sign);
+        }
+    }
+    /**
+     * Calculates the product of this <code>Real</code> and the integer
+     * <code>a</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this *= a;</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     ½ ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.3
+     * </td></tr></table>
+     *
+     * @param a the <code>int</code> to multiply to this.
+     */
+    public void mul(int a) {
+        if ((this.exponent < 0 && this.mantissa != 0))
+            return;
+        if (a<0) {
+            sign ^= 1;
+            a = -a;
+        }
+        if ((this.exponent == 0 && this.mantissa == 0) || a==0) {
+            if ((this.exponent < 0 && this.mantissa == 0))
+                makeNan();
+            else
+                makeZero(sign);
+            return;
+        }
+        if ((this.exponent < 0 && this.mantissa == 0))
+            return;
+        // Normalize int
+        int t=a; t|=t>>1; t|=t>>2; t|=t>>4; t|=t>>8; t|=t>>16;
+        t = clz_tab[(t*clz_magic)>>>27];
+        exponent += 0x1F-t;
+        a <<= t;
+        if (exponent < 0) {
+            makeInfinity(sign); // Overflow
+            return;
+        }
+        long a0 = mantissa & 0x7fffffff;
+        long a1 = mantissa >>> 31;
+        long b0 = a & 0xffffffffL;
+        mantissa = a1*b0;
+        // If we're going to need normalization, we don't want to round twice
+        int round = (mantissa<0) ? 0 : 0x40000000;
+        mantissa += ((a0*b0 + round)>>>31);
+        // Simplified normalize()
+        if (mantissa < 0) {
+            mantissa = (mantissa+1)>>>1;
+            exponent ++;
+            if (exponent < 0) // Overflow
+                makeInfinity(sign);
+        }
+    }
+    /**
+     * Calculates the product of this <code>Real</code> and <code>a</code> with
+     * extended precision.
+     * Replaces the contents of this <code>Real</code> with the result.
+     * Returns the extra mantissa of the extended precision result.
+     *
+     * <p>An extra 64 bits of mantissa is added to both arguments for
+     * extended precision. If any of the arguments are not of extended
+     * precision, use <code>0</code> for the extra mantissa. See also {@link
+     * #add128(long,Real,long)}.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this *= a;</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     2<sup>-60</sup> ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     3.1
+     * </td></tr></table>
+     *
+     * @param extra the extra 64 bits of mantissa of this extended precision
+     *     <code>Real</code>.
+     * @param a the <code>Real</code> to multiply to this.
+     * @param aExtra the extra 64 bits of mantissa of the extended precision
+     *     value <code>a</code>.
+     * @return the extra 64 bits of mantissa of the resulting extended
+     *     precision <code>Real</code>.
+     */
+    public long mul128(long extra, Real a, long aExtra) {
+        if ((this.exponent < 0 && this.mantissa != 0) || (a.exponent < 0 && a.mantissa != 0)) {
+            makeNan();
+            return 0;
+        }
+        sign ^= a.sign;
+        if ((this.exponent == 0 && this.mantissa == 0) || (a.exponent == 0 && a.mantissa == 0)) {
+            if ((this.exponent < 0 && this.mantissa == 0) || (a.exponent < 0 && a.mantissa == 0))
+                makeNan();
+            else
+                makeZero(sign);
+            return 0;
+        }
+        if ((this.exponent < 0 && this.mantissa == 0) || (a.exponent < 0 && a.mantissa == 0)) {
+            makeInfinity(sign);
+            return 0;
+        }
+        int aExp = a.exponent;
+        exponent += aExp-0x40000000;
+        if (exponent < 0) {
+            if (aExp < 0x40000000)
+                makeZero(sign); // Underflow
+            else
+                makeInfinity(sign); // Overflow
+            return 0;
+        }
+        long ffffffffL = 0xffffffffL;
+        long a0 = extra & ffffffffL;
+        long a1 = extra >>> 32;
+        long a2 = mantissa & ffffffffL;
+        long a3 = mantissa >>> 32;
+        long b0 = aExtra & ffffffffL;
+        long b1 = aExtra >>> 32;
+        long b2 = a.mantissa & ffffffffL;
+        long b3 = a.mantissa >>> 32;
+        a0 = ((a3*b0>>>2)+
+              (a2*b1>>>2)+
+              (a1*b2>>>2)+
+              (a0*b3>>>2)+
+              0x60000000)>>>28;
+        //(a2*b0>>>34)+(a1*b1>>>34)+(a0*b2>>>34)+0x08000000)>>>28;
+        a1 *= b3;
+        b0 = a2*b2;
+        b1 *= a3;
+        a0 += ((a1<<2)&ffffffffL) + ((b0<<2)&ffffffffL) + ((b1<<2)&ffffffffL);
+        a1 = (a0>>>32) + (a1>>>30) + (b0>>>30) + (b1>>>30);
+        a0 &= ffffffffL;
+        a2 *= b3;
+        b2 *= a3;
+        a1 += ((a2<<2)&ffffffffL) + ((b2<<2)&ffffffffL);
+        extra = (a1<<32) + a0;
+        mantissa = ((a3*b3)<<2) + (a1>>>32) + (a2>>>30) + (b2>>>30);
+        extra = normalize128(extra);
+        return extra;
+    }
+    private void mul10() {
+        if (!(this.exponent >= 0 && this.mantissa != 0))
+            return;
+        mantissa += (mantissa+2)>>>2;
+        exponent += 3;
+        if (mantissa < 0) {
+            mantissa = (mantissa+1)>>>1;
+            exponent++;
+        }
+        if (exponent < 0)
+            makeInfinity(sign); // Overflow
+    }
+    /**
+     * Calculates the square of this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = this*this;</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     ½ ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.1
+     * </td></tr></table>
+     */
+    public void sqr() {
+        sign = 0;
+        if (!(this.exponent >= 0 && this.mantissa != 0))
+            return;
+        int e = exponent;
+        exponent += exponent-0x40000000;
+        if (exponent < 0) {
+            if (e < 0x40000000)
+                makeZero(sign); // Underflow
+            else
+                makeInfinity(sign); // Overflow
+            return;
+        }
+        long a0 = mantissa&0x7fffffff;
+        long a1 = mantissa>>>31;
+        mantissa = a1*a1;
+        // If we're going to need normalization, we don't want to round twice
+        int round = (mantissa<0) ? 0 : 0x40000000;
+        mantissa += ((((a0*a1)<<1) + ((a0*a0)>>>31) + round)>>>31);
+        // Simplified normalize()
+        if (mantissa < 0) {
+            mantissa = (mantissa+1)>>>1;
+            exponent ++;
+            if (exponent < 0) // Overflow
+                makeInfinity(sign);
+        }
+    }
+    private static long ldiv(long a, long b) {
+        // Calculate (a<<63)/b, where a<2**64, b<2**63, b<=a and a<2*b The
+        // result will always be 63 bits, leading to a 3-stage radix-2**21
+        // (very high radix) algorithm, as described here:
+        // S.F. Oberman and M.J. Flynn, "Division Algorithms and
+        // Implementations," IEEE Trans. Computers, vol. 46, no. 8,
+        // pp. 833-854, Aug 1997 Section 4: "Very High Radix Algorithms"
+        int bInv24; // Approximate 1/b, never more than 24 bits
+        int aHi24; // High 24 bits of a (sometimes 25 bits)
+        int next21; // The next 21 bits of result, possibly 1 less
+        long q; // Resulting quotient: round((a<<63)/b)
+        // Preparations
+        bInv24 = (int)(0x400000000000L/((b>>>40)+1));
+        aHi24 = (int)(a>>32)>>>8;
+        a <<= 20; // aHi24 and a overlap by 4 bits
+        // Now perform the division
+        next21 = (int)(((long)aHi24*(long)bInv24)>>>26);
+        a -= next21*b; // Bits above 2**64 will always be cancelled
+        // No need to remove remainder, this will be cared for in next block
+        q = next21;
+        aHi24 = (int)(a>>32)>>>7;
+        a <<= 21;
+        // Two more almost identical blocks...
+        next21 = (int)(((long)aHi24*(long)bInv24)>>>26);
+        a -= next21*b;
+        q = (q<<21)+next21;
+        aHi24 = (int)(a>>32)>>>7;
+        a <<= 21;
+        next21 = (int)(((long)aHi24*(long)bInv24)>>>26);
+        a -= next21*b;
+        q = (q<<21)+next21;
+        // Remove final remainder
+        if (a<0 || a>=b) { q++; a -= b; }
+        a <<= 1;
+        // Round correctly
+        if (a<0 || a>=b) q++;
+        return q;
+    }
+    /**
+     * Calculates the quotient of this <code>Real</code> and <code>a</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p>(To achieve extended precision division, call
+     * <code>aExtra=a.{@link #recip128(long) recip128}(aExtra)</code> before
+     * calling <code>{@link #mul128(long,Real,long)
+     * mul128}(extra,a,aExtra)</code>.)
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this /= a;</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     ½ ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     2.6
+     * </td></tr></table>
+     *
+     * @param a the <code>Real</code> to divide this with.
+     */
+    public void div(Real a) {
+        if ((this.exponent < 0 && this.mantissa != 0) || (a.exponent < 0 && a.mantissa != 0)) {
+            makeNan();
+            return;
+        }
+        sign ^= a.sign;
+        if ((this.exponent < 0 && this.mantissa == 0)) {
+            if ((a.exponent < 0 && a.mantissa == 0))
+                makeNan();
+            return;
+        }
+        if ((a.exponent < 0 && a.mantissa == 0)) {
+            makeZero(sign);
+            return;
+        }
+        if ((this.exponent == 0 && this.mantissa == 0)) {
+            if ((a.exponent == 0 && a.mantissa == 0))
+                makeNan();
+            return;
+        }
+        if ((a.exponent == 0 && a.mantissa == 0)) {
+            makeInfinity(sign);
+            return;
+        }
+        exponent += 0x40000000-a.exponent;
+        if (mantissa < a.mantissa) {
+            mantissa <<= 1;
+            exponent--;
+        }
+        if (exponent < 0) {
+            if (a.exponent >= 0x40000000)
+                makeZero(sign); // Underflow
+            else
+                makeInfinity(sign); // Overflow
+            return;
+        }
+        if (a.mantissa == 0x4000000000000000L)
+            return;
+        mantissa = ldiv(mantissa,a.mantissa);
+    }
+    /**
+     * Calculates the quotient of this <code>Real</code> and the integer
+     * <code>a</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this /= a;</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     ½ ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     2.6
+     * </td></tr></table>
+     *
+     * @param a the <code>int</code> to divide this with.
+     */
+    public void div(int a) {
+        if ((this.exponent < 0 && this.mantissa != 0))
+            return;
+        if (a<0) {
+            sign ^= 1;
+            a = -a;
+        }
+        if ((this.exponent < 0 && this.mantissa == 0))
+            return;
+        if ((this.exponent == 0 && this.mantissa == 0)) {
+            if (a==0)
+                makeNan();
+            return;
+        }
+        if (a==0) {
+            makeInfinity(sign);
+            return;
+        }
+        long denom = a & 0xffffffffL;
+        long remainder = mantissa%denom;
+        mantissa /= denom;
+        // Normalizing mantissa and scaling remainder accordingly
+        int clz = 0;
+        int t = (int)(mantissa>>>32);
+        if (t == 0) { clz = 32; t = (int)mantissa; }
+        t|=t>>1; t|=t>>2; t|=t>>4; t|=t>>8; t|=t>>16;
+        clz += clz_tab[(t*clz_magic)>>>27]-1;
+        mantissa <<= clz;
+        remainder <<= clz;
+        exponent -= clz;
+        // Final division, correctly rounded
+        remainder = (remainder+denom/2)/denom;
+        mantissa += remainder;
+        if (exponent < 0) // Underflow
+            makeZero(sign);
+    }
+    /**
+     * Calculates the quotient of <code>a</code> and this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = a/this;</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     ½ ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     3.1
+     * </td></tr></table>
+     *
+     * @param a the <code>Real</code> to be divided by this.
+     */
+    public void rdiv(Real a) {
+        { recipTmp.mantissa = a.mantissa; recipTmp.exponent = a.exponent; recipTmp.sign = a.sign; };
+        recipTmp.div(this);
+        { this.mantissa = recipTmp.mantissa; this.exponent = recipTmp.exponent; this.sign = recipTmp.sign; };
+    }
+    /**
+     * Calculates the quotient of the integer <code>a</code> and this
+     * <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = a/this;</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     ½ ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     3.9
+     * </td></tr></table>
+     *
+     * @param a the <code>int</code> to be divided by this.
+     */
+    public void rdiv(int a) {
+        tmp0.assign(a);
+        rdiv(tmp0);
+    }
+    /**
+     * Calculates the reciprocal of this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = 1/this;</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     ½ ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     2.3
+     * </td></tr></table>
+     */
+    public void recip() {
+        if ((this.exponent < 0 && this.mantissa != 0))
+            return;
+        if ((this.exponent < 0 && this.mantissa == 0)) {
+            makeZero(sign);
+            return;
+        }
+        if ((this.exponent == 0 && this.mantissa == 0)) {
+            makeInfinity(sign);
+            return;
+        }
+        exponent = 0x80000000-exponent;
+        if (mantissa == 0x4000000000000000L) {
+            if (exponent < 0)
+                makeInfinity(sign); // Overflow
+            return;
+        }
+        exponent--;
+        mantissa = ldiv(0x8000000000000000L,mantissa);
+    }
+    /**
+     * Calculates the reciprocal of this <code>Real</code> with
+     * extended precision.
+     * Replaces the contents of this <code>Real</code> with the result.
+     * Returns the extra mantissa of the extended precision result.
+     *
+     * <p>An extra 64 bits of mantissa is added for extended precision.
+     * If the argument is not of extended precision, use <code>0</code>
+     * for the extra mantissa. See also {@link #add128(long,Real,long)}.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = 1/this;</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     2<sup>-60</sup> ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     17
+     * </td></tr></table>
+     *
+     * @param extra the extra 64 bits of mantissa of this extended precision
+     *     <code>Real</code>.
+     * @return the extra 64 bits of mantissa of the resulting extended
+     *     precision <code>Real</code>.
+     */
+    public long recip128(long extra) {
+        if ((this.exponent < 0 && this.mantissa != 0))
+            return 0;
+        if ((this.exponent < 0 && this.mantissa == 0)) {
+            makeZero(sign);
+            return 0;
+        }
+        if ((this.exponent == 0 && this.mantissa == 0)) {
+            makeInfinity(sign);
+            return 0;
+        }
+        byte s = sign;
+        sign = 0;
+        // Special case, simple power of 2
+        if (mantissa == 0x4000000000000000L && extra == 0) {
+            exponent = 0x80000000-exponent;
+            if (exponent<0) // Overflow
+                makeInfinity(s);
+            return 0;
+        }
+        // Normalize exponent
+        int exp = 0x40000000-exponent;
+        exponent = 0x40000000;
+        // Save -A
+        { recipTmp.mantissa = this.mantissa; recipTmp.exponent = this.exponent; recipTmp.sign = this.sign; };
+        long recipTmpExtra = extra;
+        recipTmp.neg();
+        // First establish approximate result (actually 63 bit accurate)
+        recip();
+        // Perform one Newton-Raphson iteration
+        // Xn+1 = Xn + Xn*(1-A*Xn)
+        { recipTmp2.mantissa = this.mantissa; recipTmp2.exponent = this.exponent; recipTmp2.sign = this.sign; };
+        extra = mul128(0,recipTmp,recipTmpExtra);
+        extra = add128(extra,ONE,0);
+        extra = mul128(extra,recipTmp2,0);
+        extra = add128(extra,recipTmp2,0);
+        // Fix exponent
+        scalbn(exp);
+        // Fix sign
+        if (!isNan())
+            sign = s;
+        return extra;
+    }
+    /**
+     * Calculates the mathematical integer that is less than or equal to
+     * this <code>Real</code> divided by <code>a</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#floor(double) floor}(this/a);</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     22
+     * </td></tr></table>
+     *
+     * @param a the <code>Real</code> argument.
+     */
+    public void divf(Real a) {
+        if ((this.exponent < 0 && this.mantissa != 0) || (a.exponent < 0 && a.mantissa != 0)) {
+            makeNan();
+            return;
+        }
+        if ((this.exponent < 0 && this.mantissa == 0)) {
+            if ((a.exponent < 0 && a.mantissa == 0))
+                makeNan();
+            return;
+        }
+        if ((a.exponent < 0 && a.mantissa == 0)) {
+            makeZero(sign);
+            return;
+        }
+        if ((this.exponent == 0 && this.mantissa == 0)) {
+            if ((a.exponent == 0 && a.mantissa == 0))
+                makeNan();
+            return;
+        }
+        if ((a.exponent == 0 && a.mantissa == 0)) {
+            makeInfinity(sign);
+            return;
+        }
+        { tmp0.mantissa = a.mantissa; tmp0.exponent = a.exponent; tmp0.sign = a.sign; }; // tmp0 should be free
+        // Perform same division as with mod, and don't round up
+        long extra = tmp0.recip128(0);
+        extra = mul128(0,tmp0,extra);
+        if (((tmp0.sign!=0) && (extra < 0 || extra > 0x1f)) ||
+            (!(tmp0.sign!=0) && extra < 0 && extra > 0xffffffe0))
+        {
+            // For accurate floor()
+            mantissa++;
+            normalize();
+        }
+        floor();
+    }
+    private void modInternal(/*long thisExtra,*/ Real a, long aExtra) {
+        { tmp0.mantissa = a.mantissa; tmp0.exponent = a.exponent; tmp0.sign = a.sign; }; // tmp0 should be free
+        long extra = tmp0.recip128(aExtra);
+        extra = tmp0.mul128(extra,this,0/*thisExtra*/); // tmp0 == this/a
+        if (tmp0.exponent > 0x4000003e) {
+            // floor() will be inaccurate
+            makeZero(a.sign); // What else can be done? makeNan?
+            return;
+        }
+        if (((tmp0.sign!=0) && (extra < 0 || extra > 0x1f)) ||
+            (!(tmp0.sign!=0) && extra < 0 && extra > 0xffffffe0))
+        {
+            // For accurate floor() with a bit of "magical rounding"
+            tmp0.mantissa++;
+            tmp0.normalize();
+        }
+        tmp0.floor();
+        tmp0.neg(); // tmp0 == -floor(this/a)
+        extra = tmp0.mul128(0,a,aExtra);
+        extra = add128(0/*thisExtra*/,tmp0,extra);
+        roundFrom128(extra);
+    }
+    /**
+     * Calculates the value of this <code>Real</code> modulo <code>a</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     * The modulo in this case is defined as the remainder after subtracting
+     * <code>a</code> multiplied by the mathematical integer that is less than
+     * or equal to this <code>Real</code> divided by <code>a</code>.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = this -
+     *           a*Math.{@link Math#floor(double) floor}(this/a);</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     27
+     * </td></tr></table>
+     *
+     * @param a the <code>Real</code> argument.
+     */
+    public void mod(Real a) {
+        if ((this.exponent < 0 && this.mantissa != 0) || (a.exponent < 0 && a.mantissa != 0)) {
+            makeNan();
+            return;
+        }
+        if ((this.exponent < 0 && this.mantissa == 0)) {
+            makeNan();
+            return;
+        }
+        if ((this.exponent == 0 && this.mantissa == 0)) {
+            if ((a.exponent == 0 && a.mantissa == 0))
+                makeNan();
+            else
+                sign = a.sign;
+            return;
+        }
+        if ((a.exponent < 0 && a.mantissa == 0)) {
+            if (sign != a.sign)
+                makeInfinity(a.sign);
+            return;
+        }
+        if ((a.exponent == 0 && a.mantissa == 0)) {
+            makeZero(a.sign);
+            return;
+        }
+        modInternal(a,0);
+    }
+    /**
+     * Calculates the logical <i>AND</i> of this <code>Real</code> and
+     * <code>a</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p>Semantics of bitwise logical operations exactly mimic those of
+     * Java's bitwise integer operators. In these operations, the
+     * internal binary representation of the numbers are used. If the
+     * values represented by the operands are not mathematical
+     * integers, the fractional bits are also included in the operation.
+     *
+     * <p>Negative numbers are interpreted as two's-complement,
+     * generalized to real numbers: Negating the number inverts all
+     * bits, including an infinite number of 1-bits before the radix
+     * point and an infinite number of 1-bits after the radix point. The
+     * infinite number of 1-bits after the radix is rounded upwards
+     * producing an infinite number of 0-bits, until the first 0-bit is
+     * encountered which will be switched to a 1 (rounded or not, these
+     * two forms are mathematically equivalent). For example, the number
+     * "1" negated, becomes (in binary form)
+     * <code>...1111110.111111....</code> Rounding of the infinite
+     * number of 1's after the radix gives the number
+     * <code>...1111111.000000...</code>, which is exactly the way we
+     * usually see "-1" as two's-complement.
+     *
+     * <p>This method calculates a negative value if and only
+     * if this and <code>a</code> are both negative.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>int</code><i>&nbsp;code:</i></td><td>
+     *     <code>this &= a;</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.5
+     * </td></tr></table>
+     *
+     * @param a the <code>Real</code> argument
+     */
+    public void and(Real a) {
+        if ((this.exponent < 0 && this.mantissa != 0) || (a.exponent < 0 && a.mantissa != 0)) {
+            makeNan();
+            return;
+        }
+        if ((this.exponent == 0 && this.mantissa == 0) || (a.exponent == 0 && a.mantissa == 0)) {
+            makeZero();
+            return;
+        }
+        if ((this.exponent < 0 && this.mantissa == 0) || (a.exponent < 0 && a.mantissa == 0)) {
+            if (!(this.exponent < 0 && this.mantissa == 0) && (this.sign!=0)) {
+                { this.mantissa = a.mantissa; this.exponent = a.exponent; this.sign = a.sign; };
+            } else if (!(a.exponent < 0 && a.mantissa == 0) && (a.sign!=0))
+                ; // ASSIGN(this,this)
+            else if ((this.exponent < 0 && this.mantissa == 0) && (a.exponent < 0 && a.mantissa == 0) &&
+                     (this.sign!=0) && (a.sign!=0))
+                ; // makeInfinity(1)
+            else
+                makeZero();
+            return;
+        }
+        byte s;
+        int e;
+        long m;
+        if (exponent >= a.exponent) {
+            s = a.sign;
+            e = a.exponent;
+            m = a.mantissa;
+        } else {
+            s = sign;
+            e = exponent;
+            m = mantissa;
+            sign = a.sign;
+            exponent = a.exponent;
+            mantissa = a.mantissa;
+        }
+        int shift = exponent-e;
+        if (shift>=64) {
+            if (s == 0)
+                makeZero(sign);
+            return;
+        }
+        if (s != 0)
+            m = -m;
+        if ((this.sign!=0))
+            mantissa = -mantissa;
+        mantissa &= m>>shift;
+        sign = 0;
+        if (mantissa < 0) {
+            mantissa = -mantissa;
+            sign = 1;
+        }
+        normalize();
+    }
+    /**
+     * Calculates the logical <i>OR</i> of this <code>Real</code> and
+     * <code>a</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p>See {@link #and(Real)} for an explanation of the
+     * interpretation of a <code>Real</code> in bitwise operations.
+     * This method calculates a negative value if and only
+     * if either this or <code>a</code> is negative.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>int</code><i>&nbsp;code:</i></td><td>
+     *     <code>this |= a;</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.6
+     * </td></tr></table>
+     *
+     * @param a the <code>Real</code> argument
+     */
+    public void or(Real a) {
+        if ((this.exponent < 0 && this.mantissa != 0) || (a.exponent < 0 && a.mantissa != 0)) {
+            makeNan();
+            return;
+        }
+        if ((this.exponent == 0 && this.mantissa == 0) || (a.exponent == 0 && a.mantissa == 0)) {
+            if ((this.exponent == 0 && this.mantissa == 0))
+                { this.mantissa = a.mantissa; this.exponent = a.exponent; this.sign = a.sign; };
+            return;
+        }
+        if ((this.exponent < 0 && this.mantissa == 0) || (a.exponent < 0 && a.mantissa == 0)) {
+            if (!(this.exponent < 0 && this.mantissa == 0) && (this.sign!=0))
+                ; // ASSIGN(this,this);
+            else if (!(a.exponent < 0 && a.mantissa == 0) && (a.sign!=0)) {
+                { this.mantissa = a.mantissa; this.exponent = a.exponent; this.sign = a.sign; };
+            } else
+                makeInfinity(sign | a.sign);
+            return;
+        }
+        byte s;
+        int e;
+        long m;
+        if (((this.sign!=0) && exponent <= a.exponent) ||
+            ((a.sign==0) && exponent >= a.exponent))
+        {
+            s = a.sign;
+            e = a.exponent;
+            m = a.mantissa;
+        } else {
+            s = sign;
+            e = exponent;
+            m = mantissa;
+            sign = a.sign;
+            exponent = a.exponent;
+            mantissa = a.mantissa;
+        }
+        int shift = exponent-e;
+        if (shift>=64 || shift<=-64)
+            return;
+        if (s != 0)
+            m = -m;
+        if ((this.sign!=0))
+            mantissa = -mantissa;
+        if (shift>=0)
+            mantissa |= m>>shift;
+        else
+            mantissa |= m<<(-shift);
+        sign = 0;
+        if (mantissa < 0) {
+            mantissa = -mantissa;
+            sign = 1;
+        }
+        normalize();
+    }
+    /**
+     * Calculates the logical <i>XOR</i> of this <code>Real</code> and
+     * <code>a</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p>See {@link #and(Real)} for an explanation of the
+     * interpretation of a <code>Real</code> in bitwise operations.
+     * This method calculates a negative value if and only
+     * if exactly one of this and <code>a</code> is negative.
+     *
+     * <p>The operation <i>NOT</i> has been omitted in this library
+     * because it cannot be generalized to fractional numbers. If this
+     * <code>Real</code> represents a mathematical integer, the
+     * operation <i>NOT</i> can be calculated as "this <i>XOR</i> -1",
+     * which is equivalent to "this <i>XOR</i>
+     * <code>/FFFFFFFF.0000</code>".
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>int</code><i>&nbsp;code:</i></td><td>
+     *     <code>this ^= a;</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.5
+     * </td></tr></table>
+     *
+     * @param a the <code>Real</code> argument
+     */
+    public void xor(Real a) {
+        if ((this.exponent < 0 && this.mantissa != 0) || (a.exponent < 0 && a.mantissa != 0)) {
+            makeNan();
+            return;
+        }
+        if ((this.exponent == 0 && this.mantissa == 0) || (a.exponent == 0 && a.mantissa == 0)) {
+            if ((this.exponent == 0 && this.mantissa == 0))
+                { this.mantissa = a.mantissa; this.exponent = a.exponent; this.sign = a.sign; };
+            return;
+        }
+        if ((this.exponent < 0 && this.mantissa == 0) || (a.exponent < 0 && a.mantissa == 0)) {
+            makeInfinity(sign ^ a.sign);
+            return;
+        }
+        byte s;
+        int e;
+        long m;
+        if (exponent >= a.exponent) {
+            s = a.sign;
+            e = a.exponent;
+            m = a.mantissa;
+        } else {
+            s = sign;
+            e = exponent;
+            m = mantissa;
+            sign = a.sign;
+            exponent = a.exponent;
+            mantissa = a.mantissa;
+        }
+        int shift = exponent-e;
+        if (shift>=64)
+            return;
+        if (s != 0)
+            m = -m;
+        if ((this.sign!=0))
+            mantissa = -mantissa;
+        mantissa ^= m>>shift;
+        sign = 0;
+        if (mantissa < 0) {
+            mantissa = -mantissa;
+            sign = 1;
+        }
+        normalize();
+    }
+    /**
+     * Calculates the value of this <code>Real</code> <i>AND NOT</i>
+     * <code>a</code>. The opeation is read as "bit clear".
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p>See {@link #and(Real)} for an explanation of the
+     * interpretation of a <code>Real</code> in bitwise operations.
+     * This method calculates a negative value if and only
+     * if this is negative and not <code>a</code> is negative.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>int</code><i>&nbsp;code:</i></td><td>
+     *     <code>this &= ~a;</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     1.5
+     * </td></tr></table>
+     *
+     * @param a the <code>Real</code> argument
+     */
+    public void bic(Real a) {
+        if ((this.exponent < 0 && this.mantissa != 0) || (a.exponent < 0 && a.mantissa != 0)) {
+            makeNan();
+            return;
+        }
+        if ((this.exponent == 0 && this.mantissa == 0) || (a.exponent == 0 && a.mantissa == 0))
+            return;
+        if ((this.exponent < 0 && this.mantissa == 0) || (a.exponent < 0 && a.mantissa == 0)) {
+            if (!(this.exponent < 0 && this.mantissa == 0)) {
+                if ((this.sign!=0))
+                    if ((a.sign!=0))
+                        makeInfinity(0);
+                    else
+                        makeInfinity(1);
+            } else if ((a.sign!=0)) {
+                if ((a.exponent < 0 && a.mantissa == 0))
+                    makeInfinity(0);
+                else
+                    makeZero();
+            }
+            return;
+        }
+        int shift = exponent-a.exponent;
+        if (shift>=64 || (shift<=-64 && (this.sign==0)))
+            return;
+        long m = a.mantissa;
+        if ((a.sign!=0))
+            m = -m;
+        if ((this.sign!=0))
+            mantissa = -mantissa;
+        if (shift<0) {
+            if ((this.sign!=0)) {
+                if (shift<=-64)
+                    mantissa = ~m;
+                else
+                    mantissa = (mantissa>>(-shift)) & ~m;
+                exponent = a.exponent;
+            } else
+                mantissa &= ~(m<<(-shift));
+        } else
+            mantissa &= ~(m>>shift);
+        sign = 0;
+        if (mantissa < 0) {
+            mantissa = -mantissa;
+            sign = 1;
+        }
+        normalize();
+    }
+    private int compare(int a) {
+        tmp0.assign(a);
+        return compare(tmp0);
+    }
+    /**
+     * Calculates the square root of this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#sqrt(double) sqrt}(this);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     1 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     19
+     * </td></tr></table>
+     */
+    public void sqrt() {
+        /*
+         * Adapted from:
+         * Cephes Math Library Release 2.2:  December, 1990
+         * Copyright 1984, 1990 by Stephen L. Moshier
+         *
+         * sqrtl.c
+         *
+         * long double sqrtl(long double x);
+         */
+        if ((this.exponent < 0 && this.mantissa != 0))
+            return;
+        if ((this.exponent == 0 && this.mantissa == 0)) {
+            sign=0;
+            return;
+        }
+        if ((this.sign!=0)) {
+            makeNan();
+            return;
+        }
+        if ((this.exponent < 0 && this.mantissa == 0))
+            return;
+        // Save X
+        { recipTmp.mantissa = this.mantissa; recipTmp.exponent = this.exponent; recipTmp.sign = this.sign; };
+        // normalize to range [0.5, 1)
+        int e = exponent-0x3fffffff;
+        exponent = 0x3fffffff;
+        // quadratic approximation, relative error 6.45e-4
+        { recipTmp2.mantissa = this.mantissa; recipTmp2.exponent = this.exponent; recipTmp2.sign = this.sign; };
+        { sqrtTmp.sign=(byte)1; sqrtTmp.exponent=0x3ffffffd; sqrtTmp.mantissa=0x68a7e193370ff21bL; };//-0.2044058315473477195990
+        mul(sqrtTmp);
+        { sqrtTmp.sign=(byte)0; sqrtTmp.exponent=0x3fffffff; sqrtTmp.mantissa=0x71f1e120690deae8L; };//0.89019407351052789754347
+        add(sqrtTmp);
+        mul(recipTmp2);
+        { sqrtTmp.sign=(byte)0; sqrtTmp.exponent=0x3ffffffe; sqrtTmp.mantissa=0x5045ee6baf28677aL; };//0.31356706742295303132394
+        add(sqrtTmp);
+        // adjust for odd powers of 2
+        if ((e&1) != 0)
+            mul(SQRT2);
+        // calculate exponent
+        exponent += e>>1;
+        // Newton iteratios:
+        //   Yn+1 = (Yn + X/Yn)/2
+        for (int i=0; i<3; i++) {
+            { recipTmp2.mantissa = recipTmp.mantissa; recipTmp2.exponent = recipTmp.exponent; recipTmp2.sign = recipTmp.sign; };
+            recipTmp2.div(this);
+            add(recipTmp2);
+            scalbn(-1);
+        }
+    }
+    /**
+     * Calculates the reciprocal square root of this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = 1/Math.{@link Math#sqrt(double) sqrt}(this);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     1 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     21
+     * </td></tr></table>
+     */
+    public void rsqrt() {
+        sqrt();
+        recip();
+    }
+    /**
+     * Calculates the cube root of this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     * The cube root of a negative value is the negative of the cube
+     * root of that value's magnitude.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#cbrt(double) cbrt}(this);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     2 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     32
+     * </td></tr></table>
+     */
+    public void cbrt() {
+        if (!(this.exponent >= 0 && this.mantissa != 0))
+            return;
+        byte s = sign;
+        sign = 0;
+        // Calculates recipocal cube root of normalized Real,
+        // not zero, nan or infinity
+        final long start = 0x5120000000000000L;
+        // Save -A
+        { recipTmp.mantissa = this.mantissa; recipTmp.exponent = this.exponent; recipTmp.sign = this.sign; };
+        recipTmp.neg();
+        // First establish approximate result
+        mantissa = start-(mantissa>>>2);
+        int expRmd = exponent==0 ? 2 : (exponent-1)%3;
+        exponent = 0x40000000-(exponent-0x40000000-expRmd)/3;
+        normalize();
+        if (expRmd>0) {
+            { recipTmp2.sign=(byte)0; recipTmp2.exponent=0x3fffffff; recipTmp2.mantissa=0x6597fa94f5b8f20bL; }; // cbrt(1/2)
+            mul(recipTmp2);
+            if (expRmd>1)
+                mul(recipTmp2);
+        }
+        // Now perform Newton-Raphson iteration
+        // Xn+1 = (4*Xn - A*Xn**4)/3
+        for (int i=0; i<4; i++) {
+            { recipTmp2.mantissa = this.mantissa; recipTmp2.exponent = this.exponent; recipTmp2.sign = this.sign; };
+            sqr();
+            sqr();
+            mul(recipTmp);
+            recipTmp2.scalbn(2);
+            add(recipTmp2);
+            mul(THIRD);
+        }
+        recip();
+        if (!(this.exponent < 0 && this.mantissa != 0))
+            sign = s;
+    }
+    /**
+     * Calculates the n'th root of this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     * For odd integer n, the n'th root of a negative value is the
+     * negative of the n'th root of that value's magnitude.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#pow(double,double)
+     *           pow}(this,1/a);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     2 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     110
+     * </td></tr></table>
+     *
+     * @param n the <code>Real</code> argument.
+     */
+    public void nroot(Real n) {
+        if ((n.exponent < 0 && n.mantissa != 0)) {
+            makeNan();
+            return;
+        }
+        if (n.compare(THREE)==0) {
+            cbrt(); // Most probable application of nroot...
+            return;
+        } else if (n.compare(TWO)==0) {
+            sqrt(); // Also possible, should be optimized like this
+            return;
+        }
+        boolean negative = false;
+        if ((this.sign!=0) && n.isIntegral() && n.isOdd()) {
+            negative = true;
+            abs();
+        }
+        { tmp2.mantissa = n.mantissa; tmp2.exponent = n.exponent; tmp2.sign = n.sign; }; // Copy to temporary location in case of x.nroot(x)
+        tmp2.recip();
+        pow(tmp2);
+        if (negative)
+            neg();
+    }
+    /**
+     * Calculates <code>sqrt(this*this+a*a)</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#hypot(double,double)
+     *           hypot}(this,a);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     1 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     24
+     * </td></tr></table>
+     *
+     * @param a the <code>Real</code> argument.
+     */
+    public void hypot(Real a) {
+        { tmp1.mantissa = a.mantissa; tmp1.exponent = a.exponent; tmp1.sign = a.sign; }; // Copy to temporary location in case of x.hypot(x)
+        tmp1.sqr();
+        sqr();
+        add(tmp1);
+        sqrt();
+    }
+    private void exp2Internal(long extra) {
+        if ((this.exponent < 0 && this.mantissa != 0))
+            return;
+        if ((this.exponent < 0 && this.mantissa == 0)) {
+            if ((this.sign!=0))
+                makeZero(0);
+            return;
+        }
+        if ((this.exponent == 0 && this.mantissa == 0)) {
+            { this.mantissa = ONE.mantissa; this.exponent = ONE.exponent; this.sign = ONE.sign; };
+            return;
+        }
+        // Extract integer part
+        { expTmp.mantissa = this.mantissa; expTmp.exponent = this.exponent; expTmp.sign = this.sign; };
+        expTmp.add(HALF);
+        expTmp.floor();
+        int exp = expTmp.toInteger();
+        if (exp > 0x40000000) {
+            makeInfinity(sign);
+            return;
+        }
+        if (exp < -0x40000000) {
+            makeZero(sign);
+            return;
+        }
+        // Subtract integer part (this is where we need the extra accuracy)
+        expTmp.neg();
+        add128(extra,expTmp,0);
+        /*
+         * Adapted from:
+         * Cephes Math Library Release 2.7:  May, 1998
+         * Copyright 1984, 1991, 1998 by Stephen L. Moshier
+         *
+         * exp2l.c
+         *
+         * long double exp2l(long double x);
+         */
+        // Now -0.5<X<0.5
+        // rational approximation
+        // exp2(x) = 1 + 2x P(x²)/(Q(x²) - x P(x²))
+        { expTmp2.mantissa = this.mantissa; expTmp2.exponent = this.exponent; expTmp2.sign = this.sign; };
+        expTmp2.sqr();
+        // P(x²)
+        { expTmp.sign=(byte)0; expTmp.exponent=0x40000005; expTmp.mantissa=0x793ace15b56b7fecL; };//60.614853552242266094567
+        expTmp.mul(expTmp2);
+        { expTmp3.sign=(byte)0; expTmp3.exponent=0x4000000e; expTmp3.mantissa=0x764ef8cf96e29a13L; };//30286.971917562792508623
+        expTmp.add(expTmp3);
+        expTmp.mul(expTmp2);
+        { expTmp3.sign=(byte)0; expTmp3.exponent=0x40000014; expTmp3.mantissa=0x7efa0173e820bf60L; };//2080384.3631901852422887
+        expTmp.add(expTmp3);
+        mul(expTmp);
+        // Q(x²)
+        expTmp.assign(expTmp2);
+        { expTmp3.sign=(byte)0; expTmp3.exponent=0x4000000a; expTmp3.mantissa=0x6d549a6b4dc9abadL; };//1749.2876999891839021063
+        expTmp.add(expTmp3);
+        expTmp.mul(expTmp2);
+        { expTmp3.sign=(byte)0; expTmp3.exponent=0x40000012; expTmp3.mantissa=0x5002d27836ba71c6L; };//327725.15434906797273099
+        expTmp.add(expTmp3);
+        expTmp.mul(expTmp2);
+        { expTmp3.sign=(byte)0; expTmp3.exponent=0x40000016; expTmp3.mantissa=0x5b98206867dd59bfL; };//6002720.4078348487957118
+        expTmp.add(expTmp3);
+        expTmp.sub(this);
+        div(expTmp);
+        scalbn(1);
+        add(ONE);
+        // Scale by power of 2
+        scalbn(exp);
+    }
+    /**
+     * Calculates <i>e</i> raised to the power of this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#exp(double) exp}(this);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     1 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     31
+     * </td></tr></table>
+     */
+    public void exp() {
+        { expTmp.sign=(byte)0; expTmp.exponent=0x40000000; expTmp.mantissa=0x5c551d94ae0bf85dL; }; // log2(e)
+        long extra = mul128(0,expTmp,0xdf43ff68348e9f44L);
+        exp2Internal(extra);
+    }
+    /**
+     * Calculates 2 raised to the power of this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#exp(double) exp}(this *
+     *           Math.{@link Math#log(double) log}(2));</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     1 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     27
+     * </td></tr></table>
+     */
+    public void exp2() {
+        exp2Internal(0);
+    }
+    /**
+     * Calculates 10 raised to the power of this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#exp(double) exp}(this *
+     *           Math.{@link Math#log(double) log}(10));</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     1 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     31
+     * </td></tr></table>
+     */
+    public void exp10() {
+        { expTmp.sign=(byte)0; expTmp.exponent=0x40000001; expTmp.mantissa=0x6a4d3c25e68dc57fL; }; // log2(10)
+        long extra = mul128(0,expTmp,0x2495fb7fa6d7eda6L);
+        exp2Internal(extra);
+    }
+    private int lnInternal()
+    {
+        if ((this.exponent < 0 && this.mantissa != 0))
+            return 0;
+        if ((this.sign!=0)) {
+            makeNan();
+            return 0;
+        }
+        if ((this.exponent == 0 && this.mantissa == 0)) {
+            makeInfinity(1);
+            return 0;
+        }
+        if ((this.exponent < 0 && this.mantissa == 0))
+            return 0;
+        /*
+         * Adapted from:
+         * Cephes Math Library Release 2.7:  May, 1998
+         * Copyright 1984, 1990, 1998 by Stephen L. Moshier
+         *
+         * logl.c
+         *
+         * long double logl(long double x);
+         */
+        // normalize to range [0.5, 1)
+        int e = exponent-0x3fffffff;
+        exponent = 0x3fffffff;
+        // rational appriximation
+        // log(1+x) = x - x²/2 + x³ P(x)/Q(x)
+        if (this.compare(SQRT1_2) < 0) {
+            e--;
+            exponent++;
+        }
+        sub(ONE);
+        { expTmp2.mantissa = this.mantissa; expTmp2.exponent = this.exponent; expTmp2.sign = this.sign; };
+        // P(x)
+        { this.sign=(byte)0; this.exponent=0x3ffffff1; this.mantissa=0x5ef0258ace5728ddL; };//4.5270000862445199635215E-5
+        mul(expTmp2);
+        { expTmp3.sign=(byte)0; expTmp3.exponent=0x3ffffffe; expTmp3.mantissa=0x7fa06283f86a0ce8L; };//0.4985410282319337597221
+        add(expTmp3);
+        mul(expTmp2);
+        { expTmp3.sign=(byte)0; expTmp3.exponent=0x40000002; expTmp3.mantissa=0x69427d1bd3e94ca1L; };//6.5787325942061044846969
+        add(expTmp3);
+        mul(expTmp2);
+        { expTmp3.sign=(byte)0; expTmp3.exponent=0x40000004; expTmp3.mantissa=0x77a5ce2e32e7256eL; };//29.911919328553073277375
+        add(expTmp3);
+        mul(expTmp2);
+        { expTmp3.sign=(byte)0; expTmp3.exponent=0x40000005; expTmp3.mantissa=0x79e63ae1b0cd4222L; };//60.949667980987787057556
+        add(expTmp3);
+        mul(expTmp2);
+        { expTmp3.sign=(byte)0; expTmp3.exponent=0x40000005; expTmp3.mantissa=0x7239d65d1e6840d6L; };//57.112963590585538103336
+        add(expTmp3);
+        mul(expTmp2);
+        { expTmp3.sign=(byte)0; expTmp3.exponent=0x40000004; expTmp3.mantissa=0x502880b6660c265fL; };//20.039553499201281259648
+        add(expTmp3);
+        // Q(x)
+        { expTmp.mantissa = expTmp2.mantissa; expTmp.exponent = expTmp2.exponent; expTmp.sign = expTmp2.sign; };
+        { expTmp3.sign=(byte)0; expTmp3.exponent=0x40000003; expTmp3.mantissa=0x7880d67a40f8dc5cL; };//15.062909083469192043167
+        expTmp.add(expTmp3);
+        expTmp.mul(expTmp2);
+        { expTmp3.sign=(byte)0; expTmp3.exponent=0x40000006; expTmp3.mantissa=0x530c2d4884d25e18L; };//83.047565967967209469434
+        expTmp.add(expTmp3);
+        expTmp.mul(expTmp2);
+        { expTmp3.sign=(byte)0; expTmp3.exponent=0x40000007; expTmp3.mantissa=0x6ee19643f3ed5776L; };//221.76239823732856465394
+        expTmp.add(expTmp3);
+        expTmp.mul(expTmp2);
+        { expTmp3.sign=(byte)0; expTmp3.exponent=0x40000008; expTmp3.mantissa=0x4d465177242295efL; };//309.09872225312059774938
+        expTmp.add(expTmp3);
+        expTmp.mul(expTmp2);
+        { expTmp3.sign=(byte)0; expTmp3.exponent=0x40000007; expTmp3.mantissa=0x6c36c4f923819890L; };//216.42788614495947685003
+        expTmp.add(expTmp3);
+        expTmp.mul(expTmp2);
+        { expTmp3.sign=(byte)0; expTmp3.exponent=0x40000005; expTmp3.mantissa=0x783cc111991239a3L; };//60.118660497603843919306
+        expTmp.add(expTmp3);
+        div(expTmp);
+        { expTmp3.mantissa = expTmp2.mantissa; expTmp3.exponent = expTmp2.exponent; expTmp3.sign = expTmp2.sign; };
+        expTmp3.sqr();
+        mul(expTmp3);
+        mul(expTmp2);
+        expTmp3.scalbn(-1);
+        sub(expTmp3);
+        add(expTmp2);
+        return e;
+    }
+    /**
+     * Calculates the natural logarithm (base-<i>e</i>) of this
+     * <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#log(double) log}(this);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     2 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     51
+     * </td></tr></table>
+     */
+    public void ln() {
+        int exp = lnInternal();
+        expTmp.assign(exp);
+        expTmp.mul(LN2);
+        add(expTmp);
+    }
+    /**
+     * Calculates the base-2 logarithm of this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#log(double) log}(this)/Math.{@link
+     *           Math#log(double) log}(2);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     1 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     51
+     * </td></tr></table>
+     */
+    public void log2() {
+        int exp = lnInternal();
+        mul(LOG2E);
+        add(exp);
+    }
+    /**
+     * Calculates the base-10 logarithm of this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#log10(double) log10}(this);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     2 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     53
+     * </td></tr></table>
+     */
+    public void log10() {
+        int exp = lnInternal();
+        expTmp.assign(exp);
+        expTmp.mul(LN2);
+        add(expTmp);
+        mul(LOG10E);
+    }
+    /**
+     * Calculates the closest power of 10 that is less than or equal to this
+     * <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     * The base-10 exponent of the result is returned.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>int exp = (int)(Math.{@link Math#floor(double)
+     *       floor}(Math.{@link Math#log10(double) log10}(this)));
+     *       <br>this = Math.{@link Math#pow(double,double) pow}(10, exp);<br>
+     *           return exp;</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     ½ ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     3.6
+     * </td></tr></table>
+     *
+     * @return the base-10 exponent
+     */
+    public int lowPow10() {
+        if (!(this.exponent >= 0 && this.mantissa != 0))
+            return 0;
+        { tmp2.mantissa = this.mantissa; tmp2.exponent = this.exponent; tmp2.sign = this.sign; };
+        // Approximate log10 using exponent only
+        int e = exponent - 0x40000000;
+        if (e<0) // it's important to achieve floor(exponent*ln2/ln10)
+            e = -(int)(((-e)*0x4d104d43L+((1L<<32)-1)) >> 32);
+        else
+            e = (int)(e*0x4d104d43L >> 32);
+        // Now, e < log10(this) < e+1
+        { this.mantissa = TEN.mantissa; this.exponent = TEN.exponent; this.sign = TEN.sign; };
+        pow(e);
+        if ((this.exponent == 0 && this.mantissa == 0)) { // A *really* small number, then
+            { tmp3.mantissa = TEN.mantissa; tmp3.exponent = TEN.exponent; tmp3.sign = TEN.sign; };
+            tmp3.pow(e+1);
+        } else {
+            { tmp3.mantissa = this.mantissa; tmp3.exponent = this.exponent; tmp3.sign = this.sign; };
+            tmp3.mul10();
+        }
+        if (tmp3.compare(tmp2) <= 0) {
+            // First estimate of log10 was too low
+            e++;
+            { this.mantissa = tmp3.mantissa; this.exponent = tmp3.exponent; this.sign = tmp3.sign; };
+        }
+        return e;
+    }
+    /**
+     * Calculates the value of this <code>Real</code> raised to the power of
+     * <code>a</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p> Special cases:
+     * <ul>
+     * <li> if a is 0.0 or -0.0 then result is 1.0
+     * <li> if a is NaN then result is NaN
+     * <li> if this is NaN and a is not zero then result is NaN
+     * <li> if a is 1.0 then result is this
+     * <li> if |this| > 1.0 and a is +Infinity then result is +Infinity
+     * <li> if |this| < 1.0 and a is -Infinity then result is +Infinity
+     * <li> if |this| > 1.0 and a is -Infinity then result is +0
+     * <li> if |this| < 1.0 and a is +Infinity then result is +0
+     * <li> if |this| = 1.0 and a is ±Infinity then result is NaN
+     * <li> if this = +0 and a > 0 then result is +0
+     * <li> if this = +0 and a < 0 then result is +Inf
+     * <li> if this = -0 and a > 0, and odd integer then result is -0
+     * <li> if this = -0 and a < 0, and odd integer then result is -Inf
+     * <li> if this = -0 and a > 0, not odd integer then result is +0
+     * <li> if this = -0 and a < 0, not odd integer then result is +Inf
+     * <li> if this = +Inf and a > 0 then result is +Inf
+     * <li> if this = +Inf and a < 0 then result is +0
+     * <li> if this = -Inf and a not integer then result is NaN
+     * <li> if this = -Inf and a > 0, and odd integer then result is -Inf
+     * <li> if this = -Inf and a > 0, not odd integer then result is +Inf
+     * <li> if this = -Inf and a < 0, and odd integer then result is -0
+     * <li> if this = -Inf and a < 0, not odd integer then result is +0
+     * <li> if this < 0 and a not integer then result is NaN
+     * <li> if this < 0 and a odd integer then result is -(|this|<sup>a</sup>)
+     * <li> if this < 0 and a not odd integer then result is |this|<sup>a</sup>
+     * <li> else result is exp(ln(this)*a)
+     * </ul>
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *   <code>this = Math.{@link Math#pow(double,double) pow}(this, a);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     2 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     110
+     * </td></tr></table>
+     *
+     * @param a the <code>Real</code> argument.
+     */
+    public void pow(Real a) {
+        if ((a.exponent == 0 && a.mantissa == 0)) {
+            { this.mantissa = ONE.mantissa; this.exponent = ONE.exponent; this.sign = ONE.sign; };
+            return;
+        }
+        if ((this.exponent < 0 && this.mantissa != 0) || (a.exponent < 0 && a.mantissa != 0)) {
+            makeNan();
+            return;
+        }
+        if (a.compare(ONE)==0)
+            return;
+        if ((a.exponent < 0 && a.mantissa == 0)) {
+            { tmp1.mantissa = this.mantissa; tmp1.exponent = this.exponent; tmp1.sign = this.sign; };
+            tmp1.abs();
+            int test = tmp1.compare(ONE);
+            if (test>0) {
+                if ((a.sign==0))
+                    makeInfinity(0);
+                else
+                    makeZero();
+            } else if (test<0) {
+                if ((a.sign!=0))
+                    makeInfinity(0);
+                else
+                    makeZero();
+            } else {
+                makeNan();
+            }
+            return;
+        }
+        if ((this.exponent == 0 && this.mantissa == 0)) {
+            if ((this.sign==0)) {
+                if ((a.sign==0))
+                    makeZero();
+                else
+                    makeInfinity(0);
+            } else {
+                if (a.isIntegral() && a.isOdd()) {
+                    if ((a.sign==0))
+                        makeZero(1);
+                    else
+                        makeInfinity(1);
+                } else {
+                    if ((a.sign==0))
+                        makeZero();
+                    else
+                        makeInfinity(0);
+                }
+            }
+            return;
+        }
+        if ((this.exponent < 0 && this.mantissa == 0)) {
+            if ((this.sign==0)) {
+                if ((a.sign==0))
+                    makeInfinity(0);
+                else
+                    makeZero();
+            } else {
+                if (a.isIntegral()) {
+                    if (a.isOdd()) {
+                        if ((a.sign==0))
+                            makeInfinity(1);
+                        else
+                            makeZero(1);
+                    } else {
+                        if ((a.sign==0))
+                            makeInfinity(0);
+                        else
+                            makeZero();
+                    }
+                } else {
+                    makeNan();
+                }
+            }
+            return;
+        }
+        if (a.isIntegral() && a.exponent <= 0x4000001e) {
+            pow(a.toInteger());
+            return;
+        }
+        byte s=0;
+        if ((this.sign!=0)) {
+            if (a.isIntegral()) {
+                if (a.isOdd())
+                    s = 1;
+            } else {
+                makeNan();
+                return;
+            }
+            sign = 0;
+        }
+        { tmp1.mantissa = a.mantissa; tmp1.exponent = a.exponent; tmp1.sign = a.sign; };
+        if (tmp1.exponent <= 0x4000001e) {
+            // For increased accuracy, exponentiate with integer part of
+            // exponent by successive squaring
+            // (I really don't know why this works)
+            { tmp2.mantissa = tmp1.mantissa; tmp2.exponent = tmp1.exponent; tmp2.sign = tmp1.sign; };
+            tmp2.floor();
+            { tmp3.mantissa = this.mantissa; tmp3.exponent = this.exponent; tmp3.sign = this.sign; };
+            tmp3.pow(tmp2.toInteger());
+            tmp1.sub(tmp2);
+        } else {
+            { tmp3.mantissa = ONE.mantissa; tmp3.exponent = ONE.exponent; tmp3.sign = ONE.sign; };
+        }
+        // Do log2 and maintain accuracy
+        int e = lnInternal();
+        { tmp2.sign=(byte)0; tmp2.exponent=0x40000000; tmp2.mantissa=0x5c551d94ae0bf85dL; }; // log2(e)
+        long extra = mul128(0,tmp2,0xdf43ff68348e9f44L);
+        tmp2.assign(e);
+        extra = add128(extra,tmp2,0);
+        // Do exp2 of this multiplied by (fractional part of) exponent
+        extra = tmp1.mul128(0,this,extra);
+        tmp1.exp2Internal(extra);
+        { this.mantissa = tmp1.mantissa; this.exponent = tmp1.exponent; this.sign = tmp1.sign; };
+        mul(tmp3);
+        if (!(this.exponent < 0 && this.mantissa != 0))
+            sign = s;
+    }
+    /**
+     * Calculates the value of this <code>Real</code> raised to the power of
+     * the integer <code>a</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *   <code>this = Math.{@link Math#pow(double,double) pow}(this, a);</code>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     ½ ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     84
+     * </td></tr></table>
+     *
+     * @param a the integer argument.
+     */
+    public void pow(int a) {
+        // Calculate power of integer by successive squaring
+        boolean recp=false;
+        if (a < 0) {
+            a = -a; // Also works for 0x80000000
+            recp = true;
+        }
+        long extra = 0, expTmpExtra = 0;
+        { expTmp.mantissa = this.mantissa; expTmp.exponent = this.exponent; expTmp.sign = this.sign; };
+        { this.mantissa = ONE.mantissa; this.exponent = ONE.exponent; this.sign = ONE.sign; };
+        for (; a!=0; a>>>=1) {
+            if ((a & 1) != 0)
+                extra = mul128(extra,expTmp,expTmpExtra);
+            expTmpExtra = expTmp.mul128(expTmpExtra,expTmp,expTmpExtra);
+        }
+        if (recp)
+            extra = recip128(extra);
+        roundFrom128(extra);
+    }
+    private void sinInternal() {
+        /*
+         * Adapted from:
+         * Cephes Math Library Release 2.7:  May, 1998
+         * Copyright 1985, 1990, 1998 by Stephen L. Moshier
+         *
+         * sinl.c
+         *
+         * long double sinl(long double x);
+         */
+        // X<PI/4
+        // polynomial approximation
+        // sin(x) = x + x³ P(x²)
+        { tmp1.mantissa = this.mantissa; tmp1.exponent = this.exponent; tmp1.sign = this.sign; };
+        { tmp2.mantissa = this.mantissa; tmp2.exponent = this.exponent; tmp2.sign = this.sign; };
+        tmp2.sqr();
+        { this.sign=(byte)1; this.exponent=0x3fffffd7; this.mantissa=0x6aa891c4f0eb2713L; };//-7.578540409484280575629E-13
+        mul(tmp2);
+        { tmp3.sign=(byte)0; tmp3.exponent=0x3fffffdf; tmp3.mantissa=0x58482311f383326cL; };//1.6058363167320443249231E-10
+        add(tmp3);
+        mul(tmp2);
+        { tmp3.sign=(byte)1; tmp3.exponent=0x3fffffe6; tmp3.mantissa=0x6b9914a35f9a00d8L; };//-2.5052104881870868784055E-8
+        add(tmp3);
+        mul(tmp2);
+        { tmp3.sign=(byte)0; tmp3.exponent=0x3fffffed; tmp3.mantissa=0x5c778e94cc22e47bL; };//2.7557319214064922217861E-6
+        add(tmp3);
+        mul(tmp2);
+        { tmp3.sign=(byte)1; tmp3.exponent=0x3ffffff3; tmp3.mantissa=0x680680680629b28aL; };//-1.9841269841254799668344E-4
+        add(tmp3);
+        mul(tmp2);
+        { tmp3.sign=(byte)0; tmp3.exponent=0x3ffffff9; tmp3.mantissa=0x4444444444442b4dL; };//8.3333333333333225058715E-3
+        add(tmp3);
+        mul(tmp2);
+        { tmp3.sign=(byte)1; tmp3.exponent=0x3ffffffd; tmp3.mantissa=0x555555555555554cL; };//-1.6666666666666666640255E-1
+        add(tmp3);
+        mul(tmp2);
+        mul(tmp1);
+        add(tmp1);
+    }
+    private void cosInternal() {
+        /*
+         * Adapted from:
+         * Cephes Math Library Release 2.7:  May, 1998
+         * Copyright 1985, 1990, 1998 by Stephen L. Moshier
+         *
+         * sinl.c
+         *
+         * long double cosl(long double x);
+         */
+        // X<PI/4
+        // polynomial approximation
+        // cos(x) = 1 - x²/2 + x**4 Q(x²)
+        { tmp1.mantissa = this.mantissa; tmp1.exponent = this.exponent; tmp1.sign = this.sign; };
+        { tmp2.mantissa = this.mantissa; tmp2.exponent = this.exponent; tmp2.sign = this.sign; };
+        tmp2.sqr();
+        { this.sign=(byte)0; this.exponent=0x3fffffd3; this.mantissa=0x6aaf461d37ccba1bL; };//4.7377507964246204691685E-14
+        mul(tmp2);
+        { tmp3.sign=(byte)1; tmp3.exponent=0x3fffffdb; tmp3.mantissa=0x64e4c907ac7a179bL; };//-1.147028484342535976567E-11
+        add(tmp3);
+        mul(tmp2);
+        { tmp3.sign=(byte)0; tmp3.exponent=0x3fffffe3; tmp3.mantissa=0x47bb632432cf29a8L; };//2.0876754287081521758361E-9
+        add(tmp3);
+        mul(tmp2);
+        { tmp3.sign=(byte)1; tmp3.exponent=0x3fffffea; tmp3.mantissa=0x49f93edd7ae32696L; };//-2.7557319214999787979814E-7
+        add(tmp3);
+        mul(tmp2);
+        { tmp3.sign=(byte)0; tmp3.exponent=0x3ffffff0; tmp3.mantissa=0x68068068063329f7L; };//2.4801587301570552304991E-5L
+        add(tmp3);
+        mul(tmp2);
+        { tmp3.sign=(byte)1; tmp3.exponent=0x3ffffff6; tmp3.mantissa=0x5b05b05b05b03db3L; };//-1.3888888888888872993737E-3
+        add(tmp3);
+        mul(tmp2);
+        { tmp3.sign=(byte)0; tmp3.exponent=0x3ffffffb; tmp3.mantissa=0x555555555555554dL; };//4.1666666666666666609054E-2
+        add(tmp3);
+        mul(tmp2);
+        sub(HALF);
+        mul(tmp2);
+        add(ONE);
+    }
+    /**
+     * Calculates the trigonometric sine of this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     * The input value is treated as an angle measured in radians.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#sin(double) sin}(this);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     1 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     28
+     * </td></tr></table>
+     */
+    public void sin() {
+        if (!(this.exponent >= 0 && this.mantissa != 0)) {
+            if (!(this.exponent == 0 && this.mantissa == 0))
+                makeNan();
+            return;
+        }
+        // Since sin(-x) = -sin(x) we can make sure that x > 0
+        boolean negative = false;
+        if ((this.sign!=0)) {
+            abs();
+            negative = true;
+        }
+        // Then reduce the argument to the range of 0 < x < pi*2
+        if (this.compare(PI2) > 0)
+            modInternal(PI2,0x62633145c06e0e69L);
+        // Since sin(pi*2 - x) = -sin(x) we can reduce the range 0 < x < pi
+        if (this.compare(PI) > 0) {
+            sub(PI2);
+            neg();
+            negative = !negative;
+        }
+        // Since sin(x) = sin(pi - x) we can reduce the range to 0 < x < pi/2
+        if (this.compare(PI_2) > 0) {
+            sub(PI);
+            neg();
+        }
+        // Since sin(x) = cos(pi/2 - x) we can reduce the range to 0 < x < pi/4
+        if (this.compare(PI_4) > 0) {
+            sub(PI_2);
+            neg();
+            cosInternal();
+        } else {
+            sinInternal();
+        }
+        if (negative)
+            neg();
+        if ((this.exponent == 0 && this.mantissa == 0))
+            abs(); // Remove confusing "-"
+    }
+    /**
+     * Calculates the trigonometric cosine of this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     * The input value is treated as an angle measured in radians.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#cos(double) cos}(this);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     1 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     37
+     * </td></tr></table>
+     */
+    public void cos() {
+        if ((this.exponent == 0 && this.mantissa == 0)) {
+            { this.mantissa = ONE.mantissa; this.exponent = ONE.exponent; this.sign = ONE.sign; };
+            return;
+        }
+        if ((this.sign!=0))
+            abs();
+        if (this.compare(PI_4) < 0) {
+            cosInternal();
+        } else {
+            add(PI_2);
+            sin();
+        }
+    }
+    /**
+     * Calculates the trigonometric tangent of this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     * The input value is treated as an angle measured in radians.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#tan(double) tan}(this);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     2 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     70
+     * </td></tr></table>
+     */
+    public void tan() {
+        { tmp4.mantissa = this.mantissa; tmp4.exponent = this.exponent; tmp4.sign = this.sign; };
+        tmp4.cos();
+        sin();
+        div(tmp4);
+    }
+    /**
+     * Calculates the trigonometric arc sine of this <code>Real</code>,
+     * in the range -&pi;/2 to &pi;/2.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#asin(double) asin}(this);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     3 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     68
+     * </td></tr></table>
+     */
+    public void asin() {
+        { tmp1.mantissa = this.mantissa; tmp1.exponent = this.exponent; tmp1.sign = this.sign; };
+        sqr();
+        neg();
+        add(ONE);
+        rsqrt();
+        mul(tmp1);
+        atan();
+    }
+    /**
+     * Calculates the trigonometric arc cosine of this <code>Real</code>,
+     * in the range 0.0 to &pi;.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#acos(double) acos}(this);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     2 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     67
+     * </td></tr></table>
+     */
+    public void acos() {
+        boolean negative = (this.sign!=0);
+        abs();
+        { tmp1.mantissa = this.mantissa; tmp1.exponent = this.exponent; tmp1.sign = this.sign; };
+        sqr();
+        neg();
+        add(ONE);
+        sqrt();
+        div(tmp1);
+        atan();
+        if (negative) {
+            neg();
+            add(PI);
+        }
+    }
+    /**
+     * Calculates the trigonometric arc tangent of this <code>Real</code>,
+     * in the range -&pi;/2 to &pi;/2.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#atan(double) atan}(this);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     2 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     37
+     * </td></tr></table>
+     */
+    public void atan() {
+        /*
+         * Adapted from:
+         * Cephes Math Library Release 2.7:  May, 1998
+         * Copyright 1984, 1990, 1998 by Stephen L. Moshier
+         *
+         * atanl.c
+         *
+         * long double atanl(long double x);
+         */
+        if ((this.exponent == 0 && this.mantissa == 0) || (this.exponent < 0 && this.mantissa != 0))
+            return;
+        if ((this.exponent < 0 && this.mantissa == 0)) {
+            byte s = sign;
+            { this.mantissa = PI_2.mantissa; this.exponent = PI_2.exponent; this.sign = PI_2.sign; };
+            sign = s;
+            return;
+        }
+        byte s = sign;
+        sign = 0;
+        // range reduction
+        boolean addPI_2 = false;
+        boolean addPI_4 = false;
+        { tmp1.mantissa = SQRT2.mantissa; tmp1.exponent = SQRT2.exponent; tmp1.sign = SQRT2.sign; };
+        tmp1.add(ONE);
+        if (this.compare(tmp1) > 0) {
+            addPI_2 = true;
+            recip();
+            neg();
+        } else {
+            tmp1.sub(TWO);
+            if (this.compare(tmp1) > 0) {
+                addPI_4 = true;
+                { tmp1.mantissa = this.mantissa; tmp1.exponent = this.exponent; tmp1.sign = this.sign; };
+                tmp1.add(ONE);
+                sub(ONE);
+                div(tmp1);
+            }
+        }
+        // Now |X|<sqrt(2)-1
+        // rational approximation
+        // atan(x) = x + x³ P(x²)/Q(x²)
+        { tmp1.mantissa = this.mantissa; tmp1.exponent = this.exponent; tmp1.sign = this.sign; };
+        { tmp2.mantissa = this.mantissa; tmp2.exponent = this.exponent; tmp2.sign = this.sign; };
+        tmp2.sqr();
+        mul(tmp2);
+        { tmp3.sign=(byte)1; tmp3.exponent=0x3fffffff; tmp3.mantissa=0x6f2f89336729c767L; };//-0.8686381817809218753544
+        tmp3.mul(tmp2);
+        { tmp4.sign=(byte)1; tmp4.exponent=0x40000003; tmp4.mantissa=0x7577d35fd03083f3L; };//-14.683508633175792446076
+        tmp3.add(tmp4);
+        tmp3.mul(tmp2);
+        { tmp4.sign=(byte)1; tmp4.exponent=0x40000005; tmp4.mantissa=0x7ff42abff948a9f7L; };//-63.976888655834347413154
+        tmp3.add(tmp4);
+        tmp3.mul(tmp2);
+        { tmp4.sign=(byte)1; tmp4.exponent=0x40000006; tmp4.mantissa=0x63fd1f9f76d37cebL; };//-99.988763777265819915721
+        tmp3.add(tmp4);
+        tmp3.mul(tmp2);
+        { tmp4.sign=(byte)1; tmp4.exponent=0x40000005; tmp4.mantissa=0x65c9c9b0b55e5b62L; };//-50.894116899623603312185
+        tmp3.add(tmp4);
+        mul(tmp3);
+        { tmp3.mantissa = tmp2.mantissa; tmp3.exponent = tmp2.exponent; tmp3.sign = tmp2.sign; };
+        { tmp4.sign=(byte)0; tmp4.exponent=0x40000004; tmp4.mantissa=0x5bed73b744a72a6aL; };//22.981886733594175366172
+        tmp3.add(tmp4);
+        tmp3.mul(tmp2);
+        { tmp4.sign=(byte)0; tmp4.exponent=0x40000007; tmp4.mantissa=0x47fed7d13d233b5cL; };//143.99096122250781605352
+        tmp3.add(tmp4);
+        tmp3.mul(tmp2);
+        { tmp4.sign=(byte)0; tmp4.exponent=0x40000008; tmp4.mantissa=0x5a5c35f774e071d5L; };//361.44079386152023162701
+        tmp3.add(tmp4);
+        tmp3.mul(tmp2);
+        { tmp4.sign=(byte)0; tmp4.exponent=0x40000008; tmp4.mantissa=0x61e4d84c2853d5e0L; };//391.57570175111990631099
+        tmp3.add(tmp4);
+        tmp3.mul(tmp2);
+        { tmp4.sign=(byte)0; tmp4.exponent=0x40000007; tmp4.mantissa=0x4c5757448806c48eL; };//152.68235069887081006606
+        tmp3.add(tmp4);
+        div(tmp3);
+        add(tmp1);
+        if (addPI_2)
+            add(PI_2);
+        if (addPI_4)
+            add(PI_4);
+        if (s != 0)
+            neg();
+    }
+    /**
+     * Calculates the trigonometric arc tangent of this
+     * <code>Real</code> divided by <code>x</code>, in the range -&pi;
+     * to &pi;. The signs of both arguments are used to determine the
+     * quadrant of the result. Replaces the contents of this
+     * <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#atan2(double,double)
+     *           atan2}(this,x);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     2 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     48
+     * </td></tr></table>
+     *
+     * @param x the <code>Real</code> argument.
+     */
+    public void atan2(Real x) {
+        if ((this.exponent < 0 && this.mantissa != 0) || (x.exponent < 0 && x.mantissa != 0) || ((this.exponent < 0 && this.mantissa == 0) && (x.exponent < 0 && x.mantissa == 0))) {
+            makeNan();
+            return;
+        }
+        if ((this.exponent == 0 && this.mantissa == 0) && (x.exponent == 0 && x.mantissa == 0))
+            return;
+        byte s = sign;
+        byte s2 = x.sign;
+        sign = 0;
+        x.sign = 0;
+        div(x);
+        atan();
+        if (s2 != 0) {
+            neg();
+            add(PI);
+        }
+        sign = s;
+    }
+    /**
+     * Calculates the hyperbolic sine of this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#sinh(double) sinh}(this);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     2 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     67
+     * </td></tr></table>
+     */
+    public void sinh() {
+        { tmp1.mantissa = this.mantissa; tmp1.exponent = this.exponent; tmp1.sign = this.sign; };
+        tmp1.neg();
+        tmp1.exp();
+        exp();
+        sub(tmp1);
+        scalbn(-1);
+    }
+    /**
+     * Calculates the hyperbolic cosine of this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#cosh(double) cosh}(this);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     2 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     66
+     * </td></tr></table>
+     */
+    public void cosh() {
+        { tmp1.mantissa = this.mantissa; tmp1.exponent = this.exponent; tmp1.sign = this.sign; };
+        tmp1.neg();
+        tmp1.exp();
+        exp();
+        add(tmp1);
+        scalbn(-1);
+    }
+    /**
+     * Calculates the hyperbolic tangent of this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#tanh(double) tanh}(this);</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     2 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     70
+     * </td></tr></table>
+     */
+    public void tanh() {
+        { tmp1.mantissa = this.mantissa; tmp1.exponent = this.exponent; tmp1.sign = this.sign; };
+        tmp1.neg();
+        tmp1.exp();
+        exp();
+        { tmp2.mantissa = this.mantissa; tmp2.exponent = this.exponent; tmp2.sign = this.sign; };
+        tmp2.add(tmp1);
+        sub(tmp1);
+        div(tmp2);
+    }
+    /**
+     * Calculates the hyperbolic arc sine of this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <i>none</i>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     2 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     77
+     * </td></tr></table>
+     */
+    public void asinh() {
+        if (!(this.exponent >= 0 && this.mantissa != 0))
+            return;
+        // Use symmetry to prevent underflow error for very large negative
+        // values
+        byte s = sign;
+        sign = 0;
+        { tmp1.mantissa = this.mantissa; tmp1.exponent = this.exponent; tmp1.sign = this.sign; };
+        tmp1.sqr();
+        tmp1.add(ONE);
+        tmp1.sqrt();
+        add(tmp1);
+        ln();
+        if (!(this.exponent < 0 && this.mantissa != 0))
+            sign = s;
+    }
+    /**
+     * Calculates the hyperbolic arc cosine of this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <i>none</i>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     2 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     75
+     * </td></tr></table>
+     */
+    public void acosh() {
+        { tmp1.mantissa = this.mantissa; tmp1.exponent = this.exponent; tmp1.sign = this.sign; };
+        tmp1.sqr();
+        tmp1.sub(ONE);
+        tmp1.sqrt();
+        add(tmp1);
+        ln();
+    }
+    /**
+     * Calculates the hyperbolic arc tangent of this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <i>none</i>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     2 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     57
+     * </td></tr></table>
+     */
+    public void atanh() {
+        { tmp1.mantissa = this.mantissa; tmp1.exponent = this.exponent; tmp1.sign = this.sign; };
+        tmp1.neg();
+        tmp1.add(ONE);
+        add(ONE);
+        div(tmp1);
+        ln();
+        scalbn(-1);
+    }
+    /**
+     * Calculates the factorial of this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     * The definition is generalized to all real numbers (not only integers),
+     * by using the fact that <code>(n!)={@link #gamma() gamma}(n+1)</code>.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <i>none</i>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     15 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     8-190
+     * </td></tr></table>
+     */
+    public void fact() {
+        if (!(this.exponent >= 0))
+            return;
+        if (!this.isIntegral() || this.compare(ZERO)<0 || this.compare(200)>0)
+        {
+            // x<0, x>200 or not integer: fact(x) = gamma(x+1)
+            add(ONE);
+            gamma();
+            return;
+        }
+        { tmp1.mantissa = this.mantissa; tmp1.exponent = this.exponent; tmp1.sign = this.sign; };
+        { this.mantissa = ONE.mantissa; this.exponent = ONE.exponent; this.sign = ONE.sign; };
+        while (tmp1.compare(ONE) > 0) {
+            mul(tmp1);
+            tmp1.sub(ONE);
+        }
+    }
+    /**
+     * Calculates the gamma function for this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <i>none</i>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     100+ ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     190
+     * </td></tr></table>
+     */
+    public void gamma() {
+        if (!(this.exponent >= 0))
+            return;
+        // x<0: gamma(-x) = -pi/(x*gamma(x)*sin(pi*x))
+        boolean negative = (this.sign!=0);
+        abs();
+        { tmp1.mantissa = this.mantissa; tmp1.exponent = this.exponent; tmp1.sign = this.sign; };
+        // x<n: gamma(x) = gamma(x+m)/x*(x+1)*(x+2)*...*(x+m-1)
+        // n=20
+        { tmp2.mantissa = ONE.mantissa; tmp2.exponent = ONE.exponent; tmp2.sign = ONE.sign; };
+        boolean divide = false;
+        while (this.compare(20) < 0) {
+            divide = true;
+            tmp2.mul(this);
+            add(ONE);
+        }
+        // x>n: gamma(x) = exp((x-1/2)*ln(x) - x + ln(2*pi)/2 + 1/12x - 1/360x³
+        //                     + 1/1260x**5 - 1/1680x**7+1/1188x**9)
+        { tmp3.mantissa = this.mantissa; tmp3.exponent = this.exponent; tmp3.sign = this.sign; }; // x
+        { tmp4.mantissa = this.mantissa; tmp4.exponent = this.exponent; tmp4.sign = this.sign; };
+        tmp4.sqr(); // x²
+        // (x-1/2)*ln(x)-x
+        ln(); { tmp5.mantissa = tmp3.mantissa; tmp5.exponent = tmp3.exponent; tmp5.sign = tmp3.sign; }; tmp5.sub(HALF); mul(tmp5); sub(tmp3);
+        // + ln(2*pi)/2
+        { tmp5.sign=(byte)0; tmp5.exponent=0x3fffffff; tmp5.mantissa=0x759fc72192fad29aL; }; add(tmp5);
+        // + 1/12x
+        tmp5.assign( 12); tmp5.mul(tmp3); tmp5.recip(); add(tmp5); tmp3.mul(tmp4);
+        // - 1/360x³
+        tmp5.assign( 360); tmp5.mul(tmp3); tmp5.recip(); sub(tmp5); tmp3.mul(tmp4);
+        // + 1/1260x**5
+        tmp5.assign(1260); tmp5.mul(tmp3); tmp5.recip(); add(tmp5); tmp3.mul(tmp4);
+        // - 1/1680x**7
+        tmp5.assign(1680); tmp5.mul(tmp3); tmp5.recip(); sub(tmp5); tmp3.mul(tmp4);
+        // + 1/1188x**9
+        tmp5.assign(1188); tmp5.mul(tmp3); tmp5.recip(); add(tmp5);
+        exp();
+        if (divide)
+            div(tmp2);
+        if (negative) {
+            { tmp5.mantissa = tmp1.mantissa; tmp5.exponent = tmp1.exponent; tmp5.sign = tmp1.sign; }; // sin() uses tmp1
+            // -pi/(x*gamma(x)*sin(pi*x))
+            mul(tmp5);
+            tmp5.scalbn(-1); tmp5.frac(); tmp5.mul(PI2); // Fixes integer inaccuracy
+            tmp5.sin(); mul(tmp5); recip(); mul(PI); neg();
+        }
+    }
+    private void erfc1Internal() {
+        //                                3       5        7        9
+        //                 2    /        x       x        x        x                  // erfc(x) = 1 - ------ | x  -  ---  +  ----  -  ----  +  ----  - ... |
+        //              sqrt(pi)\        3      2!*5     3!*7     4!*9        /
+        //
+        long extra=0,tmp1Extra,tmp2Extra,tmp3Extra,tmp4Extra;
+        { tmp1.mantissa = this.mantissa; tmp1.exponent = this.exponent; tmp1.sign = this.sign; }; tmp1Extra = 0;
+        { tmp2.mantissa = this.mantissa; tmp2.exponent = this.exponent; tmp2.sign = this.sign; };
+        tmp2Extra = tmp2.mul128(0,tmp2,0);
+        tmp2.neg();
+        { tmp3.mantissa = ONE.mantissa; tmp3.exponent = ONE.exponent; tmp3.sign = ONE.sign; }; tmp3Extra = 0;
+        int i=1;
+        do {
+            tmp1Extra = tmp1.mul128(tmp1Extra,tmp2,tmp2Extra);
+            tmp4.assign(i);
+            tmp3Extra = tmp3.mul128(tmp3Extra,tmp4,0);
+            tmp4.assign(2*i+1);
+            tmp4Extra = tmp4.mul128(0,tmp3,tmp3Extra);
+            tmp4Extra = tmp4.recip128(tmp4Extra);
+            tmp4Extra = tmp4.mul128(tmp4Extra,tmp1,tmp1Extra);
+            extra = add128(extra,tmp4,tmp4Extra);
+            i++;
+        } while (exponent - tmp4.exponent < 128);
+        { tmp1.sign=(byte)1; tmp1.exponent=0x40000000; tmp1.mantissa=0x48375d410a6db446L; }; // -2/sqrt(pi)
+        extra = mul128(extra,tmp1,0xb8ea453fb5ff61a2L);
+        extra = add128(extra,ONE,0);
+        roundFrom128(extra);
+    }
+    private void erfc2Internal() {
+        //             -x² -1
+        //            e   x   /      1      3       3*5     3*5*7                // erfc(x) = -------- | 1 - --- + ------ - ------ + ------ - ... |
+        //           sqrt(pi) \     2x²        2        3        4       /
+        //                                (2x²)    (2x²)    (2x²)
+        // Calculate iteration stop criteria
+        { tmp1.mantissa = this.mantissa; tmp1.exponent = this.exponent; tmp1.sign = this.sign; };
+        tmp1.sqr();
+        { tmp2.sign=(byte)0; tmp2.exponent=0x40000000; tmp2.mantissa=0x5c3811b4bfd0c8abL; }; // 1/0.694
+        tmp2.mul(tmp1);
+        tmp2.sub(HALF);
+        int digits = tmp2.toInteger(); // number of accurate digits = x*x/0.694-0.5
+        if (digits > 64)
+            digits = 64;
+        tmp1.scalbn(1);
+        int dxq = tmp1.toInteger()+1;
+        { tmp1.mantissa = this.mantissa; tmp1.exponent = this.exponent; tmp1.sign = this.sign; };
+        recip();
+        { tmp2.mantissa = this.mantissa; tmp2.exponent = this.exponent; tmp2.sign = this.sign; };
+        { tmp3.mantissa = this.mantissa; tmp3.exponent = this.exponent; tmp3.sign = this.sign; };
+        tmp3.sqr();
+        tmp3.neg();
+        tmp3.scalbn(-1);
+        { this.mantissa = ONE.mantissa; this.exponent = ONE.exponent; this.sign = ONE.sign; };
+        { tmp4.mantissa = ONE.mantissa; tmp4.exponent = ONE.exponent; tmp4.sign = ONE.sign; };
+        int i=1;
+        do {
+            tmp4.mul(2*i-1);
+            tmp4.mul(tmp3);
+            add(tmp4);
+            i++;
+        } while (tmp4.exponent-0x40000000>-(digits+2) && 2*i-1<dxq);
+        mul(tmp2);
+        tmp1.sqr();
+        tmp1.neg();
+        tmp1.exp();
+        mul(tmp1);
+        { tmp1.sign=(byte)0; tmp1.exponent=0x3fffffff; tmp1.mantissa=0x48375d410a6db447L; }; // 1/sqrt(pi)
+        mul(tmp1);
+    }
+    /**
+     * Calculates the complementary error function for this <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p>The complementary error function is defined as the integral from
+     * x to infinity of 2/&#8730;<span style="text-decoration:
+     * overline;">&pi;</span>&nbsp;·<i>e</i><sup>-t²</sup>&nbsp;dt. It is
+     * related to the error function, <i>erf</i>, by the formula
+     * erfc(x)=1-erf(x).
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <i>none</i>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     2<sup>19</sup> ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     80-4900
+     * </td></tr></table>
+     */
+    public void erfc() {
+        if ((this.exponent < 0 && this.mantissa != 0))
+            return;
+        if ((this.exponent == 0 && this.mantissa == 0)) {
+            { this.mantissa = ONE.mantissa; this.exponent = ONE.exponent; this.sign = ONE.sign; };
+            return;
+        }
+        if ((this.exponent < 0 && this.mantissa == 0) || toInteger()>27281) {
+            if ((this.sign!=0)) {
+                { this.mantissa = TWO.mantissa; this.exponent = TWO.exponent; this.sign = TWO.sign; };
+            } else
+                makeZero(0);
+            return;
+        }
+        byte s = sign;
+        sign = 0;
+        { tmp1.sign=(byte)0; tmp1.exponent=0x40000002; tmp1.mantissa=0x570a3d70a3d70a3dL; }; // 5.44
+        if (this.lessThan(tmp1))
+            erfc1Internal();
+        else
+            erfc2Internal();
+        if (s != 0) {
+            neg();
+            add(TWO);
+        }
+    }
+    /**
+     * Calculates the inverse complementary error function for this
+     * <code>Real</code>.
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <i>none</i>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     2<sup>19</sup> ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     240-5100
+     * </td></tr></table>
+     */
+    public void inverfc() {
+        if ((this.exponent < 0 && this.mantissa != 0) || (this.sign!=0) || this.greaterThan(TWO)) {
+            makeNan();
+            return;
+        }
+        if ((this.exponent == 0 && this.mantissa == 0)) {
+            makeInfinity(0);
+            return;
+        }
+        if (this.equalTo(TWO)) {
+            makeInfinity(1);
+            return;
+        }
+        int sign = ONE.compare(this);
+        if (sign==0) {
+            makeZero();
+            return;
+        }
+        if (sign<0) {
+            neg();
+            add(TWO);
+        }
+        // Using invphi to calculate inverfc, like this
+        // inverfc(x) = -invphi(x/2)/(sqrt(2))
+        scalbn(-1);
+        // Inverse Phi Algorithm (phi(Z)=P, so invphi(P)=Z)
+        // ------------------------------------------------
+        // Part 1: Numerical Approximation Method for Inverse Phi
+        // This accepts input of P and outputs approximate Z as Y
+        // Source:Odeh & Evans. 1974. AS 70. Applied Statistics.
+        // R = sqrt(Ln(1/(Q²)))
+        { tmp1.mantissa = this.mantissa; tmp1.exponent = this.exponent; tmp1.sign = this.sign; };
+        tmp1.ln();
+        tmp1.mul(-2);
+        tmp1.sqrt();
+        // Y = -(R+((((P4*R+P3)*R+P2)*R+P1)*R+P0)/((((Q4*R+Q3)*R*Q2)*R+Q1)*R+Q0))
+        { tmp2.sign=(byte)1; tmp2.exponent=0x3ffffff1; tmp2.mantissa=0x5f22bb0fb4698674L; }; // P4=-0.0000453642210148
+        tmp2.mul(tmp1);
+        { tmp3.sign=(byte)1; tmp3.exponent=0x3ffffffa; tmp3.mantissa=0x53a731ce1ea0be15L; }; // P3=-0.0204231210245
+        tmp2.add(tmp3);
+        tmp2.mul(tmp1);
+        { tmp3.sign=(byte)1; tmp3.exponent=0x3ffffffe; tmp3.mantissa=0x579d2d719fc517f3L; }; // P2=-0.342242088547
+        tmp2.add(tmp3);
+        tmp2.mul(tmp1);
+        tmp2.add(-1); // P1=-1
+        tmp2.mul(tmp1);
+        { tmp3.sign=(byte)1; tmp3.exponent=0x3ffffffe; tmp3.mantissa=0x527dd3193bc8dd4cL; }; // P0=-0.322232431088
+        tmp2.add(tmp3);
+        { tmp3.sign=(byte)0; tmp3.exponent=0x3ffffff7; tmp3.mantissa=0x7e5b0f681d161e7dL; }; // Q4=0.0038560700634
+        tmp3.mul(tmp1);
+        { tmp4.sign=(byte)0; tmp4.exponent=0x3ffffffc; tmp4.mantissa=0x6a05ccf9917da0a8L; }; // Q3=0.103537752850
+        tmp3.add(tmp4);
+        tmp3.mul(tmp1);
+        { tmp4.sign=(byte)0; tmp4.exponent=0x3fffffff; tmp4.mantissa=0x43fb32c0d3c14ec4L; }; // Q2=0.531103462366
+        tmp3.add(tmp4);
+        tmp3.mul(tmp1);
+        { tmp4.sign=(byte)0; tmp4.exponent=0x3fffffff; tmp4.mantissa=0x4b56a41226f4ba95L; }; // Q1=0.588581570495
+        tmp3.add(tmp4);
+        tmp3.mul(tmp1);
+        { tmp4.sign=(byte)0; tmp4.exponent=0x3ffffffc; tmp4.mantissa=0x65bb9a7733dd5062L; }; // Q0=0.0993484626060
+        tmp3.add(tmp4);
+        tmp2.div(tmp3);
+        tmp1.add(tmp2);
+        tmp1.neg();
+        { sqrtTmp.mantissa = tmp1.mantissa; sqrtTmp.exponent = tmp1.exponent; sqrtTmp.sign = tmp1.sign; }; // sqrtTmp and tmp5 not used by erfc() and exp()
+        // Part 2: Refine to accuracy of erfc Function
+        // This accepts inputs Y and P (from above) and outputs Z
+        // (Using Halley's third order method for finding roots of equations)
+        // Q = erfc(-Y/sqrt(2))/2-P
+        { tmp5.mantissa = sqrtTmp.mantissa; tmp5.exponent = sqrtTmp.exponent; tmp5.sign = sqrtTmp.sign; };
+        tmp5.mul(SQRT1_2);
+        tmp5.neg();
+        tmp5.erfc();
+        tmp5.scalbn(-1);
+        tmp5.sub(this);
+        // R = Q*sqrt(2*pi)*e^(Y²/2)
+        { tmp3.mantissa = sqrtTmp.mantissa; tmp3.exponent = sqrtTmp.exponent; tmp3.sign = sqrtTmp.sign; };
+        tmp3.sqr();
+        tmp3.scalbn(-1);
+        tmp3.exp();
+        tmp5.mul(tmp3);
+        { tmp3.sign=(byte)0; tmp3.exponent=0x40000001; tmp3.mantissa=0x50364c7fd89c1659L; }; // sqrt(2*pi)
+        tmp5.mul(tmp3);
+        // Z = Y-R/(1+R*Y/2)
+        { this.mantissa = sqrtTmp.mantissa; this.exponent = sqrtTmp.exponent; this.sign = sqrtTmp.sign; };
+        mul(tmp5);
+        scalbn(-1);
+        add(ONE);
+        rdiv(tmp5);
+        neg();
+        add(sqrtTmp);
+        // calculate inverfc(x) = -invphi(x/2)/(sqrt(2))
+        mul(SQRT1_2);
+        if (sign>0)
+            neg();
+    }
+    //*************************************************************************
+    // Calendar conversions taken from
+    // http://www.fourmilab.ch/documents/calendar/
+    private static int floorDiv(int a, int b) {
+        if (a>=0)
+            return a/b;
+        return -((-a+b-1)/b);
+    }
+    private static int floorMod(int a, int b) {
+        if (a>=0)
+            return a%b;
+        return a+((-a+b-1)/b)*b;
+    }
+    private static boolean leap_gregorian(int year) {
+        return ((year % 4) == 0) &&
+            (!(((year % 100) == 0) && ((year % 400) != 0)));
+    }
+    // GREGORIAN_TO_JD -- Determine Julian day number from Gregorian
+    // calendar date -- Except that we use 1/1-0 as day 0
+    private static int gregorian_to_jd(int year, int month, int day) {
+        return ((366 - 1) +
+                (365 * (year - 1)) +
+                (floorDiv(year - 1, 4)) +
+                (-floorDiv(year - 1, 100)) +
+                (floorDiv(year - 1, 400)) +
+                ((((367 * month) - 362) / 12) +
+                 ((month <= 2) ? 0 : (leap_gregorian(year) ? -1 : -2)) + day));
+    }
+    // JD_TO_GREGORIAN -- Calculate Gregorian calendar date from Julian
+    // day -- Except that we use 1/1-0 as day 0
+    private static int jd_to_gregorian(int jd) {
+        int wjd, depoch, quadricent, dqc, cent, dcent, quad, dquad,
+            yindex, year, yearday, leapadj, month, day;
+        wjd = jd;
+        depoch = wjd - 366;
+        quadricent = floorDiv(depoch, 146097);
+        dqc = floorMod(depoch, 146097);
+        cent = floorDiv(dqc, 36524);
+        dcent = floorMod(dqc, 36524);
+        quad = floorDiv(dcent, 1461);
+        dquad = floorMod(dcent, 1461);
+        yindex = floorDiv(dquad, 365);
+        year = (quadricent * 400) + (cent * 100) + (quad * 4) + yindex;
+        if (!((cent == 4) || (yindex == 4)))
+            year++;
+        yearday = wjd - gregorian_to_jd(year, 1, 1);
+        leapadj = ((wjd < gregorian_to_jd(year, 3, 1)) ? 0
+                   : (leap_gregorian(year) ? 1 : 2));
+        month = floorDiv(((yearday + leapadj) * 12) + 373, 367);
+        day = (wjd - gregorian_to_jd(year, month, 1)) + 1;
+        return (year*100+month)*100+day;
+    }
+    /**
+     * Converts this <code>Real</code> from "hours" to "days, hours,
+     * minutes and seconds".
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p>The format converted to is encoded into the digits of the
+     * number (in decimal form):
+     * "<code>DDDDhh.mmss</code>". Here "<code>DDDD</code>," is number
+     * of days, "<code>hh</code>" is hours (0-23), "<code>mm</code>" is
+     * minutes (0-59) and "<code>ss</code>" is seconds
+     * (0-59). Additional digits represent fractions of a second.
+     *
+     * <p>If the number of hours of the input is greater or equal to
+     * 8784 (number of hours in year <code>0</code>), the format
+     * converted to is instead "<code>YYYYMMDDhh.mmss</code>". Here
+     * "<code>YYYY</code>" is the number of years since the imaginary
+     * year <code>0</code> in the Gregorian calendar, extrapolated back
+     * from year 1582. "<code>MM</code>" is the month (1-12) and
+     * "<code>DD</code>" is the day of the month (1-31). See a thorough
+     * discussion of date calculations <a
+     * href="http://midp-calc.sourceforge.net/Calc.html#DateNote">here</a>.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <i>none</i>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     ?
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     19
+     * </td></tr></table>
+     */
+    public void toDHMS() {
+        if (!(this.exponent >= 0 && this.mantissa != 0))
+            return;
+        boolean negative = (this.sign!=0);
+        abs();
+        int D,m;
+        long h;
+        h = toLong();
+        frac();
+        tmp1.assign(60);
+        mul(tmp1);
+        m = toInteger();
+        frac();
+        mul(tmp1);
+        // MAGIC ROUNDING: Check if we are 2**-16 sec short of a whole minute
+        // i.e. "seconds" > 59.999985
+        { tmp2.mantissa = ONE.mantissa; tmp2.exponent = ONE.exponent; tmp2.sign = ONE.sign; };
+        tmp2.scalbn(-16);
+        add(tmp2);
+        if (this.compare(tmp1) >= 0) {
+            // Yes. So set zero secs instead and carry over to mins and hours
+            { this.mantissa = ZERO.mantissa; this.exponent = ZERO.exponent; this.sign = ZERO.sign; };
+            m++;
+            if (m >= 60) {
+                m -= 60;
+                h++;
+            }
+            // Phew! That was close. From now on it is integer arithmetic...
+        } else {
+            // Nope. So try to undo the damage...
+            sub(tmp2);
+        }
+        D = (int)(h/24);
+        h %= 24;
+        if (D >= 366)
+            D = jd_to_gregorian(D);
+        add(m*100);
+        div(10000);
+        tmp1.assign(D*100L+h);
+        add(tmp1);
+        if (negative)
+            neg();
+    }
+    /**
+     * Converts this <code>Real</code> from "days, hours, minutes and
+     * seconds" to "hours".
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p>The format converted from is encoded into the digits of the
+     * number (in decimal form):
+     * "<code>DDDDhh.mmss</code>". Here "<code>DDDD</code>" is number of
+     * days, "<code>hh</code>" is hours (0-23), "<code>mm</code>" is
+     * minutes (0-59) and "<code>ss</code>" is seconds
+     * (0-59). Additional digits represent fractions of a second.
+     *
+     * <p>If the number of days in the input is greater than or equal to
+     * 10000, the format converted from is instead
+     * "<code>YYYYMMDDhh.mmss</code>". Here "<code>YYYY</code>" is the
+     * number of years since the imaginary year <code>0</code> in the
+     * Gregorian calendar, extrapolated back from year
+     * 1582. "<code>MM</code>" is the month (1-12) and
+     * "<code>DD</code>" is the day of the month (1-31). If month or day
+     * is 0 it is treated as 1. See a thorough discussion of date
+     * calculations <a
+     * href="http://midp-calc.sourceforge.net/Calc.html#DateNote">here</a>.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <i>none</i>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     ?
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     19
+     * </td></tr></table>
+     */
+    public void fromDHMS() {
+        if (!(this.exponent >= 0 && this.mantissa != 0))
+            return;
+        boolean negative = (this.sign!=0);
+        abs();
+        int Y,M,D,m;
+        long h;
+        h = toLong();
+        frac();
+        tmp1.assign(100);
+        mul(tmp1);
+        m = toInteger();
+        frac();
+        mul(tmp1);
+        // MAGIC ROUNDING: Check if we are 2**-10 second short of 100 seconds
+        // i.e. "seconds" > 99.999
+        { tmp2.mantissa = ONE.mantissa; tmp2.exponent = ONE.exponent; tmp2.sign = ONE.sign; };
+        tmp2.scalbn(-10);
+        add(tmp2);
+        if (this.compare(tmp1) >= 0) {
+            // Yes. So set zero secs instead and carry over to mins and hours
+            { this.mantissa = ZERO.mantissa; this.exponent = ZERO.exponent; this.sign = ZERO.sign; };
+            m++;
+            if (m >= 100) {
+                m -= 100;
+                h++;
+            }
+            // Phew! That was close. From now on it is integer arithmetic...
+        } else {
+            // Nope. So try to undo the damage...
+            sub(tmp2);
+        }
+        D = (int)(h/100);
+        h %= 100;
+        if (D>=10000) {
+            M = D/100;
+            D %= 100;
+            if (D==0) D=1;
+            Y = M/100;
+            M %= 100;
+            if (M==0) M=1;
+            D = gregorian_to_jd(Y,M,D);
+        }
+        add(m*60);
+        div(3600);
+        tmp1.assign(D*24L+h);
+        add(tmp1);
+        if (negative)
+            neg();
+    }
+    /**
+     * Assigns this <code>Real</code> the current time. The time is
+     * encoded into the digits of the number (in decimal form), using the
+     * format "<code>hh.mmss</code>", where "<code>hh</code>" is hours,
+     * "<code>mm</code>" is minutes and "code>ss</code>" is seconds.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <i>none</i>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     ½ ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     8.9
+     * </td></tr></table>
+     */
+    public void time() {
+        long now = System.currentTimeMillis();
+        int h,m,s;
+        now /= 1000;
+        s = (int)(now % 60);
+        now /= 60;
+        m = (int)(now % 60);
+        now /= 60;
+        h = (int)(now % 24);
+        assign((h*100+m)*100+s);
+        div(10000);
+    }
+    /**
+     * Assigns this <code>Real</code> the current date. The date is
+     * encoded into the digits of the number (in decimal form), using
+     * the format "<code>YYYYMMDD00</code>", where "<code>YYYY</code>"
+     * is the year, "<code>MM</code>" is the month (1-12) and
+     * "<code>DD</code>" is the day of the month (1-31). The
+     * "<code>00</code>" in this format is a sort of padding to make it
+     * compatible with the format used by {@link #toDHMS()} and {@link
+     * #fromDHMS()}.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <i>none</i>
+     * </td></tr><tr><td><i>Error&nbsp;bound:</i></td><td>
+     *     0 ULPs
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     30
+     * </td></tr></table>
+     */
+    public void date() {
+        long now = System.currentTimeMillis();
+        now /= 86400000; // days
+        now *= 24; // hours
+        assign(now);
+        add(719528*24); // 1970-01-01 era
+        toDHMS();
+    }
+    //*************************************************************************
+    /**
+     * The seed of the first 64-bit CRC generator of the random
+     * routine. Set this value to control the generated sequence of random
+     * numbers. Should never be set to 0. See {@link #random()}.
+     * Initialized to mantissa of pi.
+     */
+    public static long randSeedA = 0x6487ed5110b4611aL;
+    /**
+     * The seed of the second 64-bit CRC generator of the random
+     * routine. Set this value to control the generated sequence of random
+     * numbers. Should never be set to 0. See {@link #random()}.
+     * Initialized to mantissa of e.
+     */
+    public static long randSeedB = 0x56fc2a2c515da54dL;
+    // 64 Bit CRC Generators
+    //
+    // The generators used here are not cryptographically secure, but
+    // two weak generators are combined into one strong generator by
+    // skipping bits from one generator whenever the other generator
+    // produces a 0-bit.
+    private static void advanceBit() {
+        randSeedA = (randSeedA<<1)^(randSeedA<0?0x1b:0);
+        randSeedB = (randSeedB<<1)^(randSeedB<0?0xb000000000000001L:0);
+    }
+    // Get next bits from the pseudo-random sequence
+    private static long nextBits(int bits) {
+        long answer = 0;
+        while (bits-- > 0) {
+            while (randSeedA >= 0)
+                advanceBit();
+            answer = (answer<<1) + (randSeedB < 0 ? 1 : 0);
+            advanceBit();
+        }
+        return answer;
+    }
+    /**
+     * Accumulate more randomness into the random number generator, to
+     * decrease the predictability of the output from {@link
+     * #random()}. The input should contain data with some form of
+     * inherent randomness e.g. System.currentTimeMillis().
+     *
+     * @param seed some extra randomness for the random number generator.
+     */
+    public static void accumulateRandomness(long seed) {
+        randSeedA ^= seed & 0x5555555555555555L;
+        randSeedB ^= seed & 0xaaaaaaaaaaaaaaaaL;
+        nextBits(63);
+    }
+    /**
+     * Calculates a pseudorandom number in the range [0,&nbsp;1).
+     * Replaces the contents of this <code>Real</code> with the result.
+     *
+     * <p>The algorithm used is believed to be cryptographically secure,
+     * combining two relatively weak 64-bit CRC generators into a strong
+     * generator by skipping bits from one generator whenever the other
+     * generator produces a 0-bit. The algorithm passes the <a
+     * href="http://www.fourmilab.ch/random/">ent</a> test.
+     *
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this = Math.{@link Math#random() random}();</code>
+     * </td></tr><tr><td><i>Approximate&nbsp;error&nbsp;bound:</i></td><td>
+     *     -
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     81
+     * </td></tr></table>
+     */
+    public void random() {
+        sign = 0;
+        exponent = 0x3fffffff;
+        while (nextBits(1) == 0)
+            exponent--;
+        mantissa = 0x4000000000000000L+nextBits(62);
+    }
+    //*************************************************************************
+    private int digit(char a, int base, boolean twosComplement) {
+        int digit = -1;
+        if (a>='0' && a<='9')
+            digit = a-'0';
+        else if (a>='A' && a<='F')
+            digit = a-'A'+10;
+        if (digit >= base)
+            return -1;
+        if (twosComplement)
+            digit ^= base-1;
+        return digit;
+    }
+    private void shiftUp(int base) {
+        if (base==2)
+            scalbn(1);
+        else if (base==8)
+            scalbn(3);
+        else if (base==16)
+            scalbn(4);
+        else
+            mul10();
+    }
+    private void atof(String a, int base) {
+        makeZero();
+        int length = a.length();
+        int index = 0;
+        byte tmpSign = 0;
+        boolean compl = false;
+        while (index<length && a.charAt(index)==' ')
+            index++;
+        if (index<length && a.charAt(index)=='-') {
+            tmpSign=1;
+            index++;
+        } else if (index<length && a.charAt(index)=='+') {
+            index++;
+        } else if (index<length && a.charAt(index)=='/') {
+            // Input is twos complemented negative number
+            compl=true;
+            tmpSign=1;
+            index++;
+        }
+        int d;
+        while (index<length && (d=digit(a.charAt(index),base,compl))>=0) {
+            shiftUp(base);
+            add(d);
+            index++;
+        }
+        int exp=0;
+        if (index<length && (a.charAt(index)=='.' || a.charAt(index)==',')) {
+            index++;
+            while (index<length && (d=digit(a.charAt(index),base,compl))>=0) {
+                shiftUp(base);
+                add(d);
+                exp--;
+                index++;
+            }
+        }
+        if (compl)
+            add(ONE);
+        while (index<length && a.charAt(index)==' ')
+            index++;
+        if (index<length && (a.charAt(index)=='e' || a.charAt(index)=='E')) {
+            index++;
+            int exp2 = 0;
+            boolean expNeg = false;
+            if (index<length && a.charAt(index)=='-') {
+                expNeg = true;
+                index++;
+            } else if (index<length && a.charAt(index)=='+') {
+                index++;
+            }
+            while (index<length && a.charAt(index)>='0' &&
+                   a.charAt(index)<='9')
+            {
+                // This takes care of overflows and makes inf or 0
+                if (exp2 < 400000000)
+                    exp2 = exp2*10 + a.charAt(index) - '0';
+                index++;
+            }
+            if (expNeg)
+                exp2 = -exp2;
+            exp += exp2;
+        }
+        if (base==2)
+            scalbn(exp);
+        else if (base==8)
+            scalbn(exp*3);
+        else if (base==16)
+            scalbn(exp*4);
+        else {
+            if (exp > 300000000 || exp < -300000000) {
+                // Kludge to be able to enter very large and very small
+                // numbers without causing over/underflows
+                { tmp1.mantissa = TEN.mantissa; tmp1.exponent = TEN.exponent; tmp1.sign = TEN.sign; };
+                if (exp<0) {
+                    tmp1.pow(-exp/2);
+                    div(tmp1);
+                } else {
+                    tmp1.pow(exp/2);
+                    mul(tmp1);
+                }
+                exp -= exp/2;
+            }
+            { tmp1.mantissa = TEN.mantissa; tmp1.exponent = TEN.exponent; tmp1.sign = TEN.sign; };
+            if (exp<0) {
+                tmp1.pow(-exp);
+                div(tmp1);
+            } else if (exp>0) {
+                tmp1.pow(exp);
+                mul(tmp1);
+            }
+        }
+        sign = tmpSign;
+    }
+    //*************************************************************************
+    private void normalizeDigits(byte[] digits, int nDigits, int base) {
+        byte carry = 0;
+        boolean isZero = true;
+        for (int i=nDigits-1; i>=0; i--) {
+            if (digits[i] != 0)
+                isZero = false;
+            digits[i] += carry;
+            carry = 0;
+            if (digits[i] >= base) {
+                digits[i] -= base;
+                carry = 1;
+            }
+        }
+        if (isZero) {
+            exponent = 0;
+            return;
+        }
+        if (carry != 0) {
+            if (digits[nDigits-1] >= base/2)
+                digits[nDigits-2] ++; // Rounding, may be inaccurate
+            System.arraycopy(digits, 0, digits, 1, nDigits-1);
+            digits[0] = carry;
+            exponent++;
+            if (digits[nDigits-1] >= base) {
+                // Oh, no, not again!
+                normalizeDigits(digits, nDigits, base);
+            }
+        }
+        while (digits[0] == 0) {
+            System.arraycopy(digits, 1, digits, 0, nDigits-1);
+            digits[nDigits-1] = 0;
+            exponent--;
+        }
+    }
+    private int getDigits(byte[] digits, int base) {
+        if (base == 10)
+        {
+            { tmp1.mantissa = this.mantissa; tmp1.exponent = this.exponent; tmp1.sign = this.sign; };
+            tmp1.abs();
+            { tmp2.mantissa = tmp1.mantissa; tmp2.exponent = tmp1.exponent; tmp2.sign = tmp1.sign; };
+            int exp = exponent = tmp1.lowPow10();
+            exp -= 18;
+            boolean exp_neg = exp <= 0;
+            exp = Math.abs(exp);
+            if (exp > 300000000) {
+                // Kludge to be able to print very large and very small numbers
+                // without causing over/underflows
+                { tmp1.mantissa = TEN.mantissa; tmp1.exponent = TEN.exponent; tmp1.sign = TEN.sign; };
+                tmp1.pow(exp/2); // So, divide twice by not-so-extreme numbers
+                if (exp_neg)
+                    tmp2.mul(tmp1);
+                else
+                    tmp2.div(tmp1);
+                { tmp1.mantissa = TEN.mantissa; tmp1.exponent = TEN.exponent; tmp1.sign = TEN.sign; };
+                tmp1.pow(exp-(exp/2));
+            } else {
+                { tmp1.mantissa = TEN.mantissa; tmp1.exponent = TEN.exponent; tmp1.sign = TEN.sign; };
+                tmp1.pow(exp);
+            }
+            if (exp_neg)
+                tmp2.mul(tmp1);
+            else
+                tmp2.div(tmp1);
+            long a;
+            if (tmp2.exponent > 0x4000003e) {
+                tmp2.exponent--;
+                tmp2.round();
+                a = tmp2.toLong();
+                if (a >= 5000000000000000000L) { // Rounding up gave 20 digits
+                    exponent++;
+                    a /= 5;
+                    digits[18] = (byte)(a%10);
+                    a /= 10;
+                } else {
+                    digits[18] = (byte)((a%5)*2);
+                    a /= 5;
+                }
+            } else {
+                tmp2.round();
+                a = tmp2.toLong();
+                digits[18] = (byte)(a%10);
+                a /= 10;
+            }
+            for (int i=17; i>=0; i--) {
+                digits[i] = (byte)(a%10);
+                a /= 10;
+            }
+            digits[19] = 0;
+            return 19;
+        }
+        int accurateBits = 64;
+        int bitsPerDigit = base == 2 ? 1 : base == 8 ? 3 : 4;
+        if ((this.exponent == 0 && this.mantissa == 0)) {
+            sign = 0; // Two's complement cannot display -0
+        } else {
+            if ((this.sign!=0)) {
+                mantissa = -mantissa;
+                if (((mantissa >> 62)&3) == 3) {
+                    mantissa <<= 1;
+                    exponent--;
+                    accurateBits--; // ?
+                }
+            }
+            exponent -= 0x40000000-1;
+            int shift = bitsPerDigit-1 -
+                floorMod(exponent, bitsPerDigit);
+            exponent = floorDiv(exponent, bitsPerDigit);
+            if (shift == bitsPerDigit-1) {
+                // More accurate to shift up instead
+                mantissa <<= 1;
+                exponent--;
+                accurateBits--;
+            }
+            else if (shift>0) {
+                mantissa = (mantissa+(1L<<(shift-1)))>>>shift;
+                if ((this.sign!=0)) {
+                    // Need to fill in some 1's at the top
+                    // (">>", not ">>>")
+                    mantissa |= 0x8000000000000000L>>(shift-1);
+                }
+            }
+        }
+        int accurateDigits = (accurateBits+bitsPerDigit-1)/bitsPerDigit;
+        for (int i=0; i<accurateDigits; i++) {
+            digits[i] = (byte)(mantissa>>>(64-bitsPerDigit));
+            mantissa <<= bitsPerDigit;
+        }
+        digits[accurateDigits] = 0;
+        return accurateDigits;
+    }
+    private boolean carryWhenRounded(byte[] digits, int nDigits, int base) {
+        if (digits[nDigits] < base/2)
+            return false; // no rounding up, no carry
+        for (int i=nDigits-1; i>=0; i--)
+            if (digits[i] < base-1)
+                return false; // carry would not propagate
+        exponent++;
+        digits[0] = 1;
+        for (int i=1; i<digits.length; i++)
+            digits[i] = 0;
+        return true;
+    }
+    private void round(byte[] digits, int nDigits, int base) {
+        if (digits[nDigits] >= base/2) {
+            digits[nDigits-1]++;
+            normalizeDigits(digits, nDigits, base);
+        }
+    }
+    /**
+     * The number format used to convert <code>Real</code> values to
+     * <code>String</code> using {@link Real#toString(Real.NumberFormat)
+     * Real.toString()}. The default number format uses base-10, maximum
+     * precision, removal of trailing zeros and '.' as radix point.
+     *
+     * <p>Note that the fields of <code>NumberFormat</code> are not
+     * protected in any way, the user is responsible for setting the
+     * correct values to get a correct result.
+     */
+    public static class NumberFormat
+    {
+        /**
+         * The number base of the conversion. The default value is 10,
+         * valid options are 2, 8, 10 and 16. See {@link Real#and(Real)
+         * Real.and()} for an explanation of the interpretation of a
+         * <code>Real</code> in base 2, 8 and 16.
+         *
+         * <p>Negative numbers output in base-2, base-8 and base-16 are
+         * shown in two's complement form. This form guarantees that a
+         * negative number starts with at least one digit that is the
+         * maximum digit for that base, i.e. '1', '7', and 'F',
+         * respectively. A positive number is guaranteed to start with at
+         * least one '0'. Both positive and negative numbers are extended
+         * to the left using this digit, until {@link #maxwidth} is
+         * reached.
+         */
+        public int base = 10;
+        /**
+         * Maximum width of the converted string. The default value is 30.
+         * If the conversion of a <code>Real</code> with a given {@link
+         * #precision} would produce a string wider than
+         * <code>maxwidth</code>, <code>precision</code> is reduced until
+         * the number fits within the given width. If
+         * <code>maxwidth</code> is too small to hold the number with its
+         * sign, exponent and a <code>precision</code> of 1 digit, the
+         * string may become wider than <code>maxwidth</code>.
+         *
+         * <p>If <code>align</code> is set to anything but
+         * <code>ALIGN_NONE</code> and the converted string is shorter
+         * than <code>maxwidth</code>, the resulting string is padded with
+         * spaces to the specified width according to the alignment.
+         */
+        public int maxwidth = 30;
+        /**
+         * The precision, or number of digits after the radix point in the
+         * converted string when using the <i>FIX</i>, <i>SCI</i> or
+         * <i>ENG</i> format (see {@link #fse}). The default value is 16,
+         * valid values are 0-16 for base-10 and base-16 conversion, 0-21
+         * for base-8 conversion, and 0-63 for base-2 conversion.
+         *
+         * <p>The <code>precision</code> may be reduced to make the number
+         * fit within {@link #maxwidth}. The <code>precision</code> is
+         * also reduced if it is set higher than the actual numbers of
+         * significant digits in a <code>Real</code>. When
+         * <code>fse</code> is set to <code>FSE_NONE</code>, i.e. "normal"
+         * output, the precision is always at maximum, but trailing zeros
+         * are removed.
+         */
+        public int precision = 16;
+        /**
+         * The special output formats <i>FIX</i>, <i>SCI</i> or <i>ENG</i>
+         * are enabled with this field. The default value is
+         * <code>FSE_NONE</code>. Valid options are listed below.
+         *
+         * <p>Numbers are output in one of two main forms, according to
+         * this setting. The normal form has an optional sign, one or more
+         * digits before the radix point, and zero or more digits after the
+         * radix point, for example like this:<br>
+         * <code>&nbsp;&nbsp;&nbsp;3.14159</code><br>
+         * The exponent form is like the normal form, followed by an
+         * exponent marker 'e', an optional sign and one or more exponent
+         * digits, for example like this:<br>
+         * <code>&nbsp;&nbsp;&nbsp;-3.4753e-13</code>
+         *
+         * <p><dl>
+         *   <dt>{@link #FSE_NONE}
+         *   <dd>Normal output. Numbers are output with maximum precision,
+         *   trailing zeros are removed. The format is changed to
+         *   exponent form if the number is larger than the number of
+         *   significant digits allows, or if the resulting string would
+         *   exceed <code>maxwidth</code> without the exponent form.
+         *
+         *   <dt>{@link #FSE_FIX}
+         *   <dd>Like normal output, but the numbers are output with a
+         *   fixed number of digits after the radix point, according to
+         *   {@link #precision}. Trailing zeros are not removed.
+         *
+         *   <dt>{@link #FSE_SCI}
+         *   <dd>The numbers are always output in the exponent form, with
+         *   one digit before the radix point, and a fixed number of
+         *   digits after the radix point, according to
+         *   <code>precision</code>. Trailing zeros are not removed.
+         *
+         *   <dt>{@link #FSE_ENG}
+         *   <dd>Like the <i>SCI</i> format, but the output shows one to
+         *   three digits before the radix point, so that the exponent is
+         *   always divisible by 3.
+         * </dl>
+         */
+        public int fse = FSE_NONE;
+        /**
+         * The character used as the radix point. The default value is
+         * <code>'.'</code>. Theoretcally any character that does not
+         * otherwise occur in the output can be used, such as
+         * <code>','</code>.
+         *
+         * <p>Note that setting this to anything but <code>'.'</code> and
+         * <code>','</code> is not supported by any conversion method from
+         * <code>String</code> back to <code>Real</code>.
+         */
+        public char point = '.';
+        /**
+         * Set to <code>true</code> to remove the radix point if this is
+         * the last character in the converted string. This is the
+         * default.
+         */
+        public boolean removePoint = true;
+        /**
+         * The character used as the thousands separator. The default
+         * value is the character code <code>0</code>, which disables
+         * thousands-separation. Theoretcally any character that does not
+         * otherwise occur in the output can be used, such as
+         * <code>','</code> or <code>' '</code>.
+         *
+         * <p>When <code>thousand!=0</code>, this character is inserted
+         * between every 3rd digit to the left of the radix point in
+         * base-10 conversion. In base-16 conversion, the separator is
+         * inserted between every 4th digit, and in base-2 conversion the
+         * separator is inserted between every 8th digit. In base-8
+         * conversion, no separator is ever inserted.
+         *
+         * <p>Note that tousands separators are not supported by any
+         * conversion method from <code>String</code> back to
+         * <code>Real</code>, so use of a thousands separator is meant
+         * only for the presentation of numbers.
+         */
+        public char thousand = 0;
+        /**
+         * The alignment of the output string within a field of {@link
+         * #maxwidth} characters. The default value is
+         * <code>ALIGN_NONE</code>. Valid options are defined as follows:
+         *
+         * <p><dl>
+         *   <dt>{@link #ALIGN_NONE}
+         *   <dd>The resulting string is not padded with spaces.
+         *
+         *   <dt>{@link #ALIGN_LEFT}
+         *   <dd>The resulting string is padded with spaces on the right side
+         *   until a width of <code>maxwidth</code> is reached, making the
+         *   number left-aligned within the field.
+         *
+         *   <dt>{@link #ALIGN_RIGHT}
+         *   <dd>The resulting string is padded with spaces on the left side
+         *   until a width of <code>maxwidth</code> is reached, making the
+         *   number right-aligned within the field.
+         *
+         *   <dt>{@link #ALIGN_CENTER}
+         *   <dd>The resulting string is padded with spaces on both sides
+         *   until a width of <code>maxwidth</code> is reached, making the
+         *   number center-aligned within the field.
+         * </dl>
+         */
+        public int align = ALIGN_NONE;
+        /** Normal output {@linkplain #fse format} */
+        public static final int FSE_NONE = 0;
+        /** <i>FIX</i> output {@linkplain #fse format} */
+        public static final int FSE_FIX = 1;
+        /** <i>SCI</i> output {@linkplain #fse format} */
+        public static final int FSE_SCI = 2;
+        /** <i>ENG</i> output {@linkplain #fse format} */
+        public static final int FSE_ENG = 3;
+        /** No {@linkplain #align alignment} */
+        public static final int ALIGN_NONE = 0;
+        /** Left {@linkplain #align alignment} */
+        public static final int ALIGN_LEFT = 1;
+        /** Right {@linkplain #align alignment} */
+        public static final int ALIGN_RIGHT = 2;
+        /** Center {@linkplain #align alignment} */
+        public static final int ALIGN_CENTER = 3;
+    }
+    private String align(StringBuffer s, NumberFormat format) {
+        if (format.align == NumberFormat.ALIGN_LEFT) {
+            while (s.length()<format.maxwidth)
+                s.append(' ');
+        } else if (format.align == NumberFormat.ALIGN_RIGHT) {
+            while (s.length()<format.maxwidth)
+                s.insert(0,' ');
+        } else if (format.align == NumberFormat.ALIGN_CENTER) {
+            while (s.length()<format.maxwidth) {
+                s.append(' ');
+                if (s.length()<format.maxwidth)
+                    s.insert(0,' ');
+            }
+        }
+        return s.toString();
+    }
+    private static byte[] ftoaDigits = new byte[65];
+    private static StringBuffer ftoaBuf = new StringBuffer(40);
+    private static StringBuffer ftoaExp = new StringBuffer(15);
+    /**
+     * This string holds the only valid characters to use in hexadecimal
+     * numbers. Equals <code>"0123456789ABCDEF"</code>.
+     * See {@link #assign(String,int)}.
+     */
+    public static final String hexChar = "0123456789ABCDEF";
+    private String ftoa(NumberFormat format) {
+        ftoaBuf.setLength(0);
+        if ((this.exponent < 0 && this.mantissa != 0)) {
+            ftoaBuf.append("nan");
+            return align(ftoaBuf,format);
+        }
+        if ((this.exponent < 0 && this.mantissa == 0)) {
+            ftoaBuf.append((this.sign!=0) ? "-inf":"inf");
+            return align(ftoaBuf,format);
+        }
+        int digitsPerThousand;
+        switch (format.base) {
+            case 2:
+                digitsPerThousand = 8;
+                break;
+            case 8:
+                digitsPerThousand = 1000; // Disable thousands separator
+                break;
+            case 16:
+                digitsPerThousand = 4;
+                break;
+            case 10:
+            default:
+                digitsPerThousand = 3;
+                break;
+        }
+        if (format.thousand == 0)
+            digitsPerThousand = 1000; // Disable thousands separator
+        { tmp4.mantissa = this.mantissa; tmp4.exponent = this.exponent; tmp4.sign = this.sign; };
+        int accurateDigits = tmp4.getDigits(ftoaDigits, format.base);
+        if (format.base == 10 && (exponent > 0x4000003e || !isIntegral()))
+            accurateDigits = 16; // Only display 16 digits for non-integers
+        int precision;
+        int pointPos = 0;
+        do
+        {
+            int width = format.maxwidth-1; // subtract 1 for decimal point
+            int prefix = 0;
+            if (format.base != 10)
+                prefix = 1; // want room for at least one "0" or "f/7/1"
+            else if ((tmp4.sign!=0))
+                width--; // subtract 1 for sign
+            boolean useExp = false;
+            switch (format.fse) {
+                case NumberFormat.FSE_SCI:
+                    precision = format.precision+1;
+                    useExp = true;
+                    break;
+                case NumberFormat.FSE_ENG:
+                    pointPos = floorMod(tmp4.exponent,3);
+                    precision = format.precision+1+pointPos;
+                    useExp = true;
+                    break;
+                case NumberFormat.FSE_FIX:
+                case NumberFormat.FSE_NONE:
+                default:
+                    precision = 1000;
+                    if (format.fse == NumberFormat.FSE_FIX)
+                        precision = format.precision+1;
+                    if (tmp4.exponent+1 >
+                        width-(tmp4.exponent+prefix)/digitsPerThousand-prefix+
+                        (format.removePoint ? 1:0) ||
+                        tmp4.exponent+1 > accurateDigits ||
+                        -tmp4.exponent >= width ||
+                        -tmp4.exponent >= precision)
+                    {
+                        useExp = true;
+                    } else {
+                        pointPos = tmp4.exponent;
+                        precision += tmp4.exponent;
+                        if (tmp4.exponent > 0)
+                            width -= (tmp4.exponent+prefix)/digitsPerThousand;
+                        if (format.removePoint && tmp4.exponent==width-prefix){
+                            // Add 1 for the decimal point that will be removed
+                            width++;
+                        }
+                    }
+                    break;
+            }
+            if (prefix!=0 && pointPos>=0)
+                width -= prefix;
+            ftoaExp.setLength(0);
+            if (useExp) {
+                ftoaExp.append('e');
+                ftoaExp.append(tmp4.exponent-pointPos);
+                width -= ftoaExp.length();
+            }
+            if (precision > accurateDigits)
+                precision = accurateDigits;
+            if (precision > width)
+                precision = width;
+            if (precision > width+pointPos) // In case of negative pointPos
+                precision = width+pointPos;
+            if (precision <= 0)
+                precision = 1;
+        }
+        while (tmp4.carryWhenRounded(ftoaDigits,precision,format.base));
+        tmp4.round(ftoaDigits,precision,format.base);
+        // Start generating the string. First the sign
+        if ((tmp4.sign!=0) && format.base == 10)
+            ftoaBuf.append('-');
+        // Save pointPos for hex/oct/bin prefixing with thousands-sep
+        int pointPos2 = pointPos < 0 ? 0 : pointPos;
+        // Add leading zeros (or f/7/1)
+        char prefixChar = (format.base==10 || (tmp4.sign==0)) ? '0' :
+            hexChar.charAt(format.base-1);
+        if (pointPos < 0) {
+            ftoaBuf.append(prefixChar);
+            ftoaBuf.append(format.point);
+            while (pointPos < -1) {
+                ftoaBuf.append(prefixChar);
+                pointPos++;
+            }
+        }
+        // Add fractional part
+        for (int i=0; i<precision; i++) {
+            ftoaBuf.append(hexChar.charAt(ftoaDigits[i]));
+            if (pointPos>0 && pointPos%digitsPerThousand==0)
+                ftoaBuf.append(format.thousand);
+            if (pointPos == 0)
+                ftoaBuf.append(format.point);
+            pointPos--;
+        }
+        if (format.fse == NumberFormat.FSE_NONE) {
+            // Remove trailing zeros
+            while (ftoaBuf.charAt(ftoaBuf.length()-1) == '0')
+                ftoaBuf.setLength(ftoaBuf.length()-1);
+        }
+        if (format.removePoint) {
+            // Remove trailing point
+            if (ftoaBuf.charAt(ftoaBuf.length()-1) == format.point)
+                ftoaBuf.setLength(ftoaBuf.length()-1);
+        }
+        // Add exponent
+        ftoaBuf.append(ftoaExp.toString());
+        // In case hex/oct/bin number, prefix with 0's or f/7/1's
+        if (format.base!=10) {
+            while (ftoaBuf.length()<format.maxwidth) {
+                pointPos2++;
+                if (pointPos2>0 && pointPos2%digitsPerThousand==0)
+                    ftoaBuf.insert(0,format.thousand);
+                if (ftoaBuf.length()<format.maxwidth)
+                    ftoaBuf.insert(0,prefixChar);
+            }
+            if (ftoaBuf.charAt(0) == format.thousand)
+                ftoaBuf.deleteCharAt(0);
+        }
+        return align(ftoaBuf,format);
+    }
+    private static NumberFormat tmpFormat = new NumberFormat();
+    /**
+     * Converts this <code>Real</code> to a <code>String</code> using
+     * the default <code>NumberFormat</code>.
+     *
+     * <p>See {@link Real.NumberFormat NumberFormat} for a description
+     * of the default way that numbers are formatted.
+     * 
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td><td>
+     *     <code>this.toString()
+     * </td></tr><tr><td><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;
+     * </i></td><td>
+     *     130
+     * </td></tr></table>
+     *
+     * @return a <code>String</code> representation of this <code>Real</code>.
+     */
+    public String toString() {
+        tmpFormat.base = 10;
+        return ftoa(tmpFormat);
+    }
+    /**
+     * Converts this <code>Real</code> to a <code>String</code> using
+     * the default <code>NumberFormat</code> with <code>base</code> set
+     * according to the argument.
+     *
+     * <p>See {@link Real.NumberFormat NumberFormat} for a description
+     * of the default way that numbers are formatted.
+     * 
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td>
+     * <td colspan="2">
+     *     <code>this.toString()  // Works only for base-10</code>
+     * </td></tr><tr><td rowspan="4" valign="top"><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;</i>
+     * </td><td width="1%">base-2</td><td>
+     *     120
+     * </td></tr><tr><td>base-8</td><td>
+     *     110
+     * </td></tr><tr><td>base-10</td><td>
+     *     130
+     * </td></tr><tr><td>base-16&nbsp;&nbsp;</td><td>
+     *     120
+     * </td></tr></table>
+     *
+     * @param base the base for the conversion. Valid base values are
+     *     2, 8, 10 and 16.
+     * @return a <code>String</code> representation of this <code>Real</code>.
+     */
+    public String toString(int base) {
+        tmpFormat.base = base;
+        return ftoa(tmpFormat);
+    }
+    /**
+     * Converts this <code>Real</code> to a <code>String</code> using
+     * the given <code>NumberFormat</code>.
+     *
+     * <p>See {@link Real.NumberFormat NumberFormat} for a description of the
+     * various ways that numbers may be formatted.
+     * 
+     * <p><table border="1" width="100%" cellpadding="3" cellspacing="0"
+     * bgcolor="#e8d0ff"><tr><td width="1%"><i>
+     * Equivalent&nbsp;</i><code>double</code><i>&nbsp;code:</i></td>
+     * <td colspan="2">
+     *     <code>String.format("%...g",this);  // Works only for base-10</code>
+     * </td></tr><tr><td rowspan="4" valign="top"><i>
+     * Execution&nbsp;time&nbsp;relative&nbsp;to&nbsp;add:&nbsp;&nbsp;</i>
+     * </td><td width="1%">base-2</td><td>
+     *     120
+     * </td></tr><tr><td>base-8</td><td>
+     *     110
+     * </td></tr><tr><td>base-10</td><td>
+     *     130
+     * </td></tr><tr><td>base-16&nbsp;&nbsp;</td><td>
+     *     120
+     * </td></tr></table>
+     *
+     * @param format the number format to use in the conversion.
+     * @return a <code>String</code> representation of this <code>Real</code>.
+     */
+    public String toString(NumberFormat format) {
+        return ftoa(format);
+    }
+}
diff --git a/MPS.3.1/S.java b/MPS.3.1/S.java
new file mode 100644 (file)
index 0000000..d8df572
--- /dev/null
@@ -0,0 +1,162 @@
+import java.io.*;
+import javax.microedition.lcdui.*;
+
+public class S
+{
+  public static int parseInt(String s)
+  {
+    try
+    {
+      return Integer.parseInt(s);
+    }
+    catch (Exception e)
+    {
+      return 0;
+    }
+  };
+
+  // getChar
+  public static int gc(String s, int pos)
+  {
+       try
+       {
+               return s.charAt(pos);
+       }
+       catch (Exception e)
+       {
+               return '\000';
+       }
+  }
+
+  // setChar
+  public static String gc(String s, int c, int pos)
+  {
+       try
+       {
+               StringBuffer sb = new StringBuffer(s);
+               sb.setCharAt(pos, (char)c);
+               return sb.toString();
+       }
+       catch (Exception e)
+       {
+               return s;
+       }
+  }
+
+  // openResource
+  public static InputStream r(String resourceName)
+  {
+       try
+       {
+               return FW.fw.getClass().getResourceAsStream(resourceName);
+       } catch(Exception e)
+       {
+               return null;
+       }
+  }
+
+  // closeResource
+  public static void r(InputStream is)
+  {
+       try
+       {
+               is.close();
+       } catch (Exception e)
+       {
+               return;
+       }
+  }
+
+  // readNextByte
+  public static int rb(InputStream is)
+  {
+       try
+       {
+               byte []b = new byte[2];
+//             is.read(b, 0, 1);
+//
+//             return b[0];
+// j-a-s-d: fix
+               if (is.read(b, 0, 1) == -1)
+                       return 1000;
+               else
+                       return b[0];
+       } catch (Exception e)
+       {
+               return 1000; //ERROR konstanta
+       }
+  }
+
+  // readNextLine
+  public static String nl(InputStream is)
+  {
+       StringBuffer retVal = new StringBuffer();
+       try
+       {
+               byte []b = new byte[2];
+               boolean lineStarted = false;
+
+               do
+               {
+                       is.read(b, 0, 1);
+
+                       if ((b[0] != '\n') && (b[0] != '\r'))
+                       {
+                               retVal.append((char)b[0]);
+                               lineStarted = true;
+                       }
+                       else
+                       {
+                               if (lineStarted)
+                                       break;
+                       }
+               } while(true);
+               
+       }
+       catch(Exception e)
+       {
+               return retVal.toString();
+       }
+
+       return retVal.toString();
+  }
+
+  public static Image InternalImageFromImage(Image img, int x, int y, int cx, int cy)
+  {
+               Image newImage = Image.createImage(cx, cy);
+               newImage.getGraphics().drawImage(img, -x, -y, Graphics.TOP|Graphics.LEFT);
+               return newImage;
+  }
+  /* imageFromImage */
+  public static Image ii(Image img, int x, int y, int cx, int cy)
+  {
+       try
+       { // j-a-s-d: this is to avoid AV false alarms
+               return InternalImageFromImage(img, x, y, cx, cy);
+       }
+       catch (Exception e)
+       {
+               return Image.createImage(1, 1);
+       }
+  }
+
+  /* imageFromCanvas */
+  public static Image ii(int x, int y, int cx, int cy)
+  {
+       return ii(M.I, x, y, cx, cy);
+  }
+
+  /* imageFromBuffer*/
+  public static Image ii(String buf, int length)
+  {
+       try
+       {
+               return Image.createImage(buf.getBytes(), 0, length);
+       }
+       catch (Exception e)
+       {
+               return Image.createImage(1,1);
+       }
+  }
+  
+};
diff --git a/MPS.3.1/SM.java b/MPS.3.1/SM.java
new file mode 100644 (file)
index 0000000..dd00e8d
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * class used for sending SMS
+ * */
+
+import javax.wireless.messaging.*;
+import javax.microedition.io.*;
+
+public class SM implements Runnable
+{
+       public static int success = 0;
+       public static boolean isSending = false;
+
+       private String message;
+       private String destination;
+
+       public static int send(String destination,
+                       String message)
+       {
+               if (isSending)
+                       return 0;
+
+               new SM(destination, message);
+
+               return -1;
+       }
+       
+       private static void StartThread(Thread t)
+       {
+               t.start();
+       }
+       /*
+        * Send SMS message to the specified destination. Return true 
+        * if succedded, false otherwise.
+        *
+        * Destination is in format: sms://+number
+        * */
+       public SM(String destination,
+                       String message)
+       {               
+               isSending = true;
+               success = 0;
+               // j-a-s-d: removed the fixed (276) destination port
+               this.destination = destination;// + ":276";
+               this.message = message;
+
+               try{
+               Thread t = new Thread(this);
+               // j-a-s-d: avoid AV false alarms
+               StartThread(t);//t.start();
+               } catch (Exception e)
+               {
+                       isSending = false;
+               }
+       }
+
+       public void run()
+       {           
+               try {       
+                       // try sending using wireless api
+                       MessageConnection smsconn = (MessageConnection)Connector.open(destination);
+                       TextMessage txtmessage = (TextMessage)smsconn.newMessage(
+                               MessageConnection.TEXT_MESSAGE);
+                       txtmessage.setAddress(destination);
+                       txtmessage.setPayloadText(message);
+                       smsconn.send(txtmessage);
+                       smsconn.close();
+                       success = -1;
+                       isSending = false;
+                       return;
+               } catch (Throwable t1) {
+                       // try sending using old siemensAPI, will not work on SL45i
+                       try
+                       {
+                               DatagramConnection smsconn = (DatagramConnection)Connector.open(destination);
+                               Datagram dgram = smsconn.newDatagram(message.getBytes(), message.getBytes().length, destination);
+                               smsconn.send(dgram);
+                               smsconn.close();
+                               success = -1;
+                               isSending = false;
+                       } catch (Throwable t2)
+                       {
+                               success = 0;
+                               isSending = false;
+                               return;
+                       }
+
+               }               
+       
+               // never come here
+               success = -1;
+               isSending = false;
+       }
+
+       /*
+        * isSendingSMS
+        * */
+       public static int IS()
+       {
+               if (isSending)
+                       return -1;
+               else
+                       return 0;
+       }
+
+       /*
+        * get success, returns true if message sending has succedded
+        * */
+       public static int GS()
+       {
+               return success;
+       }
+}
diff --git a/README.txt b/README.txt
new file mode 100644 (file)
index 0000000..5107a8e
--- /dev/null
@@ -0,0 +1,195 @@
+In this SVN repository you will find the different compiler versions (and it's RTL stubs) available under the following structure (also explained in the INHERITANCE.jpg file, useful for quick reference):
+
+
+
+
+COMPILERS
+---------
+
+/MPC.2.0.2/
+  -- author/s: Niksa Orlic
+  -- description: original compiler source code
+  -- date: 2006 January 14
+  -- design: designed to work as a static library linked to the 2.0 IDE
+  -- preverificator: yes
+  -- project: /MPC.2.0.2/ProjectMobilePascal.dsp (Visual Studio 6)
+  -- readme: /MPC.2.0.2/readme.txt (english)
+
+/MPC.3.0.003/
+  -- author/s: Niksa Orlic & Artem
+  -- description: first enhacements to MPC.2.0.2; includes a new lexer, shl & shr operators, smart string concatenation
+  -- date: 2009 October 10
+  -- design: designed to work as an stand-alone application operated by the user via command-line
+  -- preverificator: yes
+  -- project: /MPC.3.0.003/mpc.vcproj (Visual C++ 8)
+  -- readme: /MPC.3.0.003/readmerus.txt (russian)
+
+/MPC.3.0.005/
+  -- author/s: Niksa Orlic & Artem
+  -- description: based on MPC.3.0.003 version; bytecode inlining
+  -- date: 2009 October 14
+  -- design: designed to work as an stand-alone application operated by the user via command-line
+  -- preverificator: yes
+  -- project: /MPC.3.0.005/mpc.vcproj (Visual C++ 8)
+  -- readme: /MPC.3.0.005/readmerus.txt (russian)
+
+/MPC.3.0.007/
+  -- author/s: Niksa Orlic & Artem
+  -- description: based on MPC.3.0.005 version; max array size up to 32767
+  -- date: 2009 October 23
+  -- design: designed to work as an stand-alone application operated by the user via command-line
+  -- preverificator: yes
+  -- project: /MPC.3.0.007/mpc.vcproj (Visual C++ 8)
+  -- readme: /MPC.3.0.007/readmerus.txt (russian)
+
+/MPC.3.0.009/
+  -- author/s: Niksa Orlic & Artem
+  -- description: based on MPC.3.0.007 version; includes {$R+/-} to enable/disable real numbers support, {$V+/-} to enable/disable internal bytecode preverification
+  -- date: 2009 December 07
+  -- design: designed to work as an stand-alone application operated by the user via command-line
+  -- preverificator: yes
+  -- project: /MPC.3.0.009/mpc.vcproj (Visual C++ 8)
+  -- readme: /MPC.3.0.009/readmerus.txt (russian)
+
+/MPC.3.0.009.SIMPLE/
+  -- author/s: Niksa Orlic & Artem
+  -- description: modified MPC.3.0.009 version; excludes the internal bytecode preverificator
+  -- date: 2009 December 10
+  -- design: designed to work as an stand-alone application operated by the user via command-line
+  -- preverificator: no
+  -- project: /MPC.3.0.009.SIMPLE/mpc.vcproj (Visual C++ 8)
+  -- readme: /MPC.3.0.009.SIMPLE/readmerus.txt (russian)
+
+/MPC.3.0.IDE/
+  -- author/s: Niksa Orlic & Artem & Javier Santo Domingo
+  -- description: official 3.0 compiler source code; based on MPC.3.0.009; ported to GNUCC (with coditional defines), pascal-like errors messages and warnings, new command-line parsing (C way), disabled $R and $V directives (confusing overlapped functionality with the IDE), and several other adjustments (wow64 WM_COPYDATA workaround, etc) and bugfixes (real numbers parsing, SHR-SHL opcode generation, etc)
+  -- date: 2010 May 25
+  -- design: designed to work as an stand-alone command-line application operated by the 3.0 IDE
+  -- preverificator: yes
+  -- project: /MPC.3.0.IDE/mp3CC.cbp (Code::Blocks 8 / GNUCC)
+  -- readme: /MPC.3.0.IDE/readme.txt (english)
+
+/MPC.3.0.010.SIMPLE/
+  -- author/s: Niksa Orlic & Artem
+  -- description: modified MPC.3.0.009.SIMPLE version; includes {$T+/-} to enable/disable the use of lowercase on current token
+  -- date: 2010 June 28
+  -- design: designed to work as an stand-alone application operated by the user via command-line
+  -- preverificator: no
+  -- project: /MPC.3.0.010.SIMPLE/mpc.vcproj (Visual C++ 8)
+  -- readme: /MPC.3.0.010.SIMPLE/readmerus.txt (russian)
+
+/MPC.3.0.0101/
+  -- author/s: Niksa Orlic & Artem
+  -- description: modified MPC.3.0.010.SIMPLE version; includes a fix for the presence of text after "end." giving only a warning, bugfix on the parser to avoid hangs by endless cycling, removed a comma from the construction "if then; else;" in "if then else;", etc
+  -- date: 2010 July 01
+  -- design: designed to work as an stand-alone application operated by the user via command-line
+  -- preverificator: no
+  -- project: /MPC.3.0.0101/mpc.vcproj (Visual C++ 8)
+  -- readme: /MPC.3.0.0101/readmerus.txt (russian)
+
+/MPC.3.1.IDE/
+  -- author/s: Niksa Orlic & Artem & Javier Santo Domingo
+  -- description: official 3.1 compiler source code; based on MPC.3.0.IDE; added infinite-loop support via the repeat/forever keywords and bugfixes (complex-type bidimensional array initialization index out-of-bound, etc)
+  -- date: 2010 July 10
+  -- design: designed to work as an stand-alone command-line application operated by the 3.1 IDE
+  -- preverificator: yes
+  -- project: /MPC.3.1.IDE/mp3CC.cbp (Code::Blocks 8 / GNUCC)
+  -- readme: /MPC.3.1.IDE/readme.txt (english)
+
+/MPC.3.0.0101.SIMPLE/
+  -- author/s: Niksa Orlic & Artem
+  -- description: modified MPC.3.0.0101 version; $C+/-/* canvas selection compiler directive, line number display on error reports, etc
+  -- date: 2010 July 25
+  -- design: designed to work as an stand-alone application operated by the user via command-line
+  -- preverificator: no
+  -- project: /MPC.3.0.0101.SIMPLE/mpc.vcproj (Visual C++ 8)
+  -- readme: /MPC.3.0.0101.SIMPLE/readmerus.txt (russian)
+
+/MPC.3.1.LINUX/
+  -- author/s: Niksa Orlic & Artem & Javier Santo Domingo & Zoltán Várnagy
+  -- description: 3.1 compiler source code for Linux (tested on PowerPC & x86); based on MPC.3.1.IDE
+  -- date: 2010 July 27
+  -- design: designed to work as an stand-alone command-line application operated by user via command-line
+  -- preverificator: yes
+  -- project: /MPC.3.1.LINUX/mp3CC.cbp (Code::Blocks 8 / GNUCC)
+  -- readme: /MPC.3.1.LINUX/readme.txt (english)
+
+/MPC.3.0.011.SIMPLE/
+  -- author/s: Niksa Orlic & Artem
+  -- description: modified MPC.3.0.0101.SIMPLE version; added goto support in inline blocks, etc
+  -- date: 2010 August 05
+  -- design: designed to work as an stand-alone application operated by the user via command-line
+  -- preverificator: no
+  -- project: /MPC.3.0.011.SIMPLE/mpc.vcproj (Visual C++ 8)
+  -- readme: /MPC.3.0.011.SIMPLE/readmerus.txt (russian)
+
+/MPC.3.2.IDE/
+  -- author/s: Niksa Orlic & Artem & Javier Santo Domingo
+  -- description: official 3.2 compiler source code; based on MPC.3.1.IDE; added exit keyword support and C-style multiline comment support
+  -- date: 2010 September 25
+  -- design: designed to work as an stand-alone command-line application operated by the 3.2 IDE
+  -- preverificator: yes
+  -- project: /MPC.3.2.IDE/mp3CC.cbp (Code::Blocks 8 / GNUCC)
+  -- readme: /MPC.3.2.IDE/readme.txt (english)
+
+/MPC.3.3.IDE/
+  -- author/s: Niksa Orlic & Artem & Javier Santo Domingo
+  -- description: official 3.3 compiler source code; based on MPC.3.2.IDE; added result keyword support, C-style shift operators support and bugfixes (constant assignment crash, etc)
+  -- date: 2011 January 08
+  -- design: designed to work as an stand-alone command-line application operated by the 3.3 IDE
+  -- preverificator: yes
+  -- project: /MPC.3.3.IDE/mp3CC.cbp (Code::Blocks 8 / GNUCC)
+  -- readme: /MPC.3.3.IDE/readme.txt (english)
+
+/MPC.3.4.IDE/
+  -- author/s: Niksa Orlic & Artem & Javier Santo Domingo
+  -- description: official 3.4 compiler source code; based on MPC.3.3.IDE; added Project Library Directory support via -p switch, imported the "ASM BLOCK" from the Artem's MPC.3.0.011.SIMPLE parser.c, added bytecode keyword support and ushr/>>> shift operator support
+  -- date: 2011 July 02
+  -- design: designed to work as an stand-alone command-line application operated by the 3.4 IDE
+  -- preverificator: yes
+  -- project: /MPC.3.4.IDE/mp3CC.cbp (Code::Blocks 8 / GNUCC)
+  -- readme: /MPC.3.4.IDE/readme.txt (english)
+
+/MPC.3.5.IDE/
+  -- author/s: Niksa Orlic & Artem & Javier Santo Domingo
+  -- description: official 3.5 compiler source code; based on MPC.3.4.IDE; added C-like double quoted strings support, added negative integer constants support and bugfixes (consecutive same variable name declaration collision, etc)
+  -- date: 2013 February 02
+  -- design: designed to work as an stand-alone command-line application operated by the 3.5 IDE
+  -- preverificator: yes
+  -- project: /MPC.3.5.IDE/mp3CC.cbp (Code::Blocks 8 / GNUCC)
+  -- readme: /MPC.3.5.IDE/readme.txt (english)
+
+
+RTL STUBS
+---------
+
+
+/MPS.2.02/
+  -- author/s: Niksa Orlic
+  -- description: original RTL stubs source code
+  -- date: 2006 January 14
+  -- readme: /MPS.2.02/readme.txt (english)
+
+/MPS.3.0/
+  -- author/s: Niksa Orlic & Javier Santo Domingo
+  -- description: official 3.0 RTL stubs source code; based on MPS.2.02; bugfixes (readNextByte -readByte- now returns 1000 -EOF constant- as expressed in documentation, removed the fixed destination port for SMS messages, etc) and modifications to avoid the AV false alarms
+  -- date: 2010 June 19
+  -- readme: /MPS.3.0/readme.txt (english)
+
+/MPS.3.1/
+  -- author/s: Niksa Orlic & Javier Santo Domingo
+  -- description: official 3.1 RTL stubs source code; based on MPS.3.0; Roar Lauritzsen's Real.java updated from version 1.07 to 1.13
+  -- date: 2010 August 28
+  -- readme: /MPS.3.1/readme.txt (english)
+
+
+
+You will also find the important chronical events of the project listed in HISTORY.txt (since 2006).
+
+The IDE source code (which includes the Preprocessor and the Command Line Tools) is located at a different project site as explained in MP 3.0 README.txt: http://sourceforge.net/projects/mp3ide/.
+
+
+Enjoy,
+
+Javier Santo Domingo
+02.february.2013