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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [java/] [expr.c] - Blame information for rev 20

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

Line No. Rev Author Line
1 12 jlechner
/* Process expressions for the GNU compiler for the Java(TM) language.
2
   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
3
   Free Software Foundation, Inc.
4
 
5
This file is part of GCC.
6
 
7
GCC is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2, or (at your option)
10
any later version.
11
 
12
GCC is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GCC; see the file COPYING.  If not, write to
19
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20
Boston, MA 02110-1301, USA.
21
 
22
Java and all Java-based marks are trademarks or registered trademarks
23
of Sun Microsystems, Inc. in the United States and other countries.
24
The Free Software Foundation is independent of Sun Microsystems, Inc.  */
25
 
26
/* Hacked by Per Bothner <bothner@cygnus.com> February 1996. */
27
 
28
#include "config.h"
29
#include "system.h"
30
#include "coretypes.h"
31
#include "tm.h"
32
#include "tree.h"
33
#include "real.h"
34
#include "rtl.h"
35
#include "flags.h"
36
#include "expr.h"
37
#include "java-tree.h"
38
#include "javaop.h"
39
#include "java-opcodes.h"
40
#include "jcf.h"
41
#include "java-except.h"
42
#include "parse.h"
43
#include "toplev.h"
44
#include "except.h"
45
#include "ggc.h"
46
#include "tree-gimple.h"
47
#include "target.h"
48
 
49
static void flush_quick_stack (void);
50
static void push_value (tree);
51
static tree pop_value (tree);
52
static void java_stack_swap (void);
53
static void java_stack_dup (int, int);
54
static void build_java_athrow (tree);
55
static void build_java_jsr (int, int);
56
static void build_java_ret (tree);
57
static void expand_java_multianewarray (tree, int);
58
static void expand_java_arraystore (tree);
59
static void expand_java_arrayload (tree);
60
static void expand_java_array_length (void);
61
static tree build_java_monitor (tree, tree);
62
static void expand_java_pushc (int, tree);
63
static void expand_java_return (tree);
64
static void expand_load_internal (int, tree, int);
65
static void expand_java_NEW (tree);
66
static void expand_java_INSTANCEOF (tree);
67
static void expand_java_CHECKCAST (tree);
68
static void expand_iinc (unsigned int, int, int);
69
static void expand_java_binop (tree, enum tree_code);
70
static void note_label (int, int);
71
static void expand_compare (enum tree_code, tree, tree, int);
72
static void expand_test (enum tree_code, tree, int);
73
static void expand_cond (enum tree_code, tree, int);
74
static void expand_java_goto (int);
75
static tree expand_java_switch (tree, int);
76
static void expand_java_add_case (tree, int, int);
77
#if 0
78
static void expand_java_call (int, int);
79
static void expand_java_ret (tree);
80
#endif
81
static tree pop_arguments (tree);
82
static void expand_invoke (int, int, int);
83
static void expand_java_field_op (int, int, int);
84
static void java_push_constant_from_pool (struct JCF *, int);
85
static void java_stack_pop (int);
86
static tree build_java_throw_out_of_bounds_exception (tree);
87
static tree build_java_check_indexed_type (tree, tree);
88
static unsigned char peek_opcode_at_pc (struct JCF *, int, int);
89
static void promote_arguments (void);
90
 
91
static GTY(()) tree operand_type[59];
92
 
93
static GTY(()) tree methods_ident;
94
static GTY(()) tree ncode_ident;
95
tree dtable_ident = NULL_TREE;
96
 
97
/* Set to nonzero value in order to emit class initialization code
98
   before static field references.  */
99
int always_initialize_class_p = 0;
100
 
101
/* We store the stack state in two places:
102
   Within a basic block, we use the quick_stack, which is a
103
   pushdown list (TREE_LISTs) of expression nodes.
104
   This is the top part of the stack;  below that we use find_stack_slot.
105
   At the end of a basic block, the quick_stack must be flushed
106
   to the stack slot array (as handled by find_stack_slot).
107
   Using quick_stack generates better code (especially when
108
   compiled without optimization), because we do not have to
109
   explicitly store and load trees to temporary variables.
110
 
111
   If a variable is on the quick stack, it means the value of variable
112
   when the quick stack was last flushed.  Conceptually, flush_quick_stack
113
   saves all the quick_stack elements in parallel.  However, that is
114
   complicated, so it actually saves them (i.e. copies each stack value
115
   to is home virtual register) from low indexes.  This allows a quick_stack
116
   element at index i (counting from the bottom of stack the) to references
117
   slot virtuals for register that are >= i, but not those that are deeper.
118
   This convention makes most operations easier.  For example iadd works
119
   even when the stack contains (reg[0], reg[1]):  It results in the
120
   stack containing (reg[0]+reg[1]), which is OK.  However, some stack
121
   operations are more complicated.  For example dup given a stack
122
   containing (reg[0]) would yield (reg[0], reg[0]), which would violate
123
   the convention, since stack value 1 would refer to a register with
124
   lower index (reg[0]), which flush_quick_stack does not safely handle.
125
   So dup cannot just add an extra element to the quick_stack, but iadd can.
126
*/
127
 
128
static GTY(()) tree quick_stack;
129
 
130
/* A free-list of unused permanent TREE_LIST nodes.  */
131
static GTY((deletable)) tree tree_list_free_list;
132
 
133
/* The physical memory page size used in this computer.  See
134
   build_field_ref().  */
135
static GTY(()) tree page_size;
136
 
137
/* The stack pointer of the Java virtual machine.
138
   This does include the size of the quick_stack. */
139
 
140
int stack_pointer;
141
 
142
const unsigned char *linenumber_table;
143
int linenumber_count;
144
 
145
/* Largest pc so far in this method that has been passed to lookup_label. */
146
int highest_label_pc_this_method = -1;
147
 
148
/* Base value for this method to add to pc to get generated label. */
149
int start_label_pc_this_method = 0;
150
 
151
void
152
init_expr_processing (void)
153
{
154
  operand_type[21] = operand_type[54] = int_type_node;
155
  operand_type[22] = operand_type[55] = long_type_node;
156
  operand_type[23] = operand_type[56] = float_type_node;
157
  operand_type[24] = operand_type[57] = double_type_node;
158
  operand_type[25] = operand_type[58] = ptr_type_node;
159
}
160
 
161
tree
162
java_truthvalue_conversion (tree expr)
163
{
164
  /* It is simpler and generates better code to have only TRUTH_*_EXPR
165
     or comparison expressions as truth values at this level.
166
 
167
     This function should normally be identity for Java.  */
168
 
169
  switch (TREE_CODE (expr))
170
    {
171
    case EQ_EXPR:   case NE_EXPR:   case UNEQ_EXPR: case LTGT_EXPR:
172
    case LE_EXPR:   case GE_EXPR:   case LT_EXPR:   case GT_EXPR:
173
    case UNLE_EXPR: case UNGE_EXPR: case UNLT_EXPR: case UNGT_EXPR:
174
    case ORDERED_EXPR: case UNORDERED_EXPR:
175
    case TRUTH_ANDIF_EXPR:
176
    case TRUTH_ORIF_EXPR:
177
    case TRUTH_AND_EXPR:
178
    case TRUTH_OR_EXPR:
179
    case TRUTH_XOR_EXPR:
180
    case TRUTH_NOT_EXPR:
181
    case ERROR_MARK:
182
      return expr;
183
 
184
    case INTEGER_CST:
185
      return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
186
 
187
    case REAL_CST:
188
      return real_zerop (expr) ? boolean_false_node : boolean_true_node;
189
 
190
    /* are these legal? XXX JH */
191
    case NEGATE_EXPR:
192
    case ABS_EXPR:
193
    case FLOAT_EXPR:
194
      /* These don't change whether an object is nonzero or zero.  */
195
      return java_truthvalue_conversion (TREE_OPERAND (expr, 0));
196
 
197
    case COND_EXPR:
198
      /* Distribute the conversion into the arms of a COND_EXPR.  */
199
      return fold_build3 (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
200
                          java_truthvalue_conversion (TREE_OPERAND (expr, 1)),
201
                          java_truthvalue_conversion (TREE_OPERAND (expr, 2)));
202
 
203
    case NOP_EXPR:
204
      /* If this is widening the argument, we can ignore it.  */
205
      if (TYPE_PRECISION (TREE_TYPE (expr))
206
          >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
207
        return java_truthvalue_conversion (TREE_OPERAND (expr, 0));
208
      /* fall through to default */
209
 
210
    default:
211
      return fold_build2 (NE_EXPR, boolean_type_node,
212
                          expr, boolean_false_node);
213
    }
214
}
215
 
216
/* Save any stack slots that happen to be in the quick_stack into their
217
   home virtual register slots.
218
 
219
   The copy order is from low stack index to high, to support the invariant
220
   that the expression for a slot may contain decls for stack slots with
221
   higher (or the same) index, but not lower. */
222
 
223
static void
224
flush_quick_stack (void)
225
{
226
  int stack_index = stack_pointer;
227
  tree prev, cur, next;
228
 
229
  /* First reverse the quick_stack, and count the number of slots it has. */
230
  for (cur = quick_stack, prev = NULL_TREE; cur != NULL_TREE; cur = next)
231
    {
232
      next = TREE_CHAIN (cur);
233
      TREE_CHAIN (cur) = prev;
234
      prev = cur;
235
      stack_index -= 1 + TYPE_IS_WIDE (TREE_TYPE (TREE_VALUE (cur)));
236
    }
237
  quick_stack = prev;
238
 
239
  while (quick_stack != NULL_TREE)
240
    {
241
      tree decl;
242
      tree node = quick_stack, type;
243
      quick_stack = TREE_CHAIN (node);
244
      TREE_CHAIN (node) = tree_list_free_list;
245
      tree_list_free_list = node;
246
      node = TREE_VALUE (node);
247
      type = TREE_TYPE (node);
248
 
249
      decl = find_stack_slot (stack_index, type);
250
      if (decl != node)
251
        java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (node), decl, node));
252
      stack_index += 1 + TYPE_IS_WIDE (type);
253
    }
254
}
255
 
256
/* Push TYPE on the type stack.
257
   Return true on success, 0 on overflow. */
258
 
259
int
260
push_type_0 (tree type)
261
{
262
  int n_words;
263
  type = promote_type (type);
264
  n_words = 1 + TYPE_IS_WIDE (type);
265
  if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
266
    return 0;
267
  /* Allocate decl for this variable now, so we get a temporary that
268
     survives the whole method. */
269
  find_stack_slot (stack_pointer, type);
270
  stack_type_map[stack_pointer++] = type;
271
  n_words--;
272
  while (--n_words >= 0)
273
    stack_type_map[stack_pointer++] = TYPE_SECOND;
274
  return 1;
275
}
276
 
277
void
278
push_type (tree type)
279
{
280
  if (! push_type_0 (type))
281
    abort ();
282
}
283
 
284
static void
285
push_value (tree value)
286
{
287
  tree type = TREE_TYPE (value);
288
  if (TYPE_PRECISION (type) < 32 && INTEGRAL_TYPE_P (type))
289
    {
290
      type = promote_type (type);
291
      value = convert (type, value);
292
    }
293
  push_type (type);
294
  if (tree_list_free_list == NULL_TREE)
295
    quick_stack = tree_cons (NULL_TREE, value, quick_stack);
296
  else
297
    {
298
      tree node = tree_list_free_list;
299
      tree_list_free_list = TREE_CHAIN (tree_list_free_list);
300
      TREE_VALUE (node) = value;
301
      TREE_CHAIN (node) = quick_stack;
302
      quick_stack = node;
303
    }
304
}
305
 
306
/* Pop a type from the type stack.
307
   TYPE is the expected type.   Return the actual type, which must be
308
   convertible to TYPE.
309
   On an error, *MESSAGEP is set to a freshly malloc'd error message. */
310
 
311
tree
312
pop_type_0 (tree type, char **messagep)
313
{
314
  int n_words;
315
  tree t;
316
  *messagep = NULL;
317
  if (TREE_CODE (type) == RECORD_TYPE)
318
    type = promote_type (type);
319
  n_words = 1 + TYPE_IS_WIDE (type);
320
  if (stack_pointer < n_words)
321
    {
322
      *messagep = xstrdup ("stack underflow");
323
      return type;
324
    }
325
  while (--n_words > 0)
326
    {
327
      if (stack_type_map[--stack_pointer] != void_type_node)
328
        {
329
          *messagep = xstrdup ("Invalid multi-word value on type stack");
330
          return type;
331
        }
332
    }
333
  t = stack_type_map[--stack_pointer];
334
  if (type == NULL_TREE || t == type)
335
    return t;
336
  if (TREE_CODE (t) == TREE_LIST)
337
    {
338
      do
339
        {
340
          tree tt = TREE_PURPOSE (t);
341
          if (! can_widen_reference_to (tt, type))
342
            {
343
              t = tt;
344
              goto fail;
345
            }
346
          t = TREE_CHAIN (t);
347
        }
348
      while (t);
349
      return t;
350
    }
351
  if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
352
      && TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
353
    return t;
354
  if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (t) == POINTER_TYPE)
355
    {
356
      /* If the expected type we've been passed is object or ptr
357
         (i.e. void*), the caller needs to know the real type.  */
358
      if (type == ptr_type_node || type == object_ptr_type_node)
359
        return t;
360
 
361
      /* Since the verifier has already run, we know that any
362
         types we see will be compatible.  In BC mode, this fact
363
         may be checked at runtime, but if that is so then we can
364
         assume its truth here as well.  So, we always succeed
365
         here, with the expected type.  */
366
      return type;
367
    }
368
 
369
  if (! flag_verify_invocations && flag_indirect_dispatch
370
      && t == object_ptr_type_node)
371
    {
372
      if (type != ptr_type_node)
373
        warning (0, "need to insert runtime check for %s",
374
                 xstrdup (lang_printable_name (type, 0)));
375
      return type;
376
    }
377
 
378
  /* lang_printable_name uses a static buffer, so we must save the result
379
     from calling it the first time.  */
380
 fail:
381
  {
382
    char *temp = xstrdup (lang_printable_name (type, 0));
383
    /* If the stack contains a multi-word type, keep popping the stack until
384
       the real type is found.  */
385
    while (t == void_type_node)
386
      t = stack_type_map[--stack_pointer];
387
    *messagep = concat ("expected type '", temp,
388
                        "' but stack contains '", lang_printable_name (t, 0),
389
                        "'", NULL);
390
    free (temp);
391
  }
392
  return type;
393
}
394
 
395
/* Pop a type from the type stack.
396
   TYPE is the expected type.  Return the actual type, which must be
397
   convertible to TYPE, otherwise call error. */
398
 
399
tree
400
pop_type (tree type)
401
{
402
  char *message = NULL;
403
  type = pop_type_0 (type, &message);
404
  if (message != NULL)
405
    {
406
      error ("%s", message);
407
      free (message);
408
    }
409
  return type;
410
}
411
 
412
 
413
/* Return true if two type assertions are equal.  */
414
 
415
static int
416
type_assertion_eq (const void * k1_p, const void * k2_p)
417
{
418
  type_assertion k1 = *(type_assertion *)k1_p;
419
  type_assertion k2 = *(type_assertion *)k2_p;
420
  return (k1.assertion_code == k2.assertion_code
421
          && k1.op1 == k2.op1
422
          && k1.op2 == k2.op2);
423
}
424
 
425
/* Hash a type assertion.  */
426
 
427
static hashval_t
428
type_assertion_hash (const void *p)
429
{
430
  const type_assertion *k_p = p;
431
  hashval_t hash = iterative_hash (&k_p->assertion_code, sizeof
432
                                   k_p->assertion_code, 0);
433
  hash = iterative_hash (&k_p->op1, sizeof k_p->op1, hash);
434
  return iterative_hash (&k_p->op2, sizeof k_p->op2, hash);
435
}
436
 
437
/* Add an entry to the type assertion table for the given class.
438
   CLASS is the class for which this assertion will be evaluated by the
439
   runtime during loading/initialization.
440
   ASSERTION_CODE is the 'opcode' or type of this assertion: see java-tree.h.
441
   OP1 and OP2 are the operands. The tree type of these arguments may be
442
   specific to each assertion_code. */
443
 
444
void
445
add_type_assertion (tree class, int assertion_code, tree op1, tree op2)
446
{
447
  htab_t assertions_htab;
448
  type_assertion as;
449
  void **as_pp;
450
 
451
  assertions_htab = TYPE_ASSERTIONS (class);
452
  if (assertions_htab == NULL)
453
    {
454
      assertions_htab = htab_create_ggc (7, type_assertion_hash,
455
                                         type_assertion_eq, NULL);
456
      TYPE_ASSERTIONS (current_class) = assertions_htab;
457
    }
458
 
459
  as.assertion_code = assertion_code;
460
  as.op1 = op1;
461
  as.op2 = op2;
462
 
463
  as_pp = htab_find_slot (assertions_htab, &as, INSERT);
464
 
465
  /* Don't add the same assertion twice.  */
466
  if (*as_pp)
467
    return;
468
 
469
  *as_pp = ggc_alloc (sizeof (type_assertion));
470
  **(type_assertion **)as_pp = as;
471
}
472
 
473
 
474
/* Return 1 if SOURCE_TYPE can be safely widened to TARGET_TYPE.
475
   Handles array types and interfaces.  */
476
 
