jdk/src/share/demo/jvmti/java_crw_demo/java_crw_demo.c
author xdono
Tue, 28 Jul 2009 12:12:54 -0700
changeset 3288 db82a42da273
parent 3223 24e98ad0c62e
child 5506 202f599c92aa
permissions -rw-r--r--
6862919: Update copyright year Summary: Update copyright for files that have been modified in 2009, up to 07/09 Reviewed-by: tbell, ohair
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
3288
db82a42da273 6862919: Update copyright year
xdono
parents: 3223
diff changeset
     2
 * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 * Redistribution and use in source and binary forms, with or without
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * modification, are permitted provided that the following conditions
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * are met:
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 *   - Redistributions of source code must retain the above copyright
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 *     notice, this list of conditions and the following disclaimer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 *   - Redistributions in binary form must reproduce the above copyright
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 *     notice, this list of conditions and the following disclaimer in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 *     documentation and/or other materials provided with the distribution.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 *   - Neither the name of Sun Microsystems nor the names of its
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *     contributors may be used to endorse or promote products derived
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 *     from this software without specific prior written permission.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
/* Class reader writer (java_crw_demo) for instrumenting bytecodes */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 * As long as the callbacks allow for it and the class number is unique,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 *     this code is completely re-entrant and any number of classfile
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 *     injections can happen at the same time.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 *     The current logic requires a unique number for this class instance
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 *     or (jclass,jobject loader) pair, this is done via the ClassIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 *     in hprof, which is passed in as the 'unsigned cnum' to java_crw_demo().
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 *     It's up to the user of this interface if it wants to use this
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 *     feature.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
#include <stdio.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
#include <stdlib.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
#include <string.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
/* Get Java and class file and bytecode information. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
#include <jni.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
#include "classfile_constants.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
/* Include our own interface for cross check */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
#include "java_crw_demo.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
/* Macros over error functions to capture line numbers */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
#define CRW_FATAL(ci, message) fatal_error(ci, message, __FILE__, __LINE__)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
#if defined(DEBUG) || !defined(NDEBUG)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
  #define CRW_ASSERT(ci, cond) \
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
        ((cond)?(void)0:assert_error(ci, #cond, __FILE__, __LINE__))
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
#else
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
  #define CRW_ASSERT(ci, cond)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
#define CRW_ASSERT_MI(mi) CRW_ASSERT((mi)?(mi)->ci:NULL,(mi)!=NULL)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
#define CRW_ASSERT_CI(ci) CRW_ASSERT(ci, ( (ci) != NULL && \
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
                         (ci)->input_position <= (ci)->input_len && \
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
                         (ci)->output_position <= (ci)->output_len) )
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
/* Typedefs for various integral numbers, just for code clarity */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
typedef unsigned       ClassOpcode;             /* One opcode */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
typedef unsigned char  ByteCode;                /* One byte from bytecodes */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
typedef int            ByteOffset;              /* Byte offset */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
typedef int            ClassConstant;           /* Constant pool kind */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
typedef long           CrwPosition;             /* Position in class image */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
typedef unsigned short CrwCpoolIndex;           /* Index into constant pool */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
/* Misc support macros */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
/* Given the position of an opcode, find the next 4byte boundary position */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
#define NEXT_4BYTE_BOUNDARY(opcode_pos) (((opcode_pos)+4) & (~3))
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
#define LARGEST_INJECTION               (12*3) /* 3 injections at same site */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
#define MAXIMUM_NEW_CPOOL_ENTRIES       64 /* don't add more than 32 entries */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
/* Constant Pool Entry (internal table that mirrors pool in file image) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
typedef struct {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    const char *        ptr;            /* Pointer to any string */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
    unsigned short      len;            /* Length of string */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    unsigned int        index1;         /* 1st 16 bit index or 32bit value. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
    unsigned int        index2;         /* 2nd 16 bit index or 32bit value. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    ClassConstant       tag;            /* Tag or kind of entry. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
} CrwConstantPoolEntry;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
struct MethodImage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
/* Class file image storage structure */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
typedef struct CrwClassImage {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
    /* Unique class number for this class */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    unsigned                    number;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    /* Name of class, given or gotten out of class image */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
    const char *                name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    /* Input and Output class images tracking */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
    const unsigned char *       input;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    unsigned char *             output;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
    CrwPosition                 input_len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    CrwPosition                 output_len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    CrwPosition                 input_position;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    CrwPosition                 output_position;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
    /* Mirrored constant pool */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    CrwConstantPoolEntry *      cpool;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    CrwCpoolIndex               cpool_max_elements;             /* Max count */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    CrwCpoolIndex               cpool_count_plus_one;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    /* Input flags about class (e.g. is it a system class) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
    int                         system_class;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    /* Class access flags gotten from file. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    unsigned                    access_flags;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    /* Names of classes and methods. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    char* tclass_name;          /* Name of class that has tracker methods. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
    char* tclass_sig;           /* Signature of class */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    char* call_name;            /* Method name to call at offset 0 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
    char* call_sig;             /* Signature of this method */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    char* return_name;          /* Method name to call before any return */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
    char* return_sig;           /* Signature of this method */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
    char* obj_init_name;        /* Method name to call in Object <init> */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
    char* obj_init_sig;         /* Signature of this method */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
    char* newarray_name;        /* Method name to call after newarray opcodes */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    char* newarray_sig;         /* Signature of this method */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    /* Constant pool index values for new entries */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    CrwCpoolIndex               tracker_class_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    CrwCpoolIndex               object_init_tracker_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
    CrwCpoolIndex               newarray_tracker_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
    CrwCpoolIndex               call_tracker_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
    CrwCpoolIndex               return_tracker_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    CrwCpoolIndex               class_number_index; /* Class number in pool */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
    /* Count of injections made into this class */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
    int                         injection_count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    /* This class must be the java.lang.Object class */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    jboolean                    is_object_class;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
    /* This class must be the java.lang.Thread class */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
    jboolean                    is_thread_class;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
    /* Callback functions */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
    FatalErrorHandler           fatal_error_handler;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
    MethodNumberRegister        mnum_callback;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
    /* Table of method names and descr's */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
    int                         method_count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
    const char **               method_name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
    const char **               method_descr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
    struct MethodImage *        current_mi;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
} CrwClassImage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
/* Injection bytecodes (holds injected bytecodes for each code position) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
typedef struct {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
    ByteCode *  code;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
    ByteOffset  len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
} Injection;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
/* Method transformation data (allocated/freed as each method is processed) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
typedef struct MethodImage {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
    /* Back reference to Class image data. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
    CrwClassImage *     ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
    /* Unique method number for this class. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
    unsigned            number;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    /* Method name and descr */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
    const char *        name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    const char *        descr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
    /* Map of input bytecode offsets to output bytecode offsets */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
    ByteOffset *        map;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
    /* Bytecode injections for each input bytecode offset */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
    Injection *         injections;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
    /* Widening setting for each input bytecode offset */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
    signed char *       widening;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
    /* Length of original input bytecodes, and new bytecodes. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
    ByteOffset          code_len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
    ByteOffset          new_code_len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
    /* Location in input where bytecodes are located. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
    CrwPosition         start_of_input_bytecodes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
    /* Original max_stack and new max stack */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
    unsigned            max_stack;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
    unsigned            new_max_stack;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
    jboolean            object_init_method;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
    jboolean            skip_call_return_sites;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
    /* Method access flags gotten from file. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
    unsigned            access_flags;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
} MethodImage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
/* ----------------------------------------------------------------- */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
/* General support functions (memory and error handling) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
fatal_error(CrwClassImage *ci, const char *message, const char *file, int line)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
    if ( ci != NULL && ci->fatal_error_handler != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
        (*ci->fatal_error_handler)(message, file, line);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
        /* Normal operation should NEVER reach here */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
        /* NO CRW FATAL ERROR HANDLER! */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        (void)fprintf(stderr, "CRW: %s [%s:%d]\n", message, file, line);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        abort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
