OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [interpret-run.cc] - Blame information for rev 790

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 753 jeremybenn
// interpret-run.cc - Code to interpret bytecode
2
 
3
/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
4
 
5
   This file is part of libgcj.
6
 
7
This software is copyrighted work licensed under the terms of the
8
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9
details.  */
10
 
11
/* This file is meant only to be included in interpret.cc, it should not be
12
 * compiled directly.   */
13
 
14
  using namespace java::lang::reflect;
15
 
16
  pc_t pc = NULL;
17
 
18
  // FRAME_DESC registers this particular invocation as the top-most
19
  // interpreter frame.  This lets the stack tracing code (for
20
  // Throwable) print information about the method being interpreted
21
  // rather than about the interpreter itself.  FRAME_DESC has a
22
  // destructor so it cleans up automatically when the interpreter
23
  // returns.
24
  java::lang::Thread *thread = java::lang::Thread::currentThread();
25
 
26
#ifdef __GCJ_DEBUG
27
  _Jv_InterpFrame frame_desc (meth, thread, NULL, &pc);
28
#else
29
  _Jv_InterpFrame frame_desc (meth, thread);
30
#endif
31
 
32
#ifdef DIRECT_THREADED
33
  ThreadCountAdjuster adj (meth, &frame_desc);
34
#endif // DIRECT_THREADED
35
 
36
  _Jv_word stack[meth->max_stack];
37
  _Jv_word *sp = stack;
38
 
39
  _Jv_word locals[meth->max_locals];
40
 
41
#ifdef __GCJ_DEBUG
42
  // This is the information needed to get and set local variables with
43
  // proper type checking.
44
  frame_desc.locals = locals;
45
  char locals_type[meth->max_locals];
46
  frame_desc.locals_type = locals_type;
47
 
48
  // Set all slots as invalid until they are written to.
49
  memset (locals_type, 'x', meth->max_locals);
50
 
51
  // We need to set the local variable types for the method arguments since
52
  // they are valid at invocation.
53
 
54
  _Jv_Method *method = meth->get_method ();
55
  int type_ctr = 0;
56
 
57
  // If the method is non-static, we need to set the type for the "this" pointer.
58
  if ((method->accflags & java::lang::reflect::Modifier::STATIC) == 0)
59
    {
60
      if (args)
61
        {
62
          // Set the "this" pointer for this frame.
63
          _Jv_word *this_ptr = reinterpret_cast<_Jv_word *> (args);
64
          frame_desc.obj_ptr = this_ptr[0].o;
65
        }
66
 
67
      frame_desc.locals_type[0] = 'o';
68
      type_ctr++;
69
    }
70
 
71
  // Now parse the method signature to set the types of the other arguments.  
72
  int sig_len = method->signature->len ();
73
  char *signature = method->signature->chars ();
74
  for (int i = 1; signature[i] != ')' && i <= sig_len; i++)
75
    {
76
      if (signature[i] == 'Z' || signature[i] == 'B' || signature[i] == 'C'
77
          || signature[i] == 'S' || signature[i] == 'I')
78
        {
79
          frame_desc.locals_type[type_ctr] = 'i';
80
          type_ctr++;
81
          continue;
82
        }
83
      else if (signature[i] == 'F')
84
        {
85
          frame_desc.locals_type[type_ctr] = 'f';
86
          type_ctr++;
87
          continue;
88
        }
89
      else if (signature[i] == 'J')
90
        {
91
          frame_desc.locals_type[type_ctr] = 'l';
92
          frame_desc.locals_type[type_ctr+1] = 'x';
93
          type_ctr += 2;
94
          continue;
95
        }
96
      else if (signature[i] == 'D')
97
        {
98
          frame_desc.locals_type[type_ctr] = 'd';
99
          frame_desc.locals_type[type_ctr+1] = 'x';
100
          type_ctr += 2;
101
          continue;
102
        }
103
      else if (signature[i] == 'L')
104
        {
105
          frame_desc.locals_type[type_ctr] = 'o';
106
          type_ctr++;
107
          while (signature[i] != ';')
108
            i++;
109
          continue;
110
        }
111
      else if (signature[i] == '[')
112
        {
113
          frame_desc.locals_type[type_ctr] = 'o';
114
          type_ctr++;
115
 
116
          // Ignore multi-dimensional arrays.
117
          while (signature[i] == '[')
118
            i++;
119
 
120
          // Check for an object array
121
          if (signature[i] == 'L')
122
            {
123
              while (signature[i] != ';')
124
                i++;
125
            }
126
          continue;
127
        }
128
    }
129
#endif /* __GCJ_DEBUG */
130
 
131
#define INSN_LABEL(op) &&insn_##op
132
 
133
  static const void *const insn_target[] =
134
  {
135
    INSN_LABEL(nop),
136
    INSN_LABEL(aconst_null),
137
    INSN_LABEL(iconst_m1),
138
    INSN_LABEL(iconst_0),
139
    INSN_LABEL(iconst_1),
140
    INSN_LABEL(iconst_2),
141
    INSN_LABEL(iconst_3),
142
    INSN_LABEL(iconst_4),
143
    INSN_LABEL(iconst_5),
144
    INSN_LABEL(lconst_0),
145
    INSN_LABEL(lconst_1),
146
    INSN_LABEL(fconst_0),
147
    INSN_LABEL(fconst_1),
148
    INSN_LABEL(fconst_2),
149
    INSN_LABEL(dconst_0),
150
    INSN_LABEL(dconst_1),
151
    INSN_LABEL(bipush),
152
    INSN_LABEL(sipush),
153
    INSN_LABEL(ldc),
154
    INSN_LABEL(ldc_w),
155
    INSN_LABEL(ldc2_w),
156
    INSN_LABEL(iload),
157
    INSN_LABEL(lload),
158
    INSN_LABEL(fload),
159
    INSN_LABEL(dload),
160
    INSN_LABEL(aload),
161
    INSN_LABEL(iload_0),
162
    INSN_LABEL(iload_1),
163
    INSN_LABEL(iload_2),
164
    INSN_LABEL(iload_3),
165
    INSN_LABEL(lload_0),
166
    INSN_LABEL(lload_1),
167
    INSN_LABEL(lload_2),
168
    INSN_LABEL(lload_3),
169
    INSN_LABEL(fload_0),
170
    INSN_LABEL(fload_1),
171
    INSN_LABEL(fload_2),
172
    INSN_LABEL(fload_3),
173
    INSN_LABEL(dload_0),
174
    INSN_LABEL(dload_1),
175
    INSN_LABEL(dload_2),
176
    INSN_LABEL(dload_3),
177
    INSN_LABEL(aload_0),
178
    INSN_LABEL(aload_1),
179
    INSN_LABEL(aload_2),
180
    INSN_LABEL(aload_3),
181
    INSN_LABEL(iaload),
182
    INSN_LABEL(laload),
183
    INSN_LABEL(faload),
184
    INSN_LABEL(daload),
185
    INSN_LABEL(aaload),
186
    INSN_LABEL(baload),
187
    INSN_LABEL(caload),
188
    INSN_LABEL(saload),
189
    INSN_LABEL(istore),
190
    INSN_LABEL(lstore),
191
    INSN_LABEL(fstore),
192
    INSN_LABEL(dstore),
193
    INSN_LABEL(astore),
194
    INSN_LABEL(istore_0),
195
    INSN_LABEL(istore_1),
196
    INSN_LABEL(istore_2),
197
    INSN_LABEL(istore_3),
198
    INSN_LABEL(lstore_0),
199
    INSN_LABEL(lstore_1),
200
    INSN_LABEL(lstore_2),
201
    INSN_LABEL(lstore_3),
202
    INSN_LABEL(fstore_0),
203
    INSN_LABEL(fstore_1),
204
    INSN_LABEL(fstore_2),
205
    INSN_LABEL(fstore_3),
206
    INSN_LABEL(dstore_0),
207
    INSN_LABEL(dstore_1),
208
    INSN_LABEL(dstore_2),
209
    INSN_LABEL(dstore_3),
210
    INSN_LABEL(astore_0),
211
    INSN_LABEL(astore_1),
212
    INSN_LABEL(astore_2),
213
    INSN_LABEL(astore_3),
214
    INSN_LABEL(iastore),
215
    INSN_LABEL(lastore),
216
    INSN_LABEL(fastore),
217
    INSN_LABEL(dastore),
218
    INSN_LABEL(aastore),
219
    INSN_LABEL(bastore),
220
    INSN_LABEL(castore),
221
    INSN_LABEL(sastore),
222
    INSN_LABEL(pop),
223
    INSN_LABEL(pop2),
224
    INSN_LABEL(dup),
225
    INSN_LABEL(dup_x1),
226
    INSN_LABEL(dup_x2),
227
    INSN_LABEL(dup2),
228
    INSN_LABEL(dup2_x1),
229
    INSN_LABEL(dup2_x2),
230
    INSN_LABEL(swap),
231
    INSN_LABEL(iadd),
232
    INSN_LABEL(ladd),
233
    INSN_LABEL(fadd),
234
    INSN_LABEL(dadd),
235
    INSN_LABEL(isub),
236
    INSN_LABEL(lsub),
237
    INSN_LABEL(fsub),
238
    INSN_LABEL(dsub),
239
    INSN_LABEL(imul),
240
    INSN_LABEL(lmul),
241
    INSN_LABEL(fmul),
242
    INSN_LABEL(dmul),
243
    INSN_LABEL(idiv),
244
    INSN_LABEL(ldiv),
245
    INSN_LABEL(fdiv),
246
    INSN_LABEL(ddiv),
247
    INSN_LABEL(irem),
248
    INSN_LABEL(lrem),
249
    INSN_LABEL(frem),
250
    INSN_LABEL(drem),
251
    INSN_LABEL(ineg),
252
    INSN_LABEL(lneg),
253
    INSN_LABEL(fneg),
254
    INSN_LABEL(dneg),
255
    INSN_LABEL(ishl),
256
    INSN_LABEL(lshl),
257
    INSN_LABEL(ishr),
258
    INSN_LABEL(lshr),
259
    INSN_LABEL(iushr),
260
    INSN_LABEL(lushr),
261
    INSN_LABEL(iand),
262
    INSN_LABEL(land),
263
    INSN_LABEL(ior),
264
    INSN_LABEL(lor),
265
    INSN_LABEL(ixor),
266
    INSN_LABEL(lxor),
267
    INSN_LABEL(iinc),
268
    INSN_LABEL(i2l),
269
    INSN_LABEL(i2f),
270
    INSN_LABEL(i2d),
271
    INSN_LABEL(l2i),
272
    INSN_LABEL(l2f),
273
    INSN_LABEL(l2d),
274
    INSN_LABEL(f2i),
275
    INSN_LABEL(f2l),
276
    INSN_LABEL(f2d),
277
    INSN_LABEL(d2i),
278
    INSN_LABEL(d2l),
279
    INSN_LABEL(d2f),
280
    INSN_LABEL(i2b),
281
    INSN_LABEL(i2c),
282
    INSN_LABEL(i2s),
283
    INSN_LABEL(lcmp),
284
    INSN_LABEL(fcmpl),
285
    INSN_LABEL(fcmpg),
286
    INSN_LABEL(dcmpl),
287
    INSN_LABEL(dcmpg),
288
    INSN_LABEL(ifeq),
289
    INSN_LABEL(ifne),
290
    INSN_LABEL(iflt),
291
    INSN_LABEL(ifge),
292
    INSN_LABEL(ifgt),
293
    INSN_LABEL(ifle),
294
    INSN_LABEL(if_icmpeq),
295
    INSN_LABEL(if_icmpne),
296
    INSN_LABEL(if_icmplt),
297
    INSN_LABEL(if_icmpge),
298
    INSN_LABEL(if_icmpgt),
299
    INSN_LABEL(if_icmple),
300
    INSN_LABEL(if_acmpeq),
301
    INSN_LABEL(if_acmpne),
302
    INSN_LABEL(goto),
303
    INSN_LABEL(jsr),
304
    INSN_LABEL(ret),
305
    INSN_LABEL(tableswitch),
306
    INSN_LABEL(lookupswitch),
307
    INSN_LABEL(ireturn),
308
    INSN_LABEL(lreturn),
309
    INSN_LABEL(freturn),
310
    INSN_LABEL(dreturn),
311
    INSN_LABEL(areturn),
312
    INSN_LABEL(return),
313
    INSN_LABEL(getstatic),
314
    INSN_LABEL(putstatic),
315
    INSN_LABEL(getfield),
316
    INSN_LABEL(putfield),
317
    INSN_LABEL(invokevirtual),
318
    INSN_LABEL(invokespecial),
319
    INSN_LABEL(invokestatic),
320
    INSN_LABEL(invokeinterface),
321
    INSN_LABEL(breakpoint),
322
    INSN_LABEL(new),
323
    INSN_LABEL(newarray),
324
    INSN_LABEL(anewarray),
325
    INSN_LABEL(arraylength),
326
    INSN_LABEL(athrow),
327
    INSN_LABEL(checkcast),
328
    INSN_LABEL(instanceof),
329
    INSN_LABEL(monitorenter),
330
    INSN_LABEL(monitorexit),
331
#ifdef DIRECT_THREADED
332
    0, // wide
333
#else
334
    INSN_LABEL(wide),
335
#endif
336
    INSN_LABEL(multianewarray),
337
    INSN_LABEL(ifnull),
338
    INSN_LABEL(ifnonnull),
339
    INSN_LABEL(goto_w),
340
    INSN_LABEL(jsr_w),
341
#ifdef DIRECT_THREADED
342
    INSN_LABEL (ldc_class)
343
#else
344
 
345
#endif
346
  };