477
int
478
can_widen_reference_to (tree source_type, tree target_type)
479
{
480
  if (source_type == ptr_type_node || target_type == object_ptr_type_node)
481
    return 1;
482
 
483
  /* Get rid of pointers  */
484
  if (TREE_CODE (source_type) == POINTER_TYPE)
485
    source_type = TREE_TYPE (source_type);
486
  if (TREE_CODE (target_type) == POINTER_TYPE)
487
    target_type = TREE_TYPE (target_type);
488
 
489
  if (source_type == target_type)
490
    return 1;
491
 
492
  /* FIXME: This is very pessimistic, in that it checks everything,
493
     even if we already know that the types are compatible.  If we're
494
     to support full Java class loader semantics, we need this.
495
     However, we could do something more optimal.  */
496
  if (! flag_verify_invocations)
497
    {
498
      add_type_assertion (current_class, JV_ASSERT_TYPES_COMPATIBLE,
499
                          source_type, target_type);
500
 
501
      if (!quiet_flag)
502
       warning (0, "assert: %s is assign compatible with %s",
503
                xstrdup (lang_printable_name (target_type, 0)),
504
                xstrdup (lang_printable_name (source_type, 0)));
505
      /* Punt everything to runtime.  */
506
      return 1;
507
    }
508
 
509
  if (TYPE_DUMMY (source_type) || TYPE_DUMMY (target_type))
510
    {
511
      return 1;
512
    }
513
  else
514
    {
515
      if (TYPE_ARRAY_P (source_type) || TYPE_ARRAY_P (target_type))
516
        {
517
          HOST_WIDE_INT source_length, target_length;
518
          if (TYPE_ARRAY_P (source_type) != TYPE_ARRAY_P (target_type))
519
            {
520
              /* An array implements Cloneable and Serializable.  */
521
              tree name = DECL_NAME (TYPE_NAME (target_type));
522
              return (name == java_lang_cloneable_identifier_node
523
                      || name == java_io_serializable_identifier_node);
524
            }
525
          target_length = java_array_type_length (target_type);
526
          if (target_length >= 0)
527
            {
528
              source_length = java_array_type_length (source_type);
529
              if (source_length != target_length)
530
                return 0;
531
            }
532
          source_type = TYPE_ARRAY_ELEMENT (source_type);
533
          target_type = TYPE_ARRAY_ELEMENT (target_type);
534
          if (source_type == target_type)
535
            return 1;
536
          if (TREE_CODE (source_type) != POINTER_TYPE
537
              || TREE_CODE (target_type) != POINTER_TYPE)
538
            return 0;
539
          return can_widen_reference_to (source_type, target_type);
540
        }
541
      else
542
        {
543
          int source_depth = class_depth (source_type);
544
          int target_depth = class_depth (target_type);
545
 
546
          if (TYPE_DUMMY (source_type) || TYPE_DUMMY (target_type))
547
            {
548
              if (! quiet_flag)
549
                warning (0, "assert: %s is assign compatible with %s",
550
                         xstrdup (lang_printable_name (target_type, 0)),
551
                         xstrdup (lang_printable_name (source_type, 0)));
552
              return 1;
553
            }
554
 
555
          /* class_depth can return a negative depth if an error occurred */
556
          if (source_depth < 0 || target_depth < 0)
557
            return 0;
558
 
559
          if (CLASS_INTERFACE (TYPE_NAME (target_type)))
560
            {
561
              /* target_type is OK if source_type or source_type ancestors
562
                 implement target_type. We handle multiple sub-interfaces  */
563
              tree binfo, base_binfo;
564
              int i;
565
 
566
              for (binfo = TYPE_BINFO (source_type), i = 0;
567
                   BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
568
                if (can_widen_reference_to
569
                    (BINFO_TYPE (base_binfo), target_type))
570
                  return 1;
571
 
572
              if (!i)
573
                return 0;
574
            }
575
 
576
          for ( ; source_depth > target_depth;  source_depth--)
577
            {
578
              source_type
579
                = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (source_type), 0));
580
            }
581
          return source_type == target_type;
582
        }
583
    }
584
}
585
 
586
static tree
587
pop_value (tree type)
588
{
589
  type = pop_type (type);
590
  if (quick_stack)
591
    {
592
      tree node = quick_stack;
593
      quick_stack = TREE_CHAIN (quick_stack);
594
      TREE_CHAIN (node) = tree_list_free_list;
595
      tree_list_free_list = node;
596
      node = TREE_VALUE (node);
597
      return node;
598
    }
599
  else
600
    return find_stack_slot (stack_pointer, promote_type (type));
601
}
602
 
603
 
604
/* Pop and discard the top COUNT stack slots. */
605
 
606
static void
607
java_stack_pop (int count)
608
{
609
  while (count > 0)
610
    {
611
      tree type, val;
612
 
613
      if (stack_pointer == 0)
614
        abort ();
615
 
616
      type = stack_type_map[stack_pointer - 1];
617
      if (type == TYPE_SECOND)
618
        {
619
          count--;
620
          if (stack_pointer == 1 || count <= 0)
621
            abort ();
622
 
623
          type = stack_type_map[stack_pointer - 2];
624
        }
625
      val = pop_value (type);
626
      count--;
627
    }
628
}
629
 
630
/* Implement the 'swap' operator (to swap two top stack slots). */
631
 
632
static void
633
java_stack_swap (void)
634
{
635
  tree type1, type2;
636
  tree temp;
637
  tree decl1, decl2;
638
 
639
  if (stack_pointer < 2
640
      || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
641
      || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
642
      || type1 == TYPE_SECOND || type2 == TYPE_SECOND
643
      || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
644
    /* Bad stack swap.  */
645
    abort ();
646
 
647
  flush_quick_stack ();
648
  decl1 = find_stack_slot (stack_pointer - 1, type1);
649
  decl2 = find_stack_slot (stack_pointer - 2, type2);
650
  temp = build_decl (VAR_DECL, NULL_TREE, type1);
651
  java_add_local_var (temp);
652
  java_add_stmt (build2 (MODIFY_EXPR, type1, temp, decl1));
653
  java_add_stmt (build2 (MODIFY_EXPR, type2,
654
                         find_stack_slot (stack_pointer - 1, type2),
655
                         decl2));
656
  java_add_stmt (build2 (MODIFY_EXPR, type1,
657
                         find_stack_slot (stack_pointer - 2, type1),
658
                         temp));
659
  stack_type_map[stack_pointer - 1] = type2;
660
  stack_type_map[stack_pointer - 2] = type1;
661
}
662
 
663
static void
664
java_stack_dup (int size, int offset)
665
{
666
  int low_index = stack_pointer - size - offset;
667
  int dst_index;
668
  if (low_index < 0)
669
    error ("stack underflow - dup* operation");
670
 
671
  flush_quick_stack ();
672
 
673
  stack_pointer += size;
674
  dst_index = stack_pointer;
675
 
676
  for (dst_index = stack_pointer;  --dst_index >= low_index; )
677
    {
678
      tree type;
679
      int src_index = dst_index - size;
680
      if (src_index < low_index)
681
        src_index = dst_index + size + offset;
682
      type = stack_type_map [src_index];
683
      if (type == TYPE_SECOND)
684
        {
685
          if (src_index <= low_index)
686
            /* Dup operation splits 64-bit number.  */
687
            abort ();
688
 
689
          stack_type_map[dst_index] = type;
690
          src_index--;  dst_index--;
691
          type = stack_type_map[src_index];
692
          if (! TYPE_IS_WIDE (type))
693
            abort ();
694
        }
695
      else if (TYPE_IS_WIDE (type))
696
        abort ();
697
 
698
      if (src_index != dst_index)
699
        {
700
          tree src_decl = find_stack_slot (src_index, type);
701
          tree dst_decl = find_stack_slot (dst_index, type);
702
 
703
          java_add_stmt
704
            (build2 (MODIFY_EXPR, TREE_TYPE (dst_decl), dst_decl, src_decl));
705
          stack_type_map[dst_index] = type;
706
        }
707
    }
708
}
709
 
710
/* Calls _Jv_Throw or _Jv_Sjlj_Throw.  Discard the contents of the
711
   value stack. */
712
 
713
static void
714
build_java_athrow (tree node)
715
{
716
  tree call;
717
 
718
  call = build3 (CALL_EXPR,
719
                 void_type_node,
720
                 build_address_of (throw_node),
721
                 build_tree_list (NULL_TREE, node),
722
                 NULL_TREE);
723
  TREE_SIDE_EFFECTS (call) = 1;
724
  java_add_stmt (call);
725
  java_stack_pop (stack_pointer);
726
}
727
 
728
/* Implementation for jsr/ret */
729
 
730
static void
731
build_java_jsr (int target_pc, int return_pc)
732
{
733
  tree where =  lookup_label (target_pc);
734
  tree ret = lookup_label (return_pc);
735
  tree ret_label = fold_build1 (ADDR_EXPR, return_address_type_node, ret);
736
  push_value (ret_label);
737
  flush_quick_stack ();
738
  java_add_stmt (build1 (GOTO_EXPR, void_type_node, where));
739
 
740
  /* Do not need to emit the label here.  We noted the existence of the
741
     label as a jump target in note_instructions; we'll emit the label
742
     for real at the beginning of the expand_byte_code loop.  */
743
}
744
 
745
static void
746
build_java_ret (tree location)
747
{
748
  java_add_stmt (build1 (GOTO_EXPR, void_type_node, location));
749
}
750
 
751
/* Implementation of operations on array: new, load, store, length */
752
 
753
tree
754
decode_newarray_type (int atype)
755
{
756
  switch (atype)
757
    {
758
    case 4:  return boolean_type_node;
759
    case 5:  return char_type_node;
760
    case 6:  return float_type_node;
761
    case 7:  return double_type_node;
762
    case 8:  return byte_type_node;
763
    case 9:  return short_type_node;
764
    case 10: return int_type_node;
765
    case 11: return long_type_node;
766
    default: return NULL_TREE;
767
    }
768
}
769
 
770
/* Map primitive type to the code used by OPCODE_newarray. */
771
 
772
int
773
encode_newarray_type (tree type)
774
{
775
  if (type == boolean_type_node)
776
    return 4;
777
  else if (type == char_type_node)
778
    return 5;
779
  else if (type == float_type_node)
780
    return 6;
781
  else if (type == double_type_node)
782
    return 7;
783
  else if (type == byte_type_node)
784
    return 8;
785
  else if (type == short_type_node)
786
    return 9;
787
  else if (type == int_type_node)
788
    return 10;
789
  else if (type == long_type_node)
790
    return 11;
791
  else
792
    abort ();
793
}
794
 
795
/* Build a call to _Jv_ThrowBadArrayIndex(), the
796
   ArrayIndexOfBoundsException exception handler.  */
797
 
798
static tree
799
build_java_throw_out_of_bounds_exception (tree index)
800
{
801
  tree node = build3 (CALL_EXPR, int_type_node,
802
                      build_address_of (soft_badarrayindex_node),
803
                      build_tree_list (NULL_TREE, index), NULL_TREE);
804
  TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
805
  return (node);
806
}
807
 
808
/* Return the length of an array. Doesn't perform any checking on the nature
809
   or value of the array NODE. May be used to implement some bytecodes.  */
810
 
811
tree
812
build_java_array_length_access (tree node)
813
{
814
  tree type = TREE_TYPE (node);
815
  tree array_type = TREE_TYPE (type);
816
  HOST_WIDE_INT length;
817
 
818
  if (!is_array_type_p (type))
819
    {
820
      /* With the new verifier, we will see an ordinary pointer type
821
         here.  In this case, we just use an arbitrary array type.  */
822
      array_type = build_java_array_type (object_ptr_type_node, -1);
823
      type = promote_type (array_type);
824
    }
825
 
826
  length = java_array_type_length (type);
827
  if (length >= 0)
828
    return build_int_cst (NULL_TREE, length);
829
 
830
  node = build3 (COMPONENT_REF, int_type_node,
831
                 build_java_indirect_ref (array_type, node,
832
                                          flag_check_references),
833
                 lookup_field (&array_type, get_identifier ("length")),
834
                 NULL_TREE);
835
  IS_ARRAY_LENGTH_ACCESS (node) = 1;
836
  return node;
837
}
838
 
839
/* Optionally checks a reference against the NULL pointer.  ARG1: the
840
   expr, ARG2: we should check the reference.  Don't generate extra
841
   checks if we're not generating code.  */
842
 
843
tree
844
java_check_reference (tree expr, int check)
845
{
846
  if (!flag_syntax_only && check)
847
    {
848
      expr = save_expr (expr);
849
      expr = build3 (COND_EXPR, TREE_TYPE (expr),
850
                     build2 (EQ_EXPR, boolean_type_node,
851
                             expr, null_pointer_node),
852
                     build3 (CALL_EXPR, void_type_node,
853
                             build_address_of (soft_nullpointer_node),
854
                             NULL_TREE, NULL_TREE),
855
                     expr);
856
    }
857
 
858
  return expr;
859
}
860
 
861
/* Reference an object: just like an INDIRECT_REF, but with checking.  */
862
 
863
tree
864
build_java_indirect_ref (tree type, tree expr, int check)
865
{
866
  tree t;
867
  t = java_check_reference (expr, check);
868
  t = convert (build_pointer_type (type), t);
869
  return build1 (INDIRECT_REF, type, t);
870
}
871
 
872
/* Implement array indexing (either as l-value or r-value).
873
   Returns a tree for ARRAY[INDEX], assume TYPE is the element type.
874
   Optionally performs bounds checking and/or test to NULL.
875
   At this point, ARRAY should have been verified as an array.  */
876
 
877
tree
878
build_java_arrayaccess (tree array, tree type, tree index)
879
{
880
  tree node, throw = NULL_TREE;
881
  tree data_field;
882
  tree ref;
883
  tree array_type = TREE_TYPE (TREE_TYPE (array));
884
 
885
  if (!is_array_type_p (TREE_TYPE (array)))
886
    {
887
      /* With the new verifier, we will see an ordinary pointer type
888
         here.  In this case, we just use the correct array type.  */
889
      array_type = build_java_array_type (type, -1);
890
    }
891
 
892
  if (flag_bounds_check)
893
    {
894
      /* Generate:
895
       * (unsigned jint) INDEX >= (unsigned jint) LEN
896
       *    && throw ArrayIndexOutOfBoundsException.
897
       * Note this is equivalent to and more efficient than:
898
       * INDEX < 0 || INDEX >= LEN && throw ... */
899
      tree test;
900
      tree len = convert (unsigned_int_type_node,
901
                          build_java_array_length_access (array));
902
      test = fold_build2 (GE_EXPR, boolean_type_node,
903
                          convert (unsigned_int_type_node, index),
904
                          len);
905
      if (! integer_zerop (test))
906
        {
907
          throw = build2 (TRUTH_ANDIF_EXPR, int_type_node, test,
908
                          build_java_throw_out_of_bounds_exception (index));
909
          /* allows expansion within COMPOUND */
910
          TREE_SIDE_EFFECTS( throw ) = 1;
911
        }
912
    }
913
 
914
  /* If checking bounds, wrap the index expr with a COMPOUND_EXPR in order
915
     to have the bounds check evaluated first. */
916
  if (throw != NULL_TREE)
917
    index = build2 (COMPOUND_EXPR, int_type_node, throw, index);
918
 
919
  data_field = lookup_field (&array_type, get_identifier ("data"));
920
 
921
  ref = build3 (COMPONENT_REF, TREE_TYPE (data_field),
922
                build_java_indirect_ref (array_type, array,
923
                                         flag_check_references),
924
                data_field, NULL_TREE);
925
 
926
  node = build4 (ARRAY_REF, type, ref, index, NULL_TREE, NULL_TREE);
927
  return node;
928
}
929
 
930
/* Generate code to throw an ArrayStoreException if OBJECT is not assignable
931
   (at runtime) to an element of ARRAY.  A NOP_EXPR is returned if it can
932
   determine that no check is required. */
933
 
934
tree
935
build_java_arraystore_check (tree array, tree object)
936
{
937
  tree check, element_type, source;
938
  tree array_type_p = TREE_TYPE (array);
939
  tree object_type = TYPE_NAME (TREE_TYPE (TREE_TYPE (object)));
940
 
941
  if (! flag_verify_invocations)
942
    {
943
      /* With the new verifier, we don't track precise types.  FIXME:
944
         performance regression here.  */
945
      element_type = TYPE_NAME (object_type_node);
946
    }
947
  else
948
    {
949
      if (! is_array_type_p (array_type_p))
950
        abort ();
951
 
952
      /* Get the TYPE_DECL for ARRAY's element type. */
953
      element_type
954
        = TYPE_NAME (TREE_TYPE (TREE_TYPE (TREE_TYPE (array_type_p))));
955
    }
956
 
957
  if (TREE_CODE (element_type) != TYPE_DECL
958
      || TREE_CODE (object_type) != TYPE_DECL)
959
    abort ();
960
 
961
  if (!flag_store_check)
962
    return build1 (NOP_EXPR, array_type_p, array);
963
 
964
  /* No check is needed if the element type is final.  Also check that
965
     element_type matches object_type, since in the bytecode
966
     compilation case element_type may be the actual element type of
967
     the array rather than its declared type.  However, if we're doing
968
     indirect dispatch, we can't do the `final' optimization.  */
969
  if (element_type == object_type
970
      && ! flag_indirect_dispatch
971
      && CLASS_FINAL (element_type))
972
    return build1 (NOP_EXPR, array_type_p, array);
973
 
974
  /* OBJECT might be wrapped by a SAVE_EXPR. */
975
  if (TREE_CODE (object) == SAVE_EXPR)
976
    source = TREE_OPERAND (object, 0);
977
  else
978
    source = object;
979
 
980
  /* Avoid the check if OBJECT was just loaded from the same array. */
981
  if (TREE_CODE (source) == ARRAY_REF)
982
    {
983
      tree target;
984
      source = TREE_OPERAND (source, 0); /* COMPONENT_REF. */
985
      source = TREE_OPERAND (source, 0); /* INDIRECT_REF. */
986
      source = TREE_OPERAND (source, 0); /* Source array's DECL or SAVE_EXPR. */
987
      if (TREE_CODE (source) == SAVE_EXPR)
988
        source = TREE_OPERAND (source, 0);
989
 
990
      target = array;
991
      if (TREE_CODE (target) == SAVE_EXPR)
992
        target = TREE_OPERAND (target, 0);
993
 
994
      if (source == target)
995
        return build1 (NOP_EXPR, array_type_p, array);
996
    }
997
 
998
  /* Build an invocation of _Jv_CheckArrayStore */
999
  check = build3 (CALL_EXPR, void_type_node,
1000
                  build_address_of (soft_checkarraystore_node),
1001
                  tree_cons (NULL_TREE, array,
1002
                             build_tree_list (NULL_TREE, object)),
1003
                  NULL_TREE);
1004
  TREE_SIDE_EFFECTS (check) = 1;
1005
 
1006
  return check;
1007
}
1008
 
1009
/* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
1010
   ARRAY_NODE. This function is used to retrieve something less vague than
1011
   a pointer type when indexing the first dimension of something like [[<t>.
1012
   May return a corrected type, if necessary, otherwise INDEXED_TYPE is
1013
   return unchanged.  */
1014
 
1015
static tree
1016
build_java_check_indexed_type (tree array_node ATTRIBUTE_UNUSED,
1017
                               tree indexed_type)
1018
{
1019
  /* We used to check to see if ARRAY_NODE really had array type.
1020
     However, with the new verifier, this is not necessary, as we know
1021
     that the object will be an array of the appropriate type.  */
1022
 
1023
  return indexed_type;
1024
}
1025
 
1026
/* newarray triggers a call to _Jv_NewPrimArray. This function should be
1027
   called with an integer code (the type of array to create), and the length
1028
   of the array to create.  */
1029
 
1030
tree
1031
build_newarray (int atype_value, tree length)
1032
{
1033
  tree type_arg;
1034
 
1035
  tree prim_type = decode_newarray_type (atype_value);
1036
  tree type
1037
    = build_java_array_type (prim_type,
1038
                             host_integerp (length, 0) == INTEGER_CST
1039
                             ? tree_low_cst (length, 0) : -1);
1040
 
1041
  /* If compiling to native, pass a reference to the primitive type class
1042
     and save the runtime some work. However, the bytecode generator
1043
     expects to find the type_code int here. */
1044
  if (flag_emit_class_files)
1045
    type_arg = build_int_cst (NULL_TREE, atype_value);
1046
  else
1047
    type_arg = build_class_ref (prim_type);
1048
 
1049
  return build3 (CALL_EXPR, promote_type (type),
1050
                 build_address_of (soft_newarray_node),
1051
                 tree_cons (NULL_TREE,
1052
                            type_arg,
1053
                            build_tree_list (NULL_TREE, length)),
1054
                 NULL_TREE);
1055
}
1056
 
1057
/* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
1058
   of the dimension. */
1059
 
1060
tree
1061
build_anewarray (tree class_type, tree length)
1062
{
1063
  tree type
1064
    = build_java_array_type (class_type,
1065
                             host_integerp (length, 0)
1066
                             ? tree_low_cst (length, 0) : -1);
1067
 
1068
  return build3 (CALL_EXPR, promote_type (type),
1069
                 build_address_of (soft_anewarray_node),
1070
                 tree_cons (NULL_TREE, length,
1071
                            tree_cons (NULL_TREE, build_class_ref (class_type),
1072
                                       build_tree_list (NULL_TREE,
1073
                                                        null_pointer_node))),
1074
                 NULL_TREE);
1075
}
1076
 
1077
/* Return a node the evaluates 'new TYPE[LENGTH]'. */
1078
 
1079
tree
1080
build_new_array (tree type, tree length)
1081
{
1082
  if (JPRIMITIVE_TYPE_P (type))
1083
    return build_newarray (encode_newarray_type (type), length);
1084
  else
1085
    return build_anewarray (TREE_TYPE (type), length);
1086
}
1087
 
1088
/* Generates a call to _Jv_NewMultiArray. multianewarray expects a
1089
   class pointer, a number of dimensions and the matching number of
1090
   dimensions. The argument list is NULL terminated.  */
1091
 
1092
static void
1093
expand_java_multianewarray (tree class_type, int ndim)
1094
{
1095
  int i;
1096
  tree args = build_tree_list( NULL_TREE, null_pointer_node );
1097
 
1098
  for( i = 0; i < ndim; i++ )
1099
    args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
1100
 
1101
  push_value (build3 (CALL_EXPR,
1102
                      promote_type (class_type),
1103
                      build_address_of (soft_multianewarray_node),
1104
                      tree_cons (NULL_TREE, build_class_ref (class_type),
1105
                                 tree_cons (NULL_TREE,
1106
                                            build_int_cst (NULL_TREE, ndim),
1107
                                            args)),
1108
                      NULL_TREE));
1109
}
1110
 
1111
/*  ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
1112
    ARRAY is an array type. May expand some bound checking and NULL
1113
    pointer checking. RHS_TYPE_NODE we are going to store. In the case
1114
    of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
1115
    INT. In those cases, we make the conversion.
1116
 
1117
    if ARRAy is a reference type, the assignment is checked at run-time
1118
    to make sure that the RHS can be assigned to the array element
1119
    type. It is not necessary to generate this code if ARRAY is final.  */
1120
 
1121
static void
1122
expand_java_arraystore (tree rhs_type_node)
1123
{
1124
  tree rhs_node    = pop_value ((INTEGRAL_TYPE_P (rhs_type_node)
1125
                                 && TYPE_PRECISION (rhs_type_node) <= 32) ?
1126
                                 int_type_node : rhs_type_node);
1127
  tree index = pop_value (int_type_node);
1128
  tree array_type, array;
1129
 
1130
  /* If we're processing an `aaload' we might as well just pick
1131
     `Object'.  */
1132
  if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
1133
    {
1134
      array_type = build_java_array_type (object_ptr_type_node, -1);
1135
      rhs_type_node = object_ptr_type_node;
1136
    }
1137
  else
1138
    array_type = build_java_array_type (rhs_type_node, -1);
1139
 
1140
  array = pop_value (array_type);
1141
  array = build1 (NOP_EXPR, promote_type (array_type), array);
1142
 
1143
  rhs_type_node    = build_java_check_indexed_type (array, rhs_type_node);
1144
 
1145
  flush_quick_stack ();
1146
 
1147
  index = save_expr (index);
1148
  array = save_expr (array);
1149
 
1150
  if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
1151
    {
1152
      tree check = build_java_arraystore_check (array, rhs_node);
1153
      java_add_stmt (check);
1154
    }
1155
 
1156
  array = build_java_arrayaccess (array, rhs_type_node, index);
1157
  java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (array), array, rhs_node));