#if defined(DEBUG) || !defined(NDEBUG)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
assert_error(CrwClassImage *ci, const char *condition,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
                 const char *file, int line)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
    char buf[512];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
    MethodImage *mi;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
    ByteOffset byte_code_offset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
    mi = ci->current_mi;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
    if ( mi != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        byte_code_offset = (ByteOffset)(mi->ci->input_position - mi->start_of_input_bytecodes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
        byte_code_offset=-1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
    (void)sprintf(buf,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
                "CRW ASSERTION FAILURE: %s (%s:%s:%d)",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
                condition,
3223
24e98ad0c62e 6855551: java -Xrunhprof crashes when running with classes compiled with targed=7
ohair
parents: 3067
diff changeset
   266
                ci->name==NULL?"?":ci->name,
24e98ad0c62e 6855551: java -Xrunhprof crashes when running with classes compiled with targed=7
ohair
parents: 3067
diff changeset
   267
                (mi==NULL||mi->name==NULL)?"?":mi->name,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
                byte_code_offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
    fatal_error(ci, buf, file, line);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
static void *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
allocate(CrwClassImage *ci, int nbytes)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
    void * ptr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
    if ( nbytes <= 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
        CRW_FATAL(ci, "Cannot allocate <= 0 bytes");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
    ptr = malloc(nbytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
    if ( ptr == NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        CRW_FATAL(ci, "Ran out of malloc memory");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
    return ptr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
static void *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
reallocate(CrwClassImage *ci, void *optr, int nbytes)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
    void * ptr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
    if ( optr == NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        CRW_FATAL(ci, "Cannot deallocate NULL");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
    if ( nbytes <= 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        CRW_FATAL(ci, "Cannot reallocate <= 0 bytes");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
    ptr = realloc(optr, nbytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
    if ( ptr == NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
        CRW_FATAL(ci, "Ran out of malloc memory");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
    return ptr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
static void *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
allocate_clean(CrwClassImage *ci, int nbytes)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
    void * ptr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
    if ( nbytes <= 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
        CRW_FATAL(ci, "Cannot allocate <= 0 bytes");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
    ptr = calloc(nbytes, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
    if ( ptr == NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
        CRW_FATAL(ci, "Ran out of malloc memory");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
    return ptr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
static const char *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
duplicate(CrwClassImage *ci, const char *str, int len)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
    char *copy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
    copy = (char*)allocate(ci, len+1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
    (void)memcpy(copy, str, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
    copy[len] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
    return (const char *)copy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
deallocate(CrwClassImage *ci, void *ptr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
    if ( ptr == NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
        CRW_FATAL(ci, "Cannot deallocate NULL");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
    (void)free(ptr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
/* ----------------------------------------------------------------- */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
/* Functions for reading/writing bytes to/from the class images */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
static unsigned
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
readU1(CrwClassImage *ci)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
    CRW_ASSERT_CI(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
    return ((unsigned)(ci->input[ci->input_position++])) & 0xFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
static unsigned
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
readU2(CrwClassImage *ci)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
    unsigned res;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
    res = readU1(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
    return (res << 8) + readU1(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
static signed short
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
readS2(CrwClassImage *ci)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
    unsigned res;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
    res = readU1(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
    return ((res << 8) + readU1(ci)) & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
static unsigned
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
readU4(CrwClassImage *ci)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
    unsigned res;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
    res = readU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
    return (res << 16) + readU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
writeU1(CrwClassImage *ci, unsigned val)  /* Only writes out lower 8 bits */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
    CRW_ASSERT_CI(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
    if ( ci->output != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        ci->output[ci->output_position++] = val & 0xFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
writeU2(CrwClassImage *ci, unsigned val)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
    writeU1(ci, val >> 8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
    writeU1(ci, val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
writeU4(CrwClassImage *ci, unsigned val)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
    writeU2(ci, val >> 16);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
    writeU2(ci, val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
static unsigned
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
copyU1(CrwClassImage *ci)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
    unsigned value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
    value = readU1(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
    writeU1(ci, value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
    return value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
static unsigned
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
copyU2(CrwClassImage *ci)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
    unsigned value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
    value = readU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
    writeU2(ci, value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
    return value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
static unsigned
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
copyU4(CrwClassImage *ci)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
    unsigned value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
    value = readU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
    writeU4(ci, value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
    return value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
copy(CrwClassImage *ci, unsigned count)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
    CRW_ASSERT_CI(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
    if ( ci->output != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
        (void)memcpy(ci->output+ci->output_position,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
                     ci->input+ci->input_position, count);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
        ci->output_position += count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
    ci->input_position += count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
    CRW_ASSERT_CI(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
skip(CrwClassImage *ci, unsigned count)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
    CRW_ASSERT_CI(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
    ci->input_position += count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
read_bytes(CrwClassImage *ci, void *bytes, unsigned count)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
    CRW_ASSERT_CI(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
    CRW_ASSERT(ci, bytes!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
    (void)memcpy(bytes, ci->input+ci->input_position, count);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
    ci->input_position += count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
write_bytes(CrwClassImage *ci, void *bytes, unsigned count)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
    CRW_ASSERT_CI(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
    CRW_ASSERT(ci, bytes!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
    if ( ci->output != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
        (void)memcpy(ci->output+ci->output_position, bytes, count);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
        ci->output_position += count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
random_writeU2(CrwClassImage *ci, CrwPosition pos, unsigned val)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
    CrwPosition save_position;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
    CRW_ASSERT_CI(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
    save_position = ci->output_position;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
    ci->output_position = pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
    writeU2(ci, val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
    ci->output_position = save_position;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
random_writeU4(CrwClassImage *ci, CrwPosition pos, unsigned val)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
    CrwPosition save_position;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
    CRW_ASSERT_CI(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
    save_position = ci->output_position;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
    ci->output_position = pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
    writeU4(ci, val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
    ci->output_position = save_position;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
/* ----------------------------------------------------------------- */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
/* Constant Pool handling functions. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
fillin_cpool_entry(CrwClassImage *ci, CrwCpoolIndex i,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
                   ClassConstant tag,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
                   unsigned int index1, unsigned int index2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
                   const char *ptr, int len)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
    CRW_ASSERT_CI(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
    CRW_ASSERT(ci, i > 0 && i < ci->cpool_count_plus_one);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
    ci->cpool[i].tag    = tag;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
    ci->cpool[i].index1 = index1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
    ci->cpool[i].index2 = index2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
    ci->cpool[i].ptr    = ptr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
    ci->cpool[i].len    = (unsigned short)len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
static CrwCpoolIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
add_new_cpool_entry(CrwClassImage *ci, ClassConstant tag,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
                    unsigned int index1, unsigned int index2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
                    const char *str, int len)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
    CrwCpoolIndex i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
    char *utf8 = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
    CRW_ASSERT_CI(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
    i = ci->cpool_count_plus_one++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
    /* NOTE: This implementation does not automatically expand the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
     *       constant pool table beyond the expected number needed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
     *       to handle this particular CrwTrackerInterface injections.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
     *       See MAXIMUM_NEW_CPOOL_ENTRIES
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
    CRW_ASSERT(ci,  ci->cpool_count_plus_one < ci->cpool_max_elements );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
    writeU1(ci, tag);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
    switch (tag) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
        case JVM_CONSTANT_Class:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
            writeU2(ci, index1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
        case JVM_CONSTANT_String:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
            writeU2(ci, index1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
        case JVM_CONSTANT_Fieldref:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
        case JVM_CONSTANT_Methodref:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
        case JVM_CONSTANT_InterfaceMethodref:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
        case JVM_CONSTANT_Integer:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
        case JVM_CONSTANT_Float:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
        case JVM_CONSTANT_NameAndType:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
            writeU2(ci, index1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
            writeU2(ci, index2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
        case JVM_CONSTANT_Long:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
        case JVM_CONSTANT_Double:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
            writeU4(ci, index1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
            writeU4(ci, index2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
            ci->cpool_count_plus_one++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
            CRW_ASSERT(ci,  ci->cpool_count_plus_one < ci->cpool_max_elements );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
        case JVM_CONSTANT_Utf8:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
            CRW_ASSERT(ci, len==(len & 0xFFFF));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
            writeU2(ci, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
            write_bytes(ci, (void*)str, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
            utf8 = (char*)duplicate(ci, str, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
            CRW_FATAL(ci, "Unknown constant");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
    fillin_cpool_entry(ci, i, tag, index1, index2, (const char *)utf8, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
    CRW_ASSERT(ci, i > 0 && i < ci->cpool_count_plus_one);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
    return i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
static CrwCpoolIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
add_new_class_cpool_entry(CrwClassImage *ci, const char *class_name)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
    CrwCpoolIndex name_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
    CrwCpoolIndex class_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
    int           len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
    CRW_ASSERT_CI(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
    CRW_ASSERT(ci, class_name!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
    len = (int)strlen(class_name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
    name_index = add_new_cpool_entry(ci, JVM_CONSTANT_Utf8, len, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
                        class_name, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
    class_index = add_new_cpool_entry(ci, JVM_CONSTANT_Class, name_index, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
                        NULL, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
    return class_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
static CrwCpoolIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
add_new_method_cpool_entry(CrwClassImage *ci, CrwCpoolIndex class_index,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
                     const char *name, const char *descr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
    CrwCpoolIndex name_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
    CrwCpoolIndex descr_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
    CrwCpoolIndex name_type_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
    int len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
    CRW_ASSERT_CI(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
    CRW_ASSERT(ci, name!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
    CRW_ASSERT(ci, descr!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
    len = (int)strlen(name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
    name_index =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
        add_new_cpool_entry(ci, JVM_CONSTANT_Utf8, len, 0, name, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
    len = (int)strlen(descr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
    descr_index =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
        add_new_cpool_entry(ci, JVM_CONSTANT_Utf8, len, 0, descr, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
    name_type_index =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
        add_new_cpool_entry(ci, JVM_CONSTANT_NameAndType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
                                name_index, descr_index, NULL, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
    return add_new_cpool_entry(ci, JVM_CONSTANT_Methodref,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
                                class_index, name_type_index, NULL, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
static CrwConstantPoolEntry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
cpool_entry(CrwClassImage *ci, CrwCpoolIndex c_index)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
    CRW_ASSERT_CI(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
    CRW_ASSERT(ci, c_index > 0 && c_index < ci->cpool_count_plus_one);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
    return ci->cpool[c_index];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
cpool_setup(CrwClassImage *ci)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
    CrwCpoolIndex i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
    CrwPosition cpool_output_position;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
    int count_plus_one;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
    CRW_ASSERT_CI(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
    cpool_output_position = ci->output_position;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
    count_plus_one = copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
    CRW_ASSERT(ci, count_plus_one>1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
    ci->cpool_max_elements = count_plus_one+MAXIMUM_NEW_CPOOL_ENTRIES;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
    ci->cpool = (CrwConstantPoolEntry*)allocate_clean(ci,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
                (int)((ci->cpool_max_elements)*sizeof(CrwConstantPoolEntry)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
    ci->cpool_count_plus_one = (CrwCpoolIndex)count_plus_one;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
    /* Index zero not in class file */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
    for (i = 1; i < count_plus_one; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
        CrwCpoolIndex   ipos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
        ClassConstant   tag;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
        unsigned int    index1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
        unsigned int    index2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
        unsigned        len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
        char *          utf8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
        ipos    = i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
        index1  = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
        index2  = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
        len     = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
        utf8    = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
        tag = copyU1(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
        switch (tag) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
            case JVM_CONSTANT_Class:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
                index1 = copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
            case JVM_CONSTANT_String:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
                index1 = copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
            case JVM_CONSTANT_Fieldref:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
            case JVM_CONSTANT_Methodref:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
            case JVM_CONSTANT_InterfaceMethodref:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
            case JVM_CONSTANT_Integer:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
            case JVM_CONSTANT_Float:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
            case JVM_CONSTANT_NameAndType:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
                index1 = copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
                index2 = copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
            case JVM_CONSTANT_Long:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
            case JVM_CONSTANT_Double:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
                index1 = copyU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
                index2 = copyU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
                ++i;  /* // these take two CP entries - duh! */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
            case JVM_CONSTANT_Utf8:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
                len     = copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
                index1  = (unsigned short)len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
                utf8    = (char*)allocate(ci, len+1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
                read_bytes(ci, (void*)utf8, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
                utf8[len] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
                write_bytes(ci, (void*)utf8, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
            default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
                CRW_FATAL(ci, "Unknown constant");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
        fillin_cpool_entry(ci, ipos, tag, index1, index2, (const char *)utf8, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
    if (ci->call_name != NULL || ci->return_name != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
        if ( ci->number != (ci->number & 0x7FFF) ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
            ci->class_number_index =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
                add_new_cpool_entry(ci, JVM_CONSTANT_Integer,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
                    (ci->number>>16) & 0xFFFF, ci->number & 0xFFFF, NULL, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
    if (  ci->tclass_name != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
        ci->tracker_class_index =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
                add_new_class_cpool_entry(ci, ci->tclass_name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
    if (ci->obj_init_name != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
        ci->object_init_tracker_index = add_new_method_cpool_entry(ci,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
                    ci->tracker_class_index,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
                    ci->obj_init_name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
                    ci->obj_init_sig);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
    if (ci->newarray_name != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
        ci->newarray_tracker_index = add_new_method_cpool_entry(ci,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
                    ci->tracker_class_index,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
                    ci->newarray_name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
                    ci->newarray_sig);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
    if (ci->call_name != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
        ci->call_tracker_index = add_new_method_cpool_entry(ci,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
                    ci->tracker_class_index,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
                    ci->call_name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
                    ci->call_sig);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
    if (ci->return_name != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
        ci->return_tracker_index = add_new_method_cpool_entry(ci,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
                    ci->tracker_class_index,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
                    ci->return_name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
                    ci->return_sig);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
    random_writeU2(ci, cpool_output_position, ci->cpool_count_plus_one);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
/* ----------------------------------------------------------------- */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
/* Functions that create the bytecodes to inject */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
static ByteOffset
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
push_pool_constant_bytecodes(ByteCode *bytecodes, CrwCpoolIndex index)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
    ByteOffset nbytes = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
    if ( index == (index&0x7F) ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
        bytecodes[nbytes++] = (ByteCode)JVM_OPC_ldc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
        bytecodes[nbytes++] = (ByteCode)JVM_OPC_ldc_w;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
        bytecodes[nbytes++] = (ByteCode)((index >> 8) & 0xFF);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
    bytecodes[nbytes++] = (ByteCode)(index & 0xFF);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
    return nbytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
static ByteOffset
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
push_short_constant_bytecodes(ByteCode *bytecodes, unsigned number)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
    ByteOffset nbytes = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
    if ( number <= 5 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
        bytecodes[nbytes++] = (ByteCode)(JVM_OPC_iconst_0+number);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
    } else if ( number == (number&0x7F) ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
        bytecodes[nbytes++] = (ByteCode)JVM_OPC_bipush;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
        bytecodes[nbytes++] = (ByteCode)(number & 0xFF);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
        bytecodes[nbytes++] = (ByteCode)JVM_OPC_sipush;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
        bytecodes[nbytes++] = (ByteCode)((number >> 8) & 0xFF);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
        bytecodes[nbytes++] = (ByteCode)(number & 0xFF);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
    return nbytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
static ByteOffset
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
injection_template(MethodImage *mi, ByteCode *bytecodes, ByteOffset max_nbytes,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
                        CrwCpoolIndex method_index)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
    CrwClassImage *     ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
    ByteOffset nbytes = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
    unsigned max_stack;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
    int add_dup;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
    int add_aload;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
    int push_cnum;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
    int push_mnum;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
    ci = mi->ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
    CRW_ASSERT(ci, bytecodes!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
    if ( method_index == 0 )  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
        return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
    if ( method_index == ci->newarray_tracker_index) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
        max_stack       = mi->max_stack + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
        add_dup         = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
        add_aload       = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
        push_cnum       = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
        push_mnum       = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
    } else if ( method_index == ci->object_init_tracker_index) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
        max_stack       = mi->max_stack + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
        add_dup         = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
        add_aload       = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
        push_cnum       = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
        push_mnum       = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
        max_stack       = mi->max_stack + 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
        add_dup         = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
        add_aload       = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
        push_cnum       = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
        push_mnum       = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
    if ( add_dup ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
        bytecodes[nbytes++] = (ByteCode)JVM_OPC_dup;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
    if ( add_aload ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
        bytecodes[nbytes++] = (ByteCode)JVM_OPC_aload_0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
    if ( push_cnum ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
        if ( ci->number == (ci->number & 0x7FFF) ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
            nbytes += push_short_constant_bytecodes(bytecodes+nbytes,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
                                                ci->number);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
            CRW_ASSERT(ci, ci->class_number_index!=0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
            nbytes += push_pool_constant_bytecodes(bytecodes+nbytes,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
                                                ci->class_number_index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
    if ( push_mnum ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
        nbytes += push_short_constant_bytecodes(bytecodes+nbytes,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
                                            mi->number);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
    bytecodes[nbytes++] = (ByteCode)JVM_OPC_invokestatic;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
    bytecodes[nbytes++] = (ByteCode)(method_index >> 8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
    bytecodes[nbytes++] = (ByteCode)method_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
    bytecodes[nbytes]   = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
    CRW_ASSERT(ci, nbytes<max_nbytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
    /* Make sure the new max_stack is appropriate */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
    if ( max_stack > mi->new_max_stack ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
        mi->new_max_stack = max_stack;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
    return nbytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
/* Called to create injection code at entry to a method */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
static ByteOffset
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
entry_injection_code(MethodImage *mi, ByteCode *bytecodes, ByteOffset len)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
    CrwClassImage *     ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
    ByteOffset nbytes = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
    CRW_ASSERT_MI(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
    ci = mi->ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
    if ( mi->object_init_method ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
        nbytes = injection_template(mi,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
                            bytecodes, len, ci->object_init_tracker_index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
    if ( !mi->skip_call_return_sites ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
        nbytes += injection_template(mi,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
                    bytecodes+nbytes, len-nbytes, ci->call_tracker_index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
    return nbytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
/* Called to create injection code before an opcode */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
static ByteOffset
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
before_injection_code(MethodImage *mi, ClassOpcode opcode,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
                      ByteCode *bytecodes, ByteOffset len)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
    ByteOffset nbytes = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
    CRW_ASSERT_MI(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
    switch ( opcode ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
        case JVM_OPC_return:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
        case JVM_OPC_ireturn:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
        case JVM_OPC_lreturn:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
        case JVM_OPC_freturn:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
        case JVM_OPC_dreturn:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
        case JVM_OPC_areturn:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
            if ( !mi->skip_call_return_sites ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
                nbytes = injection_template(mi,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
                            bytecodes, len, mi->ci->return_tracker_index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
    return nbytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
/* Called to create injection code after an opcode */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
static ByteOffset
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
after_injection_code(MethodImage *mi, ClassOpcode opcode,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
                     ByteCode *bytecodes, ByteOffset len)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
    CrwClassImage* ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
    ByteOffset nbytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
    ci = mi->ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
    nbytes = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
    CRW_ASSERT_MI(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
    switch ( opcode ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
        case JVM_OPC_new:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
            /* Can't inject here cannot pass around uninitialized object */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
        case JVM_OPC_newarray:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
        case JVM_OPC_anewarray:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
        case JVM_OPC_multianewarray:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
            nbytes = injection_template(mi,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
                                bytecodes, len, ci->newarray_tracker_index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
    return nbytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
/* Actually inject the bytecodes */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
inject_bytecodes(MethodImage *mi, ByteOffset at,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
                 ByteCode *bytecodes, ByteOffset len)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
    Injection injection;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
    CrwClassImage *ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
    ci = mi->ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
    CRW_ASSERT_MI(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
    CRW_ASSERT(ci, at <= mi->code_len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
    injection = mi->injections[at];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
    CRW_ASSERT(ci, len <= LARGEST_INJECTION/2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
    CRW_ASSERT(ci, injection.len+len <= LARGEST_INJECTION);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
    /* Either start an injection area or concatenate to what is there */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
    if ( injection.code == NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
        CRW_ASSERT(ci, injection.len==0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
        injection.code = (ByteCode *)allocate_clean(ci, LARGEST_INJECTION+1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
    (void)memcpy(injection.code+injection.len, bytecodes, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
    injection.len += len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
    injection.code[injection.len] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
    mi->injections[at] = injection;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
    ci->injection_count++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
/* ----------------------------------------------------------------- */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
/* Method handling functions */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
static MethodImage *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
method_init(CrwClassImage *ci, unsigned mnum, ByteOffset code_len)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
    MethodImage *       mi;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
    ByteOffset          i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
    mi                  = (MethodImage*)allocate_clean(ci, (int)sizeof(MethodImage));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
    mi->ci              = ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
    mi->name            = ci->method_name[mnum];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
    mi->descr           = ci->method_descr[mnum];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
    mi->code_len        = code_len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
    mi->map             = (ByteOffset*)allocate_clean(ci,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
                                (int)((code_len+1)*sizeof(ByteOffset)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
    for(i=0; i<=code_len; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
        mi->map[i] = i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
    mi->widening        = (signed char*)allocate_clean(ci, code_len+1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
    mi->injections      = (Injection *)allocate_clean(ci,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
                                (int)((code_len+1)*sizeof(Injection)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
    mi->number          = mnum;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
    ci->current_mi      = mi;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
    return mi;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
method_term(MethodImage *mi)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
    CrwClassImage *ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
    ci = mi->ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
    CRW_ASSERT_MI(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
    if ( mi->map != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
        deallocate(ci, (void*)mi->map);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
        mi->map = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
    if ( mi->widening != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
        deallocate(ci, (void*)mi->widening);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
        mi->widening = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
    if ( mi->injections != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
        ByteOffset i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
        for(i=0; i<= mi->code_len; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
            if ( mi->injections[i].code != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
                deallocate(ci, (void*)mi->injections[i].code);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
                mi->injections[i].code = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
        deallocate(ci, (void*)mi->injections);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
        mi->injections = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
    ci->current_mi = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
    deallocate(ci, (void*)mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
static ByteOffset
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
input_code_offset(MethodImage *mi)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
    CRW_ASSERT_MI(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
    return (ByteOffset)(mi->ci->input_position - mi->start_of_input_bytecodes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
rewind_to_beginning_of_input_bytecodes(MethodImage *mi)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
    CRW_ASSERT_MI(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
    mi->ci->input_position = mi->start_of_input_bytecodes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
/* Starting at original byte position 'at', add 'offset' to it's new
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
 *   location. This may be a negative value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
 *   NOTE: That this map is not the new bytecode location of the opcode
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
 *         but the new bytecode location that should be used when
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
 *         a goto or jump instruction was targeting the old bytecode
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
 *         location.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
adjust_map(MethodImage *mi, ByteOffset at, ByteOffset offset)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
    ByteOffset i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
    CRW_ASSERT_MI(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
    for (i = at; i <= mi->code_len; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
        mi->map[i] += offset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
widen(MethodImage *mi, ByteOffset at, ByteOffset len)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
    int delta;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
    CRW_ASSERT(mi->ci, at <= mi->code_len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
    delta = len - mi->widening[at];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
    /* Adjust everything from the current input location by delta */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
    adjust_map(mi, input_code_offset(mi), delta);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
    /* Mark at beginning of instruction */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
    mi->widening[at] = (signed char)len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
verify_opc_wide(CrwClassImage *ci, ClassOpcode wopcode)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
    switch (wopcode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
        case JVM_OPC_aload: case JVM_OPC_astore:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
        case JVM_OPC_fload: case JVM_OPC_fstore:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
        case JVM_OPC_iload: case JVM_OPC_istore:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
        case JVM_OPC_lload: case JVM_OPC_lstore:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
        case JVM_OPC_dload: case JVM_OPC_dstore:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
        case JVM_OPC_ret:   case JVM_OPC_iinc:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
            CRW_FATAL(ci, "Invalid opcode supplied to wide opcode");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
static unsigned
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
opcode_length(CrwClassImage *ci, ClassOpcode opcode)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
    /* Define array that holds length of an opcode */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
    static unsigned char _opcode_length[JVM_OPC_MAX+1] =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
                          JVM_OPCODE_LENGTH_INITIALIZER;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
    if ( opcode > JVM_OPC_MAX ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
        CRW_FATAL(ci, "Invalid opcode supplied to opcode_length()");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
    return _opcode_length[opcode];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
/* Walk one instruction and inject instrumentation */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
inject_for_opcode(MethodImage *mi)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
    CrwClassImage *  ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
    ClassOpcode      opcode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
    int              pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
    CRW_ASSERT_MI(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
    ci = mi->ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
    pos = input_code_offset(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
    opcode = readU1(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
    if (opcode == JVM_OPC_wide) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
        ClassOpcode     wopcode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
        wopcode = readU1(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
        /* lvIndex not used */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
        (void)readU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
        verify_opc_wide(ci, wopcode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
        if ( wopcode==JVM_OPC_iinc ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
            (void)readU1(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
            (void)readU1(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1103
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
        ByteCode        bytecodes[LARGEST_INJECTION+1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
        int             header;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
        int             instr_len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
        int             low;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
        int             high;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
        int             npairs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
        ByteOffset      len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
        /* Get bytecodes to inject before this opcode */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
        len = before_injection_code(mi, opcode, bytecodes, (int)sizeof(bytecodes));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1114
        if ( len > 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
            inject_bytecodes(mi, pos, bytecodes, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
            /* Adjust map after processing this opcode */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
        /* Process this opcode */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
        switch (opcode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
            case JVM_OPC_tableswitch:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
                header = NEXT_4BYTE_BOUNDARY(pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
                skip(ci, header - (pos+1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
                (void)readU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
                low = readU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
                high = readU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
                skip(ci, (high+1-low) * 4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
            case JVM_OPC_lookupswitch:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
                header = NEXT_4BYTE_BOUNDARY(pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
                skip(ci, header - (pos+1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
                (void)readU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
                npairs = readU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
                skip(ci, npairs * 8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
            default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
                instr_len = opcode_length(ci, opcode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
                skip(ci, instr_len-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
        /* Get position after this opcode is processed */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
        pos = input_code_offset(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
        /* Adjust for any before_injection_code() */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
        if ( len > 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
            /* Adjust everything past this opcode.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
             *   Why past it? Because we want any jumps to this bytecode loc
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
             *   to go to the injected code, not where the opcode
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
             *   was moved too.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
             *   Consider a 'return' opcode that is jumped too.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
             *   NOTE: This may not be correct in all cases, but will
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
             *         when we are only dealing with non-variable opcodes
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
             *         like the return opcodes. Be careful if the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
             *         before_injection_code() changes to include other
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
             *         opcodes that have variable length.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1158
            adjust_map(mi, pos, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
        /* Get bytecodes to inject after this opcode */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
        len = after_injection_code(mi, opcode, bytecodes, (int)sizeof(bytecodes));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
        if ( len > 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
            inject_bytecodes(mi, pos, bytecodes, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
            /* Adjust for any after_injection_code() */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
            adjust_map(mi, pos, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
/* Map original bytecode location to it's new location. (See adjust_map()). */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
static ByteOffset
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
method_code_map(MethodImage *mi, ByteOffset pos)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
    CRW_ASSERT_MI(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
    CRW_ASSERT(mi->ci, pos <= mi->code_len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
    return mi->map[pos];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
static int
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1183
adjust_instruction(MethodImage *mi)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1184
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1185
    CrwClassImage *     ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1186
    ClassOpcode         opcode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1187
    int                 pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1188
    int                 new_pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
    CRW_ASSERT_MI(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
    ci = mi->ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
    pos = input_code_offset(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1193
    new_pos = method_code_map(mi,pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1194
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
    opcode = readU1(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1196
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1197
    if (opcode == JVM_OPC_wide) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1198
        ClassOpcode wopcode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1199
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1200
        wopcode = readU1(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1201
        /* lvIndex not used */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1202
        (void)readU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1203
        verify_opc_wide(ci, wopcode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1204
        if ( wopcode==JVM_OPC_iinc ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1205
            (void)readU1(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1206
            (void)readU1(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1207
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1208
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1209
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1210
        int widened;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1211
        int header;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1212
        int newHeader;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1213
        int low;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1214
        int high;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1215
        int new_pad;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1216
        int old_pad;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1217
        int delta;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1218
        int new_delta;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1219
        int delta_pad;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1220
        int npairs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1221
        int instr_len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1222
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1223
        switch (opcode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1224
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1225
        case JVM_OPC_tableswitch:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1226
            widened     = mi->widening[pos];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1227
            header      = NEXT_4BYTE_BOUNDARY(pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1228
            newHeader   = NEXT_4BYTE_BOUNDARY(new_pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1229
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1230
            skip(ci, header - (pos+1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1231
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1232
            delta       = readU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1233
            low         = readU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1234
            high        = readU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1235
            skip(ci, (high+1-low) * 4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1236
            new_pad     = newHeader - new_pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1237
            old_pad     = header - pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1238
            delta_pad   = new_pad - old_pad;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1239
            if (widened != delta_pad) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1240
                widen(mi, pos, delta_pad);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1241
                return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1242
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1243
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1244
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1245
        case JVM_OPC_lookupswitch:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1246
            widened     = mi->widening[pos];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1247
            header      = NEXT_4BYTE_BOUNDARY(pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1248
            newHeader   = NEXT_4BYTE_BOUNDARY(new_pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1249
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1250
            skip(ci, header - (pos+1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1251
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1252
            delta       = readU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1253
            npairs      = readU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1254
            skip(ci, npairs * 8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1255
            new_pad     = newHeader - new_pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1256
            old_pad     = header - pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1257
            delta_pad   = new_pad - old_pad;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1258
            if (widened != delta_pad) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1259
                widen(mi, pos, delta_pad);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1260
                return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1261
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1262
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1263
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1264
        case JVM_OPC_jsr: case JVM_OPC_goto:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1265
        case JVM_OPC_ifeq: case JVM_OPC_ifge: case JVM_OPC_ifgt:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1266
        case JVM_OPC_ifle: case JVM_OPC_iflt: case JVM_OPC_ifne:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1267
        case JVM_OPC_if_icmpeq: case JVM_OPC_if_icmpne: case JVM_OPC_if_icmpge:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1268
        case JVM_OPC_if_icmpgt: case JVM_OPC_if_icmple: case JVM_OPC_if_icmplt:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1269
        case JVM_OPC_if_acmpeq: case JVM_OPC_if_acmpne:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1270
        case JVM_OPC_ifnull: case JVM_OPC_ifnonnull:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1271
            widened     = mi->widening[pos];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1272
            delta       = readS2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1273
            if (widened == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1274
                new_delta = method_code_map(mi,pos+delta) - new_pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1275
                if ((new_delta < -32768) || (new_delta > 32767)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1276
                    switch (opcode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1277
                        case JVM_OPC_jsr: case JVM_OPC_goto:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1278
                            widen(mi, pos, 2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1279
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1280
                        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1281
                            widen(mi, pos, 5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1282
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1283
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1284
                    return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1285
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1286
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1287
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1288
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1289
        case JVM_OPC_jsr_w:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1290
        case JVM_OPC_goto_w:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1291
            (void)readU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1292
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1293
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1294
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1295
            instr_len = opcode_length(ci, opcode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1296
            skip(ci, instr_len-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1297
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1298
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1299
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1300
    return 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1301
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1302
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1303
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1304
write_instruction(MethodImage *mi)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1305
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1306
    CrwClassImage *     ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1307
    ClassOpcode         opcode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1308
    ByteOffset          new_code_len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1309
    int                 pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1310
    int                 new_pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1311
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1312
    CRW_ASSERT_MI(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1313
    ci = mi->ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1314
    pos = input_code_offset(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1315
    new_pos = method_code_map(mi,pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1316
    new_code_len = mi->injections[pos].len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1317
    if (new_code_len > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1318
        write_bytes(ci, (void*)mi->injections[pos].code, new_code_len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1319
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1320
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1321
    opcode = readU1(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1322
    if (opcode == JVM_OPC_wide) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1323
        ClassOpcode     wopcode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1324
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1325
        writeU1(ci, opcode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1326
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1327
        wopcode = copyU1(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1328
        /* lvIndex not used */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1329
        (void)copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1330
        verify_opc_wide(ci, wopcode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1331
        if ( wopcode==JVM_OPC_iinc ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1332
            (void)copyU1(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1333
            (void)copyU1(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1334
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1335
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1336
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1337
        ClassOpcode new_opcode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1338
        int             header;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1339
        int             newHeader;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1340
        int             low;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1341
        int             high;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1342
        int             i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1343
        int             npairs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1344
        int             widened;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1345
        int             instr_len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1346
        int             delta;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1347
        int             new_delta;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1348
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1349
        switch (opcode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1350
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1351
            case JVM_OPC_tableswitch:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1352
                header = NEXT_4BYTE_BOUNDARY(pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1353
                newHeader = NEXT_4BYTE_BOUNDARY(new_pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1354
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1355
                skip(ci, header - (pos+1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1356
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1357
                delta = readU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1358
                new_delta = method_code_map(mi,pos+delta) - new_pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1359
                low = readU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1360
                high = readU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1361
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1362
                writeU1(ci, opcode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1363
                for (i = new_pos+1; i < newHeader; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1364
                    writeU1(ci, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1365
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1366
                writeU4(ci, new_delta);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1367
                writeU4(ci, low);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1368
                writeU4(ci, high);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1369
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1370
                for (i = low; i <= high; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1371
                    delta = readU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1372
                    new_delta = method_code_map(mi,pos+delta) - new_pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1373
                    writeU4(ci, new_delta);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1374
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1375
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1376
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1377
            case JVM_OPC_lookupswitch:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1378
                header = NEXT_4BYTE_BOUNDARY(pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1379
                newHeader = NEXT_4BYTE_BOUNDARY(new_pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1380
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1381
                skip(ci, header - (pos+1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1382
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1383
                delta = readU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1384
                new_delta = method_code_map(mi,pos+delta) - new_pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1385
                npairs = readU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1386
                writeU1(ci, opcode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1387
                for (i = new_pos+1; i < newHeader; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1388
                    writeU1(ci, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1389
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1390
                writeU4(ci, new_delta);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1391
                writeU4(ci, npairs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1392
                for (i = 0; i< npairs; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1393
                    unsigned match = readU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1394
                    delta = readU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1395
                    new_delta = method_code_map(mi,pos+delta) - new_pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1396
                    writeU4(ci, match);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1397
                    writeU4(ci, new_delta);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1398
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1399
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1400
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1401
            case JVM_OPC_jsr: case JVM_OPC_goto:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1402
            case JVM_OPC_ifeq: case JVM_OPC_ifge: case JVM_OPC_ifgt:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1403
            case JVM_OPC_ifle: case JVM_OPC_iflt: case JVM_OPC_ifne:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1404
            case JVM_OPC_if_icmpeq: case JVM_OPC_if_icmpne: case JVM_OPC_if_icmpge:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1405
            case JVM_OPC_if_icmpgt: case JVM_OPC_if_icmple: case JVM_OPC_if_icmplt:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1406
            case JVM_OPC_if_acmpeq: case JVM_OPC_if_acmpne:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1407
            case JVM_OPC_ifnull: case JVM_OPC_ifnonnull:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1408
                widened = mi->widening[pos];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1409
                delta = readS2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1410
                new_delta = method_code_map(mi,pos+delta) - new_pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1411
                new_opcode = opcode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1412
                if (widened == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1413
                    writeU1(ci, opcode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1414
                    writeU2(ci, new_delta);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1415
                } else if (widened == 2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1416
                    switch (opcode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1417
                        case JVM_OPC_jsr:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1418
                            new_opcode = JVM_OPC_jsr_w;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1419
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1420
                        case JVM_OPC_goto:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1421
                            new_opcode = JVM_OPC_goto_w;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1422
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1423
                        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1424
                            CRW_FATAL(ci, "unexpected opcode");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1425
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1426
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1427
                    writeU1(ci, new_opcode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1428
                    writeU4(ci, new_delta);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1429
                } else if (widened == 5) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1430
                    switch (opcode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1431
                        case JVM_OPC_ifeq:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1432
                            new_opcode = JVM_OPC_ifne;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1433
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1434
                        case JVM_OPC_ifge:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1435
                            new_opcode = JVM_OPC_iflt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1436
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1437
                        case JVM_OPC_ifgt:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1438
                            new_opcode = JVM_OPC_ifle;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1439
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1440
                        case JVM_OPC_ifle:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1441
                            new_opcode = JVM_OPC_ifgt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1442
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1443
                        case JVM_OPC_iflt:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1444
                            new_opcode = JVM_OPC_ifge;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1445
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1446
                        case JVM_OPC_ifne:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1447
                            new_opcode = JVM_OPC_ifeq;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1448
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1449
                        case JVM_OPC_if_icmpeq:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1450
                            new_opcode = JVM_OPC_if_icmpne;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1451
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1452
                        case JVM_OPC_if_icmpne:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1453
                            new_opcode = JVM_OPC_if_icmpeq;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1454
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1455
                        case JVM_OPC_if_icmpge:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1456
                            new_opcode = JVM_OPC_if_icmplt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1457
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1458
                        case JVM_OPC_if_icmpgt:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1459
                            new_opcode = JVM_OPC_if_icmple;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1460
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1461
                        case JVM_OPC_if_icmple:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1462
                            new_opcode = JVM_OPC_if_icmpgt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1463
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1464
                        case JVM_OPC_if_icmplt:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1465
                            new_opcode = JVM_OPC_if_icmpge;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1466
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1467
                        case JVM_OPC_if_acmpeq:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1468
                            new_opcode = JVM_OPC_if_acmpne;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1469
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1470
                        case JVM_OPC_if_acmpne:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1471
                            new_opcode = JVM_OPC_if_acmpeq;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1472
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1473
                        case JVM_OPC_ifnull:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1474
                            new_opcode = JVM_OPC_ifnonnull;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1475
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1476
                        case JVM_OPC_ifnonnull:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1477
                            new_opcode = JVM_OPC_ifnull;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1478
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1479
                        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1480
                            CRW_FATAL(ci, "Unexpected opcode");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1481
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1482
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1483
                    writeU1(ci, new_opcode);    /* write inverse branch */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1484
                    writeU2(ci, 3 + 5);         /* beyond if and goto_w */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1485
                    writeU1(ci, JVM_OPC_goto_w);    /* add a goto_w */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1486
                    writeU4(ci, new_delta-3); /* write new and wide delta */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1487
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1488
                    CRW_FATAL(ci, "Unexpected widening");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1489
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1490
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1491
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1492
            case JVM_OPC_jsr_w:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1493
            case JVM_OPC_goto_w:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1494
                delta = readU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1495
                new_delta = method_code_map(mi,pos+delta) - new_pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1496
                writeU1(ci, opcode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1497
                writeU4(ci, new_delta);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1498
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1499
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1500
            default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1501
                instr_len = opcode_length(ci, opcode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1502
                writeU1(ci, opcode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1503
                copy(ci, instr_len-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1504
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1505
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1506
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1507
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1508
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1509
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1510
method_inject_and_write_code(MethodImage *mi)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1511
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1512
    ByteCode bytecodes[LARGEST_INJECTION+1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1513
    ByteOffset   len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1514
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1515
    CRW_ASSERT_MI(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1516
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1517
    /* Do injections */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1518
    rewind_to_beginning_of_input_bytecodes(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1519
    len = entry_injection_code(mi, bytecodes, (int)sizeof(bytecodes));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1520
    if ( len > 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1521
        int pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1522
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1523
        pos = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1524
        inject_bytecodes(mi, pos, bytecodes, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1525
        /* Adjust pos 0 to map to new pos 0, you never want to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1526
         *  jump into this entry code injection. So the new pos 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1527
         *  will be past this entry_injection_code().
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1528
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1529
        adjust_map(mi, pos, len); /* Inject before behavior */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1530
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1531
    while (input_code_offset(mi) < mi->code_len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1532
        inject_for_opcode(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1533
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1534
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1535
    /* Adjust instructions */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1536
    rewind_to_beginning_of_input_bytecodes(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1537
    while (input_code_offset(mi) < mi->code_len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1538
        if (!adjust_instruction(mi)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1539
            rewind_to_beginning_of_input_bytecodes(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1540
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1541
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1542
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1543
    /* Write new instructions */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1544
    rewind_to_beginning_of_input_bytecodes(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1545
    while (input_code_offset(mi) < mi->code_len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1546
        write_instruction(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1547
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1548
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1549
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1550
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1551
copy_attribute(CrwClassImage *ci)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1552
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1553
    int len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1554
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1555
    (void)copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1556
    len = copyU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1557
    copy(ci, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1558
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1559
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1560
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1561
copy_attributes(CrwClassImage *ci)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1562
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1563
    unsigned i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1564
    unsigned count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1565
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1566
    count = copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1567
    for (i = 0; i < count; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1568
        copy_attribute(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1569
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1570
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1571
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1572
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1573
copy_all_fields(CrwClassImage *ci)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1574
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1575
    unsigned i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1576
    unsigned count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1577
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1578
    count = copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1579
    for (i = 0; i < count; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1580
        /* access, name, descriptor */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1581
        copy(ci, 6);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1582
        copy_attributes(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1583
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1584
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1585
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1586
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1587
write_line_table(MethodImage *mi)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1588
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1589
    unsigned             i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1590
    unsigned             count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1591
    CrwClassImage *      ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1592
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1593
    CRW_ASSERT_MI(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1594
    ci = mi->ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1595
    (void)copyU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1596
    count = copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1597
    for(i=0; i<count; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1598
        ByteOffset start_pc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1599
        ByteOffset new_start_pc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1600
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1601
        start_pc = readU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1602
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1603
        if ( start_pc == 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1604
            new_start_pc = 0; /* Don't skip entry injection code. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1605
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1606
            new_start_pc = method_code_map(mi, start_pc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1607
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1608
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1609
        writeU2(ci, new_start_pc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1610
        (void)copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1611
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1612
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1613
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1614
/* Used for LocalVariableTable and LocalVariableTypeTable attributes */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1615
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1616
write_var_table(MethodImage *mi)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1617
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1618
    unsigned             i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1619
    unsigned             count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1620
    CrwClassImage *      ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1621
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1622
    CRW_ASSERT_MI(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1623
    ci = mi->ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1624
    (void)copyU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1625
    count = copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1626
    for(i=0; i<count; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1627
        ByteOffset start_pc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1628
        ByteOffset new_start_pc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1629
        ByteOffset length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1630
        ByteOffset new_length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1631
        ByteOffset end_pc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1632
        ByteOffset new_end_pc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1633
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1634
        start_pc        = readU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1635
        length          = readU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1636
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1637
        if ( start_pc == 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1638
            new_start_pc = 0; /* Don't skip entry injection code. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1639
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1640
            new_start_pc = method_code_map(mi, start_pc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1641
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1642
        end_pc          = start_pc + length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1643
        new_end_pc      = method_code_map(mi, end_pc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1644
        new_length      = new_end_pc - new_start_pc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1645
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1646
        writeU2(ci, new_start_pc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1647
        writeU2(ci, new_length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1648
        (void)copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1649
        (void)copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1650
        (void)copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1651
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1652
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1653
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1654
/* The uoffset field is u2 or u4 depending on the code_len.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1655
 *   Note that the code_len is likely changing, so be careful here.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1656
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1657
static unsigned
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1658
readUoffset(MethodImage *mi)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1659
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1660
    if ( mi->code_len > 65535 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1661
        return readU4(mi->ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1662
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1663
    return readU2(mi->ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1664
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1665
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1666
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1667
writeUoffset(MethodImage *mi, unsigned val)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1668
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1669
    if ( mi->new_code_len > 65535 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1670
        writeU4(mi->ci, val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1671
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1672
    writeU2(mi->ci, val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1673
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1674
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1675
static unsigned
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1676
copyUoffset(MethodImage *mi)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1677
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1678
    unsigned uoffset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1679
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1680
    uoffset = readUoffset(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1681
    writeUoffset(mi, uoffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1682
    return uoffset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1683
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1684
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1685
/* Copy over verification_type_info structure */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1686
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1687
copy_verification_types(MethodImage *mi, int ntypes)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1688
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1689
    /* If there were ntypes, we just copy that over, no changes */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1690
    if ( ntypes > 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1691
        int j;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1692
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1693
        for ( j = 0 ; j < ntypes ; j++ ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1694
            unsigned tag;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1695
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1696
            tag = copyU1(mi->ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1697
            switch ( tag ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1698
                case JVM_ITEM_Object:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1699
                    (void)copyU2(mi->ci); /* Constant pool entry */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1700
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1701
                case JVM_ITEM_Uninitialized:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1702
                    /* Code offset for 'new' opcode is for this object */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1703
                    writeUoffset(mi, method_code_map(mi, readUoffset(mi)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1704
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1705
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1706
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1707
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1708
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1709
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1710
/* Process the StackMapTable attribute. We didn't add any basic blocks
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1711
 *   so the frame count remains the same but we may need to process the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1712
 *   frame types due to offset changes putting things out of range.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1713
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1714
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1715
write_stackmap_table(MethodImage *mi)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1716
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1717
    CrwClassImage *ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1718
    CrwPosition    save_position;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1719
    ByteOffset     last_pc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1720
    ByteOffset     last_new_pc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1721
    unsigned       i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1722
    unsigned       attr_len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1723
    unsigned       new_attr_len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1724
    unsigned       count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1725
    unsigned       delta_adj;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1726
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1727
    CRW_ASSERT_MI(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1728
    ci = mi->ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1729
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1730
    /* Save the position of the attribute length so we can fix it later */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1731
    save_position = ci->output_position;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1732
    attr_len      = copyU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1733
    count         = copyUoffset(mi);  /* uoffset: number_of_entries */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1734
    if ( count == 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1735
        CRW_ASSERT(ci, attr_len==2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1736
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1737
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1738
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1739
    /* Process entire stackmap */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1740
    last_pc     = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1741
    last_new_pc = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1742
    delta_adj   = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1743
    for ( i = 0 ; i < count ; i++ ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1744
        ByteOffset new_pc=0;    /* new pc in instrumented code */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1745
        unsigned   ft;        /* frame_type */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1746
        int        delta=0;     /* pc delta */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1747
        int        new_delta=0; /* new pc delta */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1748
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1749
        ft = readU1(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1750
        if ( ft <= 63 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1751
            /* Frame Type: same_frame ([0,63]) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1752
            unsigned   new_ft;    /* new frame_type */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1753
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1754
            delta     = (delta_adj + ft);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1755
            new_pc    = method_code_map(mi, last_pc + delta);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1756
            new_delta = new_pc - last_new_pc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1757
            new_ft    = (new_delta - delta_adj);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1758
            if ( new_ft > 63 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1759
                /* Change to same_frame_extended (251) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1760
                new_ft = 251;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1761
                writeU1(ci, new_ft);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1762
                writeUoffset(mi, (new_delta - delta_adj));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1763
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1764
                writeU1(ci, new_ft);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1765
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1766
        } else if ( ft >= 64 && ft <= 127 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1767
            /* Frame Type: same_locals_1_stack_item_frame ([64,127]) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1768
            unsigned   new_ft;    /* new frame_type */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1769
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1770
            delta     = (delta_adj + ft - 64);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1771
            new_pc    = method_code_map(mi, last_pc + delta);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1772
            new_delta = new_pc - last_new_pc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1773
            if ( (new_delta - delta_adj) > 63 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1774
                /* Change to same_locals_1_stack_item_frame_extended (247) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1775
                new_ft = 247;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1776
                writeU1(ci, new_ft);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1777
                writeUoffset(mi, (new_delta - delta_adj));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1778
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1779
                new_ft = (new_delta - delta_adj) + 64;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1780
                writeU1(ci, new_ft);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1781
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1782
            copy_verification_types(mi, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1783
        } else if ( ft >= 128 && ft <= 246 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1784
            /* Frame Type: reserved_for_future_use ([128,246]) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1785
            CRW_FATAL(ci, "Unknown frame type in StackMapTable attribute");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1786
        } else if ( ft == 247 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1787
            /* Frame Type: same_locals_1_stack_item_frame_extended (247) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1788
            delta     = (delta_adj + readUoffset(mi));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1789
            new_pc    = method_code_map(mi, last_pc + delta);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1790
            new_delta = new_pc - last_new_pc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1791
            writeU1(ci, ft);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1792
            writeUoffset(mi, (new_delta - delta_adj));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1793
            copy_verification_types(mi, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1794
        } else if ( ft >= 248 && ft <= 250 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1795
            /* Frame Type: chop_frame ([248,250]) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1796
            delta     = (delta_adj + readUoffset(mi));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1797
            new_pc    = method_code_map(mi, last_pc + delta);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1798
            new_delta = new_pc - last_new_pc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1799
            writeU1(ci, ft);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1800
            writeUoffset(mi, (new_delta - delta_adj));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1801
        } else if ( ft == 251 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1802
            /* Frame Type: same_frame_extended (251) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1803
            delta     = (delta_adj + readUoffset(mi));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1804
            new_pc    = method_code_map(mi, last_pc + delta);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1805
            new_delta = new_pc - last_new_pc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1806
            writeU1(ci, ft);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1807
            writeUoffset(mi, (new_delta - delta_adj));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1808
        } else if ( ft >= 252 && ft <= 254 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1809
            /* Frame Type: append_frame ([252,254]) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1810
            delta     = (delta_adj + readUoffset(mi));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1811
            new_pc    = method_code_map(mi, last_pc + delta);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1812
            new_delta = new_pc - last_new_pc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1813
            writeU1(ci, ft);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1814
            writeUoffset(mi, (new_delta - delta_adj));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1815
            copy_verification_types(mi, (ft - 251));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1816
        } else if ( ft == 255 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1817
            unsigned   ntypes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1818
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1819
            /* Frame Type: full_frame (255) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1820
            delta     = (delta_adj + readUoffset(mi));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1821
            new_pc    = method_code_map(mi, last_pc + delta);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1822
            new_delta = new_pc - last_new_pc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1823
            writeU1(ci, ft);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1824
            writeUoffset(mi, (new_delta - delta_adj));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1825
            ntypes    = copyU2(ci); /* ulocalvar */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1826
            copy_verification_types(mi, ntypes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1827
            ntypes    = copyU2(ci); /* ustack */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1828
            copy_verification_types(mi, ntypes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1829
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1830
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1831
        /* Update last_pc and last_new_pc (save on calls to method_code_map) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1832
        CRW_ASSERT(ci, delta >= 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1833
        CRW_ASSERT(ci, new_delta >= 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1834
        last_pc    += delta;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1835
        last_new_pc = new_pc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1836
        CRW_ASSERT(ci, last_pc <= mi->code_len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1837
        CRW_ASSERT(ci, last_new_pc <= mi->new_code_len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1838
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1839
        /* Delta adjustment, all deltas are -1 now in attribute */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1840
        delta_adj = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1841
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1842
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1843
    /* Update the attribute length */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1844
    new_attr_len = ci->output_position - (save_position + 4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1845
    CRW_ASSERT(ci, new_attr_len >= attr_len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1846
    random_writeU4(ci, save_position, new_attr_len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1847
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1848
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1849
/* Process the CLDC StackMap attribute. We didn't add any basic blocks
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1850
 *   so the frame count remains the same but we may need to process the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1851
 *   frame types due to offset changes putting things out of range.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1852
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1853
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1854
write_cldc_stackmap_table(MethodImage *mi)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1855
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1856
    CrwClassImage *ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1857
    CrwPosition    save_position;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1858
    unsigned       i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1859
    unsigned       attr_len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1860
    unsigned       new_attr_len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1861
    unsigned       count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1862
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1863
    CRW_ASSERT_MI(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1864
    ci = mi->ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1865
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1866
    /* Save the position of the attribute length so we can fix it later */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1867
    save_position = ci->output_position;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1868
    attr_len      = copyU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1869
    count         = copyUoffset(mi);  /* uoffset: number_of_entries */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1870
    if ( count == 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1871
        CRW_ASSERT(ci, attr_len==2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1872
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1873
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1874
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1875
    /* Process entire stackmap */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1876
    for ( i = 0 ; i < count ; i++ ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1877
        unsigned   ntypes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1878
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1879
        writeUoffset(mi, method_code_map(mi, readUoffset(mi)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1880
        ntypes    = copyU2(ci); /* ulocalvar */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1881
        copy_verification_types(mi, ntypes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1882
        ntypes    = copyU2(ci); /* ustack */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1883
        copy_verification_types(mi, ntypes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1884
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1885
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1886
    /* Update the attribute length */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1887
    new_attr_len = ci->output_position - (save_position + 4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1888
    CRW_ASSERT(ci, new_attr_len >= attr_len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1889
    random_writeU4(ci, save_position, new_attr_len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1890
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1891
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1892
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1893
method_write_exception_table(MethodImage *mi)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1894
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1895
    unsigned            i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1896
    unsigned            count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1897
    CrwClassImage *     ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1898
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1899
    CRW_ASSERT_MI(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1900
    ci = mi->ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1901
    count = copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1902
    for(i=0; i<count; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1903
        ByteOffset start_pc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1904
        ByteOffset new_start_pc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1905
        ByteOffset end_pc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1906
        ByteOffset new_end_pc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1907
        ByteOffset handler_pc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1908
        ByteOffset new_handler_pc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1909
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1910
        start_pc        = readU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1911
        end_pc          = readU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1912
        handler_pc      = readU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1913
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1914
        new_start_pc    = method_code_map(mi, start_pc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1915
        new_end_pc      = method_code_map(mi, end_pc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1916
        new_handler_pc  = method_code_map(mi, handler_pc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1917
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1918
        writeU2(ci, new_start_pc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1919
        writeU2(ci, new_end_pc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1920
        writeU2(ci, new_handler_pc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1921
        (void)copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1922
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1923
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1924
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1925
static int
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1926
attribute_match(CrwClassImage *ci, CrwCpoolIndex name_index, const char *name)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1927
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1928
    CrwConstantPoolEntry cs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1929
    int                  len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1930
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1931
    CRW_ASSERT_CI(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1932
    CRW_ASSERT(ci, name!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1933
    len = (int)strlen(name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1934
    cs = cpool_entry(ci, name_index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1935
    if ( cs.len==len && strncmp(cs.ptr, name, len)==0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1936
       return 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1937
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1938
    return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1939
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1940
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1941
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1942
method_write_code_attribute(MethodImage *mi)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1943
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1944
    CrwClassImage *     ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1945
    CrwCpoolIndex       name_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1946
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1947
    CRW_ASSERT_MI(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1948
    ci = mi->ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1949
    name_index = copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1950
    if ( attribute_match(ci, name_index, "LineNumberTable") ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1951
        write_line_table(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1952
    } else if ( attribute_match(ci, name_index, "LocalVariableTable") ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1953
        write_var_table(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1954
    } else if ( attribute_match(ci, name_index, "LocalVariableTypeTable") ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1955
        write_var_table(mi); /* Exact same format as the LocalVariableTable */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1956
    } else if ( attribute_match(ci, name_index, "StackMapTable") ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1957
        write_stackmap_table(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1958
    } else if ( attribute_match(ci, name_index, "StackMap") ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1959
        write_cldc_stackmap_table(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1960
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1961
        unsigned len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1962
        len = copyU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1963
        copy(ci, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1964
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1965
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1966
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1967
static int
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1968
is_init_method(const char *name)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1969
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1970
    if ( name!=NULL && strcmp(name,"<init>")==0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1971
        return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1972
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1973
    return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1974
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1975
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1976
static int
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1977
is_clinit_method(const char *name)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1978
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1979
    if ( name!=NULL && strcmp(name,"<clinit>")==0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1980
        return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1981
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1982
    return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1983
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1984
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1985
static int
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1986
is_finalize_method(const char *name)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1987
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1988
    if ( name!=NULL && strcmp(name,"finalize")==0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1989
        return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1990
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1991
    return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1992
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1993
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1994
static int
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1995
skip_method(CrwClassImage *ci, const char *name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1996
                unsigned access_flags, ByteOffset code_len,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1997
                int system_class, jboolean *pskip_call_return_sites)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1998
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1999
    *pskip_call_return_sites = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2000
    if ( system_class ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2001
        if ( code_len == 1 && is_init_method(name) ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2002
            return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2003
        } else if ( code_len == 1 && is_finalize_method(name) ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2004
            return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2005
        } else if ( is_clinit_method(name) ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2006
            return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2007
        } else if ( ci->is_thread_class && strcmp(name,"currentThread")==0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2008
            return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2009
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2010
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2011
        if ( access_flags & JVM_ACC_PRIVATE ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2012
            *pskip_call_return_sites = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2013
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2014
        */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2015
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2016
    return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2017
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2018
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2019
/* Process all code attributes */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2020
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2021
method_write_bytecodes(CrwClassImage *ci, unsigned mnum, unsigned access_flags)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2022
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2023
    CrwPosition         output_attr_len_position;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2024
    CrwPosition         output_max_stack_position;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2025
    CrwPosition         output_code_len_position;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2026
    CrwPosition         start_of_output_bytecodes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2027
    unsigned            i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2028
    unsigned            attr_len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2029
    unsigned            max_stack;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2030
    ByteOffset          code_len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2031
    unsigned            attr_count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2032
    unsigned            new_attr_len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2033
    MethodImage *       mi;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2034
    jboolean            object_init_method;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2035
    jboolean            skip_call_return_sites;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2036
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2037
    CRW_ASSERT_CI(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2038
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2039
    /* Attribute Length */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2040
    output_attr_len_position = ci->output_position;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2041
    attr_len = copyU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2042
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2043
    /* Max Stack */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2044
    output_max_stack_position = ci->output_position;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2045
    max_stack = copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2046
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2047
    /* Max Locals */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2048
    (void)copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2049
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2050
    /* Code Length */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2051
    output_code_len_position = ci->output_position;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2052
    code_len = copyU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2053
    start_of_output_bytecodes = ci->output_position;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2054
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2055
    /* Some methods should not be instrumented */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2056
    object_init_method = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2057
    skip_call_return_sites = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2058
    if ( ci->is_object_class &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2059
         is_init_method(ci->method_name[mnum]) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2060
         strcmp(ci->method_descr[mnum],"()V")==0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2061
        object_init_method = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2062
        skip_call_return_sites = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2063
    } else if ( skip_method(ci, ci->method_name[mnum], access_flags,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2064
                code_len, ci->system_class, &skip_call_return_sites) ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2065
        /* Copy remainder minus already copied, the U2 max_stack,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2066
         *   U2 max_locals, and U4 code_length fields have already
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2067
         *   been processed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2068
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2069
        copy(ci, attr_len - (2+2+4));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2070
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2071
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2072
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2073
    /* Start Injection */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2074
    mi = method_init(ci, mnum, code_len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2075
    mi->object_init_method = object_init_method;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2076
    mi->access_flags = access_flags;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2077
    mi->skip_call_return_sites = skip_call_return_sites;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2078
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2079
    /* Save the current position as the start of the input bytecodes */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2080
    mi->start_of_input_bytecodes = ci->input_position;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2081
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2082
    /* The max stack may increase */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2083
    mi->max_stack = max_stack;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2084
    mi->new_max_stack = max_stack;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2085
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2086
    /* Adjust all code offsets */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2087
    method_inject_and_write_code(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2088
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2089
    /* Fix up code length (save new_code_len for later attribute processing) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2090
    mi->new_code_len = (int)(ci->output_position - start_of_output_bytecodes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2091
    random_writeU4(ci, output_code_len_position, mi->new_code_len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2092
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2093
    /* Fixup max stack */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2094
    CRW_ASSERT(ci, mi->new_max_stack <= 0xFFFF);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2095
    random_writeU2(ci, output_max_stack_position, mi->new_max_stack);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2096
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2097
    /* Copy exception table */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2098
    method_write_exception_table(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2099
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2100
    /* Copy code attributes (needs mi->new_code_len) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2101
    attr_count = copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2102
    for (i = 0; i < attr_count; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2103
        method_write_code_attribute(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2104
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2105
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2106
    /* Fix up attribute length */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2107
    new_attr_len = (int)(ci->output_position - (output_attr_len_position + 4));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2108
    random_writeU4(ci, output_attr_len_position, new_attr_len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2109
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2110
    /* Free method data */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2111
    method_term(mi);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2112
    mi = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2113
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2114
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2115
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2116
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2117
method_write(CrwClassImage *ci, unsigned mnum)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2118
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2119
    unsigned            i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2120
    unsigned            access_flags;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2121
    CrwCpoolIndex       name_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2122
    CrwCpoolIndex       descr_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2123
    unsigned            attr_count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2124
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2125
    access_flags = copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2126
    name_index = copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2127
    ci->method_name[mnum] = cpool_entry(ci, name_index).ptr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2128
    descr_index = copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2129
    ci->method_descr[mnum] = cpool_entry(ci, descr_index).ptr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2130
    attr_count = copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2131
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2132
    for (i = 0; i < attr_count; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2133
        CrwCpoolIndex name_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2134
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2135
        name_index = copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2136
        if ( attribute_match(ci, name_index, "Code") ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2137
            method_write_bytecodes(ci, mnum, access_flags);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2138
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2139
            unsigned len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2140
            len = copyU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2141
            copy(ci, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2142
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2143
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2144
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2145
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2146
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2147
method_write_all(CrwClassImage *ci)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2148
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2149
    unsigned i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2150
    unsigned count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2151
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2152
    count = copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2153
    ci->method_count = count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2154
    if ( count > 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2155
        ci->method_name = (const char **)allocate_clean(ci, count*(int)sizeof(const char*));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2156
        ci->method_descr = (const char **)allocate_clean(ci, count*(int)sizeof(const char*));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2157
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2158
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2159
    for (i = 0; i < count; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2160
        method_write(ci, i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2161
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2162
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2163
    if ( ci->mnum_callback != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2164
        (*(ci->mnum_callback))(ci->number, ci->method_name, ci->method_descr,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2165
                         count);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2166
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2167
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2168
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2169
/* ------------------------------------------------------------------- */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2170
/* Cleanup function. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2171
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2172
static void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2173
cleanup(CrwClassImage *ci)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2174
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2175
    CRW_ASSERT_CI(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2176
    if ( ci->name != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2177
        deallocate(ci, (void*)ci->name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2178
        ci->name = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2179
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2180
    if ( ci->method_name != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2181
        deallocate(ci, (void*)ci->method_name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2182
        ci->method_name = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2183
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2184
    if ( ci->method_descr != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2185
        deallocate(ci, (void*)ci->method_descr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2186
        ci->method_descr = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2187
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2188
    if ( ci->cpool != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2189
        CrwCpoolIndex i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2190
        for(i=0; i<ci->cpool_count_plus_one; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2191
            if ( ci->cpool[i].ptr != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2192
                deallocate(ci, (void*)(ci->cpool[i].ptr));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2193
                ci->cpool[i].ptr = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2194
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2195
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2196
        deallocate(ci, (void*)ci->cpool);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2197
        ci->cpool = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2198
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2199
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2200
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2201
static jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2202
skip_class(unsigned access_flags)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2203
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2204
    if ( access_flags & JVM_ACC_INTERFACE ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2205
        return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2206
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2207
    return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2208
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2209
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2210
static long
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2211
inject_class(struct CrwClassImage *ci,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2212
                 int system_class,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2213
                 char* tclass_name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2214
                 char* tclass_sig,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2215
                 char* call_name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2216
                 char* call_sig,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2217
                 char* return_name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2218
                 char* return_sig,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2219
                 char* obj_init_name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2220
                 char* obj_init_sig,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2221
                 char* newarray_name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2222
                 char* newarray_sig,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2223
                 unsigned char *buf,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2224
                 long buf_len)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2225
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2226
    CrwConstantPoolEntry        cs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2227
    CrwCpoolIndex               this_class;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2228
    CrwCpoolIndex               super_class;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2229
    unsigned                    magic;
3067
503964947e9f 6855180: Fix classfile version check in java_crw_demo
ohair
parents: 2
diff changeset
  2230
    unsigned                    classfileMajorVersion;
503964947e9f 6855180: Fix classfile version check in java_crw_demo
ohair
parents: 2
diff changeset
  2231
    unsigned                    classfileMinorVersion;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2232
    unsigned                    interface_count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2233
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2234
    CRW_ASSERT_CI(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2235
    CRW_ASSERT(ci, buf!=NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2236
    CRW_ASSERT(ci, buf_len!=0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2237
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2238
    CRW_ASSERT(ci, strchr(tclass_name,'.')==NULL); /* internal qualified name */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2239
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2240
    ci->injection_count         = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2241
    ci->system_class            = system_class;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2242
    ci->tclass_name             = tclass_name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2243
    ci->tclass_sig              = tclass_sig;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2244
    ci->call_name               = call_name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2245
    ci->call_sig                = call_sig;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2246
    ci->return_name             = return_name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2247
    ci->return_sig              = return_sig;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2248
    ci->obj_init_name           = obj_init_name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2249
    ci->obj_init_sig            = obj_init_sig;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2250
    ci->newarray_name           = newarray_name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2251
    ci->newarray_sig            = newarray_sig;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2252
    ci->output                  = buf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2253
    ci->output_len              = buf_len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2254
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2255
    magic = copyU4(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2256
    CRW_ASSERT(ci, magic==0xCAFEBABE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2257
    if ( magic != 0xCAFEBABE ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2258
        return (long)0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2259
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2260
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2261
    /* minor version number not used */
3067
503964947e9f 6855180: Fix classfile version check in java_crw_demo
ohair
parents: 2
diff changeset
  2262
    classfileMinorVersion = copyU2(ci);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2263
    /* major version number not used */
3067
503964947e9f 6855180: Fix classfile version check in java_crw_demo
ohair
parents: 2
diff changeset
  2264
    classfileMajorVersion = copyU2(ci);
503964947e9f 6855180: Fix classfile version check in java_crw_demo
ohair
parents: 2
diff changeset
  2265
    CRW_ASSERT(ci,  (classfileMajorVersion <= JVM_CLASSFILE_MAJOR_VERSION) ||
503964947e9f 6855180: Fix classfile version check in java_crw_demo
ohair
parents: 2
diff changeset
  2266
                   ((classfileMajorVersion == JVM_CLASSFILE_MAJOR_VERSION) &&
503964947e9f 6855180: Fix classfile version check in java_crw_demo
ohair
parents: 2
diff changeset
  2267
                    (classfileMinorVersion <= JVM_CLASSFILE_MINOR_VERSION)));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2268
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2269
    cpool_setup(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2270
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2271
    ci->access_flags        = copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2272
    if ( skip_class(ci->access_flags) ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2273
        return (long)0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2274
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2275
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2276
    this_class          = copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2277
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2278
    cs = cpool_entry(ci, (CrwCpoolIndex)(cpool_entry(ci, this_class).index1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2279
    if ( ci->name == NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2280
        ci->name = duplicate(ci, cs.ptr, cs.len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2281
        CRW_ASSERT(ci, strchr(ci->name,'.')==NULL); /* internal qualified name */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2282
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2283
    CRW_ASSERT(ci, (int)strlen(ci->name)==cs.len && strncmp(ci->name, cs.ptr, cs.len)==0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2284
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2285
    super_class         = copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2286
    if ( super_class == 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2287
        ci->is_object_class = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2288
        CRW_ASSERT(ci, strcmp(ci->name,"java/lang/Object")==0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2289
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2290
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2291
    interface_count     = copyU2(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2292
    copy(ci, interface_count * 2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2293
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2294
    copy_all_fields(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2295
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2296
    method_write_all(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2297
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2298
    if ( ci->injection_count == 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2299
        return (long)0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2300
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2301
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2302
    copy_attributes(ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2303
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2304
    return (long)ci->output_position;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2305
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2306
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2307
/* ------------------------------------------------------------------- */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2308
/* Exported interfaces */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2309
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2310
JNIEXPORT void JNICALL
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2311
java_crw_demo(unsigned class_number,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2312
         const char *name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2313
         const unsigned char *file_image,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2314
         long file_len,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2315
         int system_class,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2316
         char* tclass_name,     /* Name of class that has tracker methods. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2317
         char* tclass_sig,      /* Signature of tclass */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2318
         char* call_name,       /* Method name to call at offset 0 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2319
         char* call_sig,        /* Signature of this method */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2320
         char* return_name,     /* Method name to call before any return */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2321
         char* return_sig,      /* Signature of this method */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2322
         char* obj_init_name,   /* Method name to call in Object <init> */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2323
         char* obj_init_sig,    /* Signature of this method */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2324
         char* newarray_name,   /* Method name to call after newarray opcodes */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2325
         char* newarray_sig,    /* Signature of this method */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2326
         unsigned char **pnew_file_image,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2327
         long *pnew_file_len,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2328
         FatalErrorHandler fatal_error_handler,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2329
         MethodNumberRegister mnum_callback)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2330
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2331
    CrwClassImage ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2332
    long          max_length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2333
    long          new_length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2334
    void         *new_image;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2335
    int           len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2336
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2337
    /* Initial setup of the CrwClassImage structure */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2338
    (void)memset(&ci, 0, (int)sizeof(CrwClassImage));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2339
    ci.fatal_error_handler = fatal_error_handler;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2340
    ci.mnum_callback       = mnum_callback;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2341
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2342
    /* Do some interface error checks */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2343
    if ( pnew_file_image==NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2344
        CRW_FATAL(&ci, "pnew_file_image==NULL");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2345
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2346
    if ( pnew_file_len==NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2347
        CRW_FATAL(&ci, "pnew_file_len==NULL");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2348
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2349
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2350
    /* No file length means do nothing */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2351
    *pnew_file_image = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2352
    *pnew_file_len = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2353
    if ( file_len==0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2354
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2355
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2356
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2357
    /* Do some more interface error checks */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2358
    if ( file_image == NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2359
        CRW_FATAL(&ci, "file_image == NULL");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2360
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2361
    if ( file_len < 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2362
        CRW_FATAL(&ci, "file_len < 0");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2363
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2364
    if ( system_class != 0 && system_class != 1 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2365
        CRW_FATAL(&ci, "system_class is not 0 or 1");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2366
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2367
    if ( tclass_name == NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2368
        CRW_FATAL(&ci, "tclass_name == NULL");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2369
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2370
    if ( tclass_sig == NULL || tclass_sig[0]!='L' ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2371
        CRW_FATAL(&ci, "tclass_sig is not a valid class signature");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2372
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2373
    len = (int)strlen(tclass_sig);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2374
    if ( tclass_sig[len-1]!=';' ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2375
        CRW_FATAL(&ci, "tclass_sig is not a valid class signature");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2376
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2377
    if ( call_name != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2378
        if ( call_sig == NULL || strcmp(call_sig, "(II)V") != 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2379
            CRW_FATAL(&ci, "call_sig is not (II)V");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2380
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2381
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2382
    if ( return_name != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2383
        if ( return_sig == NULL || strcmp(return_sig, "(II)V") != 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2384
            CRW_FATAL(&ci, "return_sig is not (II)V");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2385
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2386
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2387
    if ( obj_init_name != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2388
        if ( obj_init_sig == NULL || strcmp(obj_init_sig, "(Ljava/lang/Object;)V") != 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2389
            CRW_FATAL(&ci, "obj_init_sig is not (Ljava/lang/Object;)V");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2390
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2391
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2392
    if ( newarray_name != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2393
        if ( newarray_sig == NULL || strcmp(newarray_sig, "(Ljava/lang/Object;)V") != 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2394
            CRW_FATAL(&ci, "newarray_sig is not (Ljava/lang/Object;)V");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2395
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2396
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2397
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2398
    /* Finish setup the CrwClassImage structure */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2399
    ci.is_thread_class = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2400
    if ( name != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2401
        CRW_ASSERT(&ci, strchr(name,'.')==NULL); /* internal qualified name */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2402
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2403
        ci.name = duplicate(&ci, name, (int)strlen(name));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2404
        if ( strcmp(name, "java/lang/Thread")==0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2405
            ci.is_thread_class = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2406
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2407
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2408
    ci.number = class_number;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2409
    ci.input = file_image;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2410
    ci.input_len = file_len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2411
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2412
    /* Do the injection */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2413
    max_length = file_len*2 + 512; /* Twice as big + 512 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2414
    new_image = allocate(&ci, (int)max_length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2415
    new_length = inject_class(&ci,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2416
                                 system_class,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2417
                                 tclass_name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2418
                                 tclass_sig,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2419
                                 call_name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2420
                                 call_sig,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2421
                                 return_name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2422
                                 return_sig,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2423
                                 obj_init_name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2424
                                 obj_init_sig,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2425
                                 newarray_name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2426
                                 newarray_sig,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2427
                                 new_image,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2428
                                 max_length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2429
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2430
    /* Dispose or shrink the space to be returned. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2431
    if ( new_length == 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2432
        deallocate(&ci, (void*)new_image);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2433
        new_image = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2434
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2435
        new_image = (void*)reallocate(&ci, (void*)new_image, (int)new_length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2436
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2437
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2438
    /* Return the new class image */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2439
    *pnew_file_image = (unsigned char *)new_image;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2440
    *pnew_file_len = (long)new_length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2441
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2442
    /* Cleanup before we leave. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2443
    cleanup(&ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2444
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2445
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2446
/* Return the classname for this class which is inside the classfile image. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2447
JNIEXPORT char * JNICALL
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2448
java_crw_demo_classname(const unsigned char *file_image, long file_len,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2449
        FatalErrorHandler fatal_error_handler)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2450
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2451
    CrwClassImage               ci;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2452
    CrwConstantPoolEntry        cs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2453
    CrwCpoolIndex               this_class;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2454
    unsigned                    magic;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2455
    char *                      name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2456
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2457
    name = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2458
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2459
    if ( file_len==0 || file_image==NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2460
        return name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2461
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2462
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2463
    /* The only fields we need filled in are the image pointer and the error
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2464
     *    handler.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2465
     *    By not adding an output buffer pointer, no output is created.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2466
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2467
    (void)memset(&ci, 0, (int)sizeof(CrwClassImage));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2468
    ci.input     = file_image;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2469
    ci.input_len = file_len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2470
    ci.fatal_error_handler = fatal_error_handler;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2471
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2472
    /* Read out the bytes from the classfile image */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2473
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2474
    magic = readU4(&ci); /* magic number */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2475
    CRW_ASSERT(&ci, magic==0xCAFEBABE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2476
    if ( magic != 0xCAFEBABE ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2477
        return name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2478
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2479
    (void)readU2(&ci); /* minor version number */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2480
    (void)readU2(&ci); /* major version number */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2481
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2482
    /* Read in constant pool. Since no output setup, writes are NOP's */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2483
    cpool_setup(&ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2484
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2485
    (void)readU2(&ci); /* access flags */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2486
    this_class = readU2(&ci); /* 'this' class */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2487
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2488
    /* Get 'this' constant pool entry */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2489
    cs = cpool_entry(&ci, (CrwCpoolIndex)(cpool_entry(&ci, this_class).index1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2490
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2491
    /* Duplicate the name */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2492
    name = (char *)duplicate(&ci, cs.ptr, cs.len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2493
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2494
    /* Cleanup before we leave. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2495
    cleanup(&ci);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2496
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2497
    /* Return malloc space */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2498
    return name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2499
}