347
 
348
#ifdef DIRECT_THREADED
349
 
350
#ifdef __GCJ_DEBUG
351
#undef NEXT_INSN
352
#define NEXT_INSN                                                       \
353
  do                                                                    \
354
    {                                                                   \
355
      pc_t insn = pc++;                                                 \
356
      if (JVMTI_REQUESTED_EVENT (SingleStep))                           \
357
        {                                                               \
358
          JNIEnv *env = _Jv_GetCurrentJNIEnv ();                        \
359
          jmethodID method = meth->self;                                \
360
          jlocation loc = meth->insn_index (insn);                      \
361
          _Jv_JVMTI_PostEvent (JVMTI_EVENT_SINGLE_STEP, thread,         \
362
                               env, method, loc);                       \
363
        }                                                               \
364
      goto *(insn->insn);                                               \
365
    }                                                                   \
366
  while (0)
367
 
368
// We fail to rewrite a breakpoint if there is another thread
369
// currently executing this method.  This is a bug, but there's
370
// nothing else we can do that doesn't cause a data race.
371
#undef REWRITE_INSN
372
#define REWRITE_INSN(INSN,SLOT,VALUE)                                   \
373
  do                                                                    \
374
    {                                                                   \
375
      _Jv_MutexLock (&rewrite_insn_mutex);                              \
376
      if (meth->thread_count <= 1)                                      \
377
        {                                                               \
378
          if (pc[-2].insn == breakpoint_insn->insn)                     \
379
            {                                                           \
380
              using namespace ::gnu::gcj::jvmti;                        \
381
              jlocation location = meth->insn_index (pc - 2);           \
382
              _Jv_RewriteBreakpointInsn (meth->self, location, (pc_t) INSN); \
383
            }                                                           \
384
          else                                                          \
385
            pc[-2].insn = INSN;                                         \
386
                                                                        \
387
          pc[-1].SLOT = VALUE;                                          \
388
        }                                                               \
389
      _Jv_MutexUnlock (&rewrite_insn_mutex);                            \
390
    }                                                                   \
391
  while (0)
392
 
393
#undef INTERP_REPORT_EXCEPTION
394
#define INTERP_REPORT_EXCEPTION(Jthrowable) REPORT_EXCEPTION (Jthrowable)
395
#else // !__GCJ_DEBUG
396
#undef NEXT_INSN
397
#define NEXT_INSN goto *((pc++)->insn)
398
 
399
// Rewriting a multi-word instruction in the presence of multiple
400
// threads is a data race if a thread reads part of an instruction
401
// while some other thread is rewriting that instruction.  We detect
402
// more than one thread executing a method and don't rewrite the
403
// instruction.  A thread entering a method blocks on
404
// rewrite_insn_mutex until the write is complete.
405
#define REWRITE_INSN(INSN,SLOT,VALUE)           \
406
  do {                                          \
407
    _Jv_MutexLock (&rewrite_insn_mutex);        \
408
    if (meth->thread_count <= 1)                \
409
      {                                         \
410
        pc[-2].insn = INSN;                     \
411
        pc[-1].SLOT = VALUE;                    \
412
      }                                         \
413
    _Jv_MutexUnlock (&rewrite_insn_mutex);      \
414
  }                                             \
415
  while (0)
416
 
417
#undef INTERP_REPORT_EXCEPTION
418
#define INTERP_REPORT_EXCEPTION(Jthrowable) /* not needed when not debugging */
419
#endif // !__GCJ_DEBUG
420
 
421
#define INTVAL() ((pc++)->int_val)
422
#define AVAL() ((pc++)->datum)
423
 
424
#define GET1S() INTVAL ()
425
#define GET2S() INTVAL ()
426
#define GET1U() INTVAL ()
427
#define GET2U() INTVAL ()
428
#define AVAL1U() AVAL ()
429
#define AVAL2U() AVAL ()
430
#define AVAL2UP() AVAL ()
431
#define SKIP_GOTO ++pc
432
#define GOTO_VAL() (insn_slot *) pc->datum
433
#define PCVAL(unionval) unionval.p
434
#define AMPAMP(label) &&label
435
 
436
  // Compile if we must. NOTE: Double-check locking.
437
  if (meth->prepared == NULL)
438
    {
439
      _Jv_MutexLock (&compile_mutex);
440
      if (meth->prepared == NULL)
441
        meth->compile (insn_target);
442
      _Jv_MutexUnlock (&compile_mutex);
443
    }
444
 
445
  // If we're only compiling, stop here
446
  if (args == NULL)
447
    return;
448
 
449
  pc = (insn_slot *) meth->prepared;
450
 
451
#else
452
 
453
#ifdef __GCJ_DEBUG
454
#define NEXT_INSN                                                       \
455
  do                                                                    \
456
    {                                                                   \
457
      if (JVMTI_REQUESTED_EVENT (SingleStep))                           \
458
        {                                                               \
459
          JNIEnv *env = _Jv_GetCurrentJNIEnv ();                        \
460
          jmethodID method = meth->self;                                \
461
          jlocation loc = meth->insn_index (pc);                        \
462
          _Jv_JVMTI_PostEvent (JVMTI_EVENT_SINGLE_STEP, thread,         \
463
                               env, method, loc);                       \
464
        }                                                               \
465
      goto *(insn_target[*pc++])
466
#else
467
#define NEXT_INSN goto *(insn_target[*pc++])
468
#endif
469
 
470
#define GET1S() get1s (pc++)
471
#define GET2S() (pc += 2, get2s (pc- 2))
472
#define GET1U() get1u (pc++)
473
#define GET2U() (pc += 2, get2u (pc - 2))
474
  // Note that these could be more efficient when not handling 'ldc
475
  // class'.
476
#define AVAL1U()                                                \
477
  ({ int index = get1u (pc++);                                  \
478
    _Jv_Linker::resolve_pool_entry (meth->defining_class, index).o; })
479
#define AVAL2U()                                                \
480
  ({ int index = get2u (pc); pc += 2;                           \
481
    _Jv_Linker::resolve_pool_entry (meth->defining_class, index).o; })
482
  // Note that we don't need to resolve the pool entry here as class
483
  // constants are never wide.
484
#define AVAL2UP() ({ int index = get2u (pc); pc += 2; &pool_data[index]; })
485
#define SKIP_GOTO pc += 2
486
#define GOTO_VAL() pc - 1 + get2s (pc)
487
#define PCVAL(unionval) unionval.i
488
#define AMPAMP(label) NULL
489
 
490
  pc = meth->bytecode ();
491
 
492
#endif /* DIRECT_THREADED */
493
 
494
#define TAKE_GOTO pc = GOTO_VAL ()
495
 
496
  /* Go straight at it!  the ffi raw format matches the internal
497
     stack representation exactly.  At least, that's the idea.
498
  */
499
  memcpy ((void*) locals, (void*) args, meth->args_raw_size);
500
 
501
  _Jv_word *pool_data = meth->defining_class->constants.data;
502
 
503
  /* These three are temporaries for common code used by several
504
     instructions.  */
505
  void (*fun)();
506
  _Jv_ResolvedMethod* rmeth;
507
  int tmpval;
508
 
509
  try
510
    {
511
      // We keep nop around.  It is used if we're interpreting the
512
      // bytecodes and not doing direct threading.
513
    insn_nop:
514
      NEXT_INSN;
515
 
516
      /* The first few instructions here are ordered according to their
517
         frequency, in the hope that this will improve code locality a
518
         little.  */
519
 
520
    insn_aload_0:               // 0x2a
521
      LOADA (0);
522
      NEXT_INSN;
523
 
524
    insn_iload:         // 0x15
525
      LOADI (GET1U ());
526
      NEXT_INSN;
527
 
528
    insn_iload_1:               // 0x1b
529
      LOADI (1);
530
      NEXT_INSN;
531
 
532
    insn_invokevirtual: // 0xb6
533
      {
534
        SAVE_PC();
535
        int index = GET2U ();
536
 
537
        /* _Jv_Linker::resolve_pool_entry returns immediately if the
538
         * value already is resolved.  If we want to clutter up the
539
         * code here to gain a little performance, then we can check
540
         * the corresponding bit JV_CONSTANT_ResolvedFlag in the tag
541
         * directly.  For now, I don't think it is worth it.  */
542
 
543
        rmeth = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
544
                                                   index)).rmethod;
545
 
546
        sp -= rmeth->stack_item_count;
547
 
548
        if (rmeth->method->accflags & Modifier::FINAL)
549
          {
550
            // We can't rely on NULLCHECK working if the method is final.
551
            if (! sp[0].o)
552
              throw_null_pointer_exception ();
553
 
554
            // Final methods might not appear in the vtable.
555
            fun = (void (*)()) rmeth->method->ncode;
556
          }
557
        else
558
          {
559
            NULLCHECK (sp[0].o);
560
            jobject rcv = sp[0].o;
561
            _Jv_VTable *table = *(_Jv_VTable**) rcv;
562
            fun = (void (*)()) table->get_method (rmeth->method->index);
563
          }
564
 
565
#ifdef DIRECT_THREADED
566
        // Rewrite instruction so that we use a faster pre-resolved
567
        // method.
568
        REWRITE_INSN (&&invokevirtual_resolved, datum, rmeth);
569
#endif /* DIRECT_THREADED */
570
      }