1158
}
1159
 
1160
/* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes
1161
   sure that LHS is an array type. May expand some bound checking and NULL
1162
   pointer checking.
1163
   LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
1164
   BOOLEAN/SHORT, we push a promoted type back to the stack.
1165
*/
1166
 
1167
static void
1168
expand_java_arrayload (tree lhs_type_node)
1169
{
1170
  tree load_node;
1171
  tree index_node = pop_value (int_type_node);
1172
  tree array_type;
1173
  tree array_node;
1174
 
1175
  /* If we're processing an `aaload' we might as well just pick
1176
     `Object'.  */
1177
  if (TREE_CODE (lhs_type_node) == POINTER_TYPE)
1178
    {
1179
      array_type = build_java_array_type (object_ptr_type_node, -1);
1180
      lhs_type_node = object_ptr_type_node;
1181
    }
1182
  else
1183
    array_type = build_java_array_type (lhs_type_node, -1);
1184
  array_node = pop_value (array_type);
1185
  array_node = build1 (NOP_EXPR, promote_type (array_type), array_node);
1186
 
1187
  index_node = save_expr (index_node);
1188
  array_node = save_expr (array_node);
1189
 
1190
  lhs_type_node = build_java_check_indexed_type (array_node,
1191
                                                 lhs_type_node);
1192
  load_node = build_java_arrayaccess (array_node,
1193
                                      lhs_type_node,
1194
                                      index_node);
1195
  if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
1196
    load_node = fold_build1 (NOP_EXPR, int_type_node, load_node);
1197
  push_value (load_node);
1198
}
1199
 
1200
/* Expands .length. Makes sure that we deal with and array and may expand
1201
   a NULL check on the array object.  */
1202
 
1203
static void
1204
expand_java_array_length (void)
1205
{
1206
  tree array  = pop_value (ptr_type_node);
1207
  tree length = build_java_array_length_access (array);
1208
 
1209
  push_value (length);
1210
}
1211
 
1212
/* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
1213
   either soft_monitorenter_node or soft_monitorexit_node.  */
1214
 
1215
static tree
1216
build_java_monitor (tree call, tree object)
1217
{
1218
  return build3 (CALL_EXPR,
1219
                 void_type_node,
1220
                 build_address_of (call),
1221
                 build_tree_list (NULL_TREE, object),
1222
                 NULL_TREE);
1223
}
1224
 
1225
/* Emit code for one of the PUSHC instructions. */
1226
 
1227
static void
1228
expand_java_pushc (int ival, tree type)
1229
{
1230
  tree value;
1231
  if (type == ptr_type_node && ival == 0)
1232
    value = null_pointer_node;
1233
  else if (type == int_type_node || type == long_type_node)
1234
    value = build_int_cst (type, ival);
1235
  else if (type == float_type_node || type == double_type_node)
1236
    {
1237
      REAL_VALUE_TYPE x;
1238
      REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
1239
      value = build_real (type, x);
1240
    }
1241
  else
1242
    abort ();
1243
 
1244
  push_value (value);
1245
}
1246
 
1247
static void
1248
expand_java_return (tree type)
1249
{
1250
  if (type == void_type_node)
1251
    java_add_stmt (build1 (RETURN_EXPR, void_type_node, NULL));
1252
  else
1253
    {
1254
      tree retval = pop_value (type);
1255
      tree res = DECL_RESULT (current_function_decl);
1256
      retval = build2 (MODIFY_EXPR, TREE_TYPE (res), res, retval);
1257
 
1258
      /* Handle the situation where the native integer type is smaller
1259
         than the JVM integer. It can happen for many cross compilers.
1260
         The whole if expression just goes away if INT_TYPE_SIZE < 32
1261
         is false. */
1262
      if (INT_TYPE_SIZE < 32
1263
          && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (res)))
1264
              < GET_MODE_SIZE (TYPE_MODE (type))))
1265
        retval = build1(NOP_EXPR, TREE_TYPE(res), retval);
1266
 
1267
      TREE_SIDE_EFFECTS (retval) = 1;
1268
      java_add_stmt (build1 (RETURN_EXPR, TREE_TYPE (retval), retval));
1269
    }
1270
}
1271
 
1272
static void
1273
expand_load_internal (int index, tree type, int pc)
1274
{
1275
  tree copy;
1276
  tree var = find_local_variable (index, type, pc);
1277
 
1278
  /* Now VAR is the VAR_DECL (or PARM_DECL) that we are going to push
1279
     on the stack.  If there is an assignment to this VAR_DECL between
1280
     the stack push and the use, then the wrong code could be
1281
     generated.  To avoid this we create a new local and copy our
1282
     value into it.  Then we push this new local on the stack.
1283
     Hopefully this all gets optimized out.  */
1284
  copy = build_decl (VAR_DECL, NULL_TREE, type);
1285
  if ((INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
1286
      && TREE_TYPE (copy) != TREE_TYPE (var))
1287
    var = convert (type, var);
1288
  java_add_local_var (copy);
1289
  java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (var), copy, var));
1290
 
1291
  push_value (copy);
1292
}
1293
 
1294
tree
1295
build_address_of (tree value)
1296
{
1297
  return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
1298
}
1299
 
1300
bool
1301
class_has_finalize_method (tree type)
1302
{
1303
  tree super = CLASSTYPE_SUPER (type);
1304
 
1305
  if (super == NULL_TREE)
1306
    return false;       /* Every class with a real finalizer inherits   */
1307
                        /* from java.lang.Object.                       */
1308
  else
1309
    return HAS_FINALIZER_P (type) || class_has_finalize_method (super);
1310
}
1311
 
1312
tree
1313
java_create_object (tree type)
1314
{
1315
  tree alloc_node = (class_has_finalize_method (type)
1316
                     ? alloc_object_node
1317
                     : alloc_no_finalizer_node);
1318
 
1319
  return build (CALL_EXPR, promote_type (type),
1320
                build_address_of (alloc_node),
1321
                build_tree_list (NULL_TREE, build_class_ref (type)),
1322
                NULL_TREE);
1323
}
1324
 
1325
static void
1326
expand_java_NEW (tree type)
1327
{
1328
  tree alloc_node;
1329
 
1330
  alloc_node = (class_has_finalize_method (type) ? alloc_object_node
1331
                                                 : alloc_no_finalizer_node);
1332
  if (! CLASS_LOADED_P (type))
1333
    load_class (type, 1);
1334
  safe_layout_class (type);
1335
  push_value (build3 (CALL_EXPR, promote_type (type),
1336
                      build_address_of (alloc_node),
1337
                      build_tree_list (NULL_TREE, build_class_ref (type)),
1338
                      NULL_TREE));
1339
}
1340
 
1341
/* This returns an expression which will extract the class of an
1342
   object.  */
1343
 
1344
tree
1345
build_get_class (tree value)
1346
{
1347
  tree class_field = lookup_field (&dtable_type, get_identifier ("class"));
1348
  tree vtable_field = lookup_field (&object_type_node,
1349
                                    get_identifier ("vtable"));
1350
  tree tmp = build3 (COMPONENT_REF, dtable_ptr_type,
1351
                     build_java_indirect_ref (object_type_node, value,
1352
                                              flag_check_references),
1353
                     vtable_field, NULL_TREE);
1354
  return build3 (COMPONENT_REF, class_ptr_type,
1355
                 build1 (INDIRECT_REF, dtable_type, tmp),
1356
                 class_field, NULL_TREE);
1357
}
1358
 
1359
/* This builds the tree representation of the `instanceof' operator.
1360
   It tries various tricks to optimize this in cases where types are
1361
   known.  */
1362
 
1363
tree
1364
build_instanceof (tree value, tree type)
1365
{
1366
  tree expr;
1367
  tree itype = TREE_TYPE (TREE_TYPE (soft_instanceof_node));
1368
  tree valtype = TREE_TYPE (TREE_TYPE (value));
1369
  tree valclass = TYPE_NAME (valtype);
1370
  tree klass;
1371
 
1372
  /* When compiling from bytecode, we need to ensure that TYPE has
1373
     been loaded.  */
1374
  if (CLASS_P (type) && ! CLASS_LOADED_P (type))
1375
    {
1376
      load_class (type, 1);
1377
      safe_layout_class (type);
1378
      if (! TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) == ERROR_MARK)
1379
        return error_mark_node;
1380
    }
1381
  klass = TYPE_NAME (type);
1382
 
1383
  if (type == object_type_node || inherits_from_p (valtype, type))
1384
    {
1385
      /* Anything except `null' is an instance of Object.  Likewise,
1386
         if the object is known to be an instance of the class, then
1387
         we only need to check for `null'.  */
1388
      expr = build2 (NE_EXPR, itype, value, null_pointer_node);
1389
    }
1390
  else if (flag_verify_invocations
1391
           && ! TYPE_ARRAY_P (type)
1392
           && ! TYPE_ARRAY_P (valtype)
1393
           && DECL_P (klass) && DECL_P (valclass)
1394
           && ! CLASS_INTERFACE (valclass)
1395
           && ! CLASS_INTERFACE (klass)
1396
           && ! inherits_from_p (type, valtype)
1397
           && (CLASS_FINAL (klass)
1398
               || ! inherits_from_p (valtype, type)))
1399
    {
1400
      /* The classes are from different branches of the derivation
1401
         tree, so we immediately know the answer.  */
1402
      expr = boolean_false_node;
1403
    }
1404
  else if (DECL_P (klass) && CLASS_FINAL (klass))
1405
    {
1406
      tree save = save_expr (value);
1407
      expr = build3 (COND_EXPR, itype,
1408
                     build2 (NE_EXPR, boolean_type_node,
1409
                             save, null_pointer_node),
1410
                     build2 (EQ_EXPR, itype,
1411
                             build_get_class (save),
1412
                             build_class_ref (type)),
1413
                     boolean_false_node);
1414
    }
1415
  else
1416
    {
1417
      expr = build3 (CALL_EXPR, itype,
1418
                     build_address_of (soft_instanceof_node),
1419
                     tree_cons (NULL_TREE, value,
1420
                                build_tree_list (NULL_TREE,
1421
                                                 build_class_ref (type))),
1422
                     NULL_TREE);
1423
    }
1424
  TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (value);
1425
  return expr;
1426
}
1427
 
1428
static void
1429
expand_java_INSTANCEOF (tree type)
1430
{
1431
  tree value = pop_value (object_ptr_type_node);
1432
  value = build_instanceof (value, type);
1433
  push_value (value);
1434
}
1435
 
1436
static void
1437
expand_java_CHECKCAST (tree type)
1438
{
1439
  tree value = pop_value (ptr_type_node);
1440
  value = build3 (CALL_EXPR, promote_type (type),
1441
                  build_address_of (soft_checkcast_node),
1442
                  tree_cons (NULL_TREE, build_class_ref (type),
1443
                             build_tree_list (NULL_TREE, value)),
1444
                  NULL_TREE);
1445
  push_value (value);
1446
}
1447
 
1448
static void
1449
expand_iinc (unsigned int local_var_index, int ival, int pc)
1450
{
1451
  tree local_var, res;
1452
  tree constant_value;
1453
 
1454
  flush_quick_stack ();
1455
  local_var = find_local_variable (local_var_index, int_type_node, pc);
1456
  constant_value = build_int_cst (NULL_TREE, ival);
1457
  res = fold_build2 (PLUS_EXPR, int_type_node, local_var, constant_value);
1458
  java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (local_var), local_var, res));
1459
  update_aliases (local_var, local_var_index, pc);
1460
}
1461
 
1462
 
1463
tree
1464
build_java_soft_divmod (enum tree_code op, tree type, tree op1, tree op2)
1465
{
1466
  tree call = NULL;
1467
  tree arg1 = convert (type, op1);
1468
  tree arg2 = convert (type, op2);
1469
 
1470
  if (type == int_type_node)
1471
    {
1472
      switch (op)
1473
        {
1474
        case TRUNC_DIV_EXPR:
1475
          call = soft_idiv_node;
1476
          break;
1477
        case TRUNC_MOD_EXPR:
1478
          call = soft_irem_node;
1479
          break;
1480
        default:
1481
          break;
1482
        }
1483
    }
1484
  else if (type == long_type_node)
1485
    {
1486
      switch (op)
1487
        {
1488
        case TRUNC_DIV_EXPR:
1489
          call = soft_ldiv_node;
1490
          break;
1491
        case TRUNC_MOD_EXPR:
1492
          call = soft_lrem_node;
1493
          break;
1494
        default:
1495
          break;
1496
        }
1497
    }
1498
 
1499
  if (! call)
1500
    abort ();
1501
 
1502
  call = build3 (CALL_EXPR, type,
1503
                 build_address_of (call),
1504
                 tree_cons (NULL_TREE, arg1,
1505
                            build_tree_list (NULL_TREE, arg2)),
1506
                 NULL_TREE);
1507
 
1508
  return call;
1509
}
1510
 
1511
tree
1512
build_java_binop (enum tree_code op, tree type, tree arg1, tree arg2)
1513
{
1514
  tree mask;
1515
  switch (op)
1516
    {
1517
    case URSHIFT_EXPR:
1518
      {
1519
        tree u_type = java_unsigned_type (type);
1520
        arg1 = convert (u_type, arg1);
1521
        arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1522
        return convert (type, arg1);
1523
      }
1524
    case LSHIFT_EXPR:
1525
    case RSHIFT_EXPR:
1526
      mask = build_int_cst (NULL_TREE,
1527
                            TYPE_PRECISION (TREE_TYPE (arg1)) - 1);
1528
      arg2 = fold_build2 (BIT_AND_EXPR, int_type_node, arg2, mask);
1529
      break;
1530
 
1531
    case COMPARE_L_EXPR:  /* arg1 > arg2 ?  1 : arg1 == arg2 ? 0 : -1 */
1532
    case COMPARE_G_EXPR:  /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 :  1 */
1533
      arg1 = save_expr (arg1);  arg2 = save_expr (arg2);
1534
      {
1535
        tree ifexp1 = fold_build2 (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1536
                                   boolean_type_node, arg1, arg2);
1537
        tree ifexp2 = fold_build2 (EQ_EXPR, boolean_type_node, arg1, arg2);
1538
        tree second_compare = fold_build3 (COND_EXPR, int_type_node,
1539
                                           ifexp2, integer_zero_node,
1540
                                           op == COMPARE_L_EXPR
1541
                                           ? integer_minus_one_node
1542
                                           : integer_one_node);
1543
        return fold_build3 (COND_EXPR, int_type_node, ifexp1,
1544
                            op == COMPARE_L_EXPR ? integer_one_node
1545
                            : integer_minus_one_node,
1546
                            second_compare);
1547
      }
1548
    case COMPARE_EXPR:
1549
      arg1 = save_expr (arg1);  arg2 = save_expr (arg2);
1550
      {
1551
        tree ifexp1 = fold_build2 (LT_EXPR, boolean_type_node, arg1, arg2);
1552
        tree ifexp2 = fold_build2 (GT_EXPR, boolean_type_node, arg1, arg2);
1553
        tree second_compare = fold_build3 (COND_EXPR, int_type_node,
1554
                                           ifexp2, integer_one_node,
1555
                                           integer_zero_node);
1556
        return fold_build3 (COND_EXPR, int_type_node,
1557
                            ifexp1, integer_minus_one_node, second_compare);
1558
      }
1559
    case TRUNC_DIV_EXPR:
1560
    case TRUNC_MOD_EXPR:
1561
      if (TREE_CODE (type) == REAL_TYPE
1562
          && op == TRUNC_MOD_EXPR)
1563
        {
1564
          tree call;
1565
          if (type != double_type_node)
1566
            {
1567
              arg1 = convert (double_type_node, arg1);
1568
              arg2 = convert (double_type_node, arg2);
1569
            }
1570
          call = build3 (CALL_EXPR, double_type_node,
1571
                         build_address_of (soft_fmod_node),
1572
                         tree_cons (NULL_TREE, arg1,
1573
                                    build_tree_list (NULL_TREE, arg2)),
1574
                         NULL_TREE);
1575
          if (type != double_type_node)
1576
            call = convert (type, call);
1577
          return call;
1578
        }
1579
 
1580
      if (TREE_CODE (type) == INTEGER_TYPE
1581
          && flag_use_divide_subroutine
1582
          && ! flag_syntax_only)
1583
        return build_java_soft_divmod (op, type, arg1, arg2);
1584
 
1585
      break;
1586
    default:  ;
1587
    }
1588
  return fold_build2 (op, type, arg1, arg2);
1589
}
1590
 
1591
static void
1592
expand_java_binop (tree type, enum tree_code op)
1593
{
1594
  tree larg, rarg;
1595
  tree ltype = type;
1596
  tree rtype = type;
1597
  switch (op)
1598
    {
1599
    case LSHIFT_EXPR:
1600
    case RSHIFT_EXPR:
1601
    case URSHIFT_EXPR:
1602
      rtype = int_type_node;
1603
      rarg = pop_value (rtype);
1604
      break;
1605
    default:
1606
      rarg = pop_value (rtype);
1607
    }
1608
  larg = pop_value (ltype);
1609
  push_value (build_java_binop (op, type, larg, rarg));
1610
}
1611
 
1612
/* Lookup the field named NAME in *TYPEP or its super classes.
1613
   If not found, return NULL_TREE.
1614
   (If the *TYPEP is not found, or if the field reference is
1615
   ambiguous, return error_mark_node.)
1616
   If found, return the FIELD_DECL, and set *TYPEP to the
1617
   class containing the field. */
1618
 
1619
tree
1620
lookup_field (tree *typep, tree name)
1621
{
1622
  if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1623
    {
1624
      load_class (*typep, 1);
1625
      safe_layout_class (*typep);
1626
      if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1627
        return error_mark_node;
1628
    }
1629
  do
1630
    {
1631
      tree field, binfo, base_binfo;
1632
      tree save_field;
1633
      int i;
1634
 
1635
      for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1636
        if (DECL_NAME (field) == name)
1637
          return field;
1638
 
1639
      /* Process implemented interfaces. */
1640
      save_field = NULL_TREE;
1641
      for (binfo = TYPE_BINFO (*typep), i = 0;
1642
           BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
1643
        {
1644
          tree t = BINFO_TYPE (base_binfo);
1645
          if ((field = lookup_field (&t, name)))
1646
            {
1647
              if (save_field == field)
1648
                continue;
1649
              if (save_field == NULL_TREE)
1650
                save_field = field;
1651
              else
1652
                {
1653
                  tree i1 = DECL_CONTEXT (save_field);
1654
                  tree i2 = DECL_CONTEXT (field);
1655
                  error ("reference %qs is ambiguous: appears in interface %qs and interface %qs",
1656
                         IDENTIFIER_POINTER (name),
1657
                         IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i1))),
1658
                         IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i2))));
1659
                  return error_mark_node;
1660
                }
1661
            }
1662
        }
1663
 
1664
      if (save_field != NULL_TREE)
1665
        return save_field;
1666
 
1667
      *typep = CLASSTYPE_SUPER (*typep);
1668
    } while (*typep);
1669
  return NULL_TREE;
1670
}
1671
 
1672
/* Look up the field named NAME in object SELF_VALUE,
1673
   which has class SELF_CLASS (a non-handle RECORD_TYPE).
1674
   SELF_VALUE is NULL_TREE if looking for a static field. */
1675
 
1676
tree
1677
build_field_ref (tree self_value, tree self_class, tree name)
1678
{
1679
  tree base_class = self_class;
1680
  tree field_decl = lookup_field (&base_class, name);
1681
  if (field_decl == NULL_TREE)
1682
    {
1683
      error ("field %qs not found", IDENTIFIER_POINTER (name));
1684
      return error_mark_node;
1685
    }
1686
  if (self_value == NULL_TREE)
1687
    {
1688
      return build_static_field_ref (field_decl);
1689
    }
1690
  else
1691
    {
1692
      tree base_type = promote_type (base_class);
1693
 
1694
      /* CHECK is true if self_value is not the this pointer.  */
1695
      int check = (! (DECL_P (self_value)
1696
                      && DECL_NAME (self_value) == this_identifier_node));
1697
 
1698
      /* Determine whether a field offset from NULL will lie within
1699
         Page 0: this is necessary on those GNU/Linux/BSD systems that
1700
         trap SEGV to generate NullPointerExceptions.
1701
 
1702
         We assume that Page 0 will be mapped with NOPERM, and that
1703
         memory may be allocated from any other page, so only field
1704
         offsets < pagesize are guaratneed to trap.  We also assume
1705
         the smallest page size we'll encounter is 4k bytes.  */
1706
      if (! flag_syntax_only && check && ! flag_check_references
1707
          && ! flag_indirect_dispatch)
1708
        {
1709
          tree field_offset = byte_position (field_decl);
1710
          if (! page_size)
1711
            page_size = size_int (4096);
1712
          check = ! INT_CST_LT_UNSIGNED (field_offset, page_size);
1713
        }
1714
 
1715
      if (base_type != TREE_TYPE (self_value))
1716
        self_value = fold_build1 (NOP_EXPR, base_type, self_value);
1717
      if (! flag_syntax_only && flag_indirect_dispatch)
1718
        {
1719
          tree otable_index
1720
            = build_int_cst (NULL_TREE, get_symbol_table_index
1721
                             (field_decl, &TYPE_OTABLE_METHODS (output_class)));
1722
          tree field_offset
1723
            = build4 (ARRAY_REF, integer_type_node,
1724
                      TYPE_OTABLE_DECL (output_class), otable_index,
1725
                      NULL_TREE, NULL_TREE);
1726
          tree address;
1727
 
1728
          if (DECL_CONTEXT (field_decl) != output_class)
1729
            field_offset
1730
              = build3 (COND_EXPR, TREE_TYPE (field_offset),
1731
                        build2 (EQ_EXPR, boolean_type_node,
1732
                                field_offset, integer_zero_node),
1733
                        build3 (CALL_EXPR, void_type_node,
1734
                                build_address_of (soft_nosuchfield_node),
1735
                                build_tree_list (NULL_TREE, otable_index),
1736
                                NULL_TREE),
1737
                        field_offset);
1738
 
1739
          field_offset = fold (convert (sizetype, field_offset));
1740
          self_value = java_check_reference (self_value, check);
1741
          address
1742
            = fold_build2 (PLUS_EXPR,
1743
                           build_pointer_type (TREE_TYPE (field_decl)),
1744
                           self_value, field_offset);
1745
          return fold_build1 (INDIRECT_REF, TREE_TYPE (field_decl), address);
1746
        }
1747
 
1748
      self_value = build_java_indirect_ref (TREE_TYPE (TREE_TYPE (self_value)),
1749
                                            self_value, check);
1750
      return fold_build3 (COMPONENT_REF, TREE_TYPE (field_decl),
1751
                          self_value, field_decl, NULL_TREE);
1752
    }
1753
}
1754
 
1755
tree
1756
lookup_label (int pc)
1757
{
1758
  tree name;
1759
  char buf[32];
1760
  if (pc > highest_label_pc_this_method)
1761
    highest_label_pc_this_method = pc;
1762
  ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", start_label_pc_this_method + pc);
1763
  name = get_identifier (buf);
1764
  if (IDENTIFIER_LOCAL_VALUE (name))
1765
    return IDENTIFIER_LOCAL_VALUE (name);
1766
  else
1767
    {
1768
      /* The type of the address of a label is return_address_type_node. */
1769
      tree decl = create_label_decl (name);
1770
      LABEL_PC (decl) = pc;
1771
      return pushdecl (decl);
1772
    }
1773
}
1774
 
1775
/* Generate a unique name for the purpose of loops and switches
1776
   labels, and try-catch-finally blocks label or temporary variables.  */
1777
 
1778
tree
1779
generate_name (void)
1780
{
1781
  static int l_number = 0;
1782
  char buff [32];
1783
  ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
1784
  l_number++;
1785
  return get_identifier (buff);
1786
}
1787
 
1788
tree
1789
create_label_decl (tree name)
1790
{
1791
  tree decl;
1792
  decl = build_decl (LABEL_DECL, name,
1793
                     TREE_TYPE (return_address_type_node));
1794
  DECL_CONTEXT (decl) = current_function_decl;
1795
  DECL_IGNORED_P (decl) = 1;
1796
  return decl;
1797
}
1798
 
1799
/* This maps a bytecode offset (PC) to various flags. */
1800
char *instruction_bits;
1801
 
1802
static void
1803
note_label (int current_pc ATTRIBUTE_UNUSED, int target_pc)
1804
{
1805
  lookup_label (target_pc);
1806
  instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1807
}
1808
 
1809
/* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1810
   where CONDITION is one of one the compare operators. */
1811
 
1812
static void
1813
expand_compare (enum tree_code condition, tree value1, tree value2,
1814
                int target_pc)
1815
{
1816
  tree target = lookup_label (target_pc);
1817
  tree cond = fold_build2 (condition, boolean_type_node, value1, value2);
1818
  java_add_stmt
1819
    (build3 (COND_EXPR, void_type_node, java_truthvalue_conversion (cond),
1820
             build1 (GOTO_EXPR, void_type_node, target),
1821
             build_java_empty_stmt ()));
1822
}
1823
 
1824
/* Emit code for a TEST-type opcode. */
1825
 
1826
static void
1827
expand_test (enum tree_code condition, tree type, int target_pc)
1828
{
1829
  tree value1, value2;
1830
  flush_quick_stack ();
1831
  value1 = pop_value (type);
1832
  value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1833
  expand_compare (condition, value1, value2, target_pc);
1834
}
1835
 
1836
/* Emit code for a COND-type opcode. */
1837
 
1838
static void
1839
expand_cond (enum tree_code condition, tree type, int target_pc)
1840
{
1841
  tree value1, value2;
1842
  flush_quick_stack ();
1843
  /* note: pop values in opposite order */
1844
  value2 = pop_value (type);
1845
  value1 = pop_value (type);
1846
  /* Maybe should check value1 and value2 for type compatibility ??? */
1847
  expand_compare (condition, value1, value2, target_pc);
1848
}
1849
 
1850
static void
1851
expand_java_goto (int target_pc)
1852
{
1853
  tree target_label = lookup_label (target_pc);
1854
  flush_quick_stack ();
1855
  java_add_stmt (build1 (GOTO_EXPR, void_type_node, target_label));
1856
}
1857
 
1858
static tree
1859
expand_java_switch (tree selector, int default_pc)
1860
{
1861
  tree switch_expr, x;
1862
 
1863
  flush_quick_stack ();
1864
  switch_expr = build3 (SWITCH_EXPR, TREE_TYPE (selector), selector,
1865
                        NULL_TREE, NULL_TREE);
1866
  java_add_stmt (switch_expr);
1867
 
1868
  x = build3 (CASE_LABEL_EXPR, void_type_node, NULL_TREE, NULL_TREE,
1869
              create_artificial_label ());
1870
  append_to_statement_list (x, &SWITCH_BODY (switch_expr));
1871
 
1872
  x = build1 (GOTO_EXPR, void_type_node, lookup_label (default_pc));
1873
  append_to_statement_list (x, &SWITCH_BODY (switch_expr));
1874
 
1875
  return switch_expr;
1876
}
1877
 
1878
static void
1879
expand_java_add_case (tree switch_expr, int match, int target_pc)
1880
{
1881
  tree value, x;
1882
 
1883
  value = build_int_cst (TREE_TYPE (switch_expr), match);
1884
 
1885
  x = build3 (CASE_LABEL_EXPR, void_type_node, value, NULL_TREE,
1886
              create_artificial_label ());
1887
  append_to_statement_list (x, &SWITCH_BODY (switch_expr));
1888
 
1889
  x = build1 (GOTO_EXPR, void_type_node, lookup_label (target_pc));
1890
  append_to_statement_list (x, &SWITCH_BODY (switch_expr));
1891
}
1892
 