571
      goto perform_invoke;
572
 
573
#ifdef DIRECT_THREADED
574
    invokevirtual_resolved:
575
      {
576
        SAVE_PC();
577
        rmeth = (_Jv_ResolvedMethod *) AVAL ();
578
        sp -= rmeth->stack_item_count;
579
 
580
        if (rmeth->method->accflags & Modifier::FINAL)
581
          {
582
            // We can't rely on NULLCHECK working if the method is final.
583
            if (! sp[0].o)
584
              throw_null_pointer_exception ();
585
 
586
            // Final methods might not appear in the vtable.
587
            fun = (void (*)()) rmeth->method->ncode;
588
          }
589
        else
590
          {
591
            NULLCHECK (sp[0].o);
592
            jobject rcv = sp[0].o;
593
            _Jv_VTable *table = *(_Jv_VTable**) rcv;
594
            fun = (void (*)()) table->get_method (rmeth->method->index);
595
          }
596
      }
597
      goto perform_invoke;
598
#endif /* DIRECT_THREADED */
599
 
600
    perform_invoke:
601
      {
602
        /* here goes the magic again... */
603
        ffi_cif *cif = &rmeth->cif;
604
        INTERP_FFI_RAW_TYPE *raw = (INTERP_FFI_RAW_TYPE *) sp;
605
 
606
        _Jv_value rvalue;
607
 
608
#if FFI_NATIVE_RAW_API
609
        /* We assume that this is only implemented if it's correct      */
610
        /* to use it here.  On a 64 bit machine, it never is.           */
611
        ffi_raw_call (cif, fun, (void*)&rvalue, raw);
612
#else
613
        ffi_java_raw_call (cif, fun, (void*)&rvalue, raw);
614
#endif
615
 
616
        int rtype = cif->rtype->type;
617
 
618
        /* the likelyhood of object, int, or void return is very high,
619
         * so those are checked before the switch */
620
        if (rtype == FFI_TYPE_POINTER)
621
          {
622
            PUSHA (rvalue.object_value);
623
          }
624
        else if (rtype == FFI_TYPE_SINT32)
625
          {
626
            PUSHI (rvalue.int_value);
627
          }
628
        else if (rtype == FFI_TYPE_VOID)
629
          {
630
            /* skip */
631
          }
632
        else
633
          {
634
            switch (rtype)
635
              {
636
              case FFI_TYPE_SINT8:
637
                PUSHI ((jbyte)(rvalue.int_value & 0xff));
638
                break;
639
 
640
              case FFI_TYPE_SINT16:
641
                PUSHI ((jshort)(rvalue.int_value & 0xffff));
642
                break;
643
 
644
              case FFI_TYPE_UINT16:
645
                PUSHI (rvalue.int_value & 0xffff);
646
                break;
647
 
648
              case FFI_TYPE_FLOAT:
649
                PUSHF (rvalue.float_value);
650
                break;
651
 
652
              case FFI_TYPE_DOUBLE:
653
                PUSHD (rvalue.double_value);
654
                break;
655
 
656
              case FFI_TYPE_SINT64:
657
                PUSHL (rvalue.long_value);
658
                break;
659
 
660
              default:
661
                throw_internal_error ("unknown return type in invokeXXX");
662
              }
663
          }
664
      }
665
      NEXT_INSN;
666
 
667
    insn_aconst_null:
668
      PUSHA (NULL);
669
      NEXT_INSN;
670
 
671
    insn_iconst_m1:
672
      PUSHI (-1);
673
      NEXT_INSN;
674
 
675
    insn_iconst_0:
676
      PUSHI (0);
677
      NEXT_INSN;
678
 
679
    insn_iconst_1:
680
      PUSHI (1);
681
      NEXT_INSN;
682
 
683
    insn_iconst_2:
684
      PUSHI (2);
685
      NEXT_INSN;
686
 
687
    insn_iconst_3:
688
      PUSHI (3);
689
      NEXT_INSN;
690
 
691
    insn_iconst_4:
692
      PUSHI (4);
693
      NEXT_INSN;
694
 
695
    insn_iconst_5:
696
      PUSHI (5);
697
      NEXT_INSN;
698
 
699
    insn_lconst_0:
700
      PUSHL (0);
701
      NEXT_INSN;
702
 
703
    insn_lconst_1:
704
      PUSHL (1);
705
      NEXT_INSN;
706
 
707
    insn_fconst_0:
708
      PUSHF (0);
709
      NEXT_INSN;
710
 
711
    insn_fconst_1:
712
      PUSHF (1);
713
      NEXT_INSN;
714
 
715
    insn_fconst_2:
716
      PUSHF (2);
717
      NEXT_INSN;
718
 
719
    insn_dconst_0:
720
      PUSHD (0);
721
      NEXT_INSN;
722
 
723
    insn_dconst_1:
724
      PUSHD (1);
725
      NEXT_INSN;
726
 
727
    insn_bipush:
728
      // For direct threaded, bipush and sipush are the same.
729
#ifndef DIRECT_THREADED
730
      PUSHI (GET1S ());
731
      NEXT_INSN;
732
#endif /* DIRECT_THREADED */
733
    insn_sipush:
734
      PUSHI (GET2S ());
735
      NEXT_INSN;
736
 
737
    insn_ldc:
738
      // For direct threaded, ldc and ldc_w are the same.
739
#ifndef DIRECT_THREADED
740
      PUSHA ((jobject) AVAL1U ());
741
      NEXT_INSN;
742
#endif /* DIRECT_THREADED */
743
    insn_ldc_w:
744
      PUSHA ((jobject) AVAL2U ());
745
      NEXT_INSN;
746
 
747
#ifdef DIRECT_THREADED
748
      // For direct threaded we have a separate 'ldc class' operation.
749
    insn_ldc_class:
750
      {
751
        SAVE_PC();
752
        // We could rewrite the instruction at this point.
753
        int index = INTVAL ();
754
        jobject k = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
755
                                                     index)).o;
756
        PUSHA (k);
757
      }
758
      NEXT_INSN;
759
#endif /* DIRECT_THREADED */
760
 
761
    insn_ldc2_w:
762
      {
763
        void *where = AVAL2UP ();
764
        memcpy (sp, where, 2*sizeof (_Jv_word));
765
        sp += 2;
766
      }
767
      NEXT_INSN;
768
 
769
    insn_lload:
770
      LOADL (GET1U ());
771
      NEXT_INSN;
772
 
773
    insn_fload:
774
      LOADF (GET1U ());
775
      NEXT_INSN;
776
 
777
    insn_dload:
778
      LOADD (GET1U ());
779
      NEXT_INSN;
780
 
781
    insn_aload:
782
      LOADA (GET1U ());
783
      NEXT_INSN;
784
 
785
    insn_iload_0:
786
      LOADI (0);
787
      NEXT_INSN;
788
 
789
    insn_iload_2:
790
      LOADI (2);
791
      NEXT_INSN;
792
 
793
    insn_iload_3:
794
      LOADI (3);
795
      NEXT_INSN;
796
 
797
    insn_lload_0:
798
      LOADL (0);
799
      NEXT_INSN;
800
 
801
    insn_lload_1:
802
      LOADL (1);
803
      NEXT_INSN;
804
 
805
    insn_lload_2:
806
      LOADL (2);
807
      NEXT_INSN;
808
 
809
    insn_lload_3:
810
      LOADL (3);
811
      NEXT_INSN;
812
 
813
    insn_fload_0:
814
      LOADF (0);
815
      NEXT_INSN;
816
 
817
    insn_fload_1:
818
      LOADF (1);
819
      NEXT_INSN;
820
 
821
    insn_fload_2:
822
      LOADF (2);
823
      NEXT_INSN;
824
 
825
    insn_fload_3:
826
      LOADF (3);
827
      NEXT_INSN;
828
 
829
    insn_dload_0:
830
      LOADD (0);
831
      NEXT_INSN;
832
 
833
    insn_dload_1:
834
      LOADD (1);
835
      NEXT_INSN;
836
 
837
    insn_dload_2:
838
      LOADD (2);
839
      NEXT_INSN;
840
 
841
    insn_dload_3:
842
      LOADD (3);
843
      NEXT_INSN;
844
 
845
    insn_aload_1:
846
      LOADA(1);
847
      NEXT_INSN;
848
 
849
    insn_aload_2:
850
      LOADA(2);
851
      NEXT_INSN;
852
 
853
    insn_aload_3:
854
      LOADA(3);
855
      NEXT_INSN;
856
 
857
    insn_iaload:
858
      {
859
        jint index = POPI();
860
        jintArray arr = (jintArray) POPA();
861
        NULLARRAYCHECK (arr);
862
        ARRAYBOUNDSCHECK (arr, index);
863
        PUSHI( elements(arr)[index] );
864
      }
865
      NEXT_INSN;
866
 
867
    insn_laload:
868
      {
869
        jint index = POPI();
870
        jlongArray arr = (jlongArray) POPA();
871
        NULLARRAYCHECK (arr);
872
        ARRAYBOUNDSCHECK (arr, index);
873
        PUSHL( elements(arr)[index] );
874
      }
875
      NEXT_INSN;
876
 
877
    insn_faload:
878
      {
879
        jint index = POPI();
880
        jfloatArray arr = (jfloatArray) POPA();
881
        NULLARRAYCHECK (arr);
882
        ARRAYBOUNDSCHECK (arr, index);
883
        PUSHF( elements(arr)[index] );
884
      }
885
      NEXT_INSN;
886
 
887
    insn_daload:
888
      {
889
        jint index = POPI();
890
        jdoubleArray arr = (jdoubleArray) POPA();
891
        NULLARRAYCHECK (arr);
892
        ARRAYBOUNDSCHECK (arr, index);
893
        PUSHD( elements(arr)[index] );
894
      }
895
      NEXT_INSN;
896
 
897
    insn_aaload:
898
      {
899
        jint index = POPI();
900
        jobjectArray arr = (jobjectArray) POPA();
901
        NULLARRAYCHECK (arr);
902
        ARRAYBOUNDSCHECK (arr, index);
903
        PUSHA( elements(arr)[index] );
904
      }
905
      NEXT_INSN;
906
 
907
    insn_baload:
908
      {
909
        jint index = POPI();
910
        jbyteArray arr = (jbyteArray) POPA();
911
        NULLARRAYCHECK (arr);
912
        ARRAYBOUNDSCHECK (arr, index);
913
        PUSHI( elements(arr)[index] );
914
      }
915
      NEXT_INSN;
916
 
917
    insn_caload:
918
      {
919
        jint index = POPI();
920
        jcharArray arr = (jcharArray) POPA();
921
        NULLARRAYCHECK (arr);
922
        ARRAYBOUNDSCHECK (arr, index);
923
        PUSHI( elements(arr)[index] );
924
      }
925
      NEXT_INSN;
926
 
927
    insn_saload:
928
      {
929
        jint index = POPI();
930
        jshortArray arr = (jshortArray) POPA();
931
        NULLARRAYCHECK (arr);
932
        ARRAYBOUNDSCHECK (arr, index);
933
        PUSHI( elements(arr)[index] );
934
      }
935
      NEXT_INSN;