1893
static tree
1894
pop_arguments (tree arg_types)
1895
{
1896
  if (arg_types == end_params_node)
1897
    return NULL_TREE;
1898
  if (TREE_CODE (arg_types) == TREE_LIST)
1899
    {
1900
      tree tail = pop_arguments (TREE_CHAIN (arg_types));
1901
      tree type = TREE_VALUE (arg_types);
1902
      tree arg = pop_value (type);
1903
 
1904
      /* We simply cast each argument to its proper type.  This is
1905
         needed since we lose type information coming out of the
1906
         verifier.  We also have to do this when we pop an integer
1907
         type that must be promoted for the function call.  */
1908
      if (TREE_CODE (type) == POINTER_TYPE)
1909
        arg = build1 (NOP_EXPR, type, arg);
1910
      else if (targetm.calls.promote_prototypes (type)
1911
               && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1912
               && INTEGRAL_TYPE_P (type))
1913
        arg = convert (integer_type_node, arg);
1914
      return tree_cons (NULL_TREE, arg, tail);
1915
    }
1916
  abort ();
1917
}
1918
 
1919
/* Attach to PTR (a block) the declaration found in ENTRY. */
1920
 
1921
int
1922
attach_init_test_initialization_flags (void **entry, void *ptr)
1923
{
1924
  tree block = (tree)ptr;
1925
  struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
1926
 
1927
  if (block != error_mark_node)
1928
    {
1929
      if (TREE_CODE (block) == BIND_EXPR)
1930
        {
1931
          tree body = BIND_EXPR_BODY (block);
1932
          TREE_CHAIN (ite->value) = BIND_EXPR_VARS (block);
1933
          BIND_EXPR_VARS (block) = ite->value;
1934
          body = build2 (COMPOUND_EXPR, void_type_node,
1935
                         build1 (DECL_EXPR, void_type_node, ite->value), body);
1936
          BIND_EXPR_BODY (block) = body;
1937
        }
1938
      else
1939
        {
1940
          tree body = BLOCK_SUBBLOCKS (block);
1941
          TREE_CHAIN (ite->value) = BLOCK_EXPR_DECLS (block);
1942
          BLOCK_EXPR_DECLS (block) = ite->value;
1943
          body = build2 (COMPOUND_EXPR, void_type_node,
1944
                         build1 (DECL_EXPR, void_type_node, ite->value), body);
1945
          BLOCK_SUBBLOCKS (block) = body;
1946
        }
1947
 
1948
    }
1949
  return true;
1950
}
1951
 
1952
/* Build an expression to initialize the class CLAS.
1953
   if EXPR is non-NULL, returns an expression to first call the initializer
1954
   (if it is needed) and then calls EXPR. */
1955
 
1956
tree
1957
build_class_init (tree clas, tree expr)
1958
{
1959
  tree init;
1960
 
1961
  /* An optimization: if CLAS is a superclass of the class we're
1962
     compiling, we don't need to initialize it.  However, if CLAS is
1963
     an interface, it won't necessarily be initialized, even if we
1964
     implement it.  */
1965
  if ((! CLASS_INTERFACE (TYPE_NAME (clas))
1966
       && inherits_from_p (current_class, clas))
1967
      || current_class == clas)
1968
    return expr;
1969
 
1970
  if (always_initialize_class_p)
1971
    {
1972
      init = build3 (CALL_EXPR, void_type_node,
1973
                     build_address_of (soft_initclass_node),
1974
                     build_tree_list (NULL_TREE, build_class_ref (clas)),
1975
                     NULL_TREE);
1976
      TREE_SIDE_EFFECTS (init) = 1;
1977
    }
1978
  else
1979
    {
1980
      tree *init_test_decl;
1981
      tree decl;
1982
      init_test_decl = java_treetreehash_new
1983
        (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl), clas);
1984
 
1985
      if (*init_test_decl == NULL)
1986
        {
1987
          /* Build a declaration and mark it as a flag used to track
1988
             static class initializations. */
1989
          decl = build_decl (VAR_DECL, NULL_TREE,
1990
                             boolean_type_node);
1991
          MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
1992
          LOCAL_CLASS_INITIALIZATION_FLAG (decl) = 1;
1993
          DECL_CONTEXT (decl) = current_function_decl;
1994
          DECL_FUNCTION_INIT_TEST_CLASS (decl) = clas;
1995
          /* Tell the check-init code to ignore this decl when not
1996
             optimizing class initialization. */
1997
          if (!STATIC_CLASS_INIT_OPT_P ())
1998
            DECL_BIT_INDEX (decl) = -1;
1999
          DECL_INITIAL (decl) = boolean_false_node;
2000
          /* Don't emit any symbolic debugging info for this decl.  */
2001
          DECL_IGNORED_P (decl) = 1;
2002
          *init_test_decl = decl;
2003
        }
2004
 
2005
      init = build3 (CALL_EXPR, void_type_node,
2006
                     build_address_of (soft_initclass_node),
2007
                     build_tree_list (NULL_TREE, build_class_ref (clas)),
2008
                     NULL_TREE);
2009
      TREE_SIDE_EFFECTS (init) = 1;
2010
      init = build3 (COND_EXPR, void_type_node,
2011
                     build2 (EQ_EXPR, boolean_type_node,
2012
                             *init_test_decl, boolean_false_node),
2013
                     init, integer_zero_node);
2014
      TREE_SIDE_EFFECTS (init) = 1;
2015
      init = build2 (COMPOUND_EXPR, TREE_TYPE (expr), init,
2016
                     build2 (MODIFY_EXPR, boolean_type_node,
2017
                             *init_test_decl, boolean_true_node));
2018
      TREE_SIDE_EFFECTS (init) = 1;
2019
    }
2020
 
2021
  if (expr != NULL_TREE)
2022
    {
2023
      expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
2024
      TREE_SIDE_EFFECTS (expr) = 1;
2025
      return expr;
2026
    }
2027
  return init;
2028
}
2029
 
2030
tree
2031
build_known_method_ref (tree method, tree method_type ATTRIBUTE_UNUSED,
2032
                        tree self_type, tree method_signature ATTRIBUTE_UNUSED,
2033
                        tree arg_list ATTRIBUTE_UNUSED)
2034
{
2035
  tree func;
2036
  if (is_compiled_class (self_type))
2037
    {
2038
      /* With indirect dispatch we have to use indirect calls for all
2039
         publicly visible methods or gcc will use PLT indirections
2040
         to reach them.  We also have to use indirect dispatch for all
2041
         external methods.  */
2042
      if (! flag_indirect_dispatch
2043
          || (! DECL_EXTERNAL (method) && ! TREE_PUBLIC (method)))
2044
        {
2045
          func = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (method)),
2046
                         method);
2047
        }
2048
      else
2049
        {
2050
          tree table_index
2051
            = build_int_cst (NULL_TREE, get_symbol_table_index
2052
                             (method, &TYPE_ATABLE_METHODS (output_class)));
2053
          func
2054
            = build4 (ARRAY_REF,
2055
                      TREE_TYPE (TREE_TYPE (TYPE_ATABLE_DECL (output_class))),
2056
                      TYPE_ATABLE_DECL (output_class), table_index,
2057
                      NULL_TREE, NULL_TREE);
2058
        }
2059
      func = convert (method_ptr_type_node, func);
2060
    }
2061
  else
2062
    {
2063
      /* We don't know whether the method has been (statically) compiled.
2064
         Compile this code to get a reference to the method's code:
2065
 
2066
         SELF_TYPE->methods[METHOD_INDEX].ncode
2067
 
2068
      */
2069
 
2070
      int method_index = 0;
2071
      tree meth, ref;
2072
 
2073
      /* The method might actually be declared in some superclass, so
2074
         we have to use its class context, not the caller's notion of
2075
         where the method is.  */
2076
      self_type = DECL_CONTEXT (method);
2077
      ref = build_class_ref (self_type);
2078
      ref = build1 (INDIRECT_REF, class_type_node, ref);
2079
      if (ncode_ident == NULL_TREE)
2080
        ncode_ident = get_identifier ("ncode");
2081
      if (methods_ident == NULL_TREE)
2082
        methods_ident = get_identifier ("methods");
2083
      ref = build3 (COMPONENT_REF, method_ptr_type_node, ref,
2084
                    lookup_field (&class_type_node, methods_ident),
2085
                    NULL_TREE);
2086
      for (meth = TYPE_METHODS (self_type);
2087
           ; meth = TREE_CHAIN (meth))
2088
        {
2089
          if (method == meth)
2090
            break;
2091
          if (meth == NULL_TREE)
2092
            fatal_error ("method '%s' not found in class",
2093
                         IDENTIFIER_POINTER (DECL_NAME (method)));
2094
          method_index++;
2095
        }
2096
      method_index *= int_size_in_bytes (method_type_node);
2097
      ref = fold_build2 (PLUS_EXPR, method_ptr_type_node,
2098
                         ref, build_int_cst (NULL_TREE, method_index));
2099
      ref = build1 (INDIRECT_REF, method_type_node, ref);
2100
      func = build3 (COMPONENT_REF, nativecode_ptr_type_node,
2101
                     ref, lookup_field (&method_type_node, ncode_ident),
2102
                     NULL_TREE);
2103
    }
2104
  return func;
2105
}
2106
 
2107
tree
2108
invoke_build_dtable (int is_invoke_interface, tree arg_list)
2109
{
2110
  tree dtable, objectref;
2111
 
2112
  TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
2113
 
2114
  /* If we're dealing with interfaces and if the objectref
2115
     argument is an array then get the dispatch table of the class
2116
     Object rather than the one from the objectref.  */
2117
  objectref = (is_invoke_interface
2118
               && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list)))
2119
               ? build_class_ref (object_type_node) : TREE_VALUE (arg_list));
2120
 
2121
  if (dtable_ident == NULL_TREE)
2122
    dtable_ident = get_identifier ("vtable");
2123
  dtable = build_java_indirect_ref (object_type_node, objectref,
2124
                                    flag_check_references);
2125
  dtable = build3 (COMPONENT_REF, dtable_ptr_type, dtable,
2126
                   lookup_field (&object_type_node, dtable_ident), NULL_TREE);
2127
 
2128
  return dtable;
2129
}
2130
 
2131
/* Determine the index in SYMBOL_TABLE for a reference to the decl
2132
   T. If this decl has not been seen before, it will be added to the
2133
   [oa]table_methods. If it has, the existing table slot will be
2134
   reused.  */
2135
 
2136
int
2137
get_symbol_table_index (tree t, tree *symbol_table)
2138
{
2139
  int i = 1;
2140
  tree method_list;
2141
 
2142
  if (*symbol_table == NULL_TREE)
2143
    {
2144
      *symbol_table = build_tree_list (t, t);
2145
      return 1;
2146
    }
2147
 
2148
  method_list = *symbol_table;
2149
 
2150
  while (1)
2151
    {
2152
      tree value = TREE_VALUE (method_list);
2153
      if (value == t)
2154
        return i;
2155
      i++;
2156
      if (TREE_CHAIN (method_list) == NULL_TREE)
2157
        break;
2158
      else
2159
        method_list = TREE_CHAIN (method_list);
2160
    }
2161
 
2162
  TREE_CHAIN (method_list) = build_tree_list (t, t);
2163
  return i;
2164
}
2165
 
2166
tree
2167
build_invokevirtual (tree dtable, tree method)
2168
{
2169
  tree func;
2170
  tree nativecode_ptr_ptr_type_node
2171
    = build_pointer_type (nativecode_ptr_type_node);
2172
  tree method_index;
2173
  tree otable_index;
2174
 
2175
  if (flag_indirect_dispatch)
2176
    {
2177
      if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
2178
        abort ();
2179
 
2180
      otable_index
2181
        = build_int_cst (NULL_TREE, get_symbol_table_index
2182
                         (method, &TYPE_OTABLE_METHODS (output_class)));
2183
      method_index = build4 (ARRAY_REF, integer_type_node,
2184
                             TYPE_OTABLE_DECL (output_class),
2185
                             otable_index, NULL_TREE, NULL_TREE);
2186
    }
2187
  else
2188
    {
2189
      /* We fetch the DECL_VINDEX field directly here, rather than
2190
         using get_method_index().  DECL_VINDEX is the true offset
2191
         from the vtable base to a method, regrdless of any extra
2192
         words inserted at the start of the vtable.  */
2193
      method_index = DECL_VINDEX (method);
2194
      method_index = size_binop (MULT_EXPR, method_index,
2195
                                 TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node));
2196
      if (TARGET_VTABLE_USES_DESCRIPTORS)
2197
        method_index = size_binop (MULT_EXPR, method_index,
2198
                                   size_int (TARGET_VTABLE_USES_DESCRIPTORS));
2199
    }
2200
 
2201
  func = fold_build2 (PLUS_EXPR, nativecode_ptr_ptr_type_node, dtable,
2202
                      convert (nativecode_ptr_ptr_type_node, method_index));
2203
 
2204
  if (TARGET_VTABLE_USES_DESCRIPTORS)
2205
    func = build1 (NOP_EXPR, nativecode_ptr_type_node, func);
2206
  else
2207
    func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
2208
 
2209
  return func;
2210
}
2211
 
2212
static GTY(()) tree class_ident;
2213
tree
2214
build_invokeinterface (tree dtable, tree method)
2215
{
2216
  tree lookup_arg;
2217
  tree interface;
2218
  tree idx;
2219
 
2220
  /* We expand invokeinterface here.  */
2221
 
2222
  if (class_ident == NULL_TREE)
2223
    class_ident = get_identifier ("class");
2224
 
2225
  dtable = build_java_indirect_ref (dtable_type, dtable,
2226
                                    flag_check_references);
2227
  dtable = build3 (COMPONENT_REF, class_ptr_type, dtable,
2228
                   lookup_field (&dtable_type, class_ident), NULL_TREE);
2229
 
2230
  interface = DECL_CONTEXT (method);
2231
  if (! CLASS_INTERFACE (TYPE_NAME (interface)))
2232
    abort ();
2233
  layout_class_methods (interface);
2234
 
2235
  if (flag_indirect_dispatch)
2236
    {
2237
      int itable_index
2238
        = 2 * (get_symbol_table_index
2239
               (method, &TYPE_ITABLE_METHODS (output_class)));
2240
      interface
2241
        = build4 (ARRAY_REF,
2242
                 TREE_TYPE (TREE_TYPE (TYPE_ITABLE_DECL (output_class))),
2243
                 TYPE_ITABLE_DECL (output_class),
2244
                  build_int_cst (NULL_TREE, itable_index-1),
2245
                  NULL_TREE, NULL_TREE);
2246
      idx
2247
        = build4 (ARRAY_REF,
2248
                 TREE_TYPE (TREE_TYPE (TYPE_ITABLE_DECL (output_class))),
2249
                 TYPE_ITABLE_DECL (output_class),
2250
                  build_int_cst (NULL_TREE, itable_index),
2251
                  NULL_TREE, NULL_TREE);
2252
      interface = convert (class_ptr_type, interface);
2253
      idx = convert (integer_type_node, idx);
2254
    }
2255
  else
2256
    {
2257
      idx = build_int_cst (NULL_TREE,
2258
                           get_interface_method_index (method, interface));
2259
      interface = build_class_ref (interface);
2260
    }
2261
 
2262
  lookup_arg = tree_cons (NULL_TREE, dtable,
2263
                          tree_cons (NULL_TREE, interface,
2264
                                     build_tree_list (NULL_TREE, idx)));
2265
 
2266
  return build3 (CALL_EXPR, ptr_type_node,
2267
                 build_address_of (soft_lookupinterfacemethod_node),
2268
                 lookup_arg, NULL_TREE);
2269
}
2270
 
2271
/* Expand one of the invoke_* opcodes.
2272
   OPCODE is the specific opcode.
2273
   METHOD_REF_INDEX is an index into the constant pool.
2274
   NARGS is the number of arguments, or -1 if not specified. */
2275
 
2276
static void
2277
expand_invoke (int opcode, int method_ref_index, int nargs ATTRIBUTE_UNUSED)
2278
{
2279
  tree method_signature
2280
    = COMPONENT_REF_SIGNATURE(&current_jcf->cpool, method_ref_index);
2281
  tree method_name = COMPONENT_REF_NAME (&current_jcf->cpool,
2282
                                         method_ref_index);
2283
  tree self_type
2284
    = get_class_constant (current_jcf,
2285
                          COMPONENT_REF_CLASS_INDEX(&current_jcf->cpool,
2286
                          method_ref_index));
2287
  const char *const self_name
2288
    = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2289
  tree call, func, method, arg_list, method_type;
2290
  tree check = NULL_TREE;
2291
 
2292
  if (! CLASS_LOADED_P (self_type))
2293
    {
2294
      load_class (self_type, 1);
2295
      safe_layout_class (self_type);
2296
      if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
2297
        fatal_error ("failed to find class '%s'", self_name);
2298
    }
2299
  layout_class_methods (self_type);
2300
 
2301
  if (ID_INIT_P (method_name))
2302
    method = lookup_java_constructor (self_type, method_signature);
2303
  else
2304
    method = lookup_java_method (self_type, method_name, method_signature);
2305
 
2306
  /* We've found a method in a class other than the one in which it
2307
     was wanted.  This can happen if, for instance, we're trying to
2308
     compile invokespecial super.equals().  */
2309
  if (! flag_verify_invocations
2310
      && method
2311
      && ! TYPE_ARRAY_P (self_type)
2312
      && self_type != DECL_CONTEXT (method))
2313
    method = NULL_TREE;
2314
 
2315
  /* We've found a method in an interface, but this isn't an interface
2316
     call.  */
2317
  if (opcode != OPCODE_invokeinterface
2318
      && method
2319
      && (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method)))))
2320
    method = NULL_TREE;
2321
 
2322
  /* We've found a non-interface method but we are making an
2323
     interface call.  This can happen if the interface overrides a
2324
     method in Object.  */
2325
  if (! flag_verify_invocations
2326
      && opcode == OPCODE_invokeinterface
2327
      && method
2328
      && ! CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
2329
    method = NULL_TREE;
2330
 
2331
  if (method == NULL_TREE)
2332
    {
2333
      if (flag_verify_invocations || ! flag_indirect_dispatch)
2334
        {
2335
          error ("class '%s' has no method named '%s' matching signature '%s'",
2336
                 self_name,
2337
                 IDENTIFIER_POINTER (method_name),
2338
                 IDENTIFIER_POINTER (method_signature));
2339
        }
2340
      else
2341
        {
2342
          int flags = ACC_PUBLIC;
2343
          if (opcode == OPCODE_invokestatic)
2344
            flags |= ACC_STATIC;
2345
          if (opcode == OPCODE_invokeinterface)
2346
            {
2347
              flags |= ACC_INTERFACE | ACC_ABSTRACT;
2348
              CLASS_INTERFACE (TYPE_NAME (self_type)) = 1;
2349
            }
2350
          method = add_method (self_type, flags, method_name,
2351
                               method_signature);
2352
          DECL_ARTIFICIAL (method) = 1;
2353
          METHOD_DUMMY (method) = 1;
2354
          layout_class_method (self_type, NULL,
2355
                               method, NULL);
2356
        }
2357
    }
2358
 
2359
  /* Invoke static can't invoke static/abstract method */
2360
  if (method != NULL_TREE)
2361
    {
2362
      if (opcode == OPCODE_invokestatic)
2363
        {
2364
          if (!METHOD_STATIC (method))
2365
            {
2366
              error ("invokestatic on non static method");
2367
              method = NULL_TREE;
2368
            }
2369
          else if (METHOD_ABSTRACT (method))
2370
            {
2371
              error ("invokestatic on abstract method");
2372
              method = NULL_TREE;
2373
            }
2374
        }
2375
      else
2376
        {
2377
          if (METHOD_STATIC (method))
2378
            {
2379
              error ("invoke[non-static] on static method");
2380
              method = NULL_TREE;
2381
            }
2382
        }
2383
    }
2384
 
2385
  if (method == NULL_TREE)
2386
    {
2387
      /* If we got here, we emitted an error message above.  So we
2388
         just pop the arguments, push a properly-typed zero, and
2389
         continue.  */
2390
      method_type = get_type_from_signature (method_signature);
2391
      pop_arguments (TYPE_ARG_TYPES (method_type));
2392
      if (opcode != OPCODE_invokestatic)
2393
        pop_type (self_type);
2394
      method_type = promote_type (TREE_TYPE (method_type));
2395
      push_value (convert (method_type, integer_zero_node));
2396
      return;
2397
    }
2398
 
2399
  method_type = TREE_TYPE (method);
2400
  arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
2401
  flush_quick_stack ();
2402
 
2403
  func = NULL_TREE;
2404
  if (opcode == OPCODE_invokestatic)
2405
    func = build_known_method_ref (method, method_type, self_type,
2406
                                   method_signature, arg_list);
2407
  else if (opcode == OPCODE_invokespecial
2408
           || (opcode == OPCODE_invokevirtual
2409
               && (METHOD_PRIVATE (method)
2410
                   || METHOD_FINAL (method)
2411
                   || CLASS_FINAL (TYPE_NAME (self_type)))))
2412
    {
2413
      /* If the object for the method call is null, we throw an
2414
         exception.  We don't do this if the object is the current
2415
         method's `this'.  In other cases we just rely on an
2416
         optimization pass to eliminate redundant checks.  FIXME:
2417
         Unfortunately there doesn't seem to be a way to determine
2418
         what the current method is right now.
2419
         We do omit the check if we're calling <init>.  */
2420
      /* We use a SAVE_EXPR here to make sure we only evaluate
2421
         the new `self' expression once.  */
2422
      tree save_arg = save_expr (TREE_VALUE (arg_list));
2423
      TREE_VALUE (arg_list) = save_arg;
2424
      check = java_check_reference (save_arg, ! DECL_INIT_P (method));
2425
      func = build_known_method_ref (method, method_type, self_type,
2426
                                     method_signature, arg_list);
2427
    }
2428
  else
2429
    {
2430
      tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface,
2431
                                         arg_list);
2432
      if (opcode == OPCODE_invokevirtual)
2433
        func = build_invokevirtual (dtable, method);
2434
      else
2435
        func = build_invokeinterface (dtable, method);
2436
    }
2437
 
2438
  if (TREE_CODE (func) == ADDR_EXPR)
2439
    TREE_TYPE (func) = build_pointer_type (method_type);
2440
  else
2441
    func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
2442
 
2443
  call = build3 (CALL_EXPR, TREE_TYPE (method_type),
2444
                 func, arg_list, NULL_TREE);
2445
  TREE_SIDE_EFFECTS (call) = 1;
2446
  call = check_for_builtin (method, call);
2447
 
2448
  if (check != NULL_TREE)
2449
    {
2450
      call = build2 (COMPOUND_EXPR, TREE_TYPE (call), check, call);
2451
      TREE_SIDE_EFFECTS (call) = 1;
2452
    }
2453
 
2454
  if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
2455
    java_add_stmt (call);
2456
  else
2457
    {
2458
      push_value (call);
2459
      flush_quick_stack ();
2460
    }
2461
}
2462
 
2463
/* Create a stub which will be put into the vtable but which will call
2464
   a JNI function.  */
2465
 
2466
tree
2467
build_jni_stub (tree method)
2468
{
2469
  tree jnifunc, call, args, body, lookup_arg, method_sig, arg_types;
2470
  tree jni_func_type, tem;
2471
  tree env_var, res_var = NULL_TREE, block;
2472
  tree method_args, res_type;
2473
  tree meth_var;
2474
  tree bind;
2475
 
2476
  int args_size = 0;
2477
 
2478
  tree klass = DECL_CONTEXT (method);
2479
  int from_class = ! CLASS_FROM_SOURCE_P (klass);
2480
  klass = build_class_ref (klass);
2481
 
2482
  if (! METHOD_NATIVE (method) || ! flag_jni)
2483
    abort ();
2484
 
2485
  DECL_ARTIFICIAL (method) = 1;
2486
  DECL_EXTERNAL (method) = 0;
2487
 
2488
  env_var = build_decl (VAR_DECL, get_identifier ("env"), ptr_type_node);
2489
  DECL_CONTEXT (env_var) = method;
2490
 
2491
  if (TREE_TYPE (TREE_TYPE (method)) != void_type_node)
2492
    {
2493
      res_var = build_decl (VAR_DECL, get_identifier ("res"),
2494
                            TREE_TYPE (TREE_TYPE (method)));
2495
      DECL_CONTEXT (res_var) = method;
2496
      TREE_CHAIN (env_var) = res_var;
2497
    }
2498
 
2499
  meth_var = build_decl (VAR_DECL, get_identifier ("meth"), ptr_type_node);
2500
  TREE_STATIC (meth_var) = 1;
2501
  TREE_PUBLIC (meth_var) = 0;
2502
  DECL_EXTERNAL (meth_var) = 0;
2503
  DECL_CONTEXT (meth_var) = method;
2504
  DECL_ARTIFICIAL (meth_var) = 1;
2505
  DECL_INITIAL (meth_var) = null_pointer_node;
2506
  TREE_USED (meth_var) = 1;
2507
  chainon (env_var, meth_var);
2508
  build_result_decl (method);
2509
 
2510
  /* One strange way that the front ends are different is that they
2511
     store arguments differently.  */
2512
  if (from_class)
2513
    method_args = DECL_ARGUMENTS (method);
2514
  else
2515
    method_args = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (method));
2516
  block = build_block (env_var, NULL_TREE, method_args, NULL_TREE);
2517
  TREE_SIDE_EFFECTS (block) = 1;
2518
  /* When compiling from source we don't set the type of the block,
2519
     because that will prevent patch_return from ever being run.  */
2520
  if (from_class)
2521
    TREE_TYPE (block) = TREE_TYPE (TREE_TYPE (method));
2522
 
2523
  /* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame.  */
2524
  body = build2 (MODIFY_EXPR, ptr_type_node, env_var,
2525
                 build3 (CALL_EXPR, ptr_type_node,
2526
                         build_address_of (soft_getjnienvnewframe_node),
2527
                         build_tree_list (NULL_TREE, klass),
2528
                         NULL_TREE));
2529
  CAN_COMPLETE_NORMALLY (body) = 1;
2530
 
2531
  /* All the arguments to this method become arguments to the
2532
     underlying JNI function.  If we had to wrap object arguments in a
2533
     special way, we would do that here.  */
2534
  args = NULL_TREE;
2535
  for (tem = method_args; tem != NULL_TREE; tem = TREE_CHAIN (tem))
2536
    {
2537
      int arg_bits = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tem)));
2538
#ifdef PARM_BOUNDARY
2539
      arg_bits = (((arg_bits + PARM_BOUNDARY - 1) / PARM_BOUNDARY)
2540
                  * PARM_BOUNDARY);
2541
#endif
2542
      args_size += (arg_bits / BITS_PER_UNIT);
2543
 
2544
      args = tree_cons (NULL_TREE, tem, args);
2545
    }
2546
  args = nreverse (args);
2547
  arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));
2548
 
2549
  /* For a static method the second argument is the class.  For a
2550
     non-static method the second argument is `this'; that is already
2551
     available in the argument list.  */
2552
  if (METHOD_STATIC (method))
2553
    {
2554
      args_size += int_size_in_bytes (TREE_TYPE (klass));
2555
      args = tree_cons (NULL_TREE, klass, args);
2556
      arg_types = tree_cons (NULL_TREE, object_ptr_type_node, arg_types);
2557
    }
2558
 
2559
  /* The JNIEnv structure is the first argument to the JNI function.  */
2560
  args_size += int_size_in_bytes (TREE_TYPE (env_var));
2561
  args = tree_cons (NULL_TREE, env_var, args);
2562
  arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
2563
 
2564
  /* We call _Jv_LookupJNIMethod to find the actual underlying
2565
     function pointer.  _Jv_LookupJNIMethod will throw the appropriate
2566
     exception if this function is not found at runtime.  */
2567
  tem = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, args_size));
2568
  method_sig = build_java_signature (TREE_TYPE (method));
2569
  lookup_arg = tree_cons (NULL_TREE,
2570
                          build_utf8_ref (unmangle_classname
2571
                                          (IDENTIFIER_POINTER (method_sig),
2572
                                           IDENTIFIER_LENGTH (method_sig))),
2573
                          tem);
2574
  tem = DECL_NAME (method);
2575
  lookup_arg
2576
    = tree_cons (NULL_TREE, klass,
2577
                 tree_cons (NULL_TREE, build_utf8_ref (tem), lookup_arg));
2578
 
2579
  tem = build_function_type (TREE_TYPE (TREE_TYPE (method)), arg_types);
2580
 
2581
#ifdef MODIFY_JNI_METHOD_CALL
2582
  tem = MODIFY_JNI_METHOD_CALL (tem);
2583
#endif
2584
 
2585
  jni_func_type = build_pointer_type (tem);
2586
 
2587
  jnifunc = build3 (COND_EXPR, ptr_type_node,
2588
                    meth_var, meth_var,
2589
                    build2 (MODIFY_EXPR, ptr_type_node, meth_var,
2590
                            build3 (CALL_EXPR, ptr_type_node,
2591
                                    build_address_of
2592
                                      (soft_lookupjnimethod_node),
2593
                                    lookup_arg, NULL_TREE)));
2594
 
2595
  /* Now we make the actual JNI call via the resulting function
2596
     pointer.    */
2597
  call = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
2598
                 build1 (NOP_EXPR, jni_func_type, jnifunc),
2599
                 args, NULL_TREE);
2600
 
2601
  /* If the JNI call returned a result, capture it here.  If we had to
2602
     unwrap JNI object results, we would do that here.  */
2603
  if (res_var != NULL_TREE)
2604
    {
2605
      /* If the call returns an object, it may return a JNI weak
2606
         reference, in which case we must unwrap it.  */
2607
      if (! JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_TYPE (method))))
2608
        call = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
2609
                       build_address_of (soft_unwrapjni_node),
2610
                       build_tree_list (NULL_TREE, call),
2611
                       NULL_TREE);
2612
      call = build2 (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)),
2613
                     res_var, call);
2614
    }
2615
 
2616
  TREE_SIDE_EFFECTS (call) = 1;
2617
  CAN_COMPLETE_NORMALLY (call) = 1;
2618
 
2619
  body = build2 (COMPOUND_EXPR, void_type_node, body, call);
2620
  TREE_SIDE_EFFECTS (body) = 1;
2621
 
2622
  /* Now free the environment we allocated.  */
2623
  call = build3 (CALL_EXPR, ptr_type_node,
2624
                 build_address_of (soft_jnipopsystemframe_node),
2625
                 build_tree_list (NULL_TREE, env_var),
2626
                 NULL_TREE);
2627
  TREE_SIDE_EFFECTS (call) = 1;
2628
  CAN_COMPLETE_NORMALLY (call) = 1;
2629
  body = build2 (COMPOUND_EXPR, void_type_node, body, call);
2630
  TREE_SIDE_EFFECTS (body) = 1;
2631
 
2632
  /* Finally, do the return.  */
2633
  res_type = void_type_node;
2634
  if (res_var != NULL_TREE)
2635
    {
2636
      tree drt;
2637
      if (! DECL_RESULT (method))
2638
        abort ();
2639
      /* Make sure we copy the result variable to the actual
2640
         result.  We use the type of the DECL_RESULT because it
2641
         might be different from the return type of the function:
2642
         it might be promoted.  */
2643
      drt = TREE_TYPE (DECL_RESULT (method));
2644
      if (drt != TREE_TYPE (res_var))
2645
        res_var = build1 (CONVERT_EXPR, drt, res_var);
2646
      res_var = build2 (MODIFY_EXPR, drt, DECL_RESULT (method), res_var);
2647
      TREE_SIDE_EFFECTS (res_var) = 1;
2648
    }
2649
 
2650
  body = build2 (COMPOUND_EXPR, void_type_node, body,
2651
                 build1 (RETURN_EXPR, res_type, res_var));
2652
  TREE_SIDE_EFFECTS (body) = 1;
2653
 
2654
  bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block),
2655
                 body, block);
2656
  return bind;
2657
}
2658
 
2659
/* Expand an operation to extract from or store into a field.
2660
   IS_STATIC is 1 iff the field is static.
2661
   IS_PUTTING is 1 for putting into a field;  0 for getting from the field.
2662
   FIELD_REF_INDEX is an index into the constant pool.  */
2663
 
2664
static void
2665
expand_java_field_op (int is_static, int is_putting, int field_ref_index)
2666
{
2667
  tree self_type
2668
    = get_class_constant (current_jcf,
2669
                          COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
2670
                          field_ref_index));
2671
  const char *self_name
2672
    = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2673
  tree field_name = COMPONENT_REF_NAME (&current_jcf->cpool, field_ref_index);
2674
  tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool,
2675
                                                  field_ref_index);
2676
  tree field_type = get_type_from_signature (field_signature);
2677
  tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
2678
  tree field_ref;
2679
  int is_error = 0;
2680
  tree original_self_type = self_type;
2681
  tree field_decl;
2682
 
2683
  if (! CLASS_LOADED_P (self_type))
2684
    load_class (self_type, 1);
2685
  field_decl = lookup_field (&self_type, field_name);
2686
  if (field_decl == error_mark_node)
2687
    {
2688
      is_error = 1;
2689
    }
2690
  else if (field_decl == NULL_TREE)
2691
    {
2692
      if (! flag_verify_invocations)
2693
        {
2694
          int flags = ACC_PUBLIC;
2695
          if (is_static)
2696
            flags |= ACC_STATIC;
2697
          self_type = original_self_type;
2698
          field_decl = add_field (original_self_type, field_name,
2699
                                  field_type, flags);
2700
          DECL_ARTIFICIAL (field_decl) = 1;
2701
          DECL_IGNORED_P (field_decl) = 1;
2702
        }
2703
      else
2704
        {
2705
          error ("missing field '%s' in '%s'",
2706
                 IDENTIFIER_POINTER (field_name), self_name);
2707
          is_error = 1;
2708
      }
2709
    }
2710
  else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
2711
    {
2712
      error ("mismatching signature for field '%s' in '%s'",
2713
             IDENTIFIER_POINTER (field_name), self_name);
2714
      is_error = 1;
2715
    }
2716
  field_ref = is_static ? NULL_TREE : pop_value (self_type);
2717
  if (is_error)
2718
    {
2719
      if (! is_putting)
2720
        push_value (convert (field_type, integer_zero_node));
2721
      flush_quick_stack ();
2722
      return;
2723
    }
2724
 
2725
  field_ref = build_field_ref (field_ref, self_type, field_name);
2726
  if (is_static
2727
      && ! flag_indirect_dispatch)
2728
    field_ref = build_class_init (self_type, field_ref);
2729
  if (is_putting)