936
 
937
    insn_istore:
938
      STOREI (GET1U ());
939
      NEXT_INSN;
940
 
941
    insn_lstore:
942
      STOREL (GET1U ());
943
      NEXT_INSN;
944
 
945
    insn_fstore:
946
      STOREF (GET1U ());
947
      NEXT_INSN;
948
 
949
    insn_dstore:
950
      STORED (GET1U ());
951
      NEXT_INSN;
952
 
953
    insn_astore:
954
      STOREA (GET1U ());
955
      NEXT_INSN;
956
 
957
    insn_istore_0:
958
      STOREI (0);
959
      NEXT_INSN;
960
 
961
    insn_istore_1:
962
      STOREI (1);
963
      NEXT_INSN;
964
 
965
    insn_istore_2:
966
      STOREI (2);
967
      NEXT_INSN;
968
 
969
    insn_istore_3:
970
      STOREI (3);
971
      NEXT_INSN;
972
 
973
    insn_lstore_0:
974
      STOREL (0);
975
      NEXT_INSN;
976
 
977
    insn_lstore_1:
978
      STOREL (1);
979
      NEXT_INSN;
980
 
981
    insn_lstore_2:
982
      STOREL (2);
983
      NEXT_INSN;
984
 
985
    insn_lstore_3:
986
      STOREL (3);
987
      NEXT_INSN;
988
 
989
    insn_fstore_0:
990
      STOREF (0);
991
      NEXT_INSN;
992
 
993
    insn_fstore_1:
994
      STOREF (1);
995
      NEXT_INSN;
996
 
997
    insn_fstore_2:
998
      STOREF (2);
999
      NEXT_INSN;
1000
 
1001
    insn_fstore_3:
1002
      STOREF (3);
1003
      NEXT_INSN;
1004
 
1005
    insn_dstore_0:
1006
      STORED (0);
1007
      NEXT_INSN;
1008
 
1009
    insn_dstore_1:
1010
      STORED (1);
1011
      NEXT_INSN;
1012
 
1013
    insn_dstore_2:
1014
      STORED (2);
1015
      NEXT_INSN;
1016
 
1017
    insn_dstore_3:
1018
      STORED (3);
1019
      NEXT_INSN;
1020
 
1021
    insn_astore_0:
1022
      STOREA(0);
1023
      NEXT_INSN;
1024
 
1025
    insn_astore_1:
1026
      STOREA(1);
1027
      NEXT_INSN;
1028
 
1029
    insn_astore_2:
1030
      STOREA(2);
1031
      NEXT_INSN;
1032
 
1033
    insn_astore_3:
1034
      STOREA(3);
1035
      NEXT_INSN;
1036
 
1037
    insn_iastore:
1038
      {
1039
        jint value = POPI();
1040
        jint index  = POPI();
1041
        jintArray arr = (jintArray) POPA();
1042
        NULLARRAYCHECK (arr);
1043
        ARRAYBOUNDSCHECK (arr, index);
1044
        elements(arr)[index] = value;
1045
      }
1046
      NEXT_INSN;
1047
 
1048
    insn_lastore:
1049
      {
1050
        jlong value = POPL();
1051
        jint index  = POPI();
1052
        jlongArray arr = (jlongArray) POPA();
1053
        NULLARRAYCHECK (arr);
1054
        ARRAYBOUNDSCHECK (arr, index);
1055
        elements(arr)[index] = value;
1056
      }
1057
      NEXT_INSN;
1058
 
1059
    insn_fastore:
1060
      {
1061
        jfloat value = POPF();
1062
        jint index  = POPI();
1063
        jfloatArray arr = (jfloatArray) POPA();
1064
        NULLARRAYCHECK (arr);
1065
        ARRAYBOUNDSCHECK (arr, index);
1066
        elements(arr)[index] = value;
1067
      }
1068
      NEXT_INSN;
1069
 
1070
    insn_dastore:
1071
      {
1072
        jdouble value = POPD();
1073
        jint index  = POPI();
1074
        jdoubleArray arr = (jdoubleArray) POPA();
1075
        NULLARRAYCHECK (arr);
1076
        ARRAYBOUNDSCHECK (arr, index);
1077
        elements(arr)[index] = value;
1078
      }
1079
      NEXT_INSN;
1080
 
1081
    insn_aastore:
1082
      {
1083
        jobject value = POPA();
1084
        jint index  = POPI();
1085
        jobjectArray arr = (jobjectArray) POPA();
1086
        NULLARRAYCHECK (arr);
1087
        ARRAYBOUNDSCHECK (arr, index);
1088
        _Jv_CheckArrayStore (arr, value);
1089
        elements(arr)[index] = value;
1090
      }
1091
      NEXT_INSN;
1092
 
1093
    insn_bastore:
1094
      {
1095
        jbyte value = (jbyte) POPI();
1096
        jint index  = POPI();
1097
        jbyteArray arr = (jbyteArray) POPA();
1098
        NULLARRAYCHECK (arr);
1099
        ARRAYBOUNDSCHECK (arr, index);
1100
        elements(arr)[index] = value;
1101
      }
1102
      NEXT_INSN;
1103
 
1104
    insn_castore:
1105
      {
1106
        jchar value = (jchar) POPI();
1107
        jint index  = POPI();
1108
        jcharArray arr = (jcharArray) POPA();
1109
        NULLARRAYCHECK (arr);
1110
        ARRAYBOUNDSCHECK (arr, index);
1111
        elements(arr)[index] = value;
1112
      }
1113
      NEXT_INSN;
1114
 
1115
    insn_sastore:
1116
      {
1117
        jshort value = (jshort) POPI();
1118
        jint index  = POPI();
1119
        jshortArray arr = (jshortArray) POPA();
1120
        NULLARRAYCHECK (arr);
1121
        ARRAYBOUNDSCHECK (arr, index);
1122
        elements(arr)[index] = value;
1123
      }
1124
      NEXT_INSN;
1125
 
1126
    insn_pop:
1127
      sp -= 1;
1128
      NEXT_INSN;
1129
 
1130
    insn_pop2:
1131
      sp -= 2;
1132
      NEXT_INSN;
1133
 
1134
    insn_dup:
1135
      sp[0] = sp[-1];
1136
      sp += 1;
1137
      NEXT_INSN;
1138
 
1139
    insn_dup_x1:
1140
      dupx (sp, 1, 1); sp+=1;
1141
      NEXT_INSN;
1142
 
1143
    insn_dup_x2:
1144
      dupx (sp, 1, 2); sp+=1;
1145
      NEXT_INSN;
1146
 
1147
    insn_dup2:
1148
      sp[0] = sp[-2];
1149
      sp[1] = sp[-1];
1150
      sp += 2;
1151
      NEXT_INSN;
1152
 
1153
    insn_dup2_x1:
1154
      dupx (sp, 2, 1); sp+=2;
1155
      NEXT_INSN;
1156
 
1157
    insn_dup2_x2:
1158
      dupx (sp, 2, 2); sp+=2;
1159
      NEXT_INSN;
1160
 
1161
    insn_swap:
1162
      {
1163
        jobject tmp1 = POPA();
1164
        jobject tmp2 = POPA();
1165
        PUSHA (tmp1);
1166
        PUSHA (tmp2);
1167
      }
1168
      NEXT_INSN;
1169
 
1170
    insn_iadd:
1171
      BINOPI(+);
1172
      NEXT_INSN;
1173
 
1174
    insn_ladd:
1175
      BINOPL(+);
1176
      NEXT_INSN;
1177
 
1178
    insn_fadd:
1179
      BINOPF(+);
1180
      NEXT_INSN;
1181
 
1182
    insn_dadd:
1183
      BINOPD(+);
1184
      NEXT_INSN;
1185
 
1186
    insn_isub:
1187
      BINOPI(-);
1188
      NEXT_INSN;
1189
 
1190
    insn_lsub:
1191
      BINOPL(-);
1192
      NEXT_INSN;
1193
 
1194
    insn_fsub:
1195
      BINOPF(-);
1196
      NEXT_INSN;
1197
 
1198
    insn_dsub:
1199
      BINOPD(-);
1200
      NEXT_INSN;
1201
 
1202
    insn_imul:
1203
      BINOPI(*);
1204
      NEXT_INSN;
1205
 
1206
    insn_lmul:
1207
      BINOPL(*);
1208
      NEXT_INSN;
1209
 
1210
    insn_fmul:
1211
      BINOPF(*);
1212
      NEXT_INSN;
1213
 
1214
    insn_dmul:
1215
      BINOPD(*);
1216
      NEXT_INSN;
1217
 
1218
    insn_idiv:
1219
      {
1220
        SAVE_PC();
1221
        jint value2 = POPI();
1222
        jint value1 = POPI();
1223
        jint res = _Jv_divI (value1, value2);
1224
        PUSHI (res);
1225
      }
1226
      NEXT_INSN;
1227
 
1228
    insn_ldiv:
1229
      {
1230
        SAVE_PC();
1231
        jlong value2 = POPL();
1232
        jlong value1 = POPL();
1233
        jlong res = _Jv_divJ (value1, value2);
1234
        PUSHL (res);
1235
      }
1236
      NEXT_INSN;
1237
 
1238
    insn_fdiv:
1239
      {
1240
        jfloat value2 = POPF();
1241
        jfloat value1 = POPF();
1242
        jfloat res = value1 / value2;
1243
        PUSHF (res);
1244
      }
1245
      NEXT_INSN;
1246
 
1247
    insn_ddiv:
1248
      {
1249
        jdouble value2 = POPD();
1250
        jdouble value1 = POPD();
1251
        jdouble res = value1 / value2;
1252
        PUSHD (res);
1253
      }
1254
      NEXT_INSN;
1255
 
1256
    insn_irem:
1257
      {
1258
        SAVE_PC();
1259
        jint value2 = POPI();
1260
        jint value1 =  POPI();
1261
        jint res = _Jv_remI (value1, value2);
1262
        PUSHI (res);
1263
      }
1264
      NEXT_INSN;
1265
 
1266
    insn_lrem:
1267
      {
1268
        SAVE_PC();
1269
        jlong value2 = POPL();
1270
        jlong value1 = POPL();
1271
        jlong res = _Jv_remJ (value1, value2);
1272
        PUSHL (res);
1273
      }
1274
      NEXT_INSN;
1275
 
1276
    insn_frem:
1277
      {
1278
        jfloat value2 = POPF();
1279
        jfloat value1 = POPF();
1280
        jfloat res    = __ieee754_fmod (value1, value2);
1281
        PUSHF (res);
1282
      }
1283
      NEXT_INSN;
1284
 
1285
    insn_drem:
1286
      {
1287
        jdouble value2 = POPD();
1288
        jdouble value1 = POPD();
1289
        jdouble res    = __ieee754_fmod (value1, value2);
1290
        PUSHD (res);
1291
      }
1292
      NEXT_INSN;
1293
 
1294
    insn_ineg:
1295
      {
1296
        jint value = POPI();
1297
        PUSHI (value * -1);
1298
      }
1299
      NEXT_INSN;
1300
 
1301
    insn_lneg:
1302
      {
1303
        jlong value = POPL();
1304
        PUSHL (value * -1);
1305
      }
1306
      NEXT_INSN;
1307
 
1308
    insn_fneg:
1309
      {
1310
        jfloat value = POPF();
1311
        PUSHF (value * -1);
1312
      }