2730
    {
2731
      flush_quick_stack ();
2732
      if (FIELD_FINAL (field_decl))
2733
        {
2734
          if (DECL_CONTEXT (field_decl) != current_class)
2735
            error ("assignment to final field %q+D not in field's class",
2736
                   field_decl);
2737
          else if (FIELD_STATIC (field_decl))
2738
            {
2739
              if (!DECL_CLINIT_P (current_function_decl))
2740
                warning (0, "assignment to final static field %q+D not in "
2741
                         "class initializer",
2742
                         field_decl);
2743
            }
2744
          else
2745
            {
2746
              tree cfndecl_name = DECL_NAME (current_function_decl);
2747
              if (! DECL_CONSTRUCTOR_P (current_function_decl)
2748
                  && !ID_FINIT_P (cfndecl_name))
2749
                warning (0, "assignment to final field %q+D not in constructor",
2750
                         field_decl);
2751
            }
2752
        }
2753
      java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (field_ref),
2754
                             field_ref, new_value));
2755
    }
2756
  else
2757
    push_value (field_ref);
2758
}
2759
 
2760
void
2761
load_type_state (tree label)
2762
{
2763
  int i;
2764
  tree vec = LABEL_TYPE_STATE (label);
2765
  int cur_length = TREE_VEC_LENGTH (vec);
2766
  stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
2767
  for (i = 0; i < cur_length; i++)
2768
    type_map [i] = TREE_VEC_ELT (vec, i);
2769
}
2770
 
2771
/* Go over METHOD's bytecode and note instruction starts in
2772
   instruction_bits[].  */
2773
 
2774
void
2775
note_instructions (JCF *jcf, tree method)
2776
{
2777
  int PC;
2778
  unsigned char* byte_ops;
2779
  long length = DECL_CODE_LENGTH (method);
2780
 
2781
  int saw_index;
2782
  jint INT_temp;
2783
 
2784
#undef RET /* Defined by config/i386/i386.h */
2785
#undef PTR
2786
#define BCODE byte_ops
2787
#define BYTE_type_node byte_type_node
2788
#define SHORT_type_node short_type_node
2789
#define INT_type_node int_type_node
2790
#define LONG_type_node long_type_node
2791
#define CHAR_type_node char_type_node
2792
#define PTR_type_node ptr_type_node
2793
#define FLOAT_type_node float_type_node
2794
#define DOUBLE_type_node double_type_node
2795
#define VOID_type_node void_type_node
2796
#define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2797
#define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2798
#define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2799
#define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2800
 
2801
#define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
2802
 
2803
  JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2804
  byte_ops = jcf->read_ptr;
2805
  instruction_bits = xrealloc (instruction_bits, length + 1);
2806
  memset (instruction_bits, 0, length + 1);
2807
 
2808
  /* This pass figures out which PC can be the targets of jumps. */
2809
  for (PC = 0; PC < length;)
2810
    {
2811
      int oldpc = PC; /* PC at instruction start. */
2812
      instruction_bits [PC] |=  BCODE_INSTRUCTION_START;
2813
      switch (byte_ops[PC++])
2814
        {
2815
#define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2816
        case OPCODE: \
2817
          PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2818
          break;
2819
 
2820
#define NOTE_LABEL(PC) note_label(oldpc, PC)
2821
 
2822
#define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2823
#define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2824
#define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2825
#define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2826
#define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2827
#define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2828
#define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2829
#define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2830
 
2831
#define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2832
  PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2833
#define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2834
  ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2835
#define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2836
#define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2837
#define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2838
#define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2839
 
2840
/* two forms of wide instructions */
2841
#define PRE_SPECIAL_WIDE(IGNORE) \
2842
  { \
2843
    int modified_opcode = IMMEDIATE_u1; \
2844
    if (modified_opcode == OPCODE_iinc) \
2845
      { \
2846
        (void) IMMEDIATE_u2;    /* indexbyte1 and indexbyte2 */ \
2847
        (void) IMMEDIATE_s2;    /* constbyte1 and constbyte2 */ \
2848
      } \
2849
    else \
2850
      { \
2851
        (void) IMMEDIATE_u2;    /* indexbyte1 and indexbyte2 */ \
2852
      } \
2853
  }
2854
 
2855
#define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2856
 
2857
#define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2858
 
2859
#define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2860
#define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2861
          PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2862
#define PRE_ARRAY_LOAD(TYPE) /* nothing */
2863
#define PRE_ARRAY_STORE(TYPE) /* nothing */
2864
#define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2865
#define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2866
#define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2867
#define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2868
#define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2869
 
2870
#define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2871
#define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2872
#define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2873
  saw_index = 0;  INT_temp = (OPERAND_VALUE); \
2874
  if (!saw_index)  NOTE_LABEL(oldpc + INT_temp);
2875
#define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2876
  saw_index = 0;  INT_temp = (OPERAND_VALUE); \
2877
  NOTE_LABEL (PC); \
2878
  if (!saw_index)  NOTE_LABEL(oldpc + INT_temp);
2879
 
2880
#define PRE_RET(OPERAND_TYPE, OPERAND_VALUE)  (void)(OPERAND_VALUE)
2881
 
2882
#define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2883
  PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2884
 
2885
#define PRE_LOOKUP_SWITCH                                               \
2886
  { jint default_offset = IMMEDIATE_s4;  jint npairs = IMMEDIATE_s4;    \
2887
    NOTE_LABEL (default_offset+oldpc);                                  \
2888
    if (npairs >= 0)                                                     \
2889
      while (--npairs >= 0) {                                            \
2890
       jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4;                      \
2891
       jint offset = IMMEDIATE_s4;                                      \
2892
       NOTE_LABEL (offset+oldpc); }                                     \
2893
  }
2894
 
2895
#define PRE_TABLE_SWITCH                                \
2896
  { jint default_offset = IMMEDIATE_s4;                 \
2897
    jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4;  \
2898
    NOTE_LABEL (default_offset+oldpc);                  \
2899
    if (low <= high)                                    \
2900
     while (low++ <= high) {                            \
2901
       jint offset = IMMEDIATE_s4;                      \
2902
       NOTE_LABEL (offset+oldpc); }                     \
2903
  }
2904
 
2905
#define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2906
#define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2907
#define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2908
  (void)(IMMEDIATE_u2); \
2909
  PC += 2 * IS_INTERFACE /* for invokeinterface */;
2910
 
2911
#include "javaop.def"
2912
#undef JAVAOP
2913
        }
2914
    } /* for */
2915
}
2916
 
2917
void
2918
expand_byte_code (JCF *jcf, tree method)
2919
{
2920
  int PC;
2921
  int i;
2922
  const unsigned char *linenumber_pointer;
2923
  int dead_code_index = -1;
2924
  unsigned char* byte_ops;
2925
  long length = DECL_CODE_LENGTH (method);
2926
 
2927
  stack_pointer = 0;
2928
  JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2929
  byte_ops = jcf->read_ptr;
2930
 
2931
  /* We make an initial pass of the line number table, to note
2932
     which instructions have associated line number entries. */
2933
  linenumber_pointer = linenumber_table;
2934
  for (i = 0; i < linenumber_count; i++)
2935
    {
2936
      int pc = GET_u2 (linenumber_pointer);
2937
      linenumber_pointer += 4;
2938
      if (pc >= length)
2939
        warning (0, "invalid PC in line number table");
2940
      else
2941
        {
2942
          if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
2943
            instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
2944
          instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
2945
        }
2946
    }
2947
 
2948
  if (! verify_jvm_instructions_new (jcf, byte_ops, length))
2949
    return;
2950
 
2951
  promote_arguments ();
2952
 
2953
  /* Translate bytecodes.  */
2954
  linenumber_pointer = linenumber_table;
2955
  for (PC = 0; PC < length;)
2956
    {
2957
      if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2958
        {
2959
          tree label = lookup_label (PC);
2960
          flush_quick_stack ();
2961
          if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2962
            java_add_stmt (build1 (LABEL_EXPR, void_type_node, label));
2963
          if (LABEL_VERIFIED (label) || PC == 0)
2964
            load_type_state (label);
2965
        }
2966
 
2967
      if (! (instruction_bits [PC] & BCODE_VERIFIED))
2968
        {
2969
          if (dead_code_index == -1)
2970
            {
2971
              /* This is the start of a region of unreachable bytecodes.
2972
                 They still need to be processed in order for EH ranges
2973
                 to get handled correctly.  However, we can simply
2974
                 replace these bytecodes with nops.  */
2975
              dead_code_index = PC;
2976
            }
2977
 
2978
          /* Turn this bytecode into a nop.  */
2979
          byte_ops[PC] = 0x0;
2980
        }
2981
       else
2982
        {
2983
          if (dead_code_index != -1)
2984
            {
2985
              /* We've just reached the end of a region of dead code.  */
2986
              if (extra_warnings)
2987
                warning (0, "unreachable bytecode from %d to before %d",
2988
                         dead_code_index, PC);
2989
              dead_code_index = -1;
2990
            }
2991
        }
2992
 
2993
      /* Handle possible line number entry for this PC.
2994
 
2995
         This code handles out-of-order and multiple linenumbers per PC,
2996
         but is optimized for the case of line numbers increasing
2997
         monotonically with PC. */
2998
      if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2999
        {
3000
          if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
3001
              || GET_u2 (linenumber_pointer) != PC)
3002
            linenumber_pointer = linenumber_table;
3003
          while (linenumber_pointer < linenumber_table + linenumber_count * 4)
3004
            {
3005
              int pc = GET_u2 (linenumber_pointer);
3006
              linenumber_pointer += 4;
3007
              if (pc == PC)
3008
                {
3009
                  int line = GET_u2 (linenumber_pointer - 2);
3010
#ifdef USE_MAPPED_LOCATION
3011
                  input_location = linemap_line_start (&line_table, line, 1);
3012
#else
3013
                  input_location.line = line;
3014
#endif
3015
                  if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
3016
                    break;
3017
                }
3018
            }
3019
        }
3020
      maybe_pushlevels (PC);
3021
      PC = process_jvm_instruction (PC, byte_ops, length);
3022
      maybe_poplevels (PC);
3023
    } /* for */
3024
 
3025
  if (dead_code_index != -1)
3026
    {
3027
      /* We've just reached the end of a region of dead code.  */
3028
      if (extra_warnings)
3029
        warning (0, "unreachable bytecode from %d to the end of the method",
3030
                 dead_code_index);
3031
    }
3032
}
3033
 
3034
static void
3035
java_push_constant_from_pool (JCF *jcf, int index)
3036
{
3037
  tree c;
3038
  if (JPOOL_TAG (jcf, index) == CONSTANT_String)
3039
    {
3040
      tree name;
3041
      name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
3042
      index = alloc_name_constant (CONSTANT_String, name);
3043
      c = build_ref_from_constant_pool (index);
3044
      c = convert (promote_type (string_type_node), c);
3045
    }
3046
  else
3047
    c = get_constant (jcf, index);
3048
  push_value (c);
3049
}
3050
 
3051
int
3052
process_jvm_instruction (int PC, const unsigned char* byte_ops,
3053
                         long length ATTRIBUTE_UNUSED)
3054
{
3055
  const char *opname; /* Temporary ??? */
3056
  int oldpc = PC; /* PC at instruction start. */
3057
 
3058
  /* If the instruction is at the beginning of an exception handler,
3059
     replace the top of the stack with the thrown object reference.  */
3060
  if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
3061
    {
3062
      /* Note that the verifier will not emit a type map at all for
3063
         dead exception handlers.  In this case we just ignore the
3064
         situation.  */
3065
      if ((instruction_bits[PC] & BCODE_VERIFIED) != 0)
3066
        {
3067
          tree type = pop_type (promote_type (throwable_type_node));
3068
          push_value (build_exception_object_ref (type));
3069
        }
3070
    }
3071
 
3072
  switch (byte_ops[PC++])
3073
    {
3074
#define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
3075
    case OPCODE: \
3076
      opname = #OPNAME; \
3077
      OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
3078
      break;
3079
 
3080
#define RET(OPERAND_TYPE, OPERAND_VALUE)                                \
3081
  {                                                                     \
3082
    int saw_index = 0;                                                   \
3083
    int index     = OPERAND_VALUE;                                      \
3084
    build_java_ret                                                      \
3085
      (find_local_variable (index, return_address_type_node, oldpc));   \
3086
  }
3087
 
3088
#define JSR(OPERAND_TYPE, OPERAND_VALUE) \
3089
  {                                                 \
3090
    /* OPERAND_VALUE may have side-effects on PC */ \
3091
    int opvalue = OPERAND_VALUE;                    \
3092
    build_java_jsr (oldpc + opvalue, PC);           \
3093
  }
3094
 
3095
/* Push a constant onto the stack. */
3096
#define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
3097
  { int saw_index = 0;  int ival = (OPERAND_VALUE); \
3098
    if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
3099
    else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
3100
 
3101
/* internal macro added for use by the WIDE case */
3102
#define LOAD_INTERNAL(OPTYPE, OPVALUE) \
3103
  expand_load_internal (OPVALUE, type_map[OPVALUE], oldpc);
3104
 
3105
/* Push local variable onto the opcode stack. */
3106
#define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
3107
  { \
3108
    /* have to do this since OPERAND_VALUE may have side-effects */ \
3109
    int opvalue = OPERAND_VALUE; \
3110
    LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
3111
  }
3112
 
3113
#define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
3114
  expand_java_return (OPERAND_TYPE##_type_node)
3115
 
3116
#define REM_EXPR TRUNC_MOD_EXPR
3117
#define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
3118
  expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
3119
 
3120
#define FIELD(IS_STATIC, IS_PUT) \
3121
  expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
3122
 
3123
#define TEST(OPERAND_TYPE, CONDITION) \
3124
  expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
3125
 
3126
#define COND(OPERAND_TYPE, CONDITION) \
3127
  expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
3128
 
3129
#define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
3130
  BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
3131
 
3132
#define BRANCH_GOTO(OPERAND_VALUE) \
3133
  expand_java_goto (oldpc + OPERAND_VALUE)
3134
 
3135
#define BRANCH_CALL(OPERAND_VALUE) \
3136
  expand_java_call (oldpc + OPERAND_VALUE, oldpc)
3137
 
3138
#if 0
3139
#define BRANCH_RETURN(OPERAND_VALUE) \
3140
  { \
3141
    tree type = OPERAND_TYPE##_type_node; \
3142
    tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
3143
    expand_java_ret (value); \
3144
  }
3145
#endif
3146
 
3147
#define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
3148
          fprintf (stderr, "%3d: %s ", oldpc, opname); \
3149
          fprintf (stderr, "(not implemented)\n")
3150
#define NOT_IMPL1(OPERAND_VALUE) \
3151
          fprintf (stderr, "%3d: %s ", oldpc, opname); \
3152
          fprintf (stderr, "(not implemented)\n")
3153
 
3154
#define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
3155
 
3156
#define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
3157
 
3158
#define STACK_POP(COUNT) java_stack_pop (COUNT)
3159
 
3160
#define STACK_SWAP(COUNT) java_stack_swap()
3161
 
3162
#define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
3163
#define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
3164
#define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
3165
 
3166
#define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
3167
  PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
3168
 
3169
#define LOOKUP_SWITCH \
3170
  { jint default_offset = IMMEDIATE_s4;  jint npairs = IMMEDIATE_s4; \
3171
    tree selector = pop_value (INT_type_node); \
3172
    tree switch_expr = expand_java_switch (selector, oldpc + default_offset); \
3173
    while (--npairs >= 0) \
3174
      { \
3175
        jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
3176
        expand_java_add_case (switch_expr, match, oldpc + offset); \
3177
      } \
3178
  }
3179
 
3180
#define TABLE_SWITCH \
3181
  { jint default_offset = IMMEDIATE_s4; \
3182
    jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
3183
    tree selector = pop_value (INT_type_node); \
3184
    tree switch_expr = expand_java_switch (selector, oldpc + default_offset); \
3185
    for (; low <= high; low++) \
3186
      { \
3187
        jint offset = IMMEDIATE_s4; \
3188
        expand_java_add_case (switch_expr, low, oldpc + offset); \
3189
      } \
3190
  }
3191
 
3192
#define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
3193
  { int opcode = byte_ops[PC-1]; \
3194
    int method_ref_index = IMMEDIATE_u2; \
3195
    int nargs; \
3196
    if (IS_INTERFACE) { nargs = IMMEDIATE_u1;  (void) IMMEDIATE_u1; } \
3197
    else nargs = -1; \
3198
    expand_invoke (opcode, method_ref_index, nargs); \
3199
  }
3200
 
3201
/* Handle new, checkcast, instanceof */
3202
#define OBJECT(TYPE, OP) \
3203
  expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
3204
 
3205
#define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
3206
 
3207
#define ARRAY_LOAD(OPERAND_TYPE)                        \
3208
  {                                                     \
3209
    expand_java_arrayload( OPERAND_TYPE##_type_node );  \
3210
  }
3211
 
3212
#define ARRAY_STORE(OPERAND_TYPE)                       \
3213
  {                                                     \
3214
    expand_java_arraystore( OPERAND_TYPE##_type_node ); \
3215
  }
3216
 
3217
#define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
3218
#define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
3219
#define ARRAY_NEW_PTR()                                                 \
3220
    push_value (build_anewarray (get_class_constant (current_jcf,       \
3221
                                                     IMMEDIATE_u2),     \
3222
                                 pop_value (int_type_node)));
3223
#define ARRAY_NEW_NUM()                         \
3224
  {                                             \
3225
    int atype = IMMEDIATE_u1;                   \
3226
    push_value (build_newarray (atype, pop_value (int_type_node)));\
3227
  }
3228
#define ARRAY_NEW_MULTI()                                       \
3229
  {                                                             \
3230
    tree class = get_class_constant (current_jcf, IMMEDIATE_u2 );       \
3231
    int  ndims = IMMEDIATE_u1;                                  \
3232
    expand_java_multianewarray( class, ndims );                 \
3233
  }
3234
 
3235
#define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
3236
  push_value (fold_build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
3237
                           pop_value (OPERAND_TYPE##_type_node)));
3238
 
3239
#define CONVERT2(FROM_TYPE, TO_TYPE)                                     \
3240
  {                                                                      \
3241
    push_value (build1 (NOP_EXPR, int_type_node,                         \
3242
                        (convert (TO_TYPE##_type_node,                   \
3243
                                  pop_value (FROM_TYPE##_type_node))))); \
3244
  }
3245
 
3246
#define CONVERT(FROM_TYPE, TO_TYPE)                             \
3247
  {                                                             \
3248
    push_value (convert (TO_TYPE##_type_node,                   \
3249
                         pop_value (FROM_TYPE##_type_node)));   \
3250
  }
3251
 
3252
/* internal macro added for use by the WIDE case
3253
   Added TREE_TYPE (decl) assignment, apbianco  */
3254
#define STORE_INTERNAL(OPTYPE, OPVALUE)                         \
3255
  {                                                             \
3256
    tree decl, value;                                           \
3257
    int index = OPVALUE;                                        \
3258
    tree type = OPTYPE;                                         \
3259
    value = pop_value (type);                                   \
3260
    type = TREE_TYPE (value);                                   \
3261
    decl = find_local_variable (index, type, oldpc);            \
3262
    set_local_type (index, type);                               \
3263
    java_add_stmt (build2 (MODIFY_EXPR, type, decl, value));    \
3264
    update_aliases (decl, index, PC);                           \
3265
  }
3266
 
3267
#define STORE(OPERAND_TYPE, OPERAND_VALUE) \
3268
  { \
3269
    /* have to do this since OPERAND_VALUE may have side-effects */ \
3270
    int opvalue = OPERAND_VALUE; \
3271
    STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
3272
  }
3273
 
3274
#define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
3275
  SPECIAL_##INSTRUCTION(OPERAND_TYPE)
3276
 
3277
#define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
3278
#define SPECIAL_EXIT(IGNORED)  MONITOR_OPERATION (soft_monitorexit_node)
3279
 
3280
#define MONITOR_OPERATION(call)                 \
3281
  {                                             \
3282
    tree o = pop_value (ptr_type_node);         \
3283
    tree c;                                     \
3284
    flush_quick_stack ();                       \
3285
    c = build_java_monitor (call, o);           \
3286
    TREE_SIDE_EFFECTS (c) = 1;                  \
3287
    java_add_stmt (c);                          \
3288
  }
3289
 
3290
#define SPECIAL_IINC(IGNORED) \
3291
  { \
3292
    unsigned int local_var_index = IMMEDIATE_u1; \
3293
    int ival = IMMEDIATE_s1; \
3294
    expand_iinc(local_var_index, ival, oldpc); \
3295
  }
3296
 
3297
#define SPECIAL_WIDE(IGNORED) \
3298
  { \
3299
    int modified_opcode = IMMEDIATE_u1; \
3300
    unsigned int local_var_index = IMMEDIATE_u2; \
3301
    switch (modified_opcode) \
3302
      { \
3303
      case OPCODE_iinc: \
3304
        { \
3305
          int ival = IMMEDIATE_s2; \
3306
          expand_iinc (local_var_index, ival, oldpc); \
3307
          break; \
3308
        } \
3309
      case OPCODE_iload: \
3310
      case OPCODE_lload: \
3311
      case OPCODE_fload: \
3312
      case OPCODE_dload: \
3313
      case OPCODE_aload: \
3314
        { \
3315
          /* duplicate code from LOAD macro */ \
3316
          LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
3317
          break; \
3318
        } \
3319
      case OPCODE_istore: \
3320
      case OPCODE_lstore: \
3321
      case OPCODE_fstore: \
3322
      case OPCODE_dstore: \
3323
      case OPCODE_astore: \
3324
        { \
3325
          STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
3326
          break; \
3327
        } \
3328
      default: \
3329
        error ("unrecogized wide sub-instruction"); \
3330
      } \
3331
  }
3332
 
3333
#define SPECIAL_THROW(IGNORED) \
3334
  build_java_athrow (pop_value (throwable_type_node))
3335
 
3336
#define SPECIAL_BREAK NOT_IMPL1
3337
#define IMPL          NOT_IMPL
3338
 
3339
#include "javaop.def"
3340
#undef JAVAOP
3341
   default:
3342
    fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
3343
  }
3344
  return PC;
3345
}
3346
 
3347
/* Return the opcode at PC in the code section pointed to by
3348
   CODE_OFFSET.  */
3349
 
3350
static unsigned char
3351
peek_opcode_at_pc (JCF *jcf, int code_offset, int pc)
3352
{
3353
  unsigned char opcode;
3354
  long absolute_offset = (long)JCF_TELL (jcf);
3355
 
3356
  JCF_SEEK (jcf, code_offset);
3357
  opcode = jcf->read_ptr [pc];
3358
  JCF_SEEK (jcf, absolute_offset);
3359
  return opcode;
3360
}
3361
 
3362
/* Some bytecode compilers are emitting accurate LocalVariableTable
3363
   attributes. Here's an example:
3364
 
3365
     PC   <t>store_<n>
3366
     PC+1 ...
3367
 
3368
     Attribute "LocalVariableTable"
3369
     slot #<n>: ... (PC: PC+1 length: L)
3370
 
3371
   This is accurate because the local in slot <n> really exists after
3372
   the opcode at PC is executed, hence from PC+1 to PC+1+L.
3373
 
3374
   This procedure recognizes this situation and extends the live range
3375
   of the local in SLOT to START_PC-1 or START_PC-2 (depending on the
3376
   length of the store instruction.)
3377
 
3378
   This function is used by `give_name_to_locals' so that a local's
3379
   DECL features a DECL_LOCAL_START_PC such that the first related
3380
   store operation will use DECL as a destination, not an unrelated
3381
   temporary created for the occasion.
3382
 
3383
   This function uses a global (instruction_bits) `note_instructions' should
3384
   have allocated and filled properly.  */
3385
 
3386
int
3387
maybe_adjust_start_pc (struct JCF *jcf, int code_offset,
3388
                       int start_pc, int slot)
3389
{
3390
  int first, index, opcode;
3391
  int pc, insn_pc;
3392
  int wide_found = 0;
3393
 
3394
  if (!start_pc)
3395
    return start_pc;
3396
 
3397
  first = index = -1;
3398
 
3399
  /* Find last previous instruction and remember it */
3400
  for (pc = start_pc-1; pc; pc--)
3401
    if (instruction_bits [pc] & BCODE_INSTRUCTION_START)
3402
      break;
3403
  insn_pc = pc;
3404
 
3405
  /* Retrieve the instruction, handle `wide'. */
3406
  opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3407
  if (opcode == OPCODE_wide)
3408
    {
3409
      wide_found = 1;
3410
      opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3411
    }
3412
 
3413
  switch (opcode)
3414
    {
3415
    case OPCODE_astore_0:
3416
    case OPCODE_astore_1:
3417
    case OPCODE_astore_2:
3418
    case OPCODE_astore_3:
3419
      first = OPCODE_astore_0;
3420
      break;
3421
 
3422
    case OPCODE_istore_0:
3423
    case OPCODE_istore_1:
3424
    case OPCODE_istore_2:
3425
    case OPCODE_istore_3:
3426
      first = OPCODE_istore_0;
3427
      break;
3428
 
3429
    case OPCODE_lstore_0:
3430
    case OPCODE_lstore_1:
3431
    case OPCODE_lstore_2:
3432
    case OPCODE_lstore_3:
3433
      first = OPCODE_lstore_0;
3434
      break;
3435
 
3436
    case OPCODE_fstore_0:
3437
    case OPCODE_fstore_1:
3438
    case OPCODE_fstore_2:
3439
    case OPCODE_fstore_3:
3440
      first = OPCODE_fstore_0;
3441
      break;
3442
 
3443
    case OPCODE_dstore_0:
3444
    case OPCODE_dstore_1:
3445
    case OPCODE_dstore_2:
3446
    case OPCODE_dstore_3:
3447
      first = OPCODE_dstore_0;
3448
      break;
3449
 
3450
    case OPCODE_astore:
3451
    case OPCODE_istore:
3452
    case OPCODE_lstore:
3453
    case OPCODE_fstore:
3454
    case OPCODE_dstore:
3455
      index = peek_opcode_at_pc (jcf, code_offset, pc);
3456
      if (wide_found)
3457
        {
3458
          int other = peek_opcode_at_pc (jcf, code_offset, ++pc);
3459
          index = (other << 8) + index;
3460
        }
3461
      break;
3462
    }
3463
 
3464
  /* Now we decide: first >0 means we have a <t>store_<n>, index >0
3465
     means we have a <t>store. */
3466
  if ((first > 0 && opcode - first == slot) || (index > 0 && index == slot))
3467
    start_pc = insn_pc;
3468
 
3469
  return start_pc;
3470
}
3471
 
3472
/* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
3473
   order, as specified by Java Language Specification.
3474
 
3475
   The problem is that while expand_expr will evaluate its sub-operands in
3476
   left-to-right order, for variables it will just return an rtx (i.e.
3477
   an lvalue) for the variable (rather than an rvalue).  So it is possible
3478
   that a later sub-operand will change the register, and when the
3479
   actual operation is done, it will use the new value, when it should
3480
   have used the original value.
3481
 
3482
   We fix this by using save_expr.  This forces the sub-operand to be
3483
   copied into a fresh virtual register,
3484
 
3485
   For method invocation, we modify the arguments so that a
3486
   left-to-right order evaluation is performed. Saved expressions
3487
   will, in CALL_EXPR order, be reused when the call will be expanded.
3488
 
3489
   We also promote outgoing args if needed.  */
3490
 
3491
tree
3492
force_evaluation_order (tree node)
3493
{
3494
  if (flag_syntax_only)
3495
    return node;
3496
  if (TREE_CODE (node) == CALL_EXPR
3497
      || TREE_CODE (node) == NEW_CLASS_EXPR
3498
      || (TREE_CODE (node) == COMPOUND_EXPR
3499
          && TREE_CODE (TREE_OPERAND (node, 0)) == CALL_EXPR
3500
          && TREE_CODE (TREE_OPERAND (node, 1)) == SAVE_EXPR))
3501
    {
3502
      tree arg, cmp;
3503
 
3504
      arg = node;
3505
 
3506
      /* Position arg properly, account for wrapped around ctors. */
3507
      if (TREE_CODE (node) == COMPOUND_EXPR)
3508
        arg = TREE_OPERAND (node, 0);
3509
 
3510
      arg = TREE_OPERAND (arg, 1);
3511
 
3512
      /* An empty argument list is ok, just ignore it.  */
3513
      if (!arg)
3514
        return node;
3515
 
3516
      /* Not having a list of arguments here is an error. */
3517
      if (TREE_CODE (arg) != TREE_LIST)
3518
        abort ();
3519
 
3520
      /* This reverses the evaluation order. This is a desired effect. */
3521
      for (cmp = NULL_TREE; arg; arg = TREE_CHAIN (arg))
3522
        {
3523
          /* Promote types smaller than integer.  This is required by
3524
             some ABIs.  */
3525
          tree type = TREE_TYPE (TREE_VALUE (arg));
3526
          tree saved;
3527
          if (targetm.calls.promote_prototypes (type)
3528
              && INTEGRAL_TYPE_P (type)
3529
              && INT_CST_LT_UNSIGNED (TYPE_SIZE (type),
3530
                                      TYPE_SIZE (integer_type_node)))
3531
            TREE_VALUE (arg) = fold_convert (integer_type_node, TREE_VALUE (arg));
3532
 
3533
          saved = save_expr (force_evaluation_order (TREE_VALUE (arg)));
3534
          cmp = (cmp == NULL_TREE ? saved :
3535
                 build2 (COMPOUND_EXPR, void_type_node, cmp, saved));
3536
          TREE_VALUE (arg) = saved;
3537
        }
3538
 
3539
      if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
3540
        TREE_SIDE_EFFECTS (cmp) = 1;
3541
 
3542
      if (cmp)
3543
        {
3544
          cmp = build2 (COMPOUND_EXPR, TREE_TYPE (node), cmp, node);
3545
          if (TREE_TYPE (cmp) != void_type_node)
3546
            cmp = save_expr (cmp);
3547
          CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
3548
          TREE_SIDE_EFFECTS (cmp) = 1;
3549
          node = cmp;
3550
        }
3551
    }
3552
  return node;
3553
}
3554
 
3555
/* EXPR_WITH_FILE_LOCATION are used to keep track of the exact
3556
   location where an expression or an identifier were encountered. It
3557
   is necessary for languages where the frontend parser will handle
3558
   recursively more than one file (Java is one of them).  */
3559
 
3560
tree
3561
build_expr_wfl (tree node,
3562
#ifdef USE_MAPPED_LOCATION
3563
                source_location location
3564
#else
3565
                const char *file, int line, int col
3566
#endif
3567
)
3568
{
3569
  tree wfl;
3570
 
3571
#ifdef USE_MAPPED_LOCATION
3572
  wfl = make_node (EXPR_WITH_FILE_LOCATION);
3573
  SET_EXPR_LOCATION (wfl, location);
3574
#else
3575
  static const char *last_file = 0;
3576
  static tree last_filenode = NULL_TREE;
3577
 
3578
  wfl = make_node (EXPR_WITH_FILE_LOCATION);
3579
 
3580
  EXPR_WFL_SET_LINECOL (wfl, line, col);
3581
  if (file != last_file)
3582
    {
3583
      last_file = file;
3584
      last_filenode = file ? get_identifier (file) : NULL_TREE;
3585
    }
3586
  EXPR_WFL_FILENAME_NODE (wfl) = last_filenode;
3587
#endif
3588
  EXPR_WFL_NODE (wfl) = node;
3589
  if (node)
3590
    {
3591
      if (!TYPE_P (node))
3592
        TREE_SIDE_EFFECTS (wfl) = TREE_SIDE_EFFECTS (node);
3593
      TREE_TYPE (wfl) = TREE_TYPE (node);
3594
    }
3595
 
3596
  return wfl;
3597
}
3598
 
3599
#ifdef USE_MAPPED_LOCATION
3600
tree
3601
expr_add_location (tree node, source_location location, bool statement)
3602
{
3603
  tree wfl;
3604
#if 0
3605
  /* FIXME. This optimization causes failures in code that expects an
3606
     EXPR_WITH_FILE_LOCATION.  E.g. in resolve_qualified_expression_name. */
3607
  if (node && ! (statement && flag_emit_class_files))
3608
    {
3609
      source_location node_loc = EXPR_LOCATION (node);
3610
      if (node_loc == location || location == UNKNOWN_LOCATION)
3611
        return node;
3612
      if (node_loc == UNKNOWN_LOCATION
3613
          && IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (node))))
3614
        {
3615
          SET_EXPR_LOCATION (node, location);
3616
          return node;
3617
        }
3618
    }
3619
#endif
3620
  wfl = make_node (EXPR_WITH_FILE_LOCATION);
3621
  SET_EXPR_LOCATION (wfl, location);
3622
  EXPR_WFL_NODE (wfl) = node;
3623
  if (statement && debug_info_level != DINFO_LEVEL_NONE)
3624
    EXPR_WFL_EMIT_LINE_NOTE (wfl) = 1;
3625
  if (node)
3626
    {
3627
      if (!TYPE_P (node))
3628
        TREE_SIDE_EFFECTS (wfl) = TREE_SIDE_EFFECTS (node);
3629
      TREE_TYPE (wfl) = TREE_TYPE (node);
3630
    }
3631
 
3632
  return wfl;
3633
}
3634
#endif
3635
 
3636
/* Build a node to represent empty statements and blocks. */
3637
 
3638
tree
3639
build_java_empty_stmt (void)
3640
{
3641
  tree t = build_empty_stmt ();
3642
  CAN_COMPLETE_NORMALLY (t) = 1;
3643
  return t;
3644
}
3645
 
3646
/* Promote all args of integral type before generating any code.  */
3647
 
3648
static void
3649
promote_arguments (void)
3650
{
3651
  int i;
3652
  tree arg;
3653
  for (arg = DECL_ARGUMENTS (current_function_decl), i = 0;
3654
       arg != NULL_TREE;  arg = TREE_CHAIN (arg), i++)
3655
    {
3656
      tree arg_type = TREE_TYPE (arg);
3657
      if (INTEGRAL_TYPE_P (arg_type)
3658
          && TYPE_PRECISION (arg_type) < 32)
3659
        {
3660
          tree copy = find_local_variable (i, integer_type_node, -1);
3661
          java_add_stmt (build2 (MODIFY_EXPR, integer_type_node,
3662
                                 copy,
3663
                                 fold_convert (integer_type_node, arg)));
3664
        }
3665
      if (TYPE_IS_WIDE (arg_type))
3666
        i++;
3667
    }
3668
}
3669
 
3670
#include "gt-java-expr.h"

powered by: WebSVN 2.1.0

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