1313
      NEXT_INSN;
1314
 
1315
    insn_dneg:
1316
      {
1317
        jdouble value = POPD();
1318
        PUSHD (value * -1);
1319
      }
1320
      NEXT_INSN;
1321
 
1322
    insn_ishl:
1323
      {
1324
        jint shift = (POPI() & 0x1f);
1325
        jint value = POPI();
1326
        PUSHI (value << shift);
1327
      }
1328
      NEXT_INSN;
1329
 
1330
    insn_lshl:
1331
      {
1332
        jint shift = (POPI() & 0x3f);
1333
        jlong value = POPL();
1334
        PUSHL (value << shift);
1335
      }
1336
      NEXT_INSN;
1337
 
1338
    insn_ishr:
1339
      {
1340
        jint shift = (POPI() & 0x1f);
1341
        jint value = POPI();
1342
        PUSHI (value >> shift);
1343
      }
1344
      NEXT_INSN;
1345
 
1346
    insn_lshr:
1347
      {
1348
        jint shift = (POPI() & 0x3f);
1349
        jlong value = POPL();
1350
        PUSHL (value >> shift);
1351
      }
1352
      NEXT_INSN;
1353
 
1354
    insn_iushr:
1355
      {
1356
        jint shift = (POPI() & 0x1f);
1357
        _Jv_uint value = (_Jv_uint) POPI();
1358
        PUSHI ((jint) (value >> shift));
1359
      }
1360
      NEXT_INSN;
1361
 
1362
    insn_lushr:
1363
      {
1364
        jint shift = (POPI() & 0x3f);
1365
        _Jv_ulong value = (_Jv_ulong) POPL();
1366
        PUSHL ((jlong) (value >> shift));
1367
      }
1368
      NEXT_INSN;
1369
 
1370
    insn_iand:
1371
      BINOPI (&);
1372
      NEXT_INSN;
1373
 
1374
    insn_land:
1375
      BINOPL (&);
1376
      NEXT_INSN;
1377
 
1378
    insn_ior:
1379
      BINOPI (|);
1380
      NEXT_INSN;
1381
 
1382
    insn_lor:
1383
      BINOPL (|);
1384
      NEXT_INSN;
1385
 
1386
    insn_ixor:
1387
      BINOPI (^);
1388
      NEXT_INSN;
1389
 
1390
    insn_lxor:
1391
      BINOPL (^);
1392
      NEXT_INSN;
1393
 
1394
    insn_iinc:
1395
      {
1396
        jint index  = GET1U ();
1397
        jint amount = GET1S ();
1398
        locals[index].i += amount;
1399
      }
1400
      NEXT_INSN;
1401
 
1402
    insn_i2l:
1403
      {jlong value = POPI(); PUSHL (value);}
1404
      NEXT_INSN;
1405
 
1406
    insn_i2f:
1407
      {jfloat value = POPI(); PUSHF (value);}
1408
      NEXT_INSN;
1409
 
1410
    insn_i2d:
1411
      {jdouble value = POPI(); PUSHD (value);}
1412
      NEXT_INSN;
1413
 
1414
    insn_l2i:
1415
      {jint value = POPL(); PUSHI (value);}
1416
      NEXT_INSN;
1417
 
1418
    insn_l2f:
1419
      {jfloat value = POPL(); PUSHF (value);}
1420
      NEXT_INSN;
1421
 
1422
    insn_l2d:
1423
      {jdouble value = POPL(); PUSHD (value);}
1424
      NEXT_INSN;
1425
 
1426
    insn_f2i:
1427
      {
1428
        using namespace java::lang;
1429
        jint value = convert (POPF (), Integer::MIN_VALUE, Integer::MAX_VALUE);
1430
        PUSHI(value);
1431
      }
1432
      NEXT_INSN;
1433
 
1434
    insn_f2l:
1435
      {
1436
        using namespace java::lang;
1437
        jlong value = convert (POPF (), Long::MIN_VALUE, Long::MAX_VALUE);
1438
        PUSHL(value);
1439
      }
1440
      NEXT_INSN;
1441
 
1442
    insn_f2d:
1443
      { jdouble value = POPF (); PUSHD(value); }
1444
      NEXT_INSN;
1445
 
1446
    insn_d2i:
1447
      {
1448
        using namespace java::lang;
1449
        jint value = convert (POPD (), Integer::MIN_VALUE, Integer::MAX_VALUE);
1450
        PUSHI(value);
1451
      }
1452
      NEXT_INSN;
1453
 
1454
    insn_d2l:
1455
      {
1456
        using namespace java::lang;
1457
        jlong value = convert (POPD (), Long::MIN_VALUE, Long::MAX_VALUE);
1458
        PUSHL(value);
1459
      }
1460
      NEXT_INSN;
1461
 
1462
    insn_d2f:
1463
      { jfloat value = POPD (); PUSHF(value); }
1464
      NEXT_INSN;
1465
 
1466
    insn_i2b:
1467
      { jbyte value = POPI (); PUSHI(value); }
1468
      NEXT_INSN;
1469
 
1470
    insn_i2c:
1471
      { jchar value = POPI (); PUSHI(value); }
1472
      NEXT_INSN;
1473
 
1474
    insn_i2s:
1475
      { jshort value = POPI (); PUSHI(value); }
1476
      NEXT_INSN;
1477
 
1478
    insn_lcmp:
1479
      {
1480
        jlong value2 = POPL ();
1481
        jlong value1 = POPL ();
1482
        if (value1 > value2)
1483
          { PUSHI (1); }
1484
        else if (value1 == value2)
1485
          { PUSHI (0); }
1486
        else
1487
          { PUSHI (-1); }
1488
      }
1489
      NEXT_INSN;
1490
 
1491
    insn_fcmpl:
1492
      tmpval = -1;
1493
      goto fcmp;
1494
 
1495
    insn_fcmpg:
1496
      tmpval = 1;
1497
 
1498
    fcmp:
1499
      {
1500
        jfloat value2 = POPF ();
1501
        jfloat value1 = POPF ();
1502
        if (value1 > value2)
1503
          PUSHI (1);
1504
        else if (value1 == value2)
1505
          PUSHI (0);
1506
        else if (value1 < value2)
1507
          PUSHI (-1);
1508
        else
1509
          PUSHI (tmpval);
1510
      }
1511
      NEXT_INSN;
1512
 
1513
    insn_dcmpl:
1514
      tmpval = -1;
1515
      goto dcmp;
1516
 
1517
    insn_dcmpg:
1518
      tmpval = 1;
1519
 
1520
    dcmp:
1521
      {
1522
        jdouble value2 = POPD ();
1523
        jdouble value1 = POPD ();
1524
        if (value1 > value2)
1525
          PUSHI (1);
1526
        else if (value1 == value2)
1527
          PUSHI (0);
1528
        else if (value1 < value2)
1529
          PUSHI (-1);
1530
        else
1531
          PUSHI (tmpval);
1532
      }
1533
      NEXT_INSN;
1534
 
1535
    insn_ifeq:
1536
      {
1537
        if (POPI() == 0)
1538
          TAKE_GOTO;
1539
        else
1540
          SKIP_GOTO;
1541
      }
1542
      NEXT_INSN;
1543
 
1544
    insn_ifne:
1545
      {
1546
        if (POPI() != 0)
1547
          TAKE_GOTO;
1548
        else
1549
          SKIP_GOTO;
1550
      }
1551
      NEXT_INSN;
1552
 
1553
    insn_iflt:
1554
      {
1555
        if (POPI() < 0)
1556
          TAKE_GOTO;
1557
        else
1558
          SKIP_GOTO;
1559
      }
1560
      NEXT_INSN;
1561
 
1562
    insn_ifge:
1563
      {
1564
        if (POPI() >= 0)
1565
          TAKE_GOTO;
1566
        else
1567
          SKIP_GOTO;
1568
      }
1569
      NEXT_INSN;
1570
 
1571
    insn_ifgt:
1572
      {
1573
        if (POPI() > 0)
1574
          TAKE_GOTO;
1575
        else
1576
          SKIP_GOTO;
1577
      }
1578
      NEXT_INSN;
1579
 
1580
    insn_ifle:
1581
      {
1582
        if (POPI() <= 0)
1583
          TAKE_GOTO;
1584
        else
1585
          SKIP_GOTO;
1586
      }
1587
      NEXT_INSN;
1588
 
1589
    insn_if_icmpeq:
1590
      {
1591
        jint value2 = POPI();
1592
        jint value1 = POPI();
1593
        if (value1 == value2)
1594
          TAKE_GOTO;
1595
        else
1596
          SKIP_GOTO;
1597
      }
1598
      NEXT_INSN;
1599
 
1600
    insn_if_icmpne:
1601
      {
1602
        jint value2 = POPI();
1603
        jint value1 = POPI();
1604
        if (value1 != value2)
1605
          TAKE_GOTO;
1606
        else
1607
          SKIP_GOTO;
1608
      }
1609
      NEXT_INSN;
1610
 
1611
    insn_if_icmplt:
1612
      {
1613
        jint value2 = POPI();
1614
        jint value1 = POPI();
1615
        if (value1 < value2)
1616
          TAKE_GOTO;
1617
        else
1618
          SKIP_GOTO;
1619
      }
1620
      NEXT_INSN;
1621
 
1622
    insn_if_icmpge:
1623
      {
1624
        jint value2 = POPI();
1625
        jint value1 = POPI();
1626
        if (value1 >= value2)
1627
          TAKE_GOTO;
1628
        else
1629
          SKIP_GOTO;
1630
      }
1631
      NEXT_INSN;
1632
 
1633
    insn_if_icmpgt:
1634
      {
1635
        jint value2 = POPI();
1636
        jint value1 = POPI();
1637
        if (value1 > value2)
1638
          TAKE_GOTO;
1639
        else
1640
          SKIP_GOTO;
1641
      }
1642
      NEXT_INSN;
1643
 
1644
    insn_if_icmple:
1645
      {
1646
        jint value2 = POPI();
1647
        jint value1 = POPI();
1648
        if (value1 <= value2)
1649
          TAKE_GOTO;
1650
        else
1651
          SKIP_GOTO;
1652
      }
1653
      NEXT_INSN;
1654
 
1655
    insn_if_acmpeq:
1656
      {
1657
        jobject value2 = POPA();
1658
        jobject value1 = POPA();
1659
        if (value1 == value2)
1660
          TAKE_GOTO;
1661
        else
1662
          SKIP_GOTO;
1663
      }
1664
      NEXT_INSN;
1665
 
1666
    insn_if_acmpne:
1667
      {
1668
        jobject value2 = POPA();
1669
        jobject value1 = POPA();
1670
        if (value1 != value2)
1671
          TAKE_GOTO;
1672
        else
1673
          SKIP_GOTO;
1674
      }
1675
      NEXT_INSN;
1676
 
1677
    insn_goto_w:
1678
#ifndef DIRECT_THREADED
1679
      // For direct threaded, goto and goto_w are the same.
1680
      pc = pc - 1 + get4 (pc);
1681
      NEXT_INSN;
1682
#endif /* DIRECT_THREADED */
1683
    insn_goto:
1684
      TAKE_GOTO;
1685
      NEXT_INSN;
1686
 
1687
    insn_jsr_w:
1688
#ifndef DIRECT_THREADED
1689
      // For direct threaded, jsr and jsr_w are the same.
1690
      {
1691
        pc_t next = pc - 1 + get4 (pc);
1692
        pc += 4;
1693
        PUSHA ((jobject) pc);
1694
        pc = next;
1695
      }
1696
      NEXT_INSN;
1697
#endif /* DIRECT_THREADED */
1698
    insn_jsr:
1699
      {
1700
        pc_t next = GOTO_VAL();
1701
        SKIP_GOTO;
1702
        PUSHA ((jobject) pc);
1703
        pc = next;
1704
      }
1705
      NEXT_INSN;
1706
 
1707
    insn_ret:
1708
      {
1709
        jint index = GET1U ();
1710
        pc = (pc_t) PEEKA (index);
1711
      }
1712
      NEXT_INSN;
1713
 
1714
    insn_tableswitch:
1715
      {
1716
#ifdef DIRECT_THREADED
1717
        void *def = (pc++)->datum;
1718
 
1719
        int index = POPI();
1720
 
1721
        jint low = INTVAL ();
1722
        jint high = INTVAL ();
1723
 
1724
        if (index < low || index > high)
1725
          pc = (insn_slot *) def;
1726
        else
1727
          pc = (insn_slot *) ((pc + index - low)->datum);
1728
#else
1729
        pc_t base_pc = pc - 1;
1730
        int index = POPI ();
1731
 
1732
        pc_t base = (pc_t) meth->bytecode ();
1733
        while ((pc - base) % 4 != 0)
1734
          ++pc;
1735
 
1736
        jint def = get4 (pc);
1737
        jint low = get4 (pc + 4);
1738
        jint high = get4 (pc + 8);
1739
        if (index < low || index > high)
1740
          pc = base_pc + def;
1741
        else
1742
          pc = base_pc + get4 (pc + 4 * (index - low + 3));
1743
#endif /* DIRECT_THREADED */
1744
      }
1745
      NEXT_INSN;
1746
 
1747
    insn_lookupswitch:
1748
      {
1749
#ifdef DIRECT_THREADED
1750
        void *def = (pc++)->insn;
1751
 
1752
        int index = POPI();
1753
 
1754
        jint npairs = INTVAL ();
1755
 
1756
        int max = npairs - 1;
1757
        int min = 0;
1758
 
1759
        // Simple binary search...
1760
        while (min < max)
1761
          {
1762
            int half = (min + max) / 2;
1763
            int match = pc[2 * half].int_val;
1764
 
1765
            if (index == match)
1766
              {
1767
                // Found it.
1768
                pc = (insn_slot *) pc[2 * half + 1].datum;
1769
                NEXT_INSN;
1770
              }
1771
            else if (index < match)
1772
              // We can use HALF - 1 here because we check again on
1773
              // loop exit.
1774
              max = half - 1;
1775
            else
1776
              // We can use HALF + 1 here because we check again on
1777
              // loop exit.
1778
              min = half + 1;
1779
          }
1780
        if (index == pc[2 * min].int_val)
1781
          pc = (insn_slot *) pc[2 * min + 1].datum;
1782
        else
1783
          pc = (insn_slot *) def;
1784
#else
1785
        unsigned char *base_pc = pc-1;
1786
        int index = POPI();
1787
 
1788
        unsigned char* base = meth->bytecode ();
1789
        while ((pc-base) % 4 != 0)
1790
          ++pc;
1791
 
1792
        jint def     = get4 (pc);
1793
        jint npairs  = get4 (pc+4);
1794
 
1795
        int max = npairs-1;
1796
        int min = 0;
1797
 
1798
        // Simple binary search...
1799
        while (min < max)
1800
          {
1801
            int half = (min+max)/2;
1802
            int match = get4 (pc+ 4*(2 + 2*half));
1803
 
1804
            if (index == match)
1805
              min = max = half;
1806
            else if (index < match)
1807
              // We can use HALF - 1 here because we check again on
1808
              // loop exit.
1809
              max = half - 1;
1810
            else
1811
              // We can use HALF + 1 here because we check again on
1812
              // loop exit.
1813
              min = half + 1;
1814
          }
1815
 
1816
        if (index == get4 (pc+ 4*(2 + 2*min)))
1817
          pc = base_pc + get4 (pc+ 4*(2 + 2*min + 1));
1818
        else
1819
          pc = base_pc + def;
1820
#endif /* DIRECT_THREADED */
1821
      }
1822
      NEXT_INSN;
1823
 
1824
    insn_areturn:
1825
      *(jobject *) retp = POPA ();
1826
      return;
1827
 
1828
    insn_lreturn:
1829
      *(jlong *) retp = POPL ();
1830
      return;
1831
 
1832
    insn_freturn:
1833
      *(jfloat *) retp = POPF ();
1834
      return;
1835
 
1836
    insn_dreturn:
1837
      *(jdouble *) retp = POPD ();
1838
      return;
1839
 
1840
    insn_ireturn:
1841
      *(jint *) retp = POPI ();
1842
      return;
1843
 
1844
    insn_return:
1845
      return;
1846
 
1847
    insn_getstatic:
1848
      {
1849
        jint fieldref_index = GET2U ();
1850
        SAVE_PC(); // Constant pool resolution could throw.
1851
        _Jv_Linker::resolve_pool_entry (meth->defining_class, fieldref_index);
1852
        _Jv_Field *field = pool_data[fieldref_index].field;
1853
 
1854
        if ((field->flags & Modifier::STATIC) == 0)
1855
          throw_incompatible_class_change_error
1856
            (JvNewStringLatin1 ("field no longer static"));
1857
 
1858
        jclass type = field->type;
1859
 
1860
        // We rewrite the instruction once we discover what it refers
1861
        // to.
1862
        void *newinsn = NULL;
1863
        if (type->isPrimitive ())
1864
          {
1865
            switch (type->size_in_bytes)
1866
              {
1867
              case 1:
1868
                PUSHI (*field->u.byte_addr);
1869
                newinsn = AMPAMP (getstatic_resolved_1);
1870
                break;
1871
 
1872
              case 2:
1873
                if (type == JvPrimClass (char))
1874
                  {
1875
                    PUSHI (*field->u.char_addr);
1876
                    newinsn = AMPAMP (getstatic_resolved_char);
1877
                  }
1878
                else
1879
                  {
1880
                    PUSHI (*field->u.short_addr);
1881
                    newinsn = AMPAMP (getstatic_resolved_short);
1882
                  }
1883
                break;
1884
 
1885
              case 4:
1886
                PUSHI(*field->u.int_addr);
1887
                newinsn = AMPAMP (getstatic_resolved_4);
1888
                break;
1889
 
1890
              case 8:
1891
                PUSHL(*field->u.long_addr);
1892
                newinsn = AMPAMP (getstatic_resolved_8);
1893
                break;
1894
              }
1895
          }
1896
        else
1897
          {
1898
            PUSHA(*field->u.object_addr);
1899
            newinsn = AMPAMP (getstatic_resolved_obj);
1900
          }
1901
 
1902
#ifdef DIRECT_THREADED
1903
        REWRITE_INSN (newinsn, datum, field->u.addr);
1904
#endif /* DIRECT_THREADED */
1905
      }
1906
      NEXT_INSN;
1907
 
1908
#ifdef DIRECT_THREADED
1909
    getstatic_resolved_1:
1910
      PUSHI (*(jbyte *) AVAL ());
1911
      NEXT_INSN;
1912
 
1913
    getstatic_resolved_char:
1914
      PUSHI (*(jchar *) AVAL ());
1915
      NEXT_INSN;
1916
 
1917
    getstatic_resolved_short:
1918
      PUSHI (*(jshort *) AVAL ());
1919
      NEXT_INSN;
1920
 
1921
    getstatic_resolved_4:
1922
      PUSHI (*(jint *) AVAL ());
1923
      NEXT_INSN;
1924
 
1925
    getstatic_resolved_8:
1926
      PUSHL (*(jlong *) AVAL ());
1927
      NEXT_INSN;
1928
 
1929
    getstatic_resolved_obj:
1930
      PUSHA (*(jobject *) AVAL ());
1931
      NEXT_INSN;
1932
#endif /* DIRECT_THREADED */
1933
 
1934
    insn_getfield:
1935
      {
1936
        SAVE_PC();
1937
        jint fieldref_index = GET2U ();
1938
        _Jv_Linker::resolve_pool_entry (meth->defining_class, fieldref_index);
1939
        _Jv_Field *field = pool_data[fieldref_index].field;
1940
 
1941
        if ((field->flags & Modifier::STATIC) != 0)
1942
          throw_incompatible_class_change_error
1943
            (JvNewStringLatin1 ("field is static"));
1944
 
1945
        jclass type = field->type;
1946
        jint field_offset = field->u.boffset;
1947
 
1948
        jobject obj   = POPA();
1949
        NULLCHECK(obj);
1950
 
1951
        void *newinsn = NULL;
1952
        _Jv_value *val = (_Jv_value *) ((char *)obj + field_offset);
1953
        if (type->isPrimitive ())
1954
          {
1955
            switch (type->size_in_bytes)
1956
              {
1957
              case 1:
1958
                PUSHI (val->byte_value);
1959
                newinsn = AMPAMP (getfield_resolved_1);
1960
                break;
1961
 
1962
              case 2:
1963
                if (type == JvPrimClass (char))
1964
                  {
1965
                    PUSHI (val->char_value);
1966
                    newinsn = AMPAMP (getfield_resolved_char);
1967
                  }
1968
                else
1969
                  {
1970
                    PUSHI (val->short_value);
1971
                    newinsn = AMPAMP (getfield_resolved_short);
1972
                  }
1973
                break;
1974
 
1975
              case 4:
1976
                PUSHI (val->int_value);
1977
                newinsn = AMPAMP (getfield_resolved_4);
1978
                break;
1979
 
1980
              case 8:
1981
                PUSHL (val->long_value);
1982
                newinsn = AMPAMP (getfield_resolved_8);
1983
                break;
1984
              }
1985
          }
1986
        else
1987
          {
1988
            PUSHA (val->object_value);
1989
            newinsn = AMPAMP (getfield_resolved_obj);
1990
          }
1991
 
1992
#ifdef DIRECT_THREADED
1993
        REWRITE_INSN (newinsn, int_val, field_offset);
1994
#endif /* DIRECT_THREADED */
1995
      }
1996
      NEXT_INSN;
1997
 
1998
#ifdef DIRECT_THREADED
1999
    getfield_resolved_1:
2000
      {
2001
        char *obj = (char *) POPA ();
2002
        NULLCHECK (obj);
2003
        PUSHI (*(jbyte *) (obj + INTVAL ()));
2004
      }
2005
      NEXT_INSN;
2006
 
2007
    getfield_resolved_char:
2008
      {
2009
        char *obj = (char *) POPA ();
2010
        NULLCHECK (obj);
2011
        PUSHI (*(jchar *) (obj + INTVAL ()));
2012
      }
2013
      NEXT_INSN;
2014
 
2015
    getfield_resolved_short:
2016
      {
2017
        char *obj = (char *) POPA ();
2018
        NULLCHECK (obj);
2019
        PUSHI (*(jshort *) (obj + INTVAL ()));
2020
      }
2021
      NEXT_INSN;
2022
 
2023
    getfield_resolved_4:
2024
      {
2025
        char *obj = (char *) POPA ();
2026
        NULLCHECK (obj);
2027
        PUSHI (*(jint *) (obj + INTVAL ()));
2028
      }
2029
      NEXT_INSN;
2030
 
2031
    getfield_resolved_8:
2032
      {
2033
        char *obj = (char *) POPA ();
2034
        NULLCHECK (obj);
2035
        PUSHL (*(jlong *) (obj + INTVAL ()));
2036
      }
2037
      NEXT_INSN;
2038
 
2039
    getfield_resolved_obj:
2040
      {
2041
        char *obj = (char *) POPA ();
2042
        NULLCHECK (obj);
2043
        PUSHA (*(jobject *) (obj + INTVAL ()));
2044
      }
2045
      NEXT_INSN;
2046
#endif /* DIRECT_THREADED */
2047
 
2048
    insn_putstatic:
2049
      {
2050
        SAVE_PC();
2051
        jint fieldref_index = GET2U ();
2052
        _Jv_Linker::resolve_pool_entry (meth->defining_class, fieldref_index);
2053
        _Jv_Field *field = pool_data[fieldref_index].field;
2054
 
2055
        jclass type = field->type;
2056
 
2057
        // ResolvePoolEntry cannot check this
2058
        if ((field->flags & Modifier::STATIC) == 0)
2059
          throw_incompatible_class_change_error
2060
            (JvNewStringLatin1 ("field no longer static"));
2061
 
2062
        void *newinsn = NULL;
2063
        if (type->isPrimitive ())
2064
          {
2065
            switch (type->size_in_bytes)
2066
              {
2067
              case 1:
2068
                {
2069
                  jint value = POPI();
2070
                  *field->u.byte_addr = value;
2071
                  newinsn = AMPAMP (putstatic_resolved_1);
2072
                  break;
2073
                }
2074
 
2075
              case 2:
2076
                {
2077
                  jint value = POPI();
2078
                  *field->u.char_addr = value;
2079
                  newinsn = AMPAMP (putstatic_resolved_2);
2080
                  break;
2081
                }
2082
 
2083
              case 4:
2084
                {
2085
                  jint value = POPI();
2086
                  *field->u.int_addr = value;
2087
                  newinsn = AMPAMP (putstatic_resolved_4);
2088
                  break;
2089
                }
2090
 
2091
              case 8:
2092
                {
2093
                  jlong value = POPL();
2094
                  *field->u.long_addr = value;
2095
                  newinsn = AMPAMP (putstatic_resolved_8);
2096
                  break;
2097
                }
2098
              }
2099
          }
2100
        else
2101
          {
2102
            jobject value = POPA();
2103
            *field->u.object_addr = value;
2104
            newinsn = AMPAMP (putstatic_resolved_obj);
2105
          }
2106
 
2107
#ifdef DIRECT_THREADED
2108
        REWRITE_INSN (newinsn, datum, field->u.addr);
2109
#endif /* DIRECT_THREADED */
2110
      }
2111
      NEXT_INSN;
2112
 
2113
#ifdef DIRECT_THREADED
2114
    putstatic_resolved_1:
2115
      *(jbyte *) AVAL () = POPI ();
2116
      NEXT_INSN;
2117
 
2118
    putstatic_resolved_2:
2119
      *(jchar *) AVAL () = POPI ();
2120
      NEXT_INSN;
2121
 
2122
    putstatic_resolved_4:
2123
      *(jint *) AVAL () = POPI ();
2124
      NEXT_INSN;
2125
 
2126
    putstatic_resolved_8:
2127
      *(jlong *) AVAL () = POPL ();
2128
      NEXT_INSN;
2129
 
2130
    putstatic_resolved_obj:
2131
      *(jobject *) AVAL () = POPA ();
2132
      NEXT_INSN;
2133
#endif /* DIRECT_THREADED */
2134
 
2135
    insn_putfield:
2136
      {
2137
        SAVE_PC();
2138
        jint fieldref_index = GET2U ();
2139
        _Jv_Linker::resolve_pool_entry (meth->defining_class, fieldref_index);
2140
        _Jv_Field *field = pool_data[fieldref_index].field;
2141
 
2142
        jclass type = field->type;
2143
 
2144
        if ((field->flags & Modifier::STATIC) != 0)
2145
          throw_incompatible_class_change_error
2146
            (JvNewStringLatin1 ("field is static"));
2147
 
2148
        jint field_offset = field->u.boffset;
2149
 
2150
        void *newinsn = NULL;
2151
        if (type->isPrimitive ())
2152
          {
2153
            switch (type->size_in_bytes)
2154
              {
2155
              case 1:
2156
                {
2157
                  jint    value = POPI();
2158
                  jobject obj   = POPA();
2159
                  NULLCHECK(obj);
2160
                  *(jbyte*) ((char*)obj + field_offset) = value;
2161
                  newinsn = AMPAMP (putfield_resolved_1);
2162
                  break;
2163
                }
2164
 
2165
              case 2:
2166
                {
2167
                  jint    value = POPI();
2168
                  jobject obj   = POPA();
2169
                  NULLCHECK(obj);
2170
                  *(jchar*) ((char*)obj + field_offset) = value;
2171
                  newinsn = AMPAMP (putfield_resolved_2);
2172
                  break;
2173
                }
2174
 
2175
              case 4:
2176
                {
2177
                  jint    value = POPI();
2178
                  jobject obj   = POPA();
2179
                  NULLCHECK(obj);
2180
                  *(jint*) ((char*)obj + field_offset) = value;
2181
                  newinsn = AMPAMP (putfield_resolved_4);
2182
                  break;
2183
                }
2184
 
2185
              case 8:
2186
                {
2187
                  jlong   value = POPL();
2188
                  jobject obj   = POPA();
2189
                  NULLCHECK(obj);
2190
                  *(jlong*) ((char*)obj + field_offset) = value;
2191
                  newinsn = AMPAMP (putfield_resolved_8);
2192
                  break;
2193
                }
2194
              }
2195
          }
2196
        else
2197
          {
2198
            jobject value = POPA();
2199
            jobject obj   = POPA();
2200
            NULLCHECK(obj);
2201
            *(jobject*) ((char*)obj + field_offset) = value;
2202
            newinsn = AMPAMP (putfield_resolved_obj);
2203
          }
2204
 
2205
#ifdef DIRECT_THREADED
2206
        REWRITE_INSN (newinsn, int_val, field_offset);
2207
#endif /* DIRECT_THREADED */
2208
      }
2209
      NEXT_INSN;
2210
 
2211
#ifdef DIRECT_THREADED
2212
    putfield_resolved_1:
2213
      {
2214
        jint val = POPI ();
2215
        char *obj = (char *) POPA ();
2216
        NULLCHECK (obj);
2217
        *(jbyte *) (obj + INTVAL ()) = val;
2218
      }
2219
      NEXT_INSN;
2220
 
2221
    putfield_resolved_2:
2222
      {
2223
        jint val = POPI ();
2224
        char *obj = (char *) POPA ();
2225
        NULLCHECK (obj);
2226
        *(jchar *) (obj + INTVAL ()) = val;
2227
      }
2228
      NEXT_INSN;
2229
 
2230
    putfield_resolved_4:
2231
      {
2232
        jint val = POPI ();
2233
        char *obj = (char *) POPA ();
2234
        NULLCHECK (obj);
2235
        *(jint *) (obj + INTVAL ()) = val;
2236
      }
2237
      NEXT_INSN;
2238
 
2239
    putfield_resolved_8:
2240
      {
2241
        jlong val = POPL ();
2242
        char *obj = (char *) POPA ();
2243
        NULLCHECK (obj);
2244
        *(jlong *) (obj + INTVAL ()) = val;
2245
      }
2246
      NEXT_INSN;
2247
 
2248
    putfield_resolved_obj:
2249
      {
2250
        jobject val = POPA ();
2251
        char *obj = (char *) POPA ();
2252
        NULLCHECK (obj);
2253
        *(jobject *) (obj + INTVAL ()) = val;
2254
      }
2255
      NEXT_INSN;
2256
#endif /* DIRECT_THREADED */
2257
 
2258
    insn_invokespecial:
2259
      {
2260
        SAVE_PC();
2261
        int index = GET2U ();
2262
 
2263
        rmeth = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2264
                                                   index)).rmethod;
2265
 
2266
        sp -= rmeth->stack_item_count;
2267
 
2268
        // We don't use NULLCHECK here because we can't rely on that
2269
        // working for <init>.  So instead we do an explicit test.
2270
        if (! sp[0].o)
2271
          {
2272
            SAVE_PC();
2273
            throw_null_pointer_exception ();
2274
          }
2275
 
2276
        fun = (void (*)()) rmeth->method->ncode;
2277
 
2278
#ifdef DIRECT_THREADED
2279
        // Rewrite instruction so that we use a faster pre-resolved
2280
        // method.
2281
        REWRITE_INSN (&&invokespecial_resolved, datum, rmeth);
2282
#endif /* DIRECT_THREADED */
2283
      }
2284
      goto perform_invoke;
2285
 
2286
#ifdef DIRECT_THREADED
2287
    invokespecial_resolved:
2288
      {
2289
        SAVE_PC();
2290
        rmeth = (_Jv_ResolvedMethod *) AVAL ();
2291
        sp -= rmeth->stack_item_count;
2292
        // We don't use NULLCHECK here because we can't rely on that
2293
        // working for <init>.  So instead we do an explicit test.
2294
        if (! sp[0].o)
2295
          {
2296
            throw_null_pointer_exception ();
2297
          }
2298
        fun = (void (*)()) rmeth->method->ncode;
2299
      }
2300
      goto perform_invoke;
2301
#endif /* DIRECT_THREADED */
2302
 
2303
    insn_invokestatic:
2304
      {
2305
        SAVE_PC();
2306
        int index = GET2U ();
2307
 
2308
        rmeth = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2309
                                                   index)).rmethod;
2310
 
2311
        sp -= rmeth->stack_item_count;
2312
 
2313
        fun = (void (*)()) rmeth->method->ncode;
2314
 
2315
#ifdef DIRECT_THREADED
2316
        // Rewrite instruction so that we use a faster pre-resolved
2317
        // method.
2318
        REWRITE_INSN (&&invokestatic_resolved, datum, rmeth);
2319
#endif /* DIRECT_THREADED */
2320
      }
2321
      goto perform_invoke;
2322
 
2323
#ifdef DIRECT_THREADED
2324
    invokestatic_resolved:
2325
      {
2326
        SAVE_PC();
2327
        rmeth = (_Jv_ResolvedMethod *) AVAL ();
2328
        sp -= rmeth->stack_item_count;
2329
        fun = (void (*)()) rmeth->method->ncode;
2330
      }
2331
      goto perform_invoke;
2332
#endif /* DIRECT_THREADED */
2333
 
2334
    insn_invokeinterface:
2335
      {
2336
        SAVE_PC();
2337
        int index = GET2U ();
2338
 
2339
        rmeth = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2340
                                                   index)).rmethod;
2341
 
2342
        sp -= rmeth->stack_item_count;
2343
 
2344
        jobject rcv = sp[0].o;
2345
 
2346
        NULLCHECK (rcv);
2347
 
2348
        fun = (void (*)())
2349
          _Jv_LookupInterfaceMethod (rcv->getClass (),
2350
                                     rmeth->method->name,
2351
                                     rmeth->method->signature);
2352
 
2353
#ifdef DIRECT_THREADED
2354
        // Rewrite instruction so that we use a faster pre-resolved
2355
        // method.
2356
        REWRITE_INSN (&&invokeinterface_resolved, datum, rmeth);
2357
#else
2358
        // Skip dummy bytes.
2359
        pc += 2;
2360
#endif /* DIRECT_THREADED */
2361
      }
2362
      goto perform_invoke;
2363
 
2364
#ifdef DIRECT_THREADED
2365
    invokeinterface_resolved:
2366
      {
2367
        SAVE_PC();
2368
        rmeth = (_Jv_ResolvedMethod *) AVAL ();
2369
        sp -= rmeth->stack_item_count;
2370
        jobject rcv = sp[0].o;
2371
        NULLCHECK (rcv);
2372
        fun = (void (*)())
2373
          _Jv_LookupInterfaceMethod (rcv->getClass (),
2374
                                     rmeth->method->name,
2375
                                     rmeth->method->signature);
2376
      }
2377
      goto perform_invoke;
2378
#endif /* DIRECT_THREADED */
2379
 
2380
    insn_new:
2381
      {
2382
        SAVE_PC();
2383
        int index = GET2U ();
2384
        jclass klass = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2385
                                                          index)).clazz;
2386
        /* VM spec, section 3.11.5 */
2387
        if ((klass->getModifiers() & Modifier::ABSTRACT)
2388
            || klass->isInterface())
2389
          {
2390
            jthrowable t = new java::lang::InstantiationException;
2391
            INTERP_REPORT_EXCEPTION (t);
2392
            throw t;
2393
          }
2394
        jobject res = _Jv_AllocObject (klass);
2395
        PUSHA (res);
2396
 
2397
#ifdef DIRECT_THREADED
2398
        REWRITE_INSN (&&new_resolved, datum, klass);
2399
#endif /* DIRECT_THREADED */
2400
      }
2401
      NEXT_INSN;
2402
 
2403
#ifdef DIRECT_THREADED
2404
    new_resolved:
2405
      {
2406
        jclass klass = (jclass) AVAL ();
2407
        jobject res = _Jv_AllocObject (klass);
2408
        PUSHA (res);
2409
      }
2410
      NEXT_INSN;
2411
#endif /* DIRECT_THREADED */
2412
 
2413
    insn_newarray:
2414
      {
2415
        int atype = GET1U ();
2416
        int size  = POPI();
2417
        jobject result = _Jv_NewArray (atype, size);
2418
        PUSHA (result);
2419
      }
2420
      NEXT_INSN;
2421
 
2422
    insn_anewarray:
2423
      {
2424
        SAVE_PC();
2425
        int index = GET2U ();
2426
        jclass klass = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2427
                                                          index)).clazz;
2428
        int size  = POPI();
2429
        jobject result = _Jv_NewObjectArray (size, klass, 0);
2430
        PUSHA (result);
2431
 
2432
#ifdef DIRECT_THREADED
2433
        REWRITE_INSN (&&anewarray_resolved, datum, klass);
2434
#endif /* DIRECT_THREADED */
2435
      }
2436
      NEXT_INSN;
2437
 
2438
#ifdef DIRECT_THREADED
2439
    anewarray_resolved:
2440
      {
2441
        jclass klass = (jclass) AVAL ();
2442
        int size = POPI ();
2443
        jobject result = _Jv_NewObjectArray (size, klass, 0);
2444
        PUSHA (result);
2445
      }
2446
      NEXT_INSN;
2447
#endif /* DIRECT_THREADED */
2448
 
2449
    insn_arraylength:
2450
      {
2451
        __JArray *arr = (__JArray*)POPA();
2452
        NULLARRAYCHECK (arr);
2453
        PUSHI (arr->length);
2454
      }
2455
      NEXT_INSN;
2456
 
2457
    insn_athrow:
2458
      {
2459
        jobject value = POPA();
2460
        jthrowable t = static_cast<jthrowable> (value);
2461
        INTERP_REPORT_EXCEPTION (t);
2462
        throw t;
2463
      }
2464
      NEXT_INSN;
2465
 
2466
    insn_checkcast:
2467
      {
2468
        SAVE_PC();
2469
        jobject value = POPA();
2470
        jint index = GET2U ();
2471
        jclass to = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2472
                                                       index)).clazz;
2473
 
2474
        value = (jobject) _Jv_CheckCast (to, value);
2475
 
2476
        PUSHA (value);
2477
 
2478
#ifdef DIRECT_THREADED
2479
        REWRITE_INSN (&&checkcast_resolved, datum, to);
2480
#endif /* DIRECT_THREADED */
2481
      }
2482
      NEXT_INSN;
2483
 
2484
#ifdef DIRECT_THREADED
2485
    checkcast_resolved:
2486
      {
2487
        SAVE_PC();
2488
        jobject value = POPA ();
2489
        jclass to = (jclass) AVAL ();
2490
        value = (jobject) _Jv_CheckCast (to, value);
2491
        PUSHA (value);
2492
      }
2493
      NEXT_INSN;
2494
#endif /* DIRECT_THREADED */
2495
 
2496
    insn_instanceof:
2497
      {
2498
        SAVE_PC();
2499
        jobject value = POPA();
2500
        jint index = GET2U ();
2501
        jclass to = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2502
                                                       index)).clazz;
2503
        PUSHI (to->isInstance (value));
2504
 
2505
#ifdef DIRECT_THREADED
2506
        REWRITE_INSN (&&instanceof_resolved, datum, to);
2507
#endif /* DIRECT_THREADED */
2508
      }
2509
      NEXT_INSN;
2510
 
2511
#ifdef DIRECT_THREADED
2512
    instanceof_resolved:
2513
      {
2514
        jobject value = POPA ();
2515
        jclass to = (jclass) AVAL ();
2516
        PUSHI (to->isInstance (value));
2517
      }
2518
      NEXT_INSN;
2519
#endif /* DIRECT_THREADED */
2520
 
2521
    insn_monitorenter:
2522
      {
2523
        jobject value = POPA();
2524
        NULLCHECK(value);
2525
        _Jv_MonitorEnter (value);
2526
      }
2527
      NEXT_INSN;
2528
 
2529
    insn_monitorexit:
2530
      {
2531
        jobject value = POPA();
2532
        NULLCHECK(value);
2533
        _Jv_MonitorExit (value);
2534
      }
2535
      NEXT_INSN;
2536
 
2537
    insn_ifnull:
2538
      {
2539
        jobject val = POPA();
2540
        if (val == NULL)
2541
          TAKE_GOTO;
2542
        else
2543
          SKIP_GOTO;
2544
      }
2545
      NEXT_INSN;
2546
 
2547
    insn_ifnonnull:
2548
      {
2549
        jobject val = POPA();
2550
        if (val != NULL)
2551
          TAKE_GOTO;
2552
        else
2553
          SKIP_GOTO;
2554
      }
2555
      NEXT_INSN;
2556
 
2557
    insn_multianewarray:
2558
      {
2559
        SAVE_PC();
2560
        int kind_index = GET2U ();
2561
        int dim        = GET1U ();
2562
 
2563
        jclass type
2564
          = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2565
                                               kind_index)).clazz;
2566
        jint *sizes    = (jint*) __builtin_alloca (sizeof (jint)*dim);
2567
 
2568
        for (int i = dim - 1; i >= 0; i--)
2569
          {
2570
            sizes[i] = POPI ();
2571
          }
2572
 
2573
        jobject res    = _Jv_NewMultiArray (type,dim, sizes);
2574
 
2575
        PUSHA (res);
2576
      }
2577
      NEXT_INSN;
2578
 
2579
#ifndef DIRECT_THREADED
2580
    insn_wide:
2581
      {
2582
        jint the_mod_op = get1u (pc++);
2583
        jint wide       = get2u (pc); pc += 2;
2584
 
2585
        switch (the_mod_op)
2586
          {
2587
          case op_istore:
2588
            STOREI (wide);
2589
            NEXT_INSN;
2590
 
2591
          case op_fstore:
2592
            STOREF (wide);
2593
            NEXT_INSN;
2594
 
2595
          case op_astore:
2596
            STOREA (wide);
2597
            NEXT_INSN;
2598
 
2599
          case op_lload:
2600
            LOADL (wide);
2601
            NEXT_INSN;
2602
 
2603
          case op_dload:
2604
            LOADD (wide);
2605
            NEXT_INSN;
2606
 
2607
          case op_iload:
2608
            LOADI (wide);
2609
            NEXT_INSN;
2610
 
2611
          case op_fload:
2612
            LOADF (wide);
2613
            NEXT_INSN;
2614
 
2615
          case op_aload:
2616
            LOADA (wide);
2617
            NEXT_INSN;
2618
 
2619
          case op_lstore:
2620
            STOREL (wide);
2621
            NEXT_INSN;
2622
 
2623
          case op_dstore:
2624
            STORED (wide);
2625
            NEXT_INSN;
2626
 
2627
          case op_ret:
2628
            pc = (unsigned char*) PEEKA (wide);
2629
            NEXT_INSN;
2630
 
2631
          case op_iinc:
2632
            {
2633
              jint amount = get2s (pc); pc += 2;
2634
              jint value = PEEKI (wide);
2635
              POKEI (wide, value+amount);
2636
            }
2637
            NEXT_INSN;
2638
 
2639
          default:
2640
            throw_internal_error ("illegal bytecode modified by wide");
2641
          }
2642
 
2643
      }
2644
#endif /* DIRECT_THREADED */
2645
 
2646
    insn_breakpoint:
2647
      {
2648
        using namespace ::java::lang;
2649
        jmethodID method = meth->self;
2650
        jlocation location = meth->insn_index (pc - 1);
2651
 
2652
        using namespace gnu::gcj::jvmti;
2653
        Breakpoint *bp
2654
          = BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method),
2655
                                              location);
2656
        JvAssert (bp != NULL);
2657
 
2658
        // Save the insn here since the breakpoint could be removed
2659
        // before the JVMTI notification returns.
2660
        pc_t opc = reinterpret_cast<pc_t> (bp->getInsn ());
2661
 
2662
        bp->execute ();
2663
 
2664
        // Continue execution
2665
#ifdef DIRECT_THREADED
2666
        goto *(opc->insn);
2667
#else
2668
        goto *(insn_target[*opc]);
2669
#endif
2670
      }
2671
    }
2672
  catch (java::lang::Throwable *ex)
2673
    {
2674
      // Check if the exception is handled and, if so, set the pc to the start
2675
      // of the appropriate catch block.
2676
      if (meth->check_handler (&pc, meth, ex))
2677
        {
2678
          sp = stack;
2679
          sp++->o = ex; // Push exception.
2680
#ifdef __GCJ_DEBUG
2681
          if (JVMTI_REQUESTED_EVENT (ExceptionCatch))
2682
            {
2683
              using namespace gnu::gcj::jvmti;
2684
              jlong catch_meth = reinterpret_cast<jlong> (meth->get_method ());
2685
              jlong catch_loc = meth->insn_index (pc);
2686
              _Jv_JVMTI_PostEvent (JVMTI_EVENT_EXCEPTION_CATCH, thread,
2687
                                   _Jv_GetCurrentJNIEnv (), catch_meth,
2688
                                   catch_loc, ex);
2689
            }
2690
#endif
2691
          NEXT_INSN;
2692
        }
2693
 
2694
      // No handler, so re-throw.
2695
      throw ex;
2696
    }

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.