1 // $Id: bytecode.cpp,v 1.185 2004/05/20 21:01:33 elliott-oss Exp $
2 //
3 // This software is subject to the terms of the IBM Jikes Compiler
4 // License Agreement available at the following URL:
5 // http://ibm.com/developerworks/opensource/jikes.
6 // Copyright (C) 1996, 2004 IBM Corporation and others.  All Rights Reserved.
7 // You must accept the terms of that agreement to use this software.
8 //
9 
10 #include "bytecode.h"
11 #include "ast.h"
12 #include "class.h"
13 #include "control.h"
14 #include "semantic.h"
15 #include "stream.h"
16 #include "symbol.h"
17 #include "table.h"
18 #include "option.h"
19 
20 #ifdef HAVE_JIKES_NAMESPACE
21 namespace Jikes { // Open namespace Jikes block
22 #endif
23 
GenerateCode()24 void ByteCode::GenerateCode()
25 {
26     AstClassBody* class_body = unit_type -> declaration;
27     unsigned i;
28 
29     //
30     // Process static variables.
31     //
32     for (i = 0; i < class_body -> NumClassVariables(); i++)
33     {
34         AstFieldDeclaration* field_decl = class_body -> ClassVariable(i);
35         for (unsigned vi = 0;
36              vi < field_decl -> NumVariableDeclarators(); vi++)
37         {
38             AstVariableDeclarator* vd = field_decl -> VariableDeclarator(vi);
39             DeclareField(vd -> symbol);
40         }
41     }
42 
43     //
44     // Process instance variables.  We separate constant fields from others,
45     // because in 1.4 or later, constant fields are initialized before the
46     // call to super() in order to obey semantics of JLS 13.1.
47     //
48     Tuple<AstVariableDeclarator*> constant_instance_fields
49         (unit_type -> NumVariableSymbols());
50     for (i = 0; i < class_body -> NumInstanceVariables(); i++)
51     {
52         AstFieldDeclaration* field_decl  = class_body -> InstanceVariable(i);
53         for (unsigned vi = 0;
54              vi < field_decl -> NumVariableDeclarators(); vi++)
55         {
56             AstVariableDeclarator* vd = field_decl -> VariableDeclarator(vi);
57             VariableSymbol* vsym = vd -> symbol;
58             DeclareField(vsym);
59             if (vd -> variable_initializer_opt && vsym -> initial_value)
60             {
61                 AstExpression* init;
62                 assert(init = vd -> variable_initializer_opt ->
63                        ExpressionCast());
64                 assert(init -> IsConstant() && vd -> symbol -> ACC_FINAL());
65                 constant_instance_fields.Next() = vd;
66             }
67         }
68     }
69 
70     //
71     // Process synthetic fields (this$0, local shadow parameters, $class...,
72     // $array..., $noassert).
73     //
74     if (unit_type -> EnclosingType())
75         DeclareField(unit_type -> EnclosingInstance());
76     for (i = 0; i < unit_type -> NumConstructorParameters(); i++)
77         DeclareField(unit_type -> ConstructorParameter(i));
78     for (i = 0; i < unit_type -> NumClassLiterals(); i++)
79         DeclareField(unit_type -> ClassLiteral(i));
80     VariableSymbol* assert_variable = unit_type -> AssertVariable();
81     if (assert_variable)
82     {
83         assert(! control.option.noassert);
84         DeclareField(assert_variable);
85         if (control.option.target < JikesOption::SDK1_4)
86         {
87             semantic.ReportSemError(SemanticError::ASSERT_UNSUPPORTED_IN_TARGET,
88                                     unit_type -> declaration,
89                                     unit_type -> ContainingPackageName(),
90                                     unit_type -> ExternalName());
91             assert_variable = NULL;
92         }
93     }
94 
95     //
96     // Process declared methods.
97     //
98     for (i = 0; i < class_body -> NumMethods(); i++)
99     {
100         AstMethodDeclaration* method = class_body -> Method(i);
101         if (method -> method_symbol)
102         {
103             int method_index = methods.NextIndex(); // index for method
104             BeginMethod(method_index, method -> method_symbol);
105             if (method -> method_body_opt) // not an abstract method ?
106                 EmitBlockStatement(method -> method_body_opt);
107             EndMethod(method_index, method -> method_symbol);
108         }
109     }
110 
111     //
112     // Process synthetic methods (access$..., class$).
113     //
114     for (i = 0; i < unit_type -> NumPrivateAccessMethods(); i++)
115     {
116         int method_index = methods.NextIndex(); // index for method
117         MethodSymbol* method_sym = unit_type -> PrivateAccessMethod(i);
118         AstMethodDeclaration* method = method_sym -> declaration ->
119             MethodDeclarationCast();
120         assert(method);
121         BeginMethod(method_index, method_sym);
122         EmitBlockStatement(method -> method_body_opt);
123         EndMethod(method_index, method_sym);
124     }
125     MethodSymbol* class_literal_sym = unit_type -> ClassLiteralMethod();
126     if (class_literal_sym)
127     {
128         int method_index = methods.NextIndex(); // index for method
129         BeginMethod(method_index, class_literal_sym);
130         GenerateClassAccessMethod();
131         EndMethod(method_index, class_literal_sym);
132     }
133 
134     //
135     // Process the instance initializer.
136     //
137     bool has_instance_initializer = false;
138     if (unit_type -> instance_initializer_method)
139     {
140         AstMethodDeclaration* declaration = (AstMethodDeclaration*)
141             unit_type -> instance_initializer_method -> declaration;
142         AstBlock* init_block = declaration -> method_body_opt;
143         if (! IsNop(init_block))
144         {
145             int method_index = methods.NextIndex(); // index for method
146             BeginMethod(method_index,
147                         unit_type -> instance_initializer_method);
148             bool abrupt = EmitBlockStatement(init_block);
149             if (! abrupt)
150                 PutOp(OP_RETURN);
151             EndMethod(method_index, unit_type -> instance_initializer_method);
152             has_instance_initializer = true;
153         }
154     }
155 
156     //
157     // Process all constructors (including synthetic ones).
158     //
159     if (class_body -> default_constructor)
160         CompileConstructor(class_body -> default_constructor,
161                            constant_instance_fields, has_instance_initializer);
162     else
163     {
164         for (i = 0; i < class_body -> NumConstructors(); i++)
165             CompileConstructor(class_body -> Constructor(i),
166                                constant_instance_fields,
167                                has_instance_initializer);
168     }
169     for (i = 0; i < unit_type -> NumPrivateAccessConstructors(); i++)
170     {
171         MethodSymbol* constructor_sym =
172             unit_type -> PrivateAccessConstructor(i);
173         AstConstructorDeclaration* constructor =
174             constructor_sym -> declaration -> ConstructorDeclarationCast();
175         CompileConstructor(constructor, constant_instance_fields,
176                            has_instance_initializer);
177     }
178 
179     //
180     // Process the static initializer.
181     //
182     if (unit_type -> static_initializer_method)
183     {
184         AstMethodDeclaration* declaration = (AstMethodDeclaration*)
185             unit_type -> static_initializer_method -> declaration;
186         AstBlock* init_block = declaration -> method_body_opt;
187         if (assert_variable || ! IsNop(init_block))
188         {
189             int method_index = methods.NextIndex(); // index for method
190             BeginMethod(method_index, unit_type -> static_initializer_method);
191             if (assert_variable)
192                 GenerateAssertVariableInitializer(unit_type -> outermost_type,
193                                                   assert_variable);
194             bool abrupt = EmitBlockStatement(init_block);
195             if (! abrupt)
196                 PutOp(OP_RETURN);
197             EndMethod(method_index, unit_type -> static_initializer_method);
198         }
199     }
200 
201     FinishCode();
202 
203     //
204     // Check for overflow.
205     //
206     if (constant_pool.Length() > 65535)
207     {
208         semantic.ReportSemError(SemanticError::CONSTANT_POOL_OVERFLOW,
209                                 unit_type -> declaration,
210                                 unit_type -> ContainingPackageName(),
211                                 unit_type -> ExternalName());
212     }
213     if (interfaces.Length() > 65535)
214     {
215         // Interface overflow implies constant pool overflow.
216         semantic.ReportSemError(SemanticError::INTERFACES_OVERFLOW,
217                                 unit_type -> declaration,
218                                 unit_type -> ContainingPackageName(),
219                                 unit_type -> ExternalName());
220     }
221     if (fields.Length() > 65535)
222     {
223         // Field overflow implies constant pool overflow.
224         semantic.ReportSemError(SemanticError::FIELDS_OVERFLOW,
225                                 unit_type -> declaration,
226                                 unit_type -> ContainingPackageName(),
227                                 unit_type -> ExternalName());
228     }
229     if (methods.Length() > 65535)
230     {
231         // Method overflow implies constant pool overflow.
232         semantic.ReportSemError(SemanticError::METHODS_OVERFLOW,
233                                 unit_type -> declaration,
234                                 unit_type -> ContainingPackageName(),
235                                 unit_type -> ExternalName());
236     }
237     if (string_overflow)
238     {
239         semantic.ReportSemError(SemanticError::STRING_OVERFLOW,
240                                 unit_type -> declaration,
241                                 unit_type -> ContainingPackageName(),
242                                 unit_type -> ExternalName());
243     }
244     if (library_method_not_found)
245     {
246         semantic.ReportSemError(SemanticError::LIBRARY_METHOD_NOT_FOUND,
247                                 unit_type -> declaration,
248                                 unit_type -> ContainingPackageName(),
249                                 unit_type -> ExternalName());
250     }
251 
252     if (semantic.NumErrors() == 0)
253         Write(unit_type);
254 #ifdef JIKES_DEBUG
255     if (control.option.debug_dump_class)
256         Print();
257 #endif // JIKES_DEBUG
258 }
259 
260 
261 //
262 // initialized_fields is a list of fields needing code to initialize.
263 //
CompileConstructor(AstConstructorDeclaration * constructor,Tuple<AstVariableDeclarator * > & constants,bool has_instance_initializer)264 void ByteCode::CompileConstructor(AstConstructorDeclaration* constructor,
265                                   Tuple<AstVariableDeclarator*>& constants,
266                                   bool has_instance_initializer)
267 {
268     MethodSymbol* method_symbol = constructor -> constructor_symbol;
269     AstMethodBody* constructor_block = constructor -> constructor_body;
270 
271     int method_index = methods.NextIndex(); // index for method
272     BeginMethod(method_index, method_symbol);
273 
274     //
275     // Set up the index to account for this, this$0, and normal parameters,
276     // so we know where the local variable shadows begin.
277     //
278     shadow_parameter_offset = unit_type -> EnclosingType() ? 2 : 1;
279     if (unit_type -> NumConstructorParameters())
280     {
281         for (unsigned j = 0; j < method_symbol -> NumFormalParameters(); j++)
282             shadow_parameter_offset +=
283                 GetTypeWords(method_symbol -> FormalParameter(j) -> Type());
284     }
285 
286     if (control.option.target < JikesOption::SDK1_4)
287     {
288         //
289         // Prior to JDK 1.4, VMs incorrectly complained if shadow
290         // initialization happened before the superconstructor, even though
291         // the JVMS permits it.
292         //
293         if (constructor_block -> explicit_constructor_opt)
294             EmitStatement(constructor_block -> explicit_constructor_opt);
295         else
296             assert(unit_type == control.Object() &&
297                    "A constructor without an explicit constructor invocation");
298     }
299 
300     //
301     // Supply synthetic field initialization unless constructor calls this().
302     // Also initialize all constants.
303     //
304     if (constructor_block -> explicit_constructor_opt &&
305         ! constructor_block -> explicit_constructor_opt -> ThisCallCast())
306     {
307         if (unit_type -> EnclosingType())
308         {
309             //
310             // Initialize this$0
311             //
312             VariableSymbol* this0_parameter = unit_type -> EnclosingInstance();
313             PutOp(OP_ALOAD_0);
314             LoadLocal(1, this0_parameter -> Type());
315             PutOp(OP_PUTFIELD);
316             PutU2(RegisterFieldref(this0_parameter));
317         }
318 
319         for (unsigned i = 0, index = shadow_parameter_offset;
320              i < unit_type -> NumConstructorParameters(); i++)
321         {
322             VariableSymbol* shadow = unit_type -> ConstructorParameter(i);
323             PutOp(OP_ALOAD_0);
324             LoadLocal(index, shadow -> Type());
325             PutOp(OP_PUTFIELD);
326             if (control.IsDoubleWordType(shadow -> Type()))
327                 ChangeStack(-1);
328             PutU2(RegisterFieldref(shadow));
329             index += GetTypeWords(shadow -> Type());
330         }
331 
332         for (unsigned j = 0; j < constants.Length(); j ++)
333             EmitStatement(constants[j]);
334     }
335 
336     if (control.option.target >= JikesOption::SDK1_4)
337     {
338         //
339         // Since JDK 1.4, VMs correctly allow shadow initialization before
340         // the superconstructor, which is necessary to avoid null pointer
341         // exceptions with polymorphic calls from the superconstructor.
342         //
343         if (constructor_block -> explicit_constructor_opt)
344             EmitStatement(constructor_block -> explicit_constructor_opt);
345         else
346             assert(unit_type == control.Object() &&
347                    "A constructor without an explicit constructor invocation");
348     }
349 
350     //
351     // Compile instance initializers unless the constructor calls this().
352     //
353     shadow_parameter_offset = 0;
354     if (has_instance_initializer &&
355         constructor_block -> explicit_constructor_opt &&
356         ! constructor_block -> explicit_constructor_opt -> ThisCallCast())
357     {
358         PutOp(OP_ALOAD_0);
359         PutOp(OP_INVOKESPECIAL);
360         CompleteCall(unit_type -> instance_initializer_method, 0);
361     }
362 
363     EmitBlockStatement(constructor_block);
364     EndMethod(method_index, method_symbol);
365 }
366 
367 
DeclareField(VariableSymbol * symbol)368 void ByteCode::DeclareField(VariableSymbol* symbol)
369 {
370     int field_index = fields.NextIndex(); // index for field
371     fields[field_index] = new FieldInfo();
372     const TypeSymbol* type = symbol -> Type();
373     if (type -> num_dimensions > 255)
374     {
375         semantic.ReportSemError(SemanticError::ARRAY_OVERFLOW,
376                                 symbol -> declarator);
377     }
378 
379     fields[field_index] -> SetFlags(symbol -> Flags());
380     fields[field_index] -> SetNameIndex(RegisterName(symbol ->
381                                                      ExternalIdentity()));
382     fields[field_index] -> SetDescriptorIndex(RegisterUtf8(type -> signature));
383 
384     //
385     // Any final field initialized with a constant must have a ConstantValue
386     // attribute.  However, the VM only reads this value for static fields.
387     //
388     if (symbol -> initial_value)
389     {
390         assert(symbol -> ACC_FINAL());
391         assert(type -> Primitive() || type == control.String());
392         u2 index = ((control.IsSimpleIntegerValueType(type) ||
393                      type == control.boolean_type)
394                     ? RegisterInteger(DYNAMIC_CAST<IntLiteralValue*>
395                                       (symbol -> initial_value))
396                     : type == control.String()
397                     ? RegisterString(DYNAMIC_CAST<Utf8LiteralValue*>
398                                      (symbol -> initial_value))
399                     : type == control.float_type
400                     ? RegisterFloat(DYNAMIC_CAST<FloatLiteralValue*>
401                                     (symbol -> initial_value))
402                     : type == control.long_type
403                     ? RegisterLong(DYNAMIC_CAST<LongLiteralValue*>
404                                    (symbol -> initial_value))
405                     : RegisterDouble(DYNAMIC_CAST<DoubleLiteralValue*>
406                                      (symbol -> initial_value)));
407         u2 attribute_index = RegisterUtf8(control.ConstantValue_literal);
408         fields[field_index] ->
409             AddAttribute(new ConstantValueAttribute(attribute_index, index));
410     }
411 
412     if (symbol -> ACC_SYNTHETIC() &&
413         control.option.target < JikesOption::SDK1_5)
414     {
415         fields[field_index] -> AddAttribute(CreateSyntheticAttribute());
416     }
417 
418     if (symbol -> IsDeprecated())
419         fields[field_index] -> AddAttribute(CreateDeprecatedAttribute());
420 }
421 
422 
BeginMethod(int method_index,MethodSymbol * msym)423 void ByteCode::BeginMethod(int method_index, MethodSymbol* msym)
424 {
425     assert(msym);
426 
427 #ifdef DUMP
428     if (control.option.g)
429         Coutput << "(51) Generating code for method \"" << msym -> Name()
430                 << "\" in "
431                 << unit_type -> ContainingPackageName() << "/"
432                 << unit_type -> ExternalName() << endl;
433 #endif // DUMP
434 #ifdef JIKES_DEBUG
435     if (control.option.debug_trace_stack_change)
436         Coutput << endl << "Generating method "
437                 << unit_type -> ContainingPackageName() << '.'
438                 << unit_type -> ExternalName() << '.' << msym -> Name()
439                 << msym -> signature -> value << endl;
440 #endif // JIKES_DEBUG
441     MethodInitialization();
442 
443     methods[method_index] = new MethodInfo();
444     methods[method_index] ->
445         SetNameIndex(RegisterName(msym -> ExternalIdentity()));
446     methods[method_index] ->
447         SetDescriptorIndex(RegisterUtf8(msym -> signature));
448     methods[method_index] -> SetFlags(msym -> Flags());
449 
450     if (msym -> ACC_SYNTHETIC() &&
451         control.option.target < JikesOption::SDK1_5)
452     {
453         methods[method_index] -> AddAttribute(CreateSyntheticAttribute());
454     }
455 
456     if (msym -> IsDeprecated())
457         methods[method_index] -> AddAttribute(CreateDeprecatedAttribute());
458 
459     //
460     // Generate throws attribute if method throws any exceptions
461     //
462     if (msym -> NumThrows())
463     {
464         ExceptionsAttribute* exceptions_attribute =
465             new ExceptionsAttribute(RegisterUtf8(control.Exceptions_literal));
466         for (unsigned i = 0; i < msym -> NumThrows(); i++)
467             exceptions_attribute ->
468                 AddExceptionIndex(RegisterClass(msym -> Throws(i)));
469         methods[method_index] -> AddAttribute(exceptions_attribute);
470     }
471 
472     //
473     // here if need code and associated attributes.
474     //
475     if (! (msym -> ACC_ABSTRACT() || msym -> ACC_NATIVE()))
476     {
477         method_stack =
478             new MethodStack(msym -> max_block_depth,
479                             msym -> block_symbol -> max_variable_index);
480         code_attribute =
481             new CodeAttribute(RegisterUtf8(control.Code_literal),
482                               msym -> block_symbol -> max_variable_index);
483         line_number = 0;
484         line_number_table_attribute = new LineNumberTableAttribute
485             (RegisterUtf8(control.LineNumberTable_literal));
486 
487         local_variable_table_attribute = (control.option.g & JikesOption::VARS)
488             ? (new LocalVariableTableAttribute
489                (RegisterUtf8(control.LocalVariableTable_literal)))
490             : (LocalVariableTableAttribute*) NULL;
491     }
492 
493     if (msym -> Type() -> num_dimensions > 255)
494     {
495         assert(msym -> declaration -> MethodDeclarationCast());
496         Ast* type = ((AstMethodDeclaration*) msym -> declaration) -> type;
497 
498         semantic.ReportSemError(SemanticError::ARRAY_OVERFLOW, type);
499     }
500 
501     VariableSymbol* parameter = NULL;
502     for (unsigned i = 0; i < msym -> NumFormalParameters(); i++)
503     {
504         parameter = msym -> FormalParameter(i);
505         if (parameter -> Type() -> num_dimensions > 255)
506         {
507             semantic.ReportSemError(SemanticError::ARRAY_OVERFLOW,
508                                     parameter -> declarator);
509         }
510     }
511     if (parameter)
512     {
513         int last_parameter_index = parameter -> LocalVariableIndex();
514         if (control.IsDoubleWordType(parameter -> Type()))
515             last_parameter_index++;
516         if (last_parameter_index >= 255)
517         {
518             assert(msym -> declaration);
519 
520             AstMethodDeclaration* method_declaration =
521                 msym -> declaration -> MethodDeclarationCast();
522             AstConstructorDeclaration* constructor_declaration =
523                 msym -> declaration -> ConstructorDeclarationCast();
524             AstMethodDeclarator* declarator = method_declaration
525                 ? method_declaration -> method_declarator
526                 : constructor_declaration -> constructor_declarator;
527 
528             semantic.ReportSemError(SemanticError::PARAMETER_OVERFLOW,
529                                     declarator -> left_parenthesis_token,
530                                     declarator -> right_parenthesis_token,
531                                     msym -> Header(),
532                                     unit_type -> ContainingPackageName(),
533                                     unit_type -> ExternalName());
534         }
535     }
536 }
537 
538 
EndMethod(int method_index,MethodSymbol * msym)539 void ByteCode::EndMethod(int method_index, MethodSymbol* msym)
540 {
541     assert(msym);
542 
543     if (! (msym -> ACC_ABSTRACT() || msym -> ACC_NATIVE()))
544     {
545         //
546         // Make sure that no component in the code attribute exceeded its
547         // limit.
548         //
549         if (msym -> block_symbol -> max_variable_index > 65535)
550         {
551             semantic.ReportSemError(SemanticError::LOCAL_VARIABLES_OVERFLOW,
552                                     msym -> declaration, msym -> Header(),
553                                     unit_type -> ContainingPackageName(),
554                                     unit_type -> ExternalName());
555         }
556 
557         if (max_stack > 65535)
558         {
559             semantic.ReportSemError(SemanticError::STACK_OVERFLOW,
560                                     msym -> declaration, msym -> Header(),
561                                     unit_type -> ContainingPackageName(),
562                                     unit_type -> ExternalName());
563         }
564 
565         if (code_attribute -> CodeLengthExceeded())
566         {
567             semantic.ReportSemError(SemanticError::CODE_OVERFLOW,
568                                     msym -> declaration, msym -> Header(),
569                                     unit_type -> ContainingPackageName(),
570                                     unit_type -> ExternalName());
571         }
572 
573         //
574         //
575         //
576         code_attribute -> SetMaxStack(max_stack);
577 
578         //
579         // Sanity check - make sure nothing jumped past here
580         //
581         assert((u2) last_label_pc < code_attribute -> CodeLength() ||
582                code_attribute -> CodeLength() == 0x0ffff);
583         assert(stack_depth == 0);
584 
585         //
586         // attribute length:
587         // Need to review how to make attribute_name and attribute_length.
588         // Only write line number attribute if there are line numbers to
589         // write, and -g:lines is enabled.
590         //
591         if ((control.option.g & JikesOption::LINES) &&
592             line_number_table_attribute -> LineNumberTableLength())
593         {
594              code_attribute -> AddAttribute(line_number_table_attribute);
595         }
596         else
597         {
598             // line_number_table_attribute not needed, so delete it now
599             delete line_number_table_attribute;
600         }
601 
602         //
603         // Debug level -g:vars & not dealing with generated accessed method
604         //
605         if ((control.option.g & JikesOption::VARS)
606             && (! msym -> accessed_member)
607             && (msym -> Identity() != control.class_name_symbol))
608         {
609             if (! msym -> ACC_STATIC()) // add 'this' to local variable table
610             {
611                 local_variable_table_attribute ->
612                     AddLocalVariable(0, code_attribute -> CodeLength(),
613                                      RegisterUtf8(control.this_name_symbol -> Utf8_literal),
614                                      RegisterUtf8(msym -> containing_type -> signature),
615                                      0);
616             }
617 
618             //
619             // For a normal constructor or method.
620             //
621             for (unsigned i = 0; i < msym -> NumFormalParameters(); i++)
622             {
623                 VariableSymbol* parameter = msym -> FormalParameter(i);
624                 local_variable_table_attribute ->
625                     AddLocalVariable(0, code_attribute -> CodeLength(),
626                                      RegisterName(parameter -> ExternalIdentity()),
627                                      RegisterUtf8(parameter -> Type() -> signature),
628                                      parameter -> LocalVariableIndex());
629             }
630 
631             if (local_variable_table_attribute -> LocalVariableTableLength())
632                  code_attribute -> AddAttribute(local_variable_table_attribute);
633             else
634                 // local_variable_table_attribute not needed, so delete it now
635                 delete local_variable_table_attribute;
636         }
637         else delete local_variable_table_attribute;
638 
639         methods[method_index] -> AddAttribute(code_attribute);
640 
641         delete method_stack;
642     }
643 }
644 
645 
646 //
647 // This is called to initialize non-constant static fields, and all instance
648 // fields, that were declared with optional initializers.
649 //
InitializeVariable(AstVariableDeclarator * vd)650 void ByteCode::InitializeVariable(AstVariableDeclarator* vd)
651 {
652     assert(vd -> variable_initializer_opt && vd -> symbol);
653 
654     AstExpression* expression =
655         vd -> variable_initializer_opt -> ExpressionCast();
656     if (expression)
657     {
658         if (vd -> symbol -> ACC_STATIC())
659             assert(! vd -> symbol -> initial_value);
660         else
661             PutOp(OP_ALOAD_0); // load 'this' for instance variables
662         EmitExpression(expression);
663     }
664     else
665     {
666         AstArrayInitializer* array_initializer =
667             vd -> variable_initializer_opt -> ArrayInitializerCast();
668         assert(array_initializer);
669         if (! vd -> symbol -> ACC_STATIC())
670             PutOp(OP_ALOAD_0); // load 'this' for instance variables
671         InitializeArray(vd -> symbol -> Type(), array_initializer);
672     }
673 
674     PutOp(vd -> symbol -> ACC_STATIC() ? OP_PUTSTATIC : OP_PUTFIELD);
675     if (expression && control.IsDoubleWordType(expression -> Type()))
676         ChangeStack(-1);
677     PutU2(RegisterFieldref(vd -> symbol));
678 }
679 
680 
InitializeArray(const TypeSymbol * type,AstArrayInitializer * array_initializer,bool need_value)681 void ByteCode::InitializeArray(const TypeSymbol* type,
682                                AstArrayInitializer* array_initializer,
683                                bool need_value)
684 {
685     TypeSymbol* subtype = type -> ArraySubtype();
686 
687     if (need_value)
688     {
689         LoadImmediateInteger(array_initializer -> NumVariableInitializers());
690         EmitNewArray(1, type); // make the array
691     }
692     for (unsigned i = 0;
693          i < array_initializer -> NumVariableInitializers(); i++)
694     {
695         Ast* entry = array_initializer -> VariableInitializer(i);
696         AstExpression* expr = entry -> ExpressionCast();
697         if (expr && (IsZero(expr) || expr -> Type() == control.null_type))
698         {
699             bool optimize;
700             if (expr -> Type() == control.float_type)
701             {
702                 FloatLiteralValue* value = DYNAMIC_CAST<FloatLiteralValue*>
703                     (expr -> value);
704                 optimize = value -> value.IsPositiveZero();
705             }
706             else if (expr -> Type() == control.double_type)
707             {
708                 DoubleLiteralValue* value = DYNAMIC_CAST<DoubleLiteralValue*>
709                     (expr -> value);
710                 optimize = value -> value.IsPositiveZero();
711             }
712             else optimize = true;
713             if (optimize)
714             {
715                 EmitExpression(expr, false);
716                 continue;
717             }
718         }
719 
720         if (need_value)
721         {
722             PutOp(OP_DUP);
723             LoadImmediateInteger(i);
724         }
725         if (expr)
726              EmitExpression(expr, need_value);
727         else
728         {
729             assert(entry -> ArrayInitializerCast());
730             InitializeArray(subtype, entry -> ArrayInitializerCast(),
731                             need_value);
732         }
733         if (need_value)
734             StoreArrayElement(subtype);
735     }
736 }
737 
738 
739 //
740 // Generate code for local variable declaration.
741 //
DeclareLocalVariable(AstVariableDeclarator * declarator)742 void ByteCode::DeclareLocalVariable(AstVariableDeclarator* declarator)
743 {
744     if (control.option.g & JikesOption::VARS)
745     {
746 #ifdef JIKES_DEBUG
747         // Must be uninitialized.
748         assert(method_stack -> StartPc(declarator -> symbol) == 0xFFFF);
749 #endif // JIKES_DEBUG
750 #ifdef DUMP
751         Coutput << "(53) Variable \"" << declarator -> symbol -> Name()
752                 << "\" numbered "
753                 << declarator -> symbol -> LocalVariableIndex()
754                 << " was processed" << endl;
755 #endif // DUMP
756         method_stack -> StartPc(declarator -> symbol) =
757             code_attribute -> CodeLength();
758     }
759 
760     TypeSymbol* type = declarator -> symbol -> Type();
761     if (type -> num_dimensions > 255)
762         semantic.ReportSemError(SemanticError::ARRAY_OVERFLOW, declarator);
763 
764     if (declarator -> symbol -> initial_value)
765     {
766         //
767         // Optimization: If we are not tracking local variable names, we do
768         // not need to waste space on a constant as it is always inlined.
769         //
770         if (! (control.option.g & JikesOption::VARS))
771             return;
772         LoadLiteral(declarator -> symbol -> initial_value,
773                     declarator -> symbol -> Type());
774     }
775     else if (declarator -> variable_initializer_opt)
776     {
777         AstArrayCreationExpression* ace = declarator ->
778             variable_initializer_opt -> ArrayCreationExpressionCast();
779         AstArrayInitializer* ai = declarator ->
780             variable_initializer_opt -> ArrayInitializerCast();
781         if (ace)
782             EmitArrayCreationExpression(ace);
783         else if (ai)
784             InitializeArray(type, ai);
785         else // evaluation as expression
786         {
787             AstExpression* expr =
788                 (AstExpression*) declarator -> variable_initializer_opt;
789             assert(declarator -> variable_initializer_opt -> ExpressionCast());
790             EmitExpression(expr);
791             //
792             // Prior to JDK 1.5, VMs incorrectly complained if assigning an
793             // array type into an element of a null expression (in other
794             // words, null was not being treated as compatible with a
795             // multi-dimensional array on the aastore opcode).  The
796             // workaround requires a checkcast any time null might be
797             // assigned to a multi-dimensional local variable or directly
798             // used as an array access base.
799             //
800             if (control.option.target < JikesOption::SDK1_5 &&
801                 IsMultiDimensionalArray(type) &&
802                 (StripNops(expr) -> Type() == control.null_type))
803             {
804                 PutOp(OP_CHECKCAST);
805                 PutU2(RegisterClass(type));
806             }
807         }
808     }
809     else return; // if nothing to initialize
810 
811     StoreLocal(declarator -> symbol -> LocalVariableIndex(), type);
812 }
813 
814 
815 //
816 // JLS Chapter 13: Blocks and Statements
817 //  Statements control the sequence of evaluation of Java programs,
818 //  are executed for their effects and do not have values.
819 //
820 // Processing of loops requires a loop stack, especially to handle
821 // break and continue statements.
822 // Loops have three labels, LABEL_BEGIN for start of loop body,
823 // LABEL_BREAK to leave the loop, and LABEL_CONTINUE to continue the iteration.
824 // Each loop requires a break label; other labels are defined and used
825 // as needed.
826 // Labels allocated but never used incur no extra cost in the generated
827 // byte code, only in additional execution expense during compilation.
828 //
829 // This method returns true if the statement is guaranteed to complete
830 // abruptly (break, continue, throw, return, and special cases of if); it
831 // allows some dead code elimination.
832 //
EmitStatement(AstStatement * statement)833 bool ByteCode::EmitStatement(AstStatement* statement)
834 {
835     if (! statement -> BlockCast())
836     {
837         line_number_table_attribute ->
838             AddLineNumber(code_attribute -> CodeLength(),
839                           semantic.lex_stream -> Line(statement -> LeftToken()));
840     }
841 
842     assert(stack_depth == 0); // stack empty at start of statement
843 
844     switch (statement -> kind)
845     {
846     case Ast::METHOD_BODY:
847     case Ast::BLOCK: // JLS 14.2
848         return EmitBlockStatement((AstBlock*) statement);
849     case Ast::LOCAL_VARIABLE_DECLARATION: // JLS 14.3
850         {
851             AstLocalVariableStatement* lvs =
852                 statement -> LocalVariableStatementCast();
853             for (unsigned i = 0; i < lvs -> NumVariableDeclarators(); i++)
854                 DeclareLocalVariable(lvs -> VariableDeclarator(i));
855         }
856         return false;
857     case Ast::EMPTY_STATEMENT: // JLS 14.5
858         return false;
859     case Ast::EXPRESSION_STATEMENT: // JLS 14.7
860         EmitStatementExpression(statement -> ExpressionStatementCast() ->
861                                 expression);
862         return false;
863     case Ast::IF: // JLS 14.8
864         {
865             AstIfStatement* if_statement = (AstIfStatement*) statement;
866             // Constant condition.
867             if (IsOne(if_statement -> expression))
868                 return EmitBlockStatement(if_statement -> true_statement);
869             if (IsZero(if_statement -> expression))
870             {
871                 if (if_statement -> false_statement_opt)
872                     return EmitBlockStatement(if_statement ->
873                                               false_statement_opt);
874                 return false;
875             }
876             // True and false parts.
877             if (if_statement -> false_statement_opt &&
878                 ! IsNop(if_statement -> false_statement_opt))
879             {
880                 if (IsNop(if_statement -> true_statement))
881                 {
882                     Label label;
883                     EmitBranchIfExpression(if_statement -> expression,
884                                            true, label,
885                                            (if_statement ->
886                                             false_statement_opt));
887                     assert(stack_depth == 0);
888                     EmitBlockStatement(if_statement -> false_statement_opt);
889                     DefineLabel(label);
890                     CompleteLabel(label);
891                     return false;
892                 }
893                 Label label1,
894                       label2;
895                 bool abrupt;
896                 AstBlock* true_statement = if_statement -> true_statement;
897                 EmitBranchIfExpression(if_statement -> expression,
898                                        false, label1, true_statement);
899                 assert(stack_depth == 0);
900 
901                 abrupt = EmitBlockStatement(true_statement);
902                 if (! abrupt)
903                     EmitBranch(OP_GOTO, label2,
904                                if_statement -> false_statement_opt);
905 
906                 DefineLabel(label1);
907                 abrupt &= EmitBlockStatement(if_statement ->
908                                              false_statement_opt);
909 
910                 if (! abrupt)
911                 {
912                     DefineLabel(label2);
913                     CompleteLabel(label2);
914                 }
915                 CompleteLabel(label1);
916                 return abrupt;
917             }
918             // No false part.
919             if (IsNop(if_statement -> true_statement))
920             {
921                 EmitExpression(if_statement -> expression, false);
922                 return false;
923             }
924             Label label1;
925             EmitBranchIfExpression(if_statement -> expression,
926                                    false, label1,
927                                    if_statement -> true_statement);
928             assert(stack_depth == 0);
929             EmitBlockStatement(if_statement -> true_statement);
930             DefineLabel(label1);
931             CompleteLabel(label1);
932             return false;
933         }
934     case Ast::SWITCH: // JLS 14.9
935         return EmitSwitchStatement(statement -> SwitchStatementCast());
936     case Ast::SWITCH_BLOCK: // JLS 14.9
937     case Ast::SWITCH_LABEL:
938         //
939         // These nodes are handled by SwitchStatement and
940         // are not directly visited.
941         //
942         assert(false && "faulty logic encountered");
943         return false;
944     case Ast::WHILE: // JLS 14.10
945         {
946             AstWhileStatement* wp = statement -> WhileStatementCast();
947             bool abrupt = false;
948             //
949             // Branch to continuation test. This test is placed after the
950             // body of the loop we can fall through into it after each
951             // loop iteration without the need for an additional branch,
952             // unless the loop body always completes abruptly.
953             //
954             if (! wp -> statement -> can_complete_normally)
955             {
956                 if (wp -> expression -> IsConstant())
957                 {
958                     // must be true, or internal statement would be
959                     // unreachable
960                     assert(semantic.IsConstantTrue(wp -> expression));
961                     abrupt = true;
962                 }
963                 else
964                 {
965                     line_number_table_attribute ->
966                         AddLineNumber(code_attribute -> CodeLength(),
967                                       semantic.lex_stream -> Line(wp -> expression -> LeftToken()));
968                     EmitBranchIfExpression(wp -> expression, false,
969                                            method_stack -> TopBreakLabel(),
970                                            wp -> statement);
971                 }
972                 EmitBlockStatement(wp -> statement);
973                 assert(stack_depth == 0);
974                 return abrupt;
975             }
976             Label& continue_label = method_stack -> TopContinueLabel();
977             if (wp -> expression -> IsConstant())
978             {
979                 // must be true, or internal statement would be
980                 // unreachable
981                 assert(semantic.IsConstantTrue(wp -> expression));
982                 abrupt = true;
983             }
984             else
985                 EmitBranch(OP_GOTO, continue_label, wp -> statement);
986             Label begin_label;
987             DefineLabel(begin_label);
988             u2 begin_pc = code_attribute -> CodeLength();
989             abrupt |= EmitBlockStatement(wp -> statement);
990             bool empty = (begin_pc == code_attribute -> CodeLength());
991             DefineLabel(continue_label);
992             assert(stack_depth == 0);
993 
994             //
995             // Reset the line number before evaluating the expression
996             //
997             line_number_table_attribute ->
998                 AddLineNumber(code_attribute -> CodeLength(),
999                               semantic.lex_stream -> Line(wp -> expression -> LeftToken()));
1000 
1001             EmitBranchIfExpression(wp -> expression, true,
1002                                    empty ? continue_label : begin_label,
1003                                    wp -> statement);
1004             CompleteLabel(begin_label);
1005             CompleteLabel(continue_label);
1006             return abrupt && ! wp -> can_complete_normally;
1007         }
1008     case Ast::DO: // JLS 14.11
1009         {
1010             AstDoStatement* sp = statement -> DoStatementCast();
1011             Label begin_label;
1012             DefineLabel(begin_label);
1013             bool abrupt = EmitBlockStatement(sp -> statement);
1014             if (IsLabelUsed(method_stack -> TopContinueLabel()))
1015             {
1016                 DefineLabel(method_stack -> TopContinueLabel());
1017                 CompleteLabel(method_stack -> TopContinueLabel());
1018                 abrupt = false;
1019             }
1020             assert(stack_depth == 0);
1021 
1022             if (! abrupt)
1023             {
1024                 //
1025                 // Reset the line number before evaluating the expression
1026                 //
1027                 line_number_table_attribute ->
1028                     AddLineNumber(code_attribute -> CodeLength(),
1029                                   semantic.lex_stream -> Line(sp -> expression -> LeftToken()));
1030                 EmitBranchIfExpression(sp -> expression, true,
1031                                        begin_label, sp -> statement);
1032             }
1033             CompleteLabel(begin_label);
1034             return (abrupt || IsOne(sp -> expression)) &&
1035                 ! sp -> can_complete_normally;
1036         }
1037     case Ast::FOR: // JLS 14.12
1038         {
1039             AstForStatement* for_statement = statement -> ForStatementCast();
1040             bool abrupt = false;
1041             for (unsigned i = 0; i < for_statement -> NumForInitStatements(); i++)
1042                 EmitStatement(for_statement -> ForInitStatement(i));
1043             Label begin_label;
1044             Label test_label;
1045             //
1046             // The loop test is placed after the body, unless the body
1047             // always completes abruptly, to save an additional jump.
1048             //
1049             if (! for_statement -> statement -> can_complete_normally)
1050             {
1051                 abrupt = true;
1052                 if (for_statement -> end_expression_opt)
1053                 {
1054                     if (for_statement -> end_expression_opt -> IsConstant())
1055                     {
1056                         // must be true, or internal statement would be
1057                         // unreachable
1058                         assert(semantic.IsConstantTrue(for_statement -> end_expression_opt));
1059                     }
1060                     else
1061                     {
1062                         abrupt = false;
1063                         line_number_table_attribute ->
1064                             AddLineNumber(code_attribute -> CodeLength(),
1065                                           semantic.lex_stream -> Line(for_statement -> end_expression_opt -> LeftToken()));
1066                         EmitBranchIfExpression(for_statement -> end_expression_opt,
1067                                                false,
1068                                                method_stack -> TopBreakLabel(),
1069                                                for_statement -> statement);
1070                     }
1071                 }
1072                 EmitBlockStatement(for_statement -> statement);
1073                 assert(stack_depth == 0);
1074                 return abrupt;
1075             }
1076             Label& continue_label = method_stack -> TopContinueLabel();
1077             if (for_statement -> end_expression_opt &&
1078                 ! for_statement -> end_expression_opt -> IsConstant())
1079             {
1080                 EmitBranch(OP_GOTO,
1081                            (for_statement -> NumForUpdateStatements()
1082                             ? test_label : continue_label),
1083                            for_statement -> statement);
1084             }
1085             else
1086                 abrupt = true;
1087             DefineLabel(begin_label);
1088             u2 begin_pc = code_attribute -> CodeLength();
1089             abrupt |= EmitBlockStatement(for_statement -> statement);
1090             bool empty = (begin_pc == code_attribute -> CodeLength());
1091             DefineLabel(continue_label);
1092             for (unsigned j = 0;
1093                  j < for_statement -> NumForUpdateStatements(); j++)
1094             {
1095                 EmitStatement(for_statement -> ForUpdateStatement(j));
1096             }
1097             DefineLabel(test_label);
1098             CompleteLabel(test_label);
1099 
1100             AstExpression* end_expr = for_statement -> end_expression_opt;
1101             if (end_expr)
1102             {
1103                 assert(stack_depth == 0);
1104 
1105                 //
1106                 // Reset the line number before evaluating the expression
1107                 //
1108                 line_number_table_attribute ->
1109                     AddLineNumber(code_attribute -> CodeLength(),
1110                                   semantic.lex_stream -> Line(end_expr ->
1111                                                               LeftToken()));
1112 
1113                 EmitBranchIfExpression(end_expr, true,
1114                                        empty ? continue_label : begin_label,
1115                                        for_statement -> statement);
1116             }
1117             else EmitBranch(OP_GOTO, empty ? continue_label : begin_label,
1118                             for_statement -> statement);
1119             CompleteLabel(continue_label);
1120             CompleteLabel(begin_label);
1121             return abrupt && ! for_statement -> can_complete_normally;
1122         }
1123     case Ast::FOREACH: // JSR 201
1124         EmitForeachStatement((AstForeachStatement*) statement);
1125         return false;
1126     case Ast::BREAK: // JLS 14.13
1127         {
1128             unsigned nesting_level =
1129                 statement -> BreakStatementCast() -> nesting_level;
1130             AstBlock* over = method_stack -> Block(nesting_level);
1131             u2 jump_size = (over -> RightToken() - over -> LeftToken() <
1132                             TOKEN_WIDTH_REQUIRING_GOTOW) ? 3 : 5;
1133             if (ProcessAbruptExit(nesting_level, jump_size))
1134             {
1135                 EmitBranch(OP_GOTO, method_stack -> BreakLabel(nesting_level),
1136                            over);
1137             }
1138             return true;
1139         }
1140     case Ast::CONTINUE: // JLS 14.14
1141         {
1142             unsigned nesting_level =
1143                 statement -> ContinueStatementCast() -> nesting_level;
1144             AstBlock* over = method_stack -> Block(nesting_level);
1145             u2 jump_size = (over -> RightToken() - over -> LeftToken() <
1146                             TOKEN_WIDTH_REQUIRING_GOTOW) ? 3 : 5;
1147             if (ProcessAbruptExit(nesting_level, jump_size))
1148             {
1149                 EmitBranch(OP_GOTO,
1150                            method_stack -> ContinueLabel(nesting_level),
1151                            over);
1152             }
1153             return true;
1154         }
1155     case Ast::RETURN: // JLS 14.15
1156         EmitReturnStatement(statement -> ReturnStatementCast());
1157         return true;
1158     case Ast::SUPER_CALL:
1159         EmitSuperInvocation((AstSuperCall*) statement);
1160         return false;
1161     case Ast::THIS_CALL:
1162         EmitThisInvocation((AstThisCall*) statement);
1163         return false;
1164     case Ast::THROW: // JLS 14.16
1165         EmitExpression(statement -> ThrowStatementCast() -> expression);
1166         PutOp(OP_ATHROW);
1167         return true;
1168     case Ast::SYNCHRONIZED_STATEMENT: // JLS 14.17
1169         return EmitSynchronizedStatement((AstSynchronizedStatement*) statement);
1170     case Ast::TRY: // JLS 14.18
1171         EmitTryStatement((AstTryStatement*) statement);
1172         return ! statement -> can_complete_normally;
1173     case Ast::CATCH:   // JLS 14.18
1174     case Ast::FINALLY: // JLS 14.18
1175         // handled by TryStatement
1176         assert(false && "should not get here");
1177         return false;
1178     case Ast::ASSERT: // JDK 1.4 (JSR 41)
1179         EmitAssertStatement((AstAssertStatement*) statement);
1180         return false;
1181     case Ast::LOCAL_CLASS: // Class Declaration
1182         //
1183         // This is factored out by the front end; and so must be
1184         // skipped here (remember, interfaces cannot be declared locally).
1185         //
1186         return false;
1187     case Ast::VARIABLE_DECLARATOR:
1188         //
1189         // This is not really a statement, but we treat it as one to make
1190         // initializer blocks easier to intermix with variable declarations.
1191         //
1192         InitializeVariable((AstVariableDeclarator*) statement);
1193         return false;
1194     default:
1195         assert(false && "unknown statement kind");
1196         return false;
1197     }
1198 }
1199 
1200 
EmitReturnStatement(AstReturnStatement * statement)1201 void ByteCode::EmitReturnStatement(AstReturnStatement* statement)
1202 {
1203     AstExpression* expression = statement -> expression_opt;
1204 
1205     if (! expression)
1206     {
1207         if (ProcessAbruptExit(method_stack -> NestingLevel(0), 1))
1208             PutOp(OP_RETURN);
1209     }
1210     else
1211     {
1212         TypeSymbol* type = expression -> Type();
1213         assert(type != control.void_type);
1214 
1215         EmitExpression(expression);
1216 
1217         if (ProcessAbruptExit(method_stack -> NestingLevel(0), 1, type))
1218             GenerateReturn(type);
1219     }
1220 }
1221 
1222 
EmitBlockStatement(AstBlock * block)1223 bool ByteCode::EmitBlockStatement(AstBlock* block)
1224 {
1225     assert(stack_depth == 0); // stack empty at start of statement
1226 
1227     method_stack -> Push(block);
1228     bool abrupt = false;
1229     for (unsigned i = 0; i < block -> NumStatements() && ! abrupt; i++)
1230         abrupt = EmitStatement(block -> Statement(i));
1231 
1232     //
1233     // If contained break statements jump out of this block, define the label.
1234     //
1235     if (IsLabelUsed(method_stack -> TopBreakLabel()))
1236     {
1237         DefineLabel(method_stack -> TopBreakLabel());
1238         CompleteLabel(method_stack -> TopBreakLabel());
1239         abrupt = false;
1240     }
1241 
1242     if (control.option.g & JikesOption::VARS)
1243     {
1244         for (unsigned i = 0; i < block -> NumLocallyDefinedVariables(); i++)
1245         {
1246             VariableSymbol* variable = block -> LocallyDefinedVariable(i);
1247             if (method_stack -> StartPc(variable) == 0xFFFF) // never used
1248                 continue;
1249 #ifdef DUMP
1250             Coutput << "(56) The symbol \"" << variable -> Name()
1251                     << "\" numbered " << variable -> LocalVariableIndex()
1252                     << " was released" << endl;
1253 #endif // DUMP
1254             local_variable_table_attribute ->
1255                 AddLocalVariable(method_stack -> StartPc(variable),
1256                                  code_attribute -> CodeLength(),
1257                                  RegisterName(variable -> ExternalIdentity()),
1258                                  RegisterUtf8(variable -> Type() -> signature),
1259                                  variable -> LocalVariableIndex());
1260         }
1261     }
1262 
1263     method_stack -> Pop();
1264     return abrupt;
1265 }
1266 
1267 
EmitStatementExpression(AstExpression * expression)1268 void ByteCode::EmitStatementExpression(AstExpression* expression)
1269 {
1270     switch (expression -> kind)
1271     {
1272     case Ast::CALL:
1273         EmitMethodInvocation((AstMethodInvocation*) expression, false);
1274         break;
1275     case Ast::POST_UNARY:
1276         EmitPostUnaryExpression((AstPostUnaryExpression*) expression, false);
1277         break;
1278     case Ast::PRE_UNARY:
1279         EmitPreUnaryExpression((AstPreUnaryExpression*) expression, false);
1280         break;
1281     case Ast::ASSIGNMENT:
1282         EmitAssignmentExpression((AstAssignmentExpression*) expression, false);
1283         break;
1284     case Ast::CLASS_CREATION:
1285         EmitClassCreationExpression((AstClassCreationExpression*) expression,
1286                                     false);
1287         break;
1288     default:
1289         assert(false && "invalid statement expression kind");
1290     }
1291 }
1292 
1293 
1294 //
1295 // Generate code for switch statement. Good code generation requires
1296 // detailed knowledge of the target machine. Lacking this, we simply
1297 // choose between LOOKUPSWITCH and TABLESWITCH by picking that
1298 // opcode that takes the least number of bytes in the byte code.
1299 //
1300 // With TABLESWITCH, a target must be provided for every entry in the range
1301 // low..high, even though the user may not have provided an explicit entry,
1302 // in which case the default action is to be taken. For example
1303 // switch (e) {
1304 //  case 1:2:3: act1; break;
1305 //  case 5:6:   act2; break;
1306 //  default: defact; break;
1307 // }
1308 // translates as
1309 // switch (e) {
1310 //  case 1:2:3: act1; break;
1311 //  case 4: goto defa:
1312 //  case 5:6:   act2; break;
1313 //  defa:
1314 //  default: defact;
1315 // }
1316 //
EmitSwitchStatement(AstSwitchStatement * switch_statement)1317 bool ByteCode::EmitSwitchStatement(AstSwitchStatement* switch_statement)
1318 {
1319     AstBlock* switch_block = switch_statement -> switch_block;
1320     u2 op_start = code_attribute -> CodeLength();
1321     unsigned i;
1322     bool abrupt;
1323 
1324     assert(stack_depth == 0); // stack empty at start of statement
1325 
1326     //
1327     // Optimization: When switching on a constant, emit only those blocks
1328     // that it will flow through.
1329     // switch (constant) { ... } => single code path
1330     //
1331     if (switch_statement -> expression -> IsConstant())
1332     {
1333         CaseElement* target = switch_statement ->
1334             CaseForValue(DYNAMIC_CAST<IntLiteralValue*>
1335                          (switch_statement -> expression -> value) -> value);
1336         if (! target)
1337             return false;
1338         //
1339         // Bring all previously-declared variables into scope, then compile
1340         // until we run out of blocks or else complete abruptly.
1341         //
1342         method_stack -> Push(switch_block);
1343         for (i = 0; i < target -> block_index; i++)
1344             EmitSwitchBlockStatement(switch_statement -> Block(i), true);
1345         abrupt = false;
1346         for ( ; ! abrupt && i < switch_statement -> NumBlocks(); i++)
1347         {
1348             abrupt =
1349                 EmitSwitchBlockStatement(switch_statement -> Block(i), abrupt);
1350         }
1351 
1352         CloseSwitchLocalVariables(switch_block, op_start);
1353         if (IsLabelUsed(method_stack -> TopBreakLabel()))
1354         {
1355             abrupt = false;
1356             DefineLabel(method_stack -> TopBreakLabel());
1357             CompleteLabel(method_stack -> TopBreakLabel());
1358         }
1359         method_stack -> Pop();
1360         return abrupt;
1361     }
1362 
1363     //
1364     // Optimization: When there are zero blocks, emit the expression.
1365     // switch (expr) {} => expr;
1366     //
1367     if (! switch_statement -> NumBlocks())
1368     {
1369         EmitExpression(switch_statement -> expression, false);
1370         return false;
1371     }
1372 
1373     //
1374     // Optimization: When there is one block labeled by default, emit it.
1375     // switch (expr) { default: block; } => expr, block
1376     // switch (expr) { case a: default: block; } => expr, block
1377     //
1378     if (switch_statement -> NumBlocks() == 1 &&
1379         switch_statement -> DefaultCase())
1380     {
1381         EmitExpression(switch_statement -> expression, false);
1382         method_stack -> Push(switch_block);
1383         abrupt = EmitSwitchBlockStatement(switch_statement -> Block(0), false);
1384         CloseSwitchLocalVariables(switch_block, op_start);
1385         if (IsLabelUsed(method_stack -> TopBreakLabel()))
1386         {
1387             abrupt = false;
1388             DefineLabel(method_stack -> TopBreakLabel());
1389             CompleteLabel(method_stack -> TopBreakLabel());
1390         }
1391         method_stack -> Pop();
1392         return abrupt;
1393     }
1394 
1395     //
1396     // Optimization: If there is one non-default label, turn this into an
1397     // if statement.
1398     //
1399     if (switch_statement -> NumCases() == 1)
1400     {
1401         //
1402         // switch (expr) { case a: block; } => if (expr == a) block;
1403         //
1404         if (! switch_statement -> DefaultCase())
1405         {
1406             EmitExpression(switch_statement -> expression);
1407             Label lab;
1408             if (switch_statement -> Case(0) -> value)
1409             {
1410                 LoadImmediateInteger(switch_statement -> Case(0) -> value);
1411                 EmitBranch(OP_IF_ICMPNE, lab, switch_block);
1412             }
1413             else EmitBranch(OP_IFNE, lab, switch_block);
1414             method_stack -> Push(switch_block);
1415             EmitSwitchBlockStatement(switch_statement -> Block(0), false);
1416             CloseSwitchLocalVariables(switch_block, op_start);
1417             if (IsLabelUsed(method_stack -> TopBreakLabel()))
1418             {
1419                 DefineLabel(method_stack -> TopBreakLabel());
1420                 CompleteLabel(method_stack -> TopBreakLabel());
1421             }
1422             method_stack -> Pop();
1423             DefineLabel(lab);
1424             CompleteLabel(lab);
1425             return false;
1426         }
1427         //
1428         // TODO: Implement these optimizations.
1429         // switch (expr) { case a: fallthrough_block; default: block; }
1430         //  => if (expr == a) fallthrough_block; block;
1431         // switch (expr) { case a: abrupt_block; default: block; }
1432         //  => if (expr == a) abrupt_block; else block;
1433         // switch (expr) { default: fallthrough_block; case a: block; }
1434         //  => if (expr != a) fallthrough_block; block;
1435         // switch (expr) { default: abrupt_block; case a: block; }
1436         //  => if (expr != a) abrupt_block; else block;
1437         //
1438     }
1439 
1440     //
1441     // Use tableswitch if size of tableswitch case is no more than 32 bytes
1442     // (8 words) more code than lookup case.
1443     //
1444     bool use_lookup = true; // set if using LOOKUPSWITCH opcode
1445     unsigned ncases = switch_statement -> NumCases();
1446     unsigned nlabels = ncases;
1447     i4 high = 0,
1448        low = 0;
1449     if (ncases)
1450     {
1451         low = switch_statement -> Case(0) -> value;
1452         high = switch_statement -> Case(ncases - 1) -> value;
1453         assert(low <= high);
1454 
1455         //
1456         // Workaround for Sun JVM TABLESWITCH bug in JDK 1.2, 1.3
1457         // when case values of 0x7ffffff0 through 0x7fffffff are used.
1458         // Force the generation of a LOOKUPSWITCH in these circumstances.
1459         //
1460         if (high < 0x7ffffff0L ||
1461             control.option.target >= JikesOption::SDK1_4)
1462         {
1463             // We want to compute (1 + (high - low + 1)) < (ncases * 2 + 8).
1464             // However, we must beware of integer overflow.
1465             i4 range = high - low + 1;
1466             if (range > 0 && (unsigned) range < (ncases * 2 + 8))
1467             {
1468                 use_lookup = false; // use tableswitch
1469                 nlabels = range;
1470                 assert(nlabels >= ncases);
1471             }
1472         }
1473     }
1474 
1475     //
1476     // Set up the environment for the switch block.  This must be done before
1477     // emitting the expression, in case the expression is an assignment.
1478     //
1479     method_stack -> Push(switch_block);
1480 
1481     //
1482     // Reset the line number before evaluating the expression
1483     //
1484     line_number_table_attribute ->
1485         AddLineNumber(code_attribute -> CodeLength(),
1486                       semantic.lex_stream -> Line(switch_statement ->
1487                                                   expression -> LeftToken()));
1488     EmitExpression(switch_statement -> expression);
1489 
1490     PutOp(use_lookup ? OP_LOOKUPSWITCH : OP_TABLESWITCH);
1491     op_start = last_op_pc; // pc at start of instruction
1492 
1493     //
1494     // Supply any needed padding.
1495     //
1496     while (code_attribute -> CodeLength() % 4 != 0)
1497         PutU1(0);
1498 
1499     //
1500     // Note that if there is no default clause in switch statement, we create
1501     // one that corresponds to do nothing and branches to start of next
1502     // statement. The default label is case_labels[nlabels].
1503     //
1504     Label* case_labels = new Label[nlabels + 1];
1505     UseLabel(case_labels[nlabels], 4,
1506              code_attribute -> CodeLength() - op_start);
1507 
1508     if (use_lookup)
1509     {
1510         PutU4(ncases);
1511         for (i = 0; i < ncases; i++)
1512         {
1513             PutU4(switch_statement -> Case(i) -> value);
1514             UseLabel(case_labels[i], 4,
1515                      code_attribute -> CodeLength() - op_start);
1516         }
1517     }
1518     else
1519     {
1520         PutU4(low);
1521         PutU4(high);
1522         for (i = 0; i < nlabels; i++)
1523         {
1524             UseLabel(case_labels[i], 4,
1525                      code_attribute -> CodeLength() - op_start);
1526         }
1527     }
1528 
1529     //
1530     // March through switch block statements, compiling blocks in proper
1531     // order. We must respect order in which blocks are seen so that blocks
1532     // lacking a terminal break fall through to the proper place.
1533     //
1534     abrupt = false;
1535     for (i = 0; i < switch_block -> NumStatements(); i++)
1536     {
1537         AstSwitchBlockStatement* switch_block_statement =
1538             switch_statement -> Block(i);
1539         for (unsigned li = 0;
1540              li < switch_block_statement -> NumSwitchLabels(); li++)
1541         {
1542             AstSwitchLabel* switch_label =
1543                 switch_block_statement -> SwitchLabel(li);
1544             if (use_lookup)
1545                 DefineLabel(case_labels[switch_label -> map_index]);
1546             else if (switch_label -> expression_opt)
1547             {
1548                 i4 value = DYNAMIC_CAST<IntLiteralValue*>
1549                     (switch_label -> expression_opt -> value) -> value;
1550                 DefineLabel(case_labels[value - low]);
1551             }
1552             else
1553             {
1554                 DefineLabel(case_labels[nlabels]);
1555                 //
1556                 // We must also point all inserted cases to the default.
1557                 //
1558                 unsigned j = 1;
1559                 i4 k = low + 1;
1560                 for ( ; j < switch_statement -> NumCases(); j++, k++)
1561                     while (k != switch_statement -> Case(j) -> value)
1562                         DefineLabel(case_labels[k++ - low]);
1563             }
1564         }
1565         abrupt = EmitSwitchBlockStatement(switch_block_statement, false);
1566     }
1567 
1568     CloseSwitchLocalVariables(switch_block, op_start);
1569     for (i = 0; i <= nlabels; i++)
1570     {
1571         if (! case_labels[i].defined)
1572         {
1573             abrupt = false;
1574             DefineLabel(case_labels[i]);
1575         }
1576         CompleteLabel(case_labels[i]);
1577     }
1578     //
1579     // If this switch statement was "broken", we define the break label here.
1580     //
1581     if (IsLabelUsed(method_stack -> TopBreakLabel()))
1582     {
1583         // need define only if used
1584         DefineLabel(method_stack -> TopBreakLabel());
1585         CompleteLabel(method_stack -> TopBreakLabel());
1586         abrupt = false;
1587     }
1588 
1589     delete [] case_labels;
1590     method_stack -> Pop();
1591     assert(abrupt || switch_statement -> can_complete_normally);
1592     return abrupt;
1593 }
1594 
1595 
EmitSwitchBlockStatement(AstSwitchBlockStatement * block,bool abrupt)1596 bool ByteCode::EmitSwitchBlockStatement(AstSwitchBlockStatement* block,
1597                                         bool abrupt)
1598 {
1599     for (unsigned i = 0; i < block -> NumStatements(); i++)
1600     {
1601         if (! abrupt)
1602             abrupt = EmitStatement(block -> Statement(i));
1603         else if (block -> Statement(i) -> LocalVariableStatementCast())
1604         {
1605             //
1606             // In a switch statement, local variable declarations are
1607             // accessible in other case labels even if the declaration
1608             // itself is unreachable.
1609             //
1610             AstLocalVariableStatement* lvs =
1611                 (AstLocalVariableStatement*) block -> Statement(i);
1612             for (unsigned j = 0; j < lvs -> NumVariableDeclarators(); j++)
1613             {
1614                 AstVariableDeclarator* declarator =
1615                     lvs -> VariableDeclarator(j);
1616                 if (control.option.g & JikesOption::VARS)
1617                 {
1618                     method_stack -> StartPc(declarator -> symbol) =
1619                         code_attribute -> CodeLength();
1620                 }
1621                 if (declarator -> symbol -> Type() -> num_dimensions > 255)
1622                 {
1623                     semantic.ReportSemError(SemanticError::ARRAY_OVERFLOW,
1624                                             declarator);
1625                 }
1626             }
1627         }
1628     }
1629     return abrupt;
1630 }
1631 
1632 
CloseSwitchLocalVariables(AstBlock * switch_block,u2 op_start)1633 void ByteCode::CloseSwitchLocalVariables(AstBlock* switch_block,
1634                                          u2 op_start)
1635 {
1636     if (control.option.g & JikesOption::VARS)
1637     {
1638         for (unsigned i = 0;
1639              i < switch_block -> NumLocallyDefinedVariables(); i++)
1640         {
1641             VariableSymbol* variable =
1642                 switch_block -> LocallyDefinedVariable(i);
1643             if (method_stack -> StartPc(variable) > op_start)
1644             {
1645                 if (method_stack -> StartPc(variable) == 0xFFFF) // never used
1646                     continue;
1647 #ifdef DUMP
1648                 Coutput << "(58) The symbol \"" << variable -> Name()
1649                         << "\" numbered " << variable -> LocalVariableIndex()
1650                         << " was released" << endl;
1651 #endif // DUMP
1652                 local_variable_table_attribute ->
1653                     AddLocalVariable(method_stack -> StartPc(variable),
1654                                      code_attribute -> CodeLength(),
1655                                      RegisterName(variable -> ExternalIdentity()),
1656                                      RegisterUtf8(variable -> Type() -> signature),
1657                                      variable -> LocalVariableIndex());
1658             }
1659         }
1660     }
1661 }
1662 
1663 
1664 //
1665 //  13.18       The try statement
1666 //
EmitTryStatement(AstTryStatement * statement)1667 void ByteCode::EmitTryStatement(AstTryStatement* statement)
1668 {
1669     //
1670     // If the finally label in the surrounding block is used by a try
1671     // statement, it is cleared after the finally block associated with the
1672     // try statement has been processed.
1673     //
1674     assert(method_stack -> TopFinallyLabel().uses.Length() == 0);
1675     assert(method_stack -> TopFinallyLabel().defined == false);
1676     assert(method_stack -> TopFinallyLabel().definition == 0);
1677 
1678     u2 start_try_block_pc = code_attribute -> CodeLength(); // start pc
1679     assert(method_stack -> TopHandlerRangeStart().Length() == 0 &&
1680            method_stack -> TopHandlerRangeEnd().Length() == 0);
1681     method_stack -> TopHandlerRangeStart().Push(start_try_block_pc);
1682     bool emit_finally_clause = statement -> finally_clause_opt &&
1683         ! IsNop(statement -> finally_clause_opt -> block);
1684 
1685     //
1686     // If we determined the finally clause is a nop, remove the tag
1687     // TRY_CLAUSE_WITH_FINALLY so that abrupt completions do not emit JSR.
1688     // On the other hand, if the finally clause cannot complete normally,
1689     // change the tag to ABRUPT_TRY_FINALLY so that abrupt completions emit
1690     // a GOTO instead of a JSR. Also, mark a try block which has a catch
1691     // clause but no finally clause, in case an abrupt exit forces a split
1692     // in the range of protected code.
1693     //
1694     if (statement -> finally_clause_opt)
1695         if (! emit_finally_clause)
1696             statement -> block -> SetTag(AstBlock::NONE);
1697         else if (! statement -> finally_clause_opt -> block ->
1698                  can_complete_normally)
1699         {
1700             statement -> block -> SetTag(AstBlock::ABRUPT_TRY_FINALLY);
1701         }
1702     if (statement -> block -> Tag() == AstBlock::NONE &&
1703         statement -> NumCatchClauses())
1704     {
1705         statement -> block -> SetTag(AstBlock::TRY_CLAUSE_WITH_CATCH);
1706     }
1707     bool abrupt = EmitBlockStatement(statement -> block);
1708 
1709     //
1710     // The computation of end_try_block_pc, the instruction following the last
1711     // instruction in the body of the try block, does not include the code, if
1712     // any, needed to call a finally block or skip to the end of the try
1713     // statement.
1714     //
1715     u2 end_try_block_pc = code_attribute -> CodeLength();
1716     Tuple<u2> handler_starts(method_stack -> TopHandlerRangeStart());
1717     Tuple<u2> handler_ends(method_stack -> TopHandlerRangeEnd());
1718     handler_ends.Push(end_try_block_pc);
1719     assert(handler_starts.Length() == handler_ends.Length());
1720 
1721     //
1722     // If try block is not empty, process catch clauses, including "special"
1723     // clause for finally.
1724     //
1725     if (start_try_block_pc != end_try_block_pc)
1726     {
1727         // Use the label in the block immediately enclosing try statement.
1728         Label& finally_label = method_stack -> TopFinallyLabel();
1729         Label end_label;
1730 
1731         //
1732         // If try block completes normally, skip code for catch blocks.
1733         //
1734         if (! abrupt &&
1735             (emit_finally_clause || statement -> NumCatchClauses()))
1736         {
1737             EmitBranch(OP_GOTO, end_label, statement);
1738         }
1739 
1740         for (unsigned i = 0; i < statement -> NumCatchClauses(); i++)
1741         {
1742             u2 handler_pc = code_attribute -> CodeLength();
1743 
1744             AstCatchClause* catch_clause = statement -> CatchClause(i);
1745             VariableSymbol* parameter_symbol =
1746                 catch_clause -> parameter_symbol;
1747 
1748             assert(stack_depth == 0);
1749             stack_depth = 1; // account for the exception already on the stack
1750             line_number_table_attribute ->
1751                 AddLineNumber(code_attribute -> CodeLength(),
1752                               semantic.lex_stream -> Line(catch_clause ->
1753                                                           catch_token));
1754             //
1755             // Unless debugging, we don't need to waste a variable on an
1756             // empty catch.
1757             //
1758             if ((control.option.g & JikesOption::VARS) ||
1759                 ! IsNop(catch_clause -> block))
1760             {
1761                 StoreLocal(parameter_symbol -> LocalVariableIndex(),
1762                            parameter_symbol -> Type());
1763             }
1764             else PutOp(OP_POP);
1765             u2 handler_type = RegisterClass(parameter_symbol -> Type());
1766             for (int j = handler_starts.Length(); --j >= 0; )
1767             {
1768                 code_attribute ->
1769                     AddException(handler_starts[j], handler_ends[j],
1770                                  handler_pc, handler_type);
1771             }
1772 
1773             //
1774             // If we determined the finally clause is a nop, remove the tag
1775             // TRY_CLAUSE_WITH_FINALLY so that abrupt completions do not emit
1776             // JSR. On the other hand, if the finally clause cannot complete
1777             // normally, change the tag to ABRUPT_TRY_FINALLY so that abrupt
1778             // completions emit a GOTO instead of a JSR.
1779             //
1780             if (statement -> finally_clause_opt)
1781             {
1782                 if (! emit_finally_clause)
1783                     catch_clause -> block -> SetTag(AstBlock::NONE);
1784                 else if (! statement -> finally_clause_opt -> block ->
1785                          can_complete_normally)
1786                 {
1787                     catch_clause -> block ->
1788                         SetTag(AstBlock::ABRUPT_TRY_FINALLY);
1789                 }
1790             }
1791             abrupt = EmitBlockStatement(catch_clause -> block);
1792 
1793             if (control.option.g & JikesOption::VARS)
1794             {
1795                 local_variable_table_attribute ->
1796                     AddLocalVariable(handler_pc,
1797                                      code_attribute -> CodeLength(),
1798                                      RegisterName(parameter_symbol -> ExternalIdentity()),
1799                                      RegisterUtf8(parameter_symbol -> Type() -> signature),
1800                                      parameter_symbol -> LocalVariableIndex());
1801             }
1802 
1803             //
1804             // If catch block completes normally, skip further catch blocks.
1805             //
1806             if (! abrupt && (emit_finally_clause ||
1807                              i < (statement -> NumCatchClauses() - 1)))
1808             {
1809                 EmitBranch(OP_GOTO, end_label, statement);
1810             }
1811         }
1812         //
1813         // If this try statement contains a finally clause, then ...
1814         //
1815         if (emit_finally_clause)
1816         {
1817             int variable_index = method_stack -> TopBlock() ->
1818                 block_symbol -> helper_variable_index;
1819             u2 finally_start_pc = code_attribute -> CodeLength();
1820             u2 special_end_pc = finally_start_pc;
1821 
1822             //
1823             // Emit code for "special" handler to make sure finally clause is
1824             // invoked in case an otherwise uncaught exception is thrown in the
1825             // try block, or an exception is thrown from within a catch block.
1826             // This must cover all instructions through the jsr, in case of
1827             // asynchronous exceptions.
1828             //
1829             assert(stack_depth == 0);
1830             stack_depth = 1; // account for the exception already on stack
1831             if (statement -> finally_clause_opt -> block ->
1832                 can_complete_normally)
1833             {
1834                 StoreLocal(variable_index, control.Throwable()); // Save,
1835                 EmitBranch(OP_JSR, finally_label, statement);
1836                 special_end_pc = code_attribute -> CodeLength();
1837                 LoadLocal(variable_index, control.Throwable()); // reload, and
1838                 PutOp(OP_ATHROW); // rethrow exception.
1839             }
1840             else
1841             {
1842                 //
1843                 // Ignore the exception already on the stack, since we know
1844                 // the finally clause overrides it.
1845                 //
1846                 PutOp(OP_POP);
1847             }
1848             method_stack -> TopHandlerRangeEnd().Push(special_end_pc);
1849             unsigned count = method_stack -> TopHandlerRangeStart().Length();
1850             assert(count == method_stack -> TopHandlerRangeEnd().Length());
1851             while (count--)
1852             {
1853                 code_attribute ->
1854                     AddException(method_stack -> TopHandlerRangeStart().Pop(),
1855                                  method_stack -> TopHandlerRangeEnd().Pop(),
1856                                  finally_start_pc, 0);
1857             }
1858 
1859             //
1860             // Generate code for finally clause. If the finally block can
1861             // complete normally, this is reached from a JSR, so save the
1862             // return address. Otherwise, this is reached from a GOTO.
1863             //
1864             DefineLabel(finally_label);
1865             assert(stack_depth == 0);
1866             if (statement -> finally_clause_opt -> block ->
1867                 can_complete_normally)
1868             {
1869                 stack_depth = 1; // account for the return location on stack
1870                 StoreLocal(variable_index + 1, control.Object());
1871             }
1872             else if (IsLabelUsed(end_label))
1873             {
1874                 DefineLabel(end_label);
1875                 CompleteLabel(end_label);
1876             }
1877             EmitBlockStatement(statement -> finally_clause_opt -> block);
1878 
1879             //
1880             // If a finally block can complete normally, return to the saved
1881             // address of the caller.
1882             //
1883             if (statement -> finally_clause_opt -> block ->
1884                 can_complete_normally)
1885             {
1886                 PutOpWide(OP_RET, variable_index + 1);
1887                 //
1888                 // Now, if the try or catch blocks complete normally, execute
1889                 // the finally block before advancing to next statement. We
1890                 // need to trap one more possibility of an asynchronous
1891                 // exception before the jsr has started.
1892                 //
1893                 if (IsLabelUsed(end_label))
1894                 {
1895                     DefineLabel(end_label);
1896                     CompleteLabel(end_label);
1897                     EmitBranch(OP_JSR, finally_label,
1898                                statement -> finally_clause_opt -> block);
1899                     special_end_pc = code_attribute -> CodeLength();
1900                     code_attribute -> AddException(special_end_pc - 3,
1901                                                    special_end_pc,
1902                                                    finally_start_pc, 0);
1903                 }
1904             }
1905             CompleteLabel(finally_label);
1906         }
1907         else
1908         {
1909             //
1910             // Finally block is not present, advance to next statement, and
1911             // clean up the handler start/end ranges.
1912             //
1913             assert(! IsLabelUsed(finally_label));
1914             DefineLabel(end_label);
1915             CompleteLabel(end_label);
1916             method_stack -> TopHandlerRangeStart().Reset();
1917             method_stack -> TopHandlerRangeEnd().Reset();
1918         }
1919     }
1920     else
1921     {
1922         //
1923         // Try block was empty; skip all catch blocks, and a finally block
1924         // is treated normally.
1925         //
1926         method_stack -> TopHandlerRangeStart().Reset();
1927         if (emit_finally_clause)
1928             EmitBlockStatement(statement -> finally_clause_opt -> block);
1929     }
1930 }
1931 
1932 
1933 //
1934 // Exit to block at level, freeing monitor locks and invoking finally
1935 // clauses as appropriate. The width is 1 for return, 3 for normal a normal
1936 // GOTO (from a break or continue), or 5 for a GOTO_W. The return is true
1937 // unless some intervening finally block cannot complete normally.
1938 //
ProcessAbruptExit(unsigned level,u2 width,TypeSymbol * return_type)1939 bool ByteCode::ProcessAbruptExit(unsigned level, u2 width,
1940                                  TypeSymbol* return_type)
1941 {
1942     int variable_index = -1;
1943     //
1944     // We must store the return value in a variable, rather than on the
1945     // stack, in case a finally block contains an embedded try-catch which
1946     // wipes out the stack.
1947     //
1948     if (return_type)
1949     {
1950         for (unsigned i = method_stack -> Size() - 1;
1951              i > 0 && method_stack -> NestingLevel(i) != level; i--)
1952         {
1953             unsigned nesting_level = method_stack -> NestingLevel(i);
1954             unsigned enclosing_level = method_stack -> NestingLevel(i - 1);
1955             AstBlock* block = method_stack -> Block(nesting_level);
1956             if (block -> Tag() == AstBlock::TRY_CLAUSE_WITH_FINALLY)
1957             {
1958                 variable_index = method_stack -> Block(enclosing_level) ->
1959                     block_symbol -> helper_variable_index + 2;
1960             }
1961             else if (block -> Tag() == AstBlock::ABRUPT_TRY_FINALLY)
1962             {
1963                 variable_index = -1;
1964                 PutOp(control.IsDoubleWordType(return_type) ? OP_POP2 : OP_POP);
1965                 break;
1966             }
1967         }
1968     }
1969     if (variable_index >= 0)
1970         StoreLocal(variable_index, return_type);
1971 
1972     for (unsigned i = method_stack -> Size() - 1;
1973          i > 0 && method_stack -> NestingLevel(i) != level; i--)
1974     {
1975         unsigned nesting_level = method_stack -> NestingLevel(i);
1976         unsigned enclosing_level = method_stack -> NestingLevel(i - 1);
1977         AstBlock* block = method_stack -> Block(nesting_level);
1978         if (block -> Tag() == AstBlock::TRY_CLAUSE_WITH_FINALLY)
1979         {
1980             EmitBranch(OP_JSR, method_stack -> FinallyLabel(enclosing_level),
1981                        method_stack -> Block(enclosing_level));
1982             method_stack -> HandlerRangeEnd(enclosing_level).
1983                 Push(code_attribute -> CodeLength());
1984         }
1985         else if (block -> Tag() == AstBlock::ABRUPT_TRY_FINALLY)
1986         {
1987             //
1988             // Ignore the width of the abrupt instruction, because the abrupt
1989             // finally preempts it.
1990             //
1991             width = 0;
1992             EmitBranch(OP_GOTO, method_stack -> FinallyLabel(enclosing_level),
1993                        method_stack -> Block(enclosing_level));
1994             method_stack -> HandlerRangeEnd(enclosing_level).
1995                 Push(code_attribute -> CodeLength());
1996             break;
1997         }
1998         else if (block -> Tag() == AstBlock::SYNCHRONIZED)
1999         {
2000             //
2001             // This code must be safe for asynchronous exceptions.  Note that
2002             // we are splitting the range of instructions covered by the
2003             // synchronized statement catchall handler.
2004             //
2005             int variable_index = method_stack -> Block(enclosing_level) ->
2006                 block_symbol -> helper_variable_index;
2007             LoadLocal(variable_index, control.Object());
2008             PutOp(OP_MONITOREXIT);
2009             method_stack -> HandlerRangeEnd(enclosing_level).
2010                 Push(code_attribute -> CodeLength());
2011         }
2012         else if (block -> Tag() == AstBlock::TRY_CLAUSE_WITH_CATCH)
2013         {
2014             method_stack -> HandlerRangeEnd(enclosing_level).
2015                 Push(code_attribute -> CodeLength());
2016         }
2017     }
2018 
2019     if (variable_index >= 0)
2020         LoadLocal(variable_index, return_type);
2021     for (unsigned j = method_stack -> Size() - 1;
2022          j > 0 && method_stack -> NestingLevel(j) != level; j--)
2023     {
2024         unsigned nesting_level = method_stack -> NestingLevel(j);
2025         unsigned enclosing_level = method_stack -> NestingLevel(j - 1);
2026         AstBlock* block = method_stack -> Block(nesting_level);
2027         if (block -> Tag() == AstBlock::SYNCHRONIZED ||
2028             block -> Tag() == AstBlock::TRY_CLAUSE_WITH_CATCH ||
2029             block -> Tag() == AstBlock::TRY_CLAUSE_WITH_FINALLY)
2030         {
2031             method_stack -> HandlerRangeStart(enclosing_level).
2032                 Push(code_attribute -> CodeLength() + width);
2033         }
2034         else if (block -> Tag() == AstBlock::ABRUPT_TRY_FINALLY)
2035         {
2036             method_stack -> HandlerRangeStart(enclosing_level).
2037                 Push(code_attribute -> CodeLength());
2038             return false;
2039         }
2040     }
2041     return true;
2042 }
2043 
EmitBranch(Opcode opc,Label & lab,AstStatement * over)2044 void ByteCode::EmitBranch(Opcode opc, Label& lab, AstStatement* over)
2045 {
2046     // Use the number of tokens as a heuristic for the size of the statement
2047     // we're jumping over. If the statement is large enough, either change
2048     // to the 4-byte branch opcode or write out a branch around a goto_w for
2049     // branch opcodes that don't have a long form.
2050     int sizeHeuristic = over ? over -> RightToken() - over -> LeftToken() : 0;
2051     if (sizeHeuristic < TOKEN_WIDTH_REQUIRING_GOTOW) {
2052         PutOp(opc);
2053         UseLabel(lab, 2, 1);
2054         return;
2055     }
2056     if (opc == OP_GOTO) {
2057         PutOp(OP_GOTO_W);
2058         UseLabel(lab, 4, 1);
2059         return;
2060     }
2061     if (opc == OP_JSR) {
2062         PutOp(OP_JSR_W);
2063         UseLabel(lab, 4, 1);
2064         return;
2065     }
2066     // if op lab
2067     //  =>
2068     // if !op label2
2069     // goto_w lab
2070     // label2:
2071     PutOp(InvertIfOpCode(opc));
2072     Label label2;
2073     UseLabel(label2, 2, 1);
2074     PutOp(OP_GOTO_W);
2075     UseLabel(lab, 4, 1);
2076     DefineLabel(label2);
2077     CompleteLabel(label2);
2078 }
2079 
2080 //
2081 // java provides a variety of conditional branch instructions, so
2082 // that a number of operators merit special handling:
2083 //      constant operand
2084 //      negation (we eliminate it)
2085 //      equality
2086 //      ?: && and || (partial evaluation)
2087 //      comparisons
2088 // Other expressions are just evaluated and the appropriate
2089 // branch emitted.
2090 //
2091 // TODO: return a bool that is true if the statement being branched over is
2092 // even needed (if statements and other places might have a constant false
2093 // expression, allowing the next block of code to be skipped entirely).
2094 //
EmitBranchIfExpression(AstExpression * p,bool cond,Label & lab,AstStatement * over)2095 void ByteCode::EmitBranchIfExpression(AstExpression* p, bool cond, Label& lab,
2096                                       AstStatement* over)
2097 {
2098     p = StripNops(p);
2099     assert(p -> Type() == control.boolean_type);
2100 
2101     if (p -> IsConstant())
2102     {
2103         if (IsZero(p) != cond)
2104             EmitBranch(OP_GOTO, lab, over);
2105         return;
2106     }
2107 
2108     AstPreUnaryExpression* pre = p -> PreUnaryExpressionCast();
2109     if (pre) // must be !
2110     {
2111         //
2112         // branch_if(!e,c,l) => branch_if(e,!c,l)
2113         //
2114         assert(pre -> Tag() == AstPreUnaryExpression::NOT);
2115         EmitBranchIfExpression(pre -> expression, ! cond, lab, over);
2116         return;
2117     }
2118 
2119     AstConditionalExpression* conditional = p -> ConditionalExpressionCast();
2120     if (conditional)
2121     {
2122         if (conditional -> test_expression -> IsConstant())
2123         {
2124             //
2125             // branch_if(true?a:b, cond, lab) => branch_if(a, cond, lab);
2126             // branch_if(false?a:b, cond, lab) => branch_if(b, cond, lab);
2127             //
2128             EmitBranchIfExpression((IsZero(conditional -> test_expression)
2129                                     ? conditional -> false_expression
2130                                     : conditional -> true_expression),
2131                                    cond, lab, over);
2132         }
2133         else if (IsOne(conditional -> true_expression))
2134         {
2135             //
2136             // branch_if(expr?true:true, c, l) => expr, branch if c
2137             // branch_if(expr?true:false, c, l) => branch_if(expr, c, l);
2138             // branch_if(expr?true:b, c, l) => branch_if(expr || b, c, l);
2139             //
2140             if (IsOne(conditional -> false_expression))
2141             {
2142                 EmitExpression(conditional -> test_expression, false);
2143                 if (cond)
2144                     EmitBranch(OP_GOTO, lab, over);
2145             }
2146             else if (IsZero(conditional -> false_expression))
2147             {
2148                 EmitBranchIfExpression(conditional -> test_expression,
2149                                        cond, lab, over);
2150             }
2151             else if (cond)
2152             {
2153                 EmitBranchIfExpression(conditional -> test_expression, true,
2154                                        lab, over);
2155                 EmitBranchIfExpression(conditional -> false_expression, true,
2156                                        lab, over);
2157             }
2158             else
2159             {
2160                 Label skip;
2161                 EmitBranchIfExpression(conditional -> test_expression, true,
2162                                        skip, over);
2163                 EmitBranchIfExpression(conditional -> false_expression, false,
2164                                        lab, over);
2165                 DefineLabel(skip);
2166                 CompleteLabel(skip);
2167             }
2168         }
2169         else if (IsZero(conditional -> true_expression))
2170         {
2171             //
2172             // branch_if(expr?false:true, c, l) => branch_if(expr, ! c, l);
2173             // branch_if(expr?false:false, c, l) => expr, branch if ! c
2174             // branch_if(expr?false:b, c, l) => branch_if(!expr && b, c, l);
2175             //
2176             if (IsOne(conditional -> false_expression))
2177             {
2178                 EmitBranchIfExpression(conditional -> test_expression,
2179                                        ! cond, lab, over);
2180             }
2181             else if (IsZero(conditional -> false_expression))
2182             {
2183                 EmitExpression(conditional -> test_expression, false);
2184                 if (! cond)
2185                     EmitBranch(OP_GOTO, lab, over);
2186             }
2187             else if (! cond)
2188             {
2189                 EmitBranchIfExpression(conditional -> test_expression, true,
2190                                        lab, over);
2191                 EmitBranchIfExpression(conditional -> false_expression, false,
2192                                        lab, over);
2193             }
2194             else
2195             {
2196                 Label skip;
2197                 EmitBranchIfExpression(conditional -> test_expression, true,
2198                                        skip, over);
2199                 EmitBranchIfExpression(conditional -> false_expression, true,
2200                                        lab, over);
2201                 DefineLabel(skip);
2202                 CompleteLabel(skip);
2203             }
2204         }
2205         else if (IsOne(conditional -> false_expression))
2206         {
2207             //
2208             // branch_if(expr?a:true, c, l) => branch_if(!expr || a, c, l);
2209             //
2210             if (cond)
2211             {
2212                 EmitBranchIfExpression(conditional -> test_expression, false,
2213                                        lab, over);
2214                 EmitBranchIfExpression(conditional -> true_expression, true,
2215                                        lab, over);
2216             }
2217             else
2218             {
2219                 Label skip;
2220                 EmitBranchIfExpression(conditional -> test_expression, false,
2221                                        skip, over);
2222                 EmitBranchIfExpression(conditional -> true_expression, false,
2223                                        lab, over);
2224                 DefineLabel(skip);
2225                 CompleteLabel(skip);
2226             }
2227         }
2228         else if (IsZero(conditional -> false_expression))
2229         {
2230             //
2231             // branch_if(expr?a:false, c, l) => branch_if(expr && a, c, l);
2232             //
2233             if (! cond)
2234             {
2235                 EmitBranchIfExpression(conditional -> test_expression, false,
2236                                        lab, over);
2237                 EmitBranchIfExpression(conditional -> true_expression, false,
2238                                        lab, over);
2239             }
2240             else
2241             {
2242                 Label skip;
2243                 EmitBranchIfExpression(conditional -> test_expression, false,
2244                                        skip, over);
2245                 EmitBranchIfExpression(conditional -> true_expression, true,
2246                                        lab, over);
2247                 DefineLabel(skip);
2248                 CompleteLabel(skip);
2249             }
2250         }
2251         else
2252         {
2253             //
2254             // branch_if(expr?a:b, c, l) =>
2255             //   branch_if(expr, false, lab1)
2256             //   branch_if(a, c, l)
2257             //   goto lab2
2258             //   lab1: branch_if(b, c, l)
2259             //   lab2:
2260             //
2261             Label lab1, lab2;
2262             EmitBranchIfExpression(conditional -> test_expression, false, lab1,
2263                                    over);
2264             EmitBranchIfExpression(conditional -> true_expression, cond, lab,
2265                                    over);
2266             EmitBranch(OP_GOTO, lab2, over);
2267             DefineLabel(lab1);
2268             CompleteLabel(lab1);
2269             EmitBranchIfExpression(conditional -> false_expression, cond, lab,
2270                                    over);
2271             DefineLabel(lab2);
2272             CompleteLabel(lab2);
2273         }
2274         return;
2275     }
2276 
2277     AstInstanceofExpression* instanceof = p -> InstanceofExpressionCast();
2278     if (instanceof)
2279     {
2280         AstExpression* expr = StripNops(instanceof -> expression);
2281         TypeSymbol* left_type = expr -> Type();
2282         TypeSymbol* right_type = instanceof -> type -> symbol;
2283         if (right_type -> num_dimensions > 255)
2284         {
2285             semantic.ReportSemError(SemanticError::ARRAY_OVERFLOW,
2286                                     instanceof -> type);
2287         }
2288         if (left_type == control.null_type)
2289         {
2290             //
2291             // We know the result: false. But emit the left expression,
2292             // in case of side effects in (expr ? null : null).
2293             //
2294             EmitExpression(expr, false);
2295             if (! cond)
2296                 EmitBranch(OP_GOTO, lab, over);
2297         }
2298         else if (expr -> IsConstant() || // a String constant
2299                  expr -> BinaryExpressionCast()) // a String concat
2300         {
2301             //
2302             // We know the result: true, since the expression is non-null
2303             // and String is a final class.
2304             //
2305             assert(left_type == control.String());
2306             EmitExpression(expr, false);
2307             if (cond)
2308                 EmitBranch(OP_GOTO, lab, over);
2309         }
2310         else if ((expr -> ThisExpressionCast() ||
2311                   expr -> SuperExpressionCast() ||
2312                   expr -> ClassLiteralCast() ||
2313                   expr -> ClassCreationExpressionCast() ||
2314                   expr -> ArrayCreationExpressionCast()) &&
2315                  left_type -> IsSubtype(right_type))
2316         {
2317             //
2318             // We know the result: true, since the expression is non-null.
2319             //
2320             EmitExpression(expr, false);
2321             if (cond)
2322                 EmitBranch(OP_GOTO, lab, over);
2323         }
2324         else
2325         {
2326             EmitExpression(expr);
2327             PutOp(OP_INSTANCEOF);
2328             PutU2(RegisterClass(right_type));
2329             EmitBranch((cond ? OP_IFNE : OP_IFEQ), lab, over);
2330         }
2331         return;
2332     }
2333 
2334     //
2335     // dispose of non-binary expression case by just evaluating
2336     // operand and emitting appropiate test.
2337     //
2338     AstBinaryExpression* bp = p -> BinaryExpressionCast();
2339     if (! bp)
2340     {
2341         EmitExpression(p);
2342         EmitBranch((cond ? OP_IFNE : OP_IFEQ), lab, over);
2343         return;
2344     }
2345 
2346     //
2347     // Here if binary expression, so extract operands
2348     //
2349     AstExpression* left = StripNops(bp -> left_expression);
2350     AstExpression* right = StripNops(bp -> right_expression);
2351 
2352     TypeSymbol* left_type = left -> Type();
2353     TypeSymbol* right_type = right -> Type();
2354     switch (bp -> Tag())
2355     {
2356     case AstBinaryExpression::AND_AND:
2357         //
2358         // branch_if(true&&b, cond, lab) => branch_if(b, cond, lab);
2359         // branch_if(false&&b, cond, lab) => branch_if(false, cond, lab);
2360         //
2361         if (left -> IsConstant())
2362         {
2363             if (IsOne(left))
2364                 EmitBranchIfExpression(right, cond, lab, over);
2365             else if (! cond)
2366                 EmitBranch(OP_GOTO, lab, over);
2367         }
2368         //
2369         // branch_if(a&&true, cond, lab) => branch_if(a, cond, lab);
2370         // branch_if(a&&false, cond, lab) => emit(a), pop; for side effects
2371         //
2372         else if (right -> IsConstant())
2373         {
2374             if (IsOne(right))
2375                 EmitBranchIfExpression(left, cond, lab, over);
2376             else
2377             {
2378                 EmitExpression(left, false);
2379                 if (! cond)
2380                     EmitBranch(OP_GOTO, lab, over);
2381             }
2382         }
2383         //
2384         // branch_if(a&&b, true, lab) =>
2385         //   branch_if(a,false,skip);
2386         //   branch_if(b,true,lab);
2387         //   skip:
2388         // branch_if(a&&b, false, lab) =>
2389         //   branch_if(a,false,lab);
2390         //   branch_if(b,false,lab);
2391         //
2392         else if (cond)
2393         {
2394             Label skip;
2395             EmitBranchIfExpression(left, false, skip, over);
2396             EmitBranchIfExpression(right, true, lab, over);
2397             DefineLabel(skip);
2398             CompleteLabel(skip);
2399         }
2400         else
2401         {
2402             EmitBranchIfExpression(left, false, lab, over);
2403             EmitBranchIfExpression(right, false, lab, over);
2404         }
2405         return;
2406     case AstBinaryExpression::OR_OR:
2407         //
2408         // branch_if(false||b, cond, lab) => branch_if(b, cond, lab);
2409         // branch_if(true||b, cond, lab) => branch_if(true, cond, lab);
2410         //
2411         if (left -> IsConstant())
2412         {
2413             if (IsZero(left))
2414                 EmitBranchIfExpression(right, cond, lab, over);
2415             else if (cond)
2416                 EmitBranch(OP_GOTO, lab, over);
2417         }
2418         //
2419         // branch_if(a||false, cond, lab) => branch_if(a, cond, lab);
2420         // branch_if(a||true, cond, lab) => emit(a), pop; for side effects
2421         //
2422         else if (right -> IsConstant())
2423         {
2424             if (IsZero(right))
2425                 EmitBranchIfExpression(left, cond, lab, over);
2426             else
2427             {
2428                 EmitExpression(left, false);
2429                 if (cond)
2430                     EmitBranch(OP_GOTO, lab, over);
2431             }
2432         }
2433         //
2434         // branch_if(a||b,true,lab) =>
2435         //   branch_if(a,true,lab);
2436         //   branch_if(b,true,lab);
2437         // branch_if(a||b,false,lab) =>
2438         //   branch_if(a,true,skip);
2439         //   branch_if(b,false,lab);
2440         //   skip:
2441         //
2442         else if (cond)
2443         {
2444             EmitBranchIfExpression(left, true, lab, over);
2445             EmitBranchIfExpression(right, true, lab, over);
2446         }
2447         else
2448         {
2449             Label skip;
2450             EmitBranchIfExpression(left, true, skip, over);
2451             EmitBranchIfExpression(right, false, lab, over);
2452             DefineLabel(skip);
2453             CompleteLabel(skip);
2454         }
2455         return;
2456     case AstBinaryExpression::XOR: // ^ on booleans is equavalent to !=
2457         assert(left_type == control.boolean_type);
2458         // Fallthrough!
2459     case AstBinaryExpression::EQUAL_EQUAL:
2460     case AstBinaryExpression::NOT_EQUAL:
2461         //
2462         // One of the operands is null. We must evaluate both operands, to get
2463         // any side effects in (expr ? null : null).
2464         //
2465         if (left_type == control.null_type || right_type == control.null_type)
2466         {
2467             EmitExpression(left, left_type != control.null_type);
2468             EmitExpression(right, right_type != control.null_type);
2469             if (left_type == right_type)
2470             {
2471                 if (cond == (bp -> Tag() == AstBinaryExpression::EQUAL_EQUAL))
2472                 {
2473                     EmitBranch(OP_GOTO, lab, over);
2474                 }
2475             }
2476             else
2477             {
2478                 if (bp -> Tag() == AstBinaryExpression::EQUAL_EQUAL)
2479                     EmitBranch(cond ? OP_IFNULL : OP_IFNONNULL, lab, over);
2480                 else EmitBranch(cond ? OP_IFNONNULL : OP_IFNULL, lab, over);
2481             }
2482             return;
2483         }
2484 
2485         //
2486         // One of the operands is true. Branch on the other.
2487         //
2488         if (left_type == control.boolean_type &&
2489             (IsOne(left) || IsOne(right)))
2490         {
2491             EmitBranchIfExpression(IsOne(left) ? right : left,
2492                                    cond == (bp -> Tag() == AstBinaryExpression::EQUAL_EQUAL),
2493                                    lab, over);
2494             return;
2495         }
2496 
2497         //
2498         // Both operands are integer.
2499         //
2500         if (control.IsSimpleIntegerValueType(left_type) ||
2501              left_type == control.boolean_type)
2502         {
2503             assert(control.IsSimpleIntegerValueType(right_type) ||
2504                    right_type == control.boolean_type);
2505 
2506             if (IsZero(left) || IsZero(right))
2507             {
2508                 if (left_type == control.boolean_type)
2509                 {
2510                     //
2511                     // One of the operands is false. Branch on the other.
2512                     //
2513                     EmitBranchIfExpression(IsZero(left) ? right : left,
2514                                            cond == (bp -> Tag() != AstBinaryExpression::EQUAL_EQUAL),
2515                                            lab, over);
2516                 }
2517                 else
2518                 {
2519                     //
2520                     // One of the operands is zero. Only emit the other.
2521                     //
2522                     EmitExpression(IsZero(left) ? right : left);
2523 
2524                     if (bp -> Tag() == AstBinaryExpression::EQUAL_EQUAL)
2525                         EmitBranch((cond ? OP_IFEQ : OP_IFNE), lab, over);
2526                     else EmitBranch((cond ? OP_IFNE : OP_IFEQ), lab, over);
2527                 }
2528             }
2529             else
2530             {
2531                 EmitExpression(left);
2532                 EmitExpression(right);
2533 
2534                 if (bp -> Tag() == AstBinaryExpression::EQUAL_EQUAL)
2535                     EmitBranch((cond ? OP_IF_ICMPEQ : OP_IF_ICMPNE), lab, over);
2536                 else
2537                     EmitBranch((cond ? OP_IF_ICMPNE : OP_IF_ICMPEQ), lab, over);
2538             }
2539 
2540             return;
2541         }
2542 
2543         //
2544         // Both operands are reference types: just do the comparison.
2545         //
2546         if (IsReferenceType(left_type))
2547         {
2548             assert(IsReferenceType(right_type));
2549             EmitExpression(left);
2550             EmitExpression(right);
2551 
2552             if (bp -> Tag() == AstBinaryExpression::EQUAL_EQUAL)
2553                 EmitBranch((cond ? OP_IF_ACMPEQ : OP_IF_ACMPNE), lab, over);
2554             else EmitBranch((cond ? OP_IF_ACMPNE : OP_IF_ACMPEQ), lab, over);
2555 
2556             return;
2557         }
2558 
2559         break;
2560     case AstBinaryExpression::IOR:
2561         //
2562         // One argument is false. Branch on other.
2563         //
2564         if (IsZero(left) || IsZero(right))
2565         {
2566             EmitBranchIfExpression(IsZero(left) ? right : left,
2567                                    cond, lab, over);
2568             return;
2569         }
2570 
2571         //
2572         // One argument is true. Emit the other, and result is true.
2573         //
2574         if (IsOne(left) || IsOne(right))
2575         {
2576             EmitExpression(IsOne(left) ? right : left, false);
2577             if (cond)
2578                 EmitBranch(OP_GOTO, lab, over);
2579             return;
2580         }
2581         break;
2582     case AstBinaryExpression::AND:
2583         //
2584         // One argument is true. Branch on other.
2585         //
2586         if (IsOne(left) || IsOne(right))
2587         {
2588             EmitBranchIfExpression(IsOne(left) ? right : left,
2589                                    cond, lab, over);
2590             return;
2591         }
2592 
2593         //
2594         // One argument is false. Emit the other, and result is false.
2595         //
2596         if (IsZero(left) || IsZero(right))
2597         {
2598             EmitExpression(IsZero(left) ? right : left, false);
2599             if (! cond)
2600                 EmitBranch(OP_GOTO, lab, over);
2601             return;
2602         }
2603         break;
2604     default:
2605         break;
2606     }
2607 
2608     //
2609     // here if not comparison, comparison for non-integral numeric types, or
2610     // integral comparison for which no special casing needed.
2611     // Begin by dealing with non-comparisons
2612     //
2613     switch (bp -> Tag())
2614     {
2615     case AstBinaryExpression::LESS:
2616     case AstBinaryExpression::LESS_EQUAL:
2617     case AstBinaryExpression::GREATER:
2618     case AstBinaryExpression::GREATER_EQUAL:
2619     case AstBinaryExpression::EQUAL_EQUAL:
2620     case AstBinaryExpression::NOT_EQUAL:
2621         break; // break to continue comparison processing
2622     default:
2623         //
2624         // not a comparison, get the (necessarily boolean) value
2625         // of the expression and branch on the result
2626         //
2627         EmitExpression(p);
2628         EmitBranch(cond ? OP_IFNE : OP_IFEQ, lab, over);
2629         return;
2630     }
2631 
2632     //
2633     //
2634     //
2635     Opcode opcode = OP_NOP,
2636            op_true,
2637            op_false;
2638     assert(left_type != control.boolean_type);
2639     if (control.IsSimpleIntegerValueType(left_type))
2640     {
2641         //
2642         // we have already dealt with EQUAL_EQUAL and NOT_EQUAL for the case
2643         // of two integers, but still need to look for comparisons for which
2644         // one operand may be zero.
2645         //
2646         if (IsZero(left))
2647         {
2648             EmitExpression(right);
2649             switch (bp -> Tag())
2650             {
2651             case AstBinaryExpression::LESS:
2652                 // if (0 < x) same as  if (x > 0)
2653                 op_true = OP_IFGT;
2654                 op_false = OP_IFLE;
2655                 break;
2656             case AstBinaryExpression::LESS_EQUAL:
2657                 // if (0 <= x) same as if (x >= 0)
2658                 op_true = OP_IFGE;
2659                 op_false = OP_IFLT;
2660                 break;
2661             case AstBinaryExpression::GREATER:
2662                 // if (0 > x) same as if (x < 0)
2663                 op_true = OP_IFLT;
2664                 op_false = OP_IFGE;
2665                 break;
2666             case AstBinaryExpression::GREATER_EQUAL:
2667                 // if (0 >= x) same as if (x <= 0)
2668                 op_true = OP_IFLE;
2669                 op_false = OP_IFGT;
2670                 break;
2671             default:
2672                 assert(false);
2673                 break;
2674             }
2675         }
2676         else if (IsZero(right))
2677         {
2678             EmitExpression(left);
2679 
2680             switch (bp -> Tag())
2681             {
2682             case AstBinaryExpression::LESS:
2683                 op_true = OP_IFLT;
2684                 op_false = OP_IFGE;
2685                 break;
2686             case AstBinaryExpression::LESS_EQUAL:
2687                 op_true = OP_IFLE;
2688                 op_false = OP_IFGT;
2689                 break;
2690             case AstBinaryExpression::GREATER:
2691                 op_true = OP_IFGT;
2692                 op_false = OP_IFLE;
2693                 break;
2694             case AstBinaryExpression::GREATER_EQUAL:
2695                 op_true = OP_IFGE;
2696                 op_false = OP_IFLT;
2697                 break;
2698             default:
2699                 assert(false);
2700                 break;
2701             }
2702         }
2703         else
2704         {
2705             EmitExpression(left);
2706             EmitExpression(right);
2707 
2708             switch (bp -> Tag())
2709             {
2710             case AstBinaryExpression::LESS:
2711                 op_true = OP_IF_ICMPLT;
2712                 op_false = OP_IF_ICMPGE;
2713                 break;
2714             case AstBinaryExpression::LESS_EQUAL:
2715                 op_true = OP_IF_ICMPLE;
2716                 op_false = OP_IF_ICMPGT;
2717                 break;
2718             case AstBinaryExpression::GREATER:
2719                 op_true = OP_IF_ICMPGT;
2720                 op_false = OP_IF_ICMPLE;
2721                 break;
2722             case AstBinaryExpression::GREATER_EQUAL:
2723                 op_true = OP_IF_ICMPGE;
2724                 op_false = OP_IF_ICMPLT;
2725                 break;
2726             default:
2727                 assert(false);
2728                 break;
2729             }
2730         }
2731     }
2732     else if (left_type == control.long_type)
2733     {
2734         EmitExpression(left);
2735         EmitExpression(right);
2736 
2737         opcode = OP_LCMP;
2738 
2739         //
2740         // branch according to result value on stack
2741         //
2742         switch (bp -> Tag())
2743         {
2744         case AstBinaryExpression::EQUAL_EQUAL:
2745             op_true = OP_IFEQ;
2746             op_false = OP_IFNE;
2747             break;
2748         case AstBinaryExpression::NOT_EQUAL:
2749             op_true = OP_IFNE;
2750             op_false = OP_IFEQ;
2751             break;
2752         case AstBinaryExpression::LESS:
2753             op_true = OP_IFLT;
2754             op_false = OP_IFGE;
2755             break;
2756         case AstBinaryExpression::LESS_EQUAL:
2757             op_true = OP_IFLE;
2758             op_false = OP_IFGT;
2759             break;
2760         case AstBinaryExpression::GREATER:
2761             op_true = OP_IFGT;
2762             op_false = OP_IFLE;
2763             break;
2764         case AstBinaryExpression::GREATER_EQUAL:
2765             op_true = OP_IFGE;
2766             op_false = OP_IFLT;
2767             break;
2768         default:
2769             assert(false);
2770             break;
2771         }
2772     }
2773     else if (left_type == control.float_type)
2774     {
2775         EmitExpression(left);
2776         EmitExpression(right);
2777 
2778         switch (bp -> Tag())
2779         {
2780         case AstBinaryExpression::EQUAL_EQUAL:
2781             opcode = OP_FCMPL;
2782             op_true = OP_IFEQ;
2783             op_false = OP_IFNE;
2784             break;
2785         case AstBinaryExpression::NOT_EQUAL:
2786             opcode = OP_FCMPL;
2787             op_true = OP_IFNE;
2788             op_false = OP_IFEQ;
2789             break;
2790         case AstBinaryExpression::LESS:
2791             opcode = OP_FCMPG;
2792             op_true = OP_IFLT;
2793             op_false = OP_IFGE;
2794             break;
2795         case AstBinaryExpression::LESS_EQUAL:
2796             opcode = OP_FCMPG;
2797             op_true = OP_IFLE;
2798             op_false = OP_IFGT;
2799             break;
2800         case AstBinaryExpression::GREATER:
2801             opcode = OP_FCMPL;
2802             op_true = OP_IFGT;
2803             op_false = OP_IFLE;
2804             break;
2805         case AstBinaryExpression::GREATER_EQUAL:
2806             opcode = OP_FCMPL;
2807             op_true = OP_IFGE;
2808             op_false = OP_IFLT;
2809             break;
2810         default:
2811             assert(false);
2812             break;
2813         }
2814     }
2815     else if (left_type == control.double_type)
2816     {
2817         EmitExpression(left);
2818         EmitExpression(right);
2819         switch (bp -> Tag())
2820         {
2821         case AstBinaryExpression::EQUAL_EQUAL:
2822             opcode = OP_DCMPL;
2823             op_true = OP_IFEQ;
2824             op_false = OP_IFNE;
2825             break;
2826         case AstBinaryExpression::NOT_EQUAL:
2827             opcode = OP_DCMPL;
2828             op_true = OP_IFNE;
2829             op_false = OP_IFEQ;
2830             break;
2831         case AstBinaryExpression::LESS:
2832             opcode = OP_DCMPG;
2833             op_true = OP_IFLT;
2834             op_false = OP_IFGE;
2835             break;
2836         case AstBinaryExpression::LESS_EQUAL:
2837             opcode = OP_DCMPG;
2838             op_true = OP_IFLE;
2839             op_false = OP_IFGT;
2840             break;
2841         case AstBinaryExpression::GREATER:
2842             opcode = OP_DCMPL;
2843             op_true = OP_IFGT;
2844             op_false = OP_IFLE;
2845             break;
2846         case AstBinaryExpression::GREATER_EQUAL:
2847             opcode = OP_DCMPL;
2848             op_true = OP_IFGE;
2849             op_false = OP_IFLT;
2850             break;
2851         default:
2852             assert(false);
2853             break;
2854         }
2855     }
2856     else assert(false && "comparison of unsupported type");
2857 
2858     if (opcode != OP_NOP)
2859         PutOp(opcode); // if need to emit comparison before branch
2860 
2861     EmitBranch (cond ? op_true : op_false, lab, over);
2862 }
2863 
2864 
2865 //
2866 // Emits a synchronized statement, including monitor cleanup. The return
2867 // value is true if the contained statement is abrupt.
2868 //
EmitSynchronizedStatement(AstSynchronizedStatement * statement)2869 bool ByteCode::EmitSynchronizedStatement(AstSynchronizedStatement* statement)
2870 {
2871     int variable_index =
2872         method_stack -> TopBlock() -> block_symbol -> helper_variable_index;
2873 
2874     Label start_label;
2875     //
2876     // This code must be careful of asynchronous exceptions. Even if the
2877     // synchronized block is empty, user code can use Thread.stop(Throwable),
2878     // so we must ensure the monitor exits. We make sure that all instructions
2879     // after the monitorenter are covered.  By sticking the catchall code
2880     // before the synchronized block, we can even make abrupt exits inside the
2881     // statement be asynch-exception safe.  Note that the user can cause
2882     // deadlock (ie. an infinite loop), by releasing the monitor (via JNI or
2883     // some other means) in the block statement, so that the monitorexit fails
2884     // synchronously with an IllegalMonitorStateException and tries again; but
2885     // JLS 17.13 states that the compiler need not worry about such user
2886     // stupidity.
2887     //
2888     EmitBranch(OP_GOTO, start_label, NULL);
2889     u2 handler_pc = code_attribute -> CodeLength();
2890     assert(stack_depth == 0);
2891     stack_depth = 1; // account for the exception already on the stack
2892     LoadLocal(variable_index, control.Object()); // reload monitor
2893     PutOp(OP_MONITOREXIT);
2894     u2 throw_pc = code_attribute -> CodeLength();
2895     PutOp(OP_ATHROW);
2896     code_attribute -> AddException(handler_pc, throw_pc, handler_pc, 0);
2897 
2898     //
2899     // Even if enclosed statement is a nop, we must enter the monitor, because
2900     // of memory flushing side effects of synchronization.
2901     //
2902     DefineLabel(start_label);
2903     CompleteLabel(start_label);
2904     EmitExpression(statement -> expression);
2905     PutOp(OP_DUP); // duplicate for saving, entering monitor
2906     StoreLocal(variable_index, control.Object()); // save address of object
2907     PutOp(OP_MONITORENTER); // enter monitor associated with object
2908 
2909     assert(method_stack -> TopHandlerRangeStart().Length() == 0 &&
2910            method_stack -> TopHandlerRangeEnd().Length() == 0);
2911     method_stack -> TopHandlerRangeStart().Push(code_attribute -> CodeLength());
2912     bool abrupt = EmitBlockStatement(statement -> block);
2913 
2914     if (! abrupt)
2915     {
2916         LoadLocal(variable_index, control.Object()); // reload monitor
2917         PutOp(OP_MONITOREXIT);
2918     }
2919     u2 end_pc = code_attribute -> CodeLength();
2920     method_stack -> TopHandlerRangeEnd().Push(end_pc);
2921     unsigned count = method_stack -> TopHandlerRangeStart().Length();
2922     assert(count == method_stack -> TopHandlerRangeEnd().Length());
2923     while (count--)
2924     {
2925         code_attribute ->
2926             AddException(method_stack -> TopHandlerRangeStart().Pop(),
2927                          method_stack -> TopHandlerRangeEnd().Pop(),
2928                          handler_pc, 0);
2929     }
2930     return abrupt;
2931 }
2932 
2933 
EmitAssertStatement(AstAssertStatement * assertion)2934 void ByteCode::EmitAssertStatement(AstAssertStatement* assertion)
2935 {
2936     //
2937     // When constant true, the assert statement is a no-op.
2938     // Otherwise, assert a : b; is syntactic sugar for:
2939     //
2940     // while (! ($noassert && (a)))
2941     //     throw new java.lang.AssertionError(b);
2942     //
2943     if (semantic.IsConstantTrue(assertion -> condition) ||
2944         control.option.noassert ||
2945         control.option.target < JikesOption::SDK1_4)
2946     {
2947         return;
2948     }
2949     PutOp(OP_GETSTATIC);
2950     PutU2(RegisterFieldref(assertion -> assert_variable));
2951     Label label;
2952     EmitBranch(OP_IFNE, label);
2953     EmitBranchIfExpression(assertion -> condition, true, label);
2954     PutOp(OP_NEW);
2955     PutU2(RegisterClass(control.AssertionError()));
2956     PutOp(OP_DUP);
2957 
2958     MethodSymbol* constructor = NULL;
2959     if (assertion -> message_opt)
2960     {
2961         EmitExpression(assertion -> message_opt);
2962         TypeSymbol* type = assertion -> message_opt -> Type();
2963         if (! control.AssertionError() -> Bad())
2964         {
2965             // We found the class, now can we find the method?
2966             if (type == control.char_type)
2967                 constructor = control.AssertionError_InitWithCharMethod();
2968             else if (type == control.boolean_type)
2969                 constructor = control.AssertionError_InitWithBooleanMethod();
2970             else if (type == control.int_type || type == control.short_type ||
2971                      type == control.byte_type)
2972             {
2973                 constructor = control.AssertionError_InitWithIntMethod();
2974             }
2975             else if (type == control.long_type)
2976                 constructor = control.AssertionError_InitWithLongMethod();
2977             else if (type == control.float_type)
2978                 constructor = control.AssertionError_InitWithFloatMethod();
2979             else if (type == control.double_type)
2980                 constructor = control.AssertionError_InitWithDoubleMethod();
2981             else if (type == control.null_type || IsReferenceType(type))
2982                 constructor = control.AssertionError_InitWithObjectMethod();
2983             else assert (false && "Missing AssertionError constructor!");
2984             if (! constructor) // We didn't find it; suckage....
2985                 // TODO: error ought to include what we were looking for
2986                 semantic.ReportSemError(SemanticError::LIBRARY_METHOD_NOT_FOUND,
2987                                         assertion,
2988                                         unit_type -> ContainingPackageName(),
2989                                         unit_type -> ExternalName());
2990         }
2991         else
2992         {
2993             // The type for AssertionError is BAD, that means it wasn't
2994             // found! but the calls to control.AssertionError() above will
2995             // file a semantic error for us, no need to here.
2996         }
2997         ChangeStack(- GetTypeWords(type));
2998     }
2999     else constructor = control.AssertionError_InitMethod();
3000 
3001     PutOp(OP_INVOKESPECIAL);
3002     PutU2(RegisterLibraryMethodref(constructor));
3003     PutOp(OP_ATHROW);
3004     DefineLabel(label);
3005     CompleteLabel(label);
3006 }
3007 
3008 
EmitForeachStatement(AstForeachStatement * foreach)3009 void ByteCode::EmitForeachStatement(AstForeachStatement* foreach)
3010 {
3011     int helper_index =
3012         method_stack -> TopBlock() -> block_symbol -> helper_variable_index;
3013     bool abrupt;
3014     EmitExpression(foreach -> expression);
3015     Label loop;
3016     Label& comp = method_stack -> TopContinueLabel();
3017     Label end;
3018     TypeSymbol* expr_type = foreach -> expression -> Type();
3019     VariableSymbol* var =
3020         foreach -> formal_parameter -> formal_declarator -> symbol;
3021     TypeSymbol* component_type = var -> Type();
3022     if (expr_type -> IsArray())
3023     {
3024         //
3025         // Turn 'l: for(a b : c) d' into
3026         // { expr_type #0 = c;
3027         //   int #1 = #0.length;
3028         //   l: for(int #2 = 0; #2 < #1; #2++) {
3029         //     a b = #0[#2];
3030         //     d; }}
3031         // Or in bytecode:
3032         // eval c onto stack
3033         // dup
3034         // astore helper_index
3035         // arraylength
3036         // dup
3037         // istore helper_index+1
3038         // ifeq end
3039         // iconst_0
3040         // istore helper_index+2
3041         // iconst_0
3042         // loop:
3043         // aload helper_index
3044         // swap
3045         // xaload (for x = b, s, i, l, c, f, d, a)
3046         // assignment-conversion (if necessary)
3047         // xstore b (for x = i, l, f, d, a)
3048         // eval d (continue to comp, break to end)
3049         // comp:
3050         // iinc helper_index+2, 1
3051         // iload helper_index+1
3052         // iload helper_index+2
3053         // dup_x1
3054         // if_icmpgt loop
3055         // pop
3056         // end:
3057         //
3058         TypeSymbol* expr_subtype = expr_type -> ArraySubtype();
3059         if (IsNop(foreach -> statement) &&
3060             (! component_type -> Primitive() || expr_subtype -> Primitive()))
3061         {
3062             //
3063             // Optimization (arrays only): no need to increment loop counter
3064             // if nothing is done in the loop; and we simply check that the
3065             // array is non-null from arraylength. But beware of autounboxing,
3066             // which can cause NullPointerException.
3067             //
3068             PutOp(OP_ARRAYLENGTH);
3069             PutOp(OP_POP);
3070             return;
3071         }
3072         PutOp(OP_DUP);
3073         StoreLocal(helper_index, expr_type);
3074         PutOp(OP_ARRAYLENGTH);
3075         PutOp(OP_DUP);
3076         StoreLocal(helper_index + 1, control.int_type);
3077         EmitBranch(OP_IFEQ, end);
3078         PutOp(OP_ICONST_0);
3079         StoreLocal(helper_index + 2, control.int_type);
3080         PutOp(OP_ICONST_0);
3081         DefineLabel(loop);
3082         LoadLocal(helper_index, expr_type);
3083         PutOp(OP_SWAP);
3084         LoadArrayElement(expr_type -> ArraySubtype());
3085         EmitCast(component_type, expr_type -> ArraySubtype());
3086         u2 var_pc = code_attribute -> CodeLength();
3087         StoreLocal(var -> LocalVariableIndex(), component_type);
3088         abrupt = EmitStatement(foreach -> statement);
3089         if (control.option.g & JikesOption::VARS)
3090         {
3091             local_variable_table_attribute ->
3092                 AddLocalVariable(var_pc, code_attribute -> CodeLength(),
3093                                  RegisterName(var -> ExternalIdentity()),
3094                                  RegisterUtf8(component_type -> signature),
3095                                  var -> LocalVariableIndex());
3096         }
3097         if (! abrupt || foreach -> statement -> can_complete_normally)
3098         {
3099             DefineLabel(comp);
3100             PutOpIINC(helper_index + 2, 1);
3101             LoadLocal(helper_index + 1, control.int_type);
3102             LoadLocal(helper_index + 2, control.int_type);
3103             PutOp(OP_DUP_X1);
3104             EmitBranch(OP_IF_ICMPGT, loop);
3105             PutOp(OP_POP);
3106         }
3107     }
3108     else
3109     {
3110         assert(foreach -> expression -> Type() ->
3111                IsSubtype(control.Iterable()));
3112         //
3113         // Turn 'l: for(a b : c) d' into
3114         // for(java.util.Iterator #0 = c.iterator(); #0.hasNext();) {
3115         //   a b = (a) c.next();
3116         //   d; }
3117         // Or in bytecode:
3118         // eval c onto stack
3119         // invokeinterface java.lang.Iterable.iterator()Ljava/util/Iterator;
3120         // dup
3121         // invokeinterface java.util.Iterator.hasNext()Z
3122         // ifeq cleanup
3123         // dup
3124         // astore helper_index
3125         // loop:
3126         // invokeinterface java.util.Iterator.next()Ljava/lang/Object;
3127         // checkcast a
3128         // astore b
3129         // eval d (continue to comp, break to end)
3130         // comp:
3131         // aload helper_index
3132         // dup
3133         // invokeinterface java.util.Iterator.hasNext()Z
3134         // ifne loop
3135         // cleanup:
3136         // pop
3137         // end:
3138         //
3139         Label cleanup;
3140         PutOp(OP_INVOKEINTERFACE);
3141         PutU2(RegisterLibraryMethodref(control.Iterable_iteratorMethod()));
3142         PutU1(1);
3143         PutU1(0);
3144         ChangeStack(1);
3145         PutOp(OP_DUP);
3146         PutOp(OP_INVOKEINTERFACE);
3147         u2 hasNext_index =
3148             RegisterLibraryMethodref(control.Iterator_hasNextMethod());
3149         PutU2(hasNext_index);
3150         PutU1(1);
3151         PutU1(0);
3152         ChangeStack(1);
3153         EmitBranch(OP_IFEQ, cleanup);
3154         PutOp(OP_DUP);
3155         StoreLocal(helper_index, control.Iterator());
3156         DefineLabel(loop);
3157         PutOp(OP_INVOKEINTERFACE);
3158         PutU2(RegisterLibraryMethodref(control.Iterator_nextMethod()));
3159         PutU1(1);
3160         PutU1(0);
3161         ChangeStack(1);
3162         if (component_type != control.Object())
3163         {
3164             PutOp(OP_CHECKCAST);
3165             PutU2(RegisterClass(component_type));
3166         }
3167         u2 var_pc = code_attribute -> CodeLength();
3168         StoreLocal(var -> LocalVariableIndex(), component_type);
3169         abrupt = EmitStatement(foreach -> statement);
3170         if (control.option.g & JikesOption::VARS)
3171         {
3172             local_variable_table_attribute ->
3173                 AddLocalVariable(var_pc, code_attribute -> CodeLength(),
3174                                  RegisterName(var -> ExternalIdentity()),
3175                                  RegisterUtf8(component_type -> signature),
3176                                  var -> LocalVariableIndex());
3177         }
3178         if (! abrupt || foreach -> statement -> can_complete_normally)
3179         {
3180             DefineLabel(comp);
3181             LoadLocal(helper_index, control.Iterator());
3182             PutOp(OP_DUP);
3183             PutOp(OP_INVOKEINTERFACE);
3184             PutU2(hasNext_index);
3185             PutU1(1);
3186             PutU1(0);
3187             ChangeStack(1);
3188             EmitBranch(OP_IFNE, loop);
3189         }
3190         else ChangeStack(1);
3191         DefineLabel(cleanup);
3192         CompleteLabel(cleanup);
3193         PutOp(OP_POP);
3194     }
3195     DefineLabel(end);
3196     CompleteLabel(loop);
3197     CompleteLabel(comp);
3198     CompleteLabel(end);
3199 }
3200 
3201 
3202 //
3203 // JLS is Java Language Specification
3204 // JVM is Java Virtual Machine
3205 //
3206 // Expressions: Chapter 14 of JLS
3207 //
EmitExpression(AstExpression * expression,bool need_value)3208 int ByteCode::EmitExpression(AstExpression* expression, bool need_value)
3209 {
3210     expression = StripNops(expression);
3211     if (expression -> IsConstant())
3212     {
3213         if (need_value)
3214         {
3215             LoadLiteral(expression -> value, expression -> Type());
3216             return GetTypeWords(expression -> Type());
3217         }
3218         return 0;
3219     }
3220 
3221     switch (expression -> kind)
3222     {
3223     case Ast::NAME:
3224         return EmitName((AstName*) expression, need_value);
3225     case Ast::THIS_EXPRESSION:
3226         {
3227             AstThisExpression* this_expr = (AstThisExpression*) expression;
3228             if (this_expr -> resolution_opt && need_value)
3229                 return EmitExpression(this_expr -> resolution_opt, true);
3230         }
3231         if (need_value)
3232         {
3233             PutOp(OP_ALOAD_0);
3234             return 1;
3235         }
3236         return 0;
3237     case Ast::SUPER_EXPRESSION:
3238         {
3239             AstSuperExpression* super_expr = (AstSuperExpression*) expression;
3240             if (super_expr -> resolution_opt && need_value)
3241                 return EmitExpression(super_expr -> resolution_opt, true);
3242         }
3243         if (need_value)
3244         {
3245             PutOp(OP_ALOAD_0);
3246             return 1;
3247         }
3248         return 0;
3249     case Ast::CLASS_CREATION:
3250         return EmitClassCreationExpression
3251             ((AstClassCreationExpression*) expression, need_value);
3252     case Ast::ARRAY_CREATION:
3253         return EmitArrayCreationExpression((AstArrayCreationExpression*) expression, need_value);
3254     case Ast::CLASS_LITERAL:
3255         {
3256             AstClassLiteral* class_lit = (AstClassLiteral*) expression;
3257             if (class_lit -> resolution_opt)
3258                 return GenerateClassAccess(class_lit, need_value);
3259             TypeSymbol* type = expression -> symbol -> TypeCast();
3260             if (type)
3261             {
3262                 // Must load for side effect of class not found
3263                 assert(type == control.Class());
3264                 LoadConstantAtIndex(RegisterClass(class_lit -> type ->
3265                                                   symbol));
3266                 if (! need_value)
3267                     PutOp(OP_POP);
3268             }
3269             else if (need_value)
3270             {
3271                 // No side effects for Integer.TYPE and friends.
3272                 assert(expression -> symbol -> VariableCast());
3273                 PutOp(OP_GETSTATIC);
3274                 PutU2(RegisterFieldref((VariableSymbol*) expression ->
3275                                        symbol));
3276             }
3277             return need_value ? 1 : 0;
3278         }
3279     case Ast::DOT:
3280         return EmitFieldAccess((AstFieldAccess*) expression, need_value);
3281     case Ast::CALL:
3282         return EmitMethodInvocation((AstMethodInvocation*) expression,
3283                                     need_value);
3284     case Ast::ARRAY_ACCESS:
3285         {
3286             // must evaluate, for potential Exception side effects
3287             int words = EmitArrayAccessRhs((AstArrayAccess*) expression);
3288             if (need_value)
3289                 return words;
3290             PutOp(words == 1 ? OP_POP : OP_POP2);
3291             return 0;
3292         }
3293     case Ast::POST_UNARY:
3294         return EmitPostUnaryExpression((AstPostUnaryExpression*) expression,
3295                                        need_value);
3296     case Ast::PRE_UNARY:
3297         return EmitPreUnaryExpression((AstPreUnaryExpression*) expression,
3298                                       need_value);
3299     case Ast::CAST:
3300         return EmitCastExpression((AstCastExpression*) expression, need_value);
3301     case Ast::BINARY:
3302         return EmitBinaryExpression((AstBinaryExpression*) expression,
3303                                     need_value);
3304     case Ast::INSTANCEOF:
3305         return EmitInstanceofExpression((AstInstanceofExpression*) expression,
3306                                         need_value);
3307     case Ast::CONDITIONAL:
3308         return EmitConditionalExpression(((AstConditionalExpression*)
3309                                           expression),
3310                                          need_value);
3311     case Ast::ASSIGNMENT:
3312         return EmitAssignmentExpression((AstAssignmentExpression*) expression,
3313                                         need_value);
3314     case Ast::NULL_LITERAL:
3315         if (need_value)
3316         {
3317             PutOp(OP_ACONST_NULL);
3318             return 1;
3319         }
3320         return 0;
3321     default:
3322         assert(false && "unknown expression kind");
3323         break;
3324     }
3325     return 0; // even though we will not reach here
3326 }
3327 
3328 
VariableExpressionResolution(AstExpression * expression)3329 AstExpression* ByteCode::VariableExpressionResolution(AstExpression* expression)
3330 {
3331     //
3332     // JLS2 added ability for parenthesized variable to remain a variable.
3333     // If the expression was resolved, get the resolution.
3334     //
3335     expression = StripNops(expression);
3336     AstFieldAccess* field = expression -> FieldAccessCast();
3337     if (field && field -> resolution_opt)
3338         return field -> resolution_opt;
3339     AstName* name = expression -> NameCast();
3340     if (name && name -> resolution_opt)
3341         return name -> resolution_opt;
3342     return expression;
3343 }
3344 
3345 
VariableTypeResolution(AstExpression * expression,VariableSymbol * sym)3346 TypeSymbol* ByteCode::VariableTypeResolution(AstExpression* expression,
3347                                              VariableSymbol* sym)
3348 {
3349     expression = VariableExpressionResolution(expression);
3350     AstFieldAccess* field = expression -> FieldAccessCast();
3351     AstName* name = expression -> NameCast();
3352     assert(field || name);
3353 
3354     //
3355     // JLS2 13.1 Use the type of the base expression for qualified reference
3356     // (this even works for super expressions), and the innermost type that
3357     // contains the (possibly inherited) field for simple name reference.
3358     //
3359     // Prior to JDK 1.4, VMs incorrectly complained if a field declared in an
3360     // interface is referenced by inheritance, even though the JVMS permits it
3361     // and JLS 13 requires it.
3362     //
3363     TypeSymbol* candidate = field ? field -> base -> Type()
3364         : name -> base_opt ? name -> base_opt -> Type() : unit_type;
3365     return (sym -> ContainingType() -> ACC_INTERFACE() &&
3366             control.option.target < JikesOption::SDK1_4)
3367         ? sym -> ContainingType() : candidate;
3368 }
3369 
3370 
MethodTypeResolution(AstExpression * base,MethodSymbol * msym)3371 TypeSymbol* ByteCode::MethodTypeResolution(AstExpression* base,
3372                                            MethodSymbol* msym)
3373 {
3374     //
3375     // JLS 13.1 If the method is declared in Object, use Object. Otherwise,
3376     // use the type of the base expression for qualified reference (this even
3377     // works for super expressions), and the innermost type that contains the
3378     // (possibly inherited) method for simple name reference.  However, if
3379     // this is an accessor method, use the owner_type (since the base type
3380     // relates to the accessed expression, not the accessor method).
3381     //
3382     TypeSymbol* owner_type = msym -> containing_type;
3383     TypeSymbol* base_type = msym -> ACC_SYNTHETIC() ? owner_type
3384         : base ? base -> Type() : unit_type;
3385     return owner_type == control.Object() ? owner_type : base_type;
3386 }
3387 
3388 
EmitFieldAccessLhsBase(AstExpression * expression)3389 void ByteCode::EmitFieldAccessLhsBase(AstExpression* expression)
3390 {
3391     expression = VariableExpressionResolution(expression);
3392     AstFieldAccess* field = expression -> FieldAccessCast();
3393     AstName* name = expression -> NameCast();
3394 
3395     //
3396     // We now have the right expression. Check if it is qualified, in which
3397     // case we process the base. Otherwise, it must be a simple name.
3398     //
3399     if (field || (name && name -> base_opt))
3400         EmitExpression(field ? field -> base : name -> base_opt);
3401     else PutOp(OP_ALOAD_0); // get address of "this"
3402 }
3403 
3404 
EmitFieldAccessLhs(AstExpression * expression)3405 void ByteCode::EmitFieldAccessLhs(AstExpression* expression)
3406 {
3407     EmitFieldAccessLhsBase(expression);
3408     PutOp(OP_DUP);     // save base address of field for later store
3409     PutOp(OP_GETFIELD);
3410     if (control.IsDoubleWordType(expression -> Type()))
3411         ChangeStack(1);
3412 
3413     VariableSymbol* sym = (VariableSymbol*) expression -> symbol;
3414     PutU2(RegisterFieldref(VariableTypeResolution(expression, sym), sym));
3415 }
3416 
3417 
3418 //
3419 // Generate code for access method used to set class literal fields, when
3420 // compiling for older VMs.
3421 //
GenerateClassAccessMethod()3422 void ByteCode::GenerateClassAccessMethod()
3423 {
3424     assert(control.option.target < JikesOption::SDK1_5);
3425     //
3426     // Here, we add a line-number attribute entry for this method.
3427     // Even though this is a generated method, JPDA debuggers will
3428     // still fail setting breakpoints if methods don't have line numbers.
3429     // Sun's javac compiler generates a single line number entry
3430     // with start_pc set to zero and line number set to the first line of
3431     // code in the source. In testing, it appears that setting the start_pc
3432     // and line_number to zero as we do here, also works.
3433     //
3434     line_number_table_attribute -> AddLineNumber(0, 0);
3435 
3436     //
3437     // Since the VM does not have a nice way of finding a class without a
3438     // runtime object, we use this approach.  Notice that forName can throw
3439     // a checked exception, but JLS semantics do not allow this, so we must
3440     // add a catch block to convert the problem to an unchecked Error.
3441     // Likewise, note that we must not initialize the class in question,
3442     // hence the use of forName on array types in all cases.
3443     //
3444     // The generated code is semantically equivalent to:
3445     //
3446     // /*synthetic*/ static java.lang.Class class$(java.lang.String name,
3447     //                                             boolean array) {
3448     //     try {
3449     //         Class result = java.lang.Class.forName(name);
3450     //         return array ? result : result.getComponentType();
3451     //     } catch (ClassNotFoundException e) {
3452     //         throw new NoClassDefFoundError(((Throwable) e).getMessage());
3453     //     }
3454     // }
3455     //
3456     // When option.target >= SDK1_4, we use the new exception chaining,
3457     // and the catch clause becomes
3458     //   throw (Error) ((Throwable) new NoClassDefFoundError()).initCause(e);
3459     //
3460     // Since ClassNotFoundException inherits, rather than declares, getMessage,
3461     // we link to Throwable, and use the cast to Throwable in the code above to
3462     // show that we are still obeying JLS 13.1, which requires that .class
3463     // files must link to the type of the qualifying expression.
3464     //
3465     //  aload_0        load class name in array form
3466     //  invokestatic   java/lang/Class.forName(Ljava/lang/String;)Ljava/lang/Class;
3467     //  iload_1        load array
3468     //  ifne label
3469     //  invokevirtual  java/lang/Class.getComponentType()Ljava/lang/Class;
3470     //  label:
3471     //  areturn        return Class object
3472     //
3473     // pre-SDK1_4 exception handler if forName fails (optimization: the
3474     // ClassNotFoundException will already be on the stack):
3475     //
3476     //  invokevirtual  java/lang/Throwable.getMessage()Ljava/lang/String;
3477     //  new            java/lang/NoClassDefFoundError
3478     //  dup_x1         save copy to throw, but below string arg to constructor
3479     //  swap           swap string and new object to correct order
3480     //  invokespecial  java/lang/NoClassDefFoundError.<init>(Ljava/lang/String;)V
3481     //  athrow         throw the correct exception
3482     //
3483     // post-SDK1_4 exception handler if forName fails (optimization: the
3484     // ClassNotFoundException will already be on the stack):
3485     //
3486     //  new            java/lang/NoClassDefFoundError
3487     //  dup_x1         save copy, but below cause
3488     //  invokespecial  java/lang/NoClassDefFoundError.<init>()V
3489     //  invokevirtual  java/lang/Throwable.initCause(Ljava/lang/Throwable;)Ljava/lang/Throwable;
3490     //  athrow         throw the correct exception
3491     //
3492     Label label;
3493     PutOp(OP_ALOAD_0);
3494     PutOp(OP_INVOKESTATIC);
3495     PutU2(RegisterLibraryMethodref(control.Class_forNameMethod()));
3496     PutOp(OP_ILOAD_1);
3497     EmitBranch(OP_IFNE, label);
3498     PutOp(OP_INVOKEVIRTUAL);
3499     PutU2(RegisterLibraryMethodref(control.Class_getComponentTypeMethod()));
3500     ChangeStack(1); // account for the return
3501     DefineLabel(label);
3502     CompleteLabel(label);
3503     PutOp(OP_ARETURN);
3504     code_attribute ->
3505       AddException(0, 12, 12, RegisterClass(control.ClassNotFoundException()));
3506 
3507     ChangeStack(1); // account for the exception on the stack
3508     if (control.option.target < JikesOption::SDK1_4)
3509     {
3510         PutOp(OP_INVOKEVIRTUAL);
3511         PutU2(RegisterLibraryMethodref(control.Throwable_getMessageMethod()));
3512         ChangeStack(1); // account for the returned string
3513         PutOp(OP_NEW);
3514         PutU2(RegisterClass(control.NoClassDefFoundError()));
3515         PutOp(OP_DUP_X1);
3516         PutOp(OP_SWAP);
3517         PutOp(OP_INVOKESPECIAL);
3518         PutU2(RegisterLibraryMethodref(control.NoClassDefFoundError_InitStringMethod()));
3519         ChangeStack(-1); // account for the argument to the constructor
3520     }
3521     else
3522     {
3523         PutOp(OP_NEW);
3524         PutU2(RegisterClass(control.NoClassDefFoundError()));
3525         PutOp(OP_DUP_X1);
3526         PutOp(OP_INVOKESPECIAL);
3527         PutU2(RegisterLibraryMethodref(control.NoClassDefFoundError_InitMethod()));
3528         PutOp(OP_INVOKEVIRTUAL);
3529         PutU2(RegisterLibraryMethodref(control.Throwable_initCauseMethod()));
3530     }
3531     PutOp(OP_ATHROW);
3532 }
3533 
3534 
3535 //
3536 // Generate code to dymanically initialize the field for a class literal, and
3537 // return its value. Only generated for older VMs (since newer ones support
3538 // ldc class).
3539 //
GenerateClassAccess(AstClassLiteral * class_lit,bool need_value)3540 int ByteCode::GenerateClassAccess(AstClassLiteral* class_lit,
3541                                   bool need_value)
3542 {
3543     assert(control.option.target < JikesOption::SDK1_5);
3544     //
3545     // Evaluate X.class literal. If X is a primitive type, this is a
3546     // predefined field, and we emitted it directly rather than relying on
3547     // this method. Otherwise, we have created a synthetic field to cache
3548     // the desired result, and we initialize it at runtime. Within a class,
3549     // this cannot be done in the static initializer, because it is possible
3550     // to access a class literal before a class is initialized.
3551     //
3552     // Foo.Bar.class becomes
3553     // (class$Foo$Bar == null ? class$Foo$Bar = class$("[LFoo.Bar;", false)
3554     //                        : class$Foo$Bar)
3555     // int[].class becomes
3556     // (array$I == null ? array$I = class$("[I", true) : array$I)
3557     //
3558     // getstatic class_field     load class field
3559     // dup                       optimize: common case is non-null
3560     // ifnonnull label           branch if it exists, otherwise initialize
3561     // pop                       pop the null we just duplicated
3562     // load class_constant       get name of class
3563     // iconst_x                  true iff array
3564     // invokestatic              invoke synthetic class$ method
3565     // dup                       save value so can return it
3566     // put class_field           initialize the field
3567     // label:
3568     //
3569     Label label;
3570     assert(class_lit -> symbol -> VariableCast());
3571     VariableSymbol* cache = (VariableSymbol*) class_lit -> symbol;
3572 
3573     u2 field_index = RegisterFieldref(cache);
3574 
3575     PutOp(OP_GETSTATIC);
3576     PutU2(field_index);
3577     if (need_value)
3578         PutOp(OP_DUP);
3579     EmitBranch(OP_IFNONNULL, label);
3580 
3581     if (need_value)
3582         PutOp(OP_POP);
3583     TypeSymbol* type = class_lit -> type -> symbol;
3584     if (type -> num_dimensions > 255)
3585         semantic.ReportSemError(SemanticError::ARRAY_OVERFLOW, class_lit);
3586     bool is_array = type -> IsArray();
3587     if (! is_array)
3588         type = type -> GetArrayType(control.system_semantic, 1);
3589     LoadLiteral(type -> FindOrInsertClassLiteralName(control),
3590                 control.String());
3591     PutOp(is_array ? OP_ICONST_1 : OP_ICONST_0);
3592     PutOp(OP_INVOKESTATIC);
3593     CompleteCall(cache -> ContainingType() -> ClassLiteralMethod(), 2);
3594     if (need_value)
3595         PutOp(OP_DUP);
3596     PutOp(OP_PUTSTATIC);
3597     PutU2(field_index);
3598     DefineLabel(label);
3599     CompleteLabel(label);
3600     return need_value ? 1 : 0;
3601 }
3602 
3603 
3604 //
3605 // Generate code for initializing assert variable
3606 //
GenerateAssertVariableInitializer(TypeSymbol * tsym,VariableSymbol * vsym)3607 void ByteCode::GenerateAssertVariableInitializer(TypeSymbol* tsym,
3608                                                  VariableSymbol* vsym)
3609 {
3610     //
3611     // Create the field initializer. This approach avoids using a class
3612     // literal, for two reasons:
3613     //   - we use fewer bytecodes if the rest of the class does not use class
3614     //     literals (and we need no try-catch block)
3615     //   - determining assertion status will not initialize an enclosing class.
3616     //
3617     // Unfortunately, until the VM supports easier determination of classes
3618     // from a static context, we must create an empty garbage array.
3619     // We initialize to the opposite of desiredAssertionStatus to obey the
3620     // semantics of assert - until class initialization starts, the default
3621     // value of false in this variable will enable asserts anywhere in the
3622     // class.
3623     //
3624     // private static final boolean $noassert
3625     //     = ! Class.forName("[L<outermostClass>;").getComponentType()
3626     //     .desiredAssertionStatus();
3627     //
3628     //  ldc              "L[<outermostClass>;"
3629     //  invokevirtual    java/lang/Class.forName(Ljava/lang/String;)java/lang/Class
3630     //  invokevirtual    java/lang/Class.getComponentType()Ljava/lang/Class;
3631     //  invokevirtual    java/lang/Class.desiredAssertionStatus()Z
3632     //  iconst_1
3633     //  ixor             result ^ true <=> !result
3634     //  putstatic        <thisClass>.$noassert
3635     //
3636     assert(! control.option.noassert &&
3637            control.option.target >= JikesOption::SDK1_4);
3638     tsym = tsym -> GetArrayType(control.system_semantic, 1);
3639     LoadLiteral(tsym -> FindOrInsertClassLiteralName(control),
3640                 control.String());
3641     PutOp(OP_INVOKESTATIC);
3642     PutU2(RegisterLibraryMethodref(control.Class_forNameMethod()));
3643     PutOp(OP_INVOKEVIRTUAL);
3644     ChangeStack(1); // for returned value
3645     PutU2(RegisterLibraryMethodref(control.Class_getComponentTypeMethod()));
3646     PutOp(OP_INVOKEVIRTUAL);
3647     ChangeStack(1); // for returned value
3648     PutU2(RegisterLibraryMethodref(control.Class_desiredAssertionStatusMethod()));
3649     PutOp(OP_ICONST_1);
3650     PutOp(OP_IXOR);
3651     PutOp(OP_PUTSTATIC);
3652     PutU2(RegisterFieldref(vsym));
3653 }
3654 
3655 
EmitName(AstName * expression,bool need_value)3656 int ByteCode::EmitName(AstName* expression, bool need_value)
3657 {
3658     if (expression -> symbol -> TypeCast())
3659         return 0;
3660     VariableSymbol* var = expression -> symbol -> VariableCast();
3661     return LoadVariable((expression -> resolution_opt ? ACCESSED_VAR
3662                          : var -> owner -> MethodCast() ? LOCAL_VAR
3663                          : var -> ACC_STATIC() ? STATIC_VAR : FIELD_VAR),
3664                         expression, need_value);
3665 }
3666 
3667 
3668 //
3669 // see also OP_MULTIANEWARRAY
3670 //
EmitArrayCreationExpression(AstArrayCreationExpression * expression,bool need_value)3671 int ByteCode::EmitArrayCreationExpression(AstArrayCreationExpression* expression,
3672                                           bool need_value)
3673 {
3674     unsigned num_dims = expression -> NumDimExprs();
3675 
3676     if (expression -> Type() -> num_dimensions > 255)
3677         semantic.ReportSemError(SemanticError::ARRAY_OVERFLOW, expression);
3678 
3679     if (expression -> array_initializer_opt)
3680     {
3681         InitializeArray(expression -> Type(),
3682                         expression -> array_initializer_opt, need_value);
3683     }
3684     else
3685     {
3686         //
3687         // Need to push value of dimension(s) and create array. This can be
3688         // skipped if we don't need a value, but only if we know that all
3689         // dimensions are non-negative.
3690         //
3691         bool create_array = need_value;
3692         for (unsigned i = 0; ! create_array && i < num_dims; i++)
3693         {
3694             AstExpression* expr =
3695                 StripNops(expression -> DimExpr(i) -> expression);
3696             if (expr -> IsConstant())
3697             {
3698                 if (DYNAMIC_CAST<IntLiteralValue*> (expr -> value) ->
3699                     value < 0)
3700                 {
3701                     create_array = true;
3702                 }
3703             }
3704             else if (expr -> Type() != control.char_type)
3705                 create_array = true;
3706         }
3707         for (unsigned j = 0; j < num_dims; j++)
3708             EmitExpression(expression -> DimExpr(j) -> expression,
3709                            create_array);
3710         if (create_array)
3711         {
3712             EmitNewArray(num_dims, expression -> Type());
3713             if (! need_value)
3714                 PutOp(OP_POP);
3715         }
3716     }
3717 
3718     return need_value ? 1 : 0;
3719 }
3720 
3721 
3722 //
3723 // ASSIGNMENT
3724 //
EmitAssignmentExpression(AstAssignmentExpression * assignment_expression,bool need_value)3725 int ByteCode::EmitAssignmentExpression(AstAssignmentExpression* assignment_expression,
3726                                        bool need_value)
3727 {
3728     //
3729     // JLS2 added ability for parenthesized variable to remain a variable.
3730     //
3731     AstCastExpression* casted_left_hand_side =
3732         assignment_expression -> left_hand_side -> CastExpressionCast();
3733     AstExpression* left_hand_side
3734         = StripNops(casted_left_hand_side
3735                     ? casted_left_hand_side -> expression
3736                     : assignment_expression -> left_hand_side);
3737 
3738     TypeSymbol* left_type = left_hand_side -> Type();
3739 
3740     VariableCategory kind = GetVariableKind(assignment_expression);
3741     VariableSymbol* accessed_member = assignment_expression -> write_method
3742         ? (assignment_expression -> write_method -> accessed_member ->
3743            VariableCast())
3744         : (VariableSymbol*) NULL;
3745 
3746     if (assignment_expression -> SimpleAssignment())
3747     {
3748         switch (kind)
3749         {
3750         case ARRAY_VAR:
3751             // lhs must be array access
3752             EmitArrayAccessLhs(left_hand_side -> ArrayAccessCast());
3753             break;
3754         case FIELD_VAR:
3755             // load base for field access
3756             EmitFieldAccessLhsBase(left_hand_side);
3757             break;
3758         case STATIC_VAR:
3759             //
3760             // If the access is qualified by an arbitrary base
3761             // expression, evaluate it for side effects.
3762             //
3763             if (left_hand_side -> FieldAccessCast())
3764             {
3765                 AstExpression* base =
3766                     ((AstFieldAccess*) left_hand_side) -> base;
3767                 EmitExpression(base, false);
3768             }
3769             else if (left_hand_side -> NameCast())
3770             {
3771                 AstName* base = ((AstName*) left_hand_side) -> base_opt;
3772                 if (base)
3773                     EmitName(base, false);
3774             }
3775             break;
3776         case ACCESSED_VAR:
3777             // need to load address of object, obtained from resolution
3778             if (! accessed_member -> ACC_STATIC())
3779             {
3780                 AstExpression* resolve = left_hand_side -> FieldAccessCast()
3781                     ? left_hand_side -> FieldAccessCast() -> resolution_opt
3782                     : left_hand_side -> NameCast() -> resolution_opt;
3783                 assert(resolve);
3784 
3785                 AstExpression* base =
3786                     resolve -> MethodInvocationCast() -> base_opt;
3787                 assert(base);
3788                 EmitExpression(base);
3789             }
3790             else if (left_hand_side -> FieldAccessCast())
3791                 //
3792                 // If the access is qualified by an arbitrary base
3793                 // expression, evaluate it for side effects.
3794                 //
3795                 EmitExpression(((AstFieldAccess*) left_hand_side) -> base,
3796                                false);
3797             break;
3798         case LOCAL_VAR:
3799             break;
3800         default:
3801             assert(false && "bad kind in EmitAssignmentExpression");
3802         }
3803 
3804         EmitExpression(assignment_expression -> expression);
3805     }
3806     //
3807     // Here for compound assignment. Get the left operand, saving any
3808     // information necessary to update its value on the stack below the value.
3809     //
3810     else
3811     {
3812         switch (kind)
3813         {
3814         case ARRAY_VAR:
3815             // lhs must be array access
3816             EmitArrayAccessLhs(left_hand_side -> ArrayAccessCast());
3817             PutOp(OP_DUP2); // save base and index for later store
3818 
3819             //
3820             // load current value
3821             //
3822             LoadArrayElement(assignment_expression -> Type());
3823             break;
3824         case FIELD_VAR:
3825             EmitFieldAccessLhs(left_hand_side);
3826             break;
3827         case LOCAL_VAR:
3828             if (! casted_left_hand_side &&
3829                 assignment_expression -> Type() == control.int_type &&
3830                 assignment_expression -> expression -> IsConstant() &&
3831                 ((assignment_expression -> Tag() ==
3832                   AstAssignmentExpression::PLUS_EQUAL) ||
3833                  (assignment_expression -> Tag() ==
3834                   AstAssignmentExpression::MINUS_EQUAL)))
3835             {
3836                 IntLiteralValue* vp = DYNAMIC_CAST<IntLiteralValue*>
3837                     (assignment_expression -> expression -> value);
3838                 int val = ((assignment_expression -> Tag() ==
3839                             AstAssignmentExpression::MINUS_EQUAL)
3840                            ? -(vp -> value) // we treat "a -= x" as "a += (-x)"
3841                            : vp -> value);
3842                 if (val >= -32768 && val < 32768) // if value in range
3843                 {
3844                     VariableSymbol* sym =
3845                         (VariableSymbol*) left_hand_side -> symbol;
3846                     PutOpIINC(sym -> LocalVariableIndex(), val);
3847                     LoadVariable(LOCAL_VAR, left_hand_side, need_value);
3848                     return GetTypeWords(assignment_expression -> Type());
3849                 }
3850             }
3851 
3852             LoadVariable(kind, left_hand_side);
3853             break;
3854         case STATIC_VAR:
3855             LoadVariable(kind, left_hand_side);
3856             break;
3857         case ACCESSED_VAR:
3858             //
3859             // If we are accessing a static member, get value by invoking
3860             // appropriate resolution. Otherwise, in addition to getting
3861             // the value, we need to load address of the object,
3862             // obtained from the resolution, saving a copy on the stack.
3863             //
3864             if (accessed_member -> ACC_STATIC())
3865                 EmitExpression(left_hand_side);
3866             else ResolveAccess(left_hand_side);
3867             break;
3868         default:
3869             assert(false && "bad kind in EmitAssignmentExpression");
3870         }
3871 
3872         //
3873         // Here for string concatenation.
3874         //
3875         if ((assignment_expression -> Tag() ==
3876              AstAssignmentExpression::PLUS_EQUAL) &&
3877             left_type == control.String())
3878         {
3879             PutOp(OP_NEW);
3880             PutU2(RegisterClass(control.option.target >= JikesOption::SDK1_5
3881                                 ? control.StringBuilder()
3882                                 : control.StringBuffer()));
3883             PutOp(OP_DUP_X1);
3884             PutOp(OP_INVOKESPECIAL);
3885             PutU2(RegisterLibraryMethodref
3886                   (control.option.target >= JikesOption::SDK1_5
3887                    ? control.StringBuilder_InitMethod()
3888                    : control.StringBuffer_InitMethod()));
3889             EmitStringAppendMethod(control.String());
3890             AppendString(assignment_expression -> expression, true);
3891             PutOp(OP_INVOKEVIRTUAL);
3892             PutU2(RegisterLibraryMethodref
3893                   (control.option.target >= JikesOption::SDK1_5
3894                    ? control.StringBuilder_toStringMethod()
3895                    : control.StringBuffer_toStringMethod()));
3896             ChangeStack(1); // account for return value
3897         }
3898         //
3899         // Here for operation other than string concatenation. Determine the
3900         // opcode to use.
3901         //
3902         else
3903         {
3904             Opcode opc;
3905 
3906             TypeSymbol* op_type = (casted_left_hand_side
3907                                    ? casted_left_hand_side -> Type()
3908                                    : assignment_expression -> Type());
3909 
3910             if (control.IsSimpleIntegerValueType(op_type) ||
3911                 op_type == control.boolean_type)
3912             {
3913                 switch (assignment_expression -> Tag())
3914                 {
3915                 case AstAssignmentExpression::STAR_EQUAL:
3916                     opc = OP_IMUL;
3917                     break;
3918                 case AstAssignmentExpression::SLASH_EQUAL:
3919                     opc = OP_IDIV;
3920                     break;
3921                 case AstAssignmentExpression::MOD_EQUAL:
3922                     opc = OP_IREM;
3923                     break;
3924                 case AstAssignmentExpression::PLUS_EQUAL:
3925                     opc = OP_IADD;
3926                     break;
3927                 case AstAssignmentExpression::MINUS_EQUAL:
3928                     opc = OP_ISUB;
3929                     break;
3930                 case AstAssignmentExpression::LEFT_SHIFT_EQUAL:
3931                     opc = OP_ISHL;
3932                     break;
3933                 case AstAssignmentExpression::RIGHT_SHIFT_EQUAL:
3934                     opc = OP_ISHR;
3935                     break;
3936                 case AstAssignmentExpression::UNSIGNED_RIGHT_SHIFT_EQUAL:
3937                     opc = OP_IUSHR;
3938                     break;
3939                 case AstAssignmentExpression::AND_EQUAL:
3940                     opc = OP_IAND;
3941                     break;
3942                 case AstAssignmentExpression::IOR_EQUAL:
3943                     opc = OP_IOR;
3944                     break;
3945                 case AstAssignmentExpression::XOR_EQUAL:
3946                     opc = OP_IXOR;
3947                     break;
3948                 default:
3949                     assert(false && "bad op_type in EmitAssignmentExpression");
3950                 }
3951             }
3952             else if (op_type == control.long_type)
3953             {
3954                 switch (assignment_expression -> Tag())
3955                 {
3956                 case AstAssignmentExpression::STAR_EQUAL:
3957                     opc = OP_LMUL;
3958                     break;
3959                 case AstAssignmentExpression::SLASH_EQUAL:
3960                     opc = OP_LDIV;
3961                     break;
3962                 case AstAssignmentExpression::MOD_EQUAL:
3963                     opc = OP_LREM;
3964                     break;
3965                 case AstAssignmentExpression::PLUS_EQUAL:
3966                     opc = OP_LADD;
3967                     break;
3968                 case AstAssignmentExpression::MINUS_EQUAL:
3969                     opc = OP_LSUB;
3970                     break;
3971                 case AstAssignmentExpression::LEFT_SHIFT_EQUAL:
3972                     opc = OP_LSHL;
3973                     break;
3974                 case AstAssignmentExpression::RIGHT_SHIFT_EQUAL:
3975                     opc = OP_LSHR;
3976                     break;
3977                 case AstAssignmentExpression::UNSIGNED_RIGHT_SHIFT_EQUAL:
3978                     opc = OP_LUSHR;
3979                     break;
3980                 case AstAssignmentExpression::AND_EQUAL:
3981                     opc = OP_LAND;
3982                     break;
3983                 case AstAssignmentExpression::IOR_EQUAL:
3984                     opc = OP_LOR;
3985                     break;
3986                 case AstAssignmentExpression::XOR_EQUAL:
3987                     opc = OP_LXOR;
3988                     break;
3989                 default:
3990                     assert(false && "bad op_type in EmitAssignmentExpression");
3991                 }
3992             }
3993             else if (op_type == control.float_type)
3994             {
3995                 switch (assignment_expression -> Tag())
3996                 {
3997                 case AstAssignmentExpression::STAR_EQUAL:
3998                     opc = OP_FMUL;
3999                     break;
4000                 case AstAssignmentExpression::SLASH_EQUAL:
4001                     opc = OP_FDIV;
4002                     break;
4003                 case AstAssignmentExpression::MOD_EQUAL:
4004                     opc = OP_FREM;
4005                     break;
4006                 case AstAssignmentExpression::PLUS_EQUAL:
4007                     opc = OP_FADD;
4008                     break;
4009                 case AstAssignmentExpression::MINUS_EQUAL:
4010                     opc = OP_FSUB;
4011                     break;
4012                 default:
4013                     assert(false && "bad op_type in EmitAssignmentExpression");
4014                 }
4015             }
4016             else if (op_type == control.double_type)
4017             {
4018                 switch (assignment_expression -> Tag())
4019                 {
4020                 case AstAssignmentExpression::STAR_EQUAL:
4021                     opc = OP_DMUL;
4022                     break;
4023                 case AstAssignmentExpression::SLASH_EQUAL:
4024                     opc = OP_DDIV;
4025                     break;
4026                 case AstAssignmentExpression::MOD_EQUAL:
4027                     opc = OP_DREM;
4028                     break;
4029                 case AstAssignmentExpression::PLUS_EQUAL:
4030                     opc = OP_DADD;
4031                     break;
4032                 case AstAssignmentExpression::MINUS_EQUAL:
4033                     opc = OP_DSUB;
4034                     break;
4035                 default:
4036                     assert(false && "bad op_type in EmitAssignmentExpression");
4037                 }
4038             }
4039             else
4040             {
4041                 assert(false && "unrecognized op_type in EmitAssignmentExpression");
4042             }
4043 
4044             //
4045             // convert value to desired type if necessary
4046             //
4047             if (casted_left_hand_side)
4048                 EmitCast(casted_left_hand_side -> Type(), left_type);
4049 
4050             EmitExpression(assignment_expression -> expression);
4051 
4052             PutOp(opc);
4053 
4054             if (casted_left_hand_side) // now cast result back to type of result
4055                 EmitCast(left_type, casted_left_hand_side -> Type());
4056         }
4057     }
4058 
4059     //
4060     // Update left operand, saving value of right operand if it is needed.
4061     //
4062     switch (kind)
4063     {
4064     case ARRAY_VAR:
4065         if (need_value)
4066             PutOp(control.IsDoubleWordType(left_type) ? OP_DUP2_X2 : OP_DUP_X2);
4067         StoreArrayElement(assignment_expression -> Type());
4068         break;
4069     case FIELD_VAR:
4070         if (need_value)
4071             PutOp(control.IsDoubleWordType(left_type) ? OP_DUP2_X1 : OP_DUP_X1);
4072         StoreField(left_hand_side);
4073         break;
4074     case ACCESSED_VAR:
4075         {
4076             if (need_value)
4077             {
4078                 if (accessed_member -> ACC_STATIC())
4079                     PutOp(control.IsDoubleWordType(left_type)
4080                           ? OP_DUP2 : OP_DUP);
4081                 else PutOp(control.IsDoubleWordType(left_type)
4082                            ? OP_DUP2_X1 : OP_DUP_X1);
4083             }
4084 
4085             int stack_words = (GetTypeWords(left_type) +
4086                                (accessed_member -> ACC_STATIC() ? 0 : 1));
4087             PutOp(OP_INVOKESTATIC);
4088             CompleteCall(assignment_expression -> write_method, stack_words);
4089         }
4090         break;
4091     case LOCAL_VAR:
4092         //
4093         // Prior to JDK 1.5, VMs incorrectly complained if assigning an array
4094         // type into an element of a null expression (in other words, null
4095         // was not being treated as compatible with a multi-dimensional array
4096         // on the aastore opcode).  The workaround requires a checkcast any
4097         // time null might be assigned to a multi-dimensional local variable
4098         // or directly used as an array access base.
4099         //
4100         if (control.option.target < JikesOption::SDK1_5 &&
4101             IsMultiDimensionalArray(left_type) &&
4102             (StripNops(assignment_expression -> expression) -> Type() ==
4103              control.null_type))
4104         {
4105             assert(assignment_expression -> SimpleAssignment());
4106             PutOp(OP_CHECKCAST);
4107             PutU2(RegisterClass(left_type));
4108         }
4109         // fallthrough
4110     case STATIC_VAR:
4111         if (need_value)
4112             PutOp(control.IsDoubleWordType(left_type) ? OP_DUP2 : OP_DUP);
4113         StoreVariable(kind, left_hand_side);
4114         break;
4115     default:
4116         assert(false && "bad kind in EmitAssignmentExpression");
4117     }
4118 
4119     return GetTypeWords(assignment_expression -> Type());
4120 }
4121 
4122 
4123 //
4124 // BINARY: Similar code patterns are used for the ordered comparisons. This
4125 // method relies on the compiler having already inserted numeric promotion
4126 // casts, so that the type of the left and right expressions match.
4127 //
EmitBinaryExpression(AstBinaryExpression * expression,bool need_value)4128 int ByteCode::EmitBinaryExpression(AstBinaryExpression* expression,
4129                                    bool need_value)
4130 {
4131     TypeSymbol* type = expression -> Type();
4132 
4133     //
4134     // First, special case string concatenation.
4135     //
4136     if (type == control.String())
4137     {
4138         assert(expression -> Tag() == AstBinaryExpression::PLUS);
4139         ConcatenateString(expression, need_value);
4140         if (! need_value)
4141         {
4142             PutOp(OP_POP);
4143             return 0;
4144         }
4145         PutOp(OP_INVOKEVIRTUAL);
4146         PutU2(RegisterLibraryMethodref
4147               (control.option.target >= JikesOption::SDK1_5
4148                ? control.StringBuilder_toStringMethod()
4149                : control.StringBuffer_toStringMethod()));
4150         ChangeStack(1); // account for return value
4151         return 1;
4152     }
4153 
4154     //
4155     // Next, simplify if no result is needed. Be careful of side-effects with
4156     // binary / and % on integral 0, as well as evaluation order of && and ||.
4157     //
4158     if (! need_value)
4159     {
4160         if ((expression -> Tag() == AstBinaryExpression::SLASH ||
4161              expression -> Tag() == AstBinaryExpression::MOD) &&
4162             control.IsIntegral(type) &&
4163             (IsZero(expression -> right_expression) ||
4164              ! expression -> right_expression -> IsConstant()))
4165         {
4166             if (IsZero(expression -> right_expression))
4167             {
4168                 //
4169                 // Undo compiler-inserted numeric promotion.
4170                 //
4171                 AstExpression* left_expr = expression -> left_expression;
4172                 if (left_expr -> CastExpressionCast() &&
4173                     left_expr -> generated)
4174                 {
4175                     left_expr = ((AstCastExpression*) left_expr) -> expression;
4176                 }
4177                 type = left_expr -> Type();
4178                 EmitExpression(left_expr);
4179                 PutOp(type == control.long_type ? OP_LCONST_0 : OP_ICONST_0);
4180             }
4181             else
4182             {
4183                 EmitExpression(expression -> left_expression);
4184                 EmitExpression(expression -> right_expression);
4185             }
4186             if (type == control.long_type)
4187             {
4188                 PutOp(expression -> Tag() == AstBinaryExpression::SLASH
4189                       ? OP_LDIV : OP_LREM);
4190                 PutOp(OP_POP2);
4191             }
4192             else
4193             {
4194                 PutOp(expression -> Tag() == AstBinaryExpression::SLASH
4195                       ? OP_IDIV : OP_IREM);
4196                 PutOp(OP_POP);
4197             }
4198         }
4199         else if (expression -> Tag() == AstBinaryExpression::OR_OR)
4200         {
4201             //
4202             // if (cond || true); => cond;
4203             // if (cond || false); => cond;
4204             //
4205             if (expression -> right_expression -> IsConstant())
4206             {
4207                 EmitExpression(expression -> left_expression, false);
4208             }
4209             //
4210             // if (true || cond); => nop
4211             // if (a || b); => if (!a) b;
4212             //
4213             else if (! IsOne(expression -> left_expression))
4214             {
4215                 Label label;
4216                 EmitBranchIfExpression(expression -> left_expression, true,
4217                                        label);
4218                 EmitExpression(expression -> right_expression, false);
4219                 DefineLabel(label);
4220                 CompleteLabel(label);
4221             }
4222         }
4223         else if (expression -> Tag() == AstBinaryExpression::AND_AND)
4224         {
4225             //
4226             // if (cond && true); => cond;
4227             // if (cond && false); => cond;
4228             //
4229             if (expression -> right_expression -> IsConstant())
4230             {
4231                 EmitExpression(expression -> left_expression, false);
4232             }
4233             //
4234             // if (false && cond); => nop
4235             // if (a && b); => if (a) b;
4236             //
4237             else if (! IsZero(expression -> left_expression))
4238             {
4239                 Label label;
4240                 EmitBranchIfExpression(expression -> left_expression, false,
4241                                        label);
4242                 EmitExpression(expression -> right_expression, false);
4243                 DefineLabel(label);
4244                 CompleteLabel(label);
4245             }
4246         }
4247         else
4248         {
4249             EmitExpression(expression -> left_expression, false);
4250             EmitExpression(expression -> right_expression, false);
4251         }
4252         return 0;
4253     }
4254 
4255     //
4256     // Next, try to simplify if one operand known to be zero or one.
4257     //
4258     if (IsZero(expression -> left_expression))
4259     {
4260         //
4261         // Undo compiler-inserted numeric promotion, as well as narrowing from
4262         // long to int in shifts, to avoid unnecessary type conversions.
4263         //
4264         AstExpression* right_expr = expression -> right_expression;
4265         if (right_expr -> CastExpressionCast() && right_expr -> generated)
4266             right_expr = ((AstCastExpression*) right_expr) -> expression;
4267         TypeSymbol* right_type = right_expr -> Type();
4268 
4269         switch (expression -> Tag())
4270         {
4271         case AstBinaryExpression::AND_AND:
4272             PutOp(OP_ICONST_0);
4273             return 1;
4274         case AstBinaryExpression::EQUAL_EQUAL:
4275             if (right_type != control.boolean_type)
4276                 break;
4277             EmitExpression(right_expr);
4278             PutOp(OP_ICONST_1);
4279             PutOp(OP_IXOR);
4280             return 1;
4281         case AstBinaryExpression::NOT_EQUAL:
4282             if (right_type != control.boolean_type)
4283                 break;
4284             // Fallthrough on boolean case!
4285         case AstBinaryExpression::PLUS:
4286         case AstBinaryExpression::IOR:
4287         case AstBinaryExpression::XOR:
4288         case AstBinaryExpression::OR_OR:
4289             //
4290             // Note that +0.0 + expr cannot be simplified if expr is floating
4291             // point, because of -0.0 rules.
4292             //
4293             if (control.IsFloatingPoint(right_type))
4294             {
4295                 if (expression -> left_expression -> Type() ==
4296                     control.float_type)
4297                 {
4298                     FloatLiteralValue* value = DYNAMIC_CAST<FloatLiteralValue*>
4299                         (expression -> left_expression -> value);
4300                     if (value -> value.IsPositiveZero())
4301                         break;
4302                 }
4303                 else if (expression -> left_expression -> Type() ==
4304                          control.double_type)
4305                 {
4306                     DoubleLiteralValue* value = DYNAMIC_CAST<DoubleLiteralValue*>
4307                         (expression -> left_expression -> value);
4308                     if (value -> value.IsPositiveZero())
4309                         break;
4310                 }
4311             }
4312             // Use promoted version, not the stripped right_expr.
4313             EmitExpression(expression -> right_expression);
4314             return GetTypeWords(type);
4315         case AstBinaryExpression::STAR:
4316         case AstBinaryExpression::AND:
4317         case AstBinaryExpression::LEFT_SHIFT:
4318         case AstBinaryExpression::RIGHT_SHIFT:
4319         case AstBinaryExpression::UNSIGNED_RIGHT_SHIFT:
4320             //
4321             // Floating point multiplication by 0 cannot be simplified, because
4322             // of NaN, infinity, and -0.0 rules. And in general, division
4323             // cannot be simplified because of divide by 0 for integers and
4324             // corner cases for floating point.
4325             //
4326             if (control.IsFloatingPoint(type))
4327                 break;
4328 
4329             EmitExpression(right_expr, false);
4330             PutOp(type == control.long_type ? OP_LCONST_0 : OP_ICONST_0);
4331             return GetTypeWords(type);
4332         case AstBinaryExpression::MINUS:
4333             //
4334             // 0 - x is negation, but note that +0.0 - expr cannot be
4335             // simplified if expr is floating point, because of -0.0 rules.
4336             //
4337             if (control.IsFloatingPoint(right_type))
4338             {
4339                 if (expression -> left_expression -> Type() ==
4340                     control.float_type)
4341                 {
4342                     FloatLiteralValue* value = DYNAMIC_CAST<FloatLiteralValue*>
4343                         (expression -> left_expression -> value);
4344                     if (value -> value.IsPositiveZero())
4345                         break;
4346                 }
4347                 else if (expression -> left_expression -> Type() ==
4348                          control.double_type)
4349                 {
4350                     DoubleLiteralValue* value = DYNAMIC_CAST<DoubleLiteralValue*>
4351                         (expression -> left_expression -> value);
4352                     if (value -> value.IsPositiveZero())
4353                         break;
4354                 }
4355             }
4356             // Use promoted version, not the stripped right_expr.
4357             EmitExpression(expression -> right_expression);
4358 
4359             PutOp(control.IsSimpleIntegerValueType(type) ? OP_INEG
4360                   : type == control.long_type ? OP_LNEG
4361                   : type == control.float_type ? OP_FNEG
4362                   : OP_DNEG); // double_type
4363             return GetTypeWords(type);
4364         default:
4365             break;
4366         }
4367     }
4368 
4369     if (IsOne(expression -> left_expression))
4370     {
4371         if (expression -> Tag() == AstBinaryExpression::STAR)
4372         {
4373             EmitExpression(expression -> right_expression);
4374             return GetTypeWords(type);
4375         }
4376         if (expression -> left_expression -> Type() == control.boolean_type)
4377         {
4378             switch (expression -> Tag())
4379             {
4380             case AstBinaryExpression::EQUAL_EQUAL:
4381             case AstBinaryExpression::AND_AND:
4382             case AstBinaryExpression::AND:
4383                 EmitExpression(expression -> right_expression);
4384                 break;
4385             case AstBinaryExpression::IOR:
4386                 EmitExpression(expression -> right_expression, false);
4387                 // Fallthrough
4388             case AstBinaryExpression::OR_OR:
4389                 PutOp(OP_ICONST_1);
4390                 break;
4391             case AstBinaryExpression::NOT_EQUAL:
4392             case AstBinaryExpression::XOR:
4393                 EmitExpression(expression -> right_expression);
4394                 PutOp(OP_ICONST_1);
4395                 PutOp(OP_IXOR);
4396                 break;
4397             default:
4398                 assert(false && "Invalid operator on boolean");
4399             }
4400             return 1;
4401         }
4402     }
4403 
4404     if (IsZero(expression -> right_expression))
4405     {
4406         //
4407         // Undo compiler-inserted numeric promotion to avoid unnecessary type
4408         // conversions.
4409         //
4410         AstExpression* left_expr = expression -> left_expression;
4411         if (left_expr -> CastExpressionCast() && left_expr -> generated)
4412             left_expr = ((AstCastExpression*) left_expr) -> expression;
4413         TypeSymbol* left_type = left_expr -> Type();
4414 
4415         switch (expression -> Tag())
4416         {
4417         case AstBinaryExpression::EQUAL_EQUAL:
4418             if (left_type != control.boolean_type)
4419                 break;
4420             EmitExpression(left_expr);
4421             PutOp(OP_ICONST_1);
4422             PutOp(OP_IXOR);
4423             return 1;
4424         case AstBinaryExpression::NOT_EQUAL:
4425             if (left_type != control.boolean_type)
4426                 break;
4427             // Fallthrough on boolean case!
4428         case AstBinaryExpression::PLUS:
4429         case AstBinaryExpression::MINUS:
4430         case AstBinaryExpression::IOR:
4431         case AstBinaryExpression::XOR:
4432         case AstBinaryExpression::OR_OR:
4433         case AstBinaryExpression::LEFT_SHIFT:
4434         case AstBinaryExpression::RIGHT_SHIFT:
4435         case AstBinaryExpression::UNSIGNED_RIGHT_SHIFT:
4436             //
4437             // Here for cases that simplify to the left operand. Note that
4438             // (expr + +0.0) and (expr - -0.0) cannot be simplified if expr
4439             // is floating point, because of -0.0 rules.
4440             //
4441             if (control.IsFloatingPoint(left_type))
4442             {
4443                 if (expression -> right_expression -> Type() ==
4444                     control.float_type)
4445                 {
4446                     FloatLiteralValue* value = DYNAMIC_CAST<FloatLiteralValue*>
4447                         (expression -> right_expression -> value);
4448                     if (value -> value.IsPositiveZero() ==
4449                         (expression -> Tag() == AstBinaryExpression::PLUS))
4450                         break;
4451                 }
4452                 else if (expression -> right_expression -> Type() ==
4453                          control.double_type)
4454                 {
4455                     DoubleLiteralValue* value = DYNAMIC_CAST<DoubleLiteralValue*>
4456                         (expression -> right_expression -> value);
4457                     if (value -> value.IsPositiveZero() ==
4458                         (expression -> Tag() == AstBinaryExpression::PLUS))
4459                         break;
4460                 }
4461             }
4462             // Use promoted version, not the stripped left_expr.
4463             EmitExpression(expression -> left_expression);
4464             return GetTypeWords(type);
4465         case AstBinaryExpression::STAR:
4466         case AstBinaryExpression::AND:
4467         case AstBinaryExpression::AND_AND:
4468             //
4469             // Floating point multiplication by 0 cannot be simplified, because
4470             // of NaN, infinity, and -0.0 rules. And in general, division
4471             // cannot be simplified because of divide by 0 for integers and
4472             // corner cases for floating point.
4473             //
4474             if (control.IsFloatingPoint(type))
4475                 break;
4476 
4477             EmitExpression(left_expr, false);
4478             PutOp(type == control.long_type ? OP_LCONST_0 : OP_ICONST_0);
4479             return GetTypeWords(type);
4480         default:
4481             break;
4482         }
4483     }
4484 
4485     if (IsOne(expression -> right_expression))
4486     {
4487         if (expression -> Tag() == AstBinaryExpression::STAR ||
4488             expression -> Tag() == AstBinaryExpression::SLASH)
4489         {
4490             EmitExpression(expression -> left_expression);
4491             return GetTypeWords(type);
4492         }
4493         if (expression -> right_expression -> Type() == control.boolean_type)
4494         {
4495             switch (expression -> Tag())
4496             {
4497             case AstBinaryExpression::EQUAL_EQUAL:
4498             case AstBinaryExpression::AND_AND:
4499             case AstBinaryExpression::AND:
4500                 EmitExpression(expression -> left_expression);
4501                 break;
4502             case AstBinaryExpression::IOR:
4503             case AstBinaryExpression::OR_OR:
4504                 EmitExpression(expression -> left_expression, false);
4505                 PutOp(OP_ICONST_1);
4506                 break;
4507             case AstBinaryExpression::NOT_EQUAL:
4508             case AstBinaryExpression::XOR:
4509                 EmitExpression(expression -> left_expression);
4510                 PutOp(OP_ICONST_1);
4511                 PutOp(OP_IXOR);
4512                 break;
4513             default:
4514                 assert(false && "Invalid operator on boolean");
4515             }
4516             return 1;
4517         }
4518     }
4519 
4520     //
4521     // Next, simplify all remaining boolean result expressions.
4522     //
4523     if (expression -> left_expression -> Type() == control.boolean_type &&
4524         (expression -> Tag() == AstBinaryExpression::EQUAL_EQUAL ||
4525          expression -> Tag() == AstBinaryExpression::NOT_EQUAL))
4526     {
4527         EmitExpression(expression -> left_expression);
4528         EmitExpression(expression -> right_expression);
4529         PutOp(OP_IXOR);
4530         if (expression -> Tag() == AstBinaryExpression::EQUAL_EQUAL)
4531         {
4532             PutOp(OP_ICONST_1);
4533             PutOp(OP_IXOR);
4534         }
4535         return 1;
4536     }
4537 
4538     switch (expression -> Tag())
4539     {
4540     case AstBinaryExpression::OR_OR:
4541     case AstBinaryExpression::AND_AND:
4542     case AstBinaryExpression::LESS:
4543     case AstBinaryExpression::LESS_EQUAL:
4544     case AstBinaryExpression::GREATER:
4545     case AstBinaryExpression::GREATER_EQUAL:
4546     case AstBinaryExpression::EQUAL_EQUAL:
4547     case AstBinaryExpression::NOT_EQUAL:
4548         {
4549             // Assume false, and update if true.
4550             Label label;
4551             PutOp(OP_ICONST_0); // push false
4552             EmitBranchIfExpression(expression, false, label);
4553             PutOp(OP_POP); // pop the false
4554             PutOp(OP_ICONST_1); // push true
4555             DefineLabel(label);
4556             CompleteLabel(label);
4557         }
4558         return 1;
4559     default:
4560         break;
4561     }
4562 
4563     //
4564     // Finally, if we get here, the expression cannot be optimized.
4565     //
4566     EmitExpression(expression -> left_expression);
4567     EmitExpression(expression -> right_expression);
4568 
4569     bool integer_type = type == control.boolean_type ||
4570         control.IsSimpleIntegerValueType(type);
4571     switch (expression -> Tag())
4572     {
4573     case AstBinaryExpression::STAR:
4574         PutOp(integer_type ? OP_IMUL
4575               : type == control.long_type ? OP_LMUL
4576               : type == control.float_type ? OP_FMUL
4577               : OP_DMUL); // double_type
4578         break;
4579     case AstBinaryExpression::SLASH:
4580         PutOp(integer_type ? OP_IDIV
4581               : type == control.long_type ? OP_LDIV
4582               : type == control.float_type ? OP_FDIV
4583               : OP_DDIV); // double_type
4584         break;
4585     case AstBinaryExpression::MOD:
4586         PutOp(integer_type ? OP_IREM
4587               : type == control.long_type ? OP_LREM
4588               : type == control.float_type ? OP_FREM
4589               : OP_DREM); // double_type
4590         break;
4591     case AstBinaryExpression::PLUS:
4592         PutOp(integer_type ? OP_IADD
4593               : type == control.long_type ? OP_LADD
4594               : type == control.float_type ? OP_FADD
4595               : OP_DADD); // double_type
4596         break;
4597     case AstBinaryExpression::MINUS:
4598         PutOp(integer_type ? OP_ISUB
4599               : type == control.long_type ? OP_LSUB
4600               : type == control.float_type ? OP_FSUB
4601               : OP_DSUB); // double_type
4602         break;
4603     case AstBinaryExpression::LEFT_SHIFT:
4604         PutOp(integer_type ? OP_ISHL : OP_LSHL);
4605         break;
4606     case AstBinaryExpression::RIGHT_SHIFT:
4607         PutOp(integer_type ? OP_ISHR : OP_LSHR);
4608         break;
4609     case AstBinaryExpression::UNSIGNED_RIGHT_SHIFT:
4610         PutOp(integer_type ? OP_IUSHR : OP_LUSHR);
4611         break;
4612     case AstBinaryExpression::AND:
4613         PutOp(integer_type ? OP_IAND : OP_LAND);
4614         break;
4615     case AstBinaryExpression::XOR:
4616         PutOp(integer_type ? OP_IXOR : OP_LXOR);
4617         break;
4618     case AstBinaryExpression::IOR:
4619         PutOp(integer_type ? OP_IOR : OP_LOR);
4620         break;
4621     default:
4622         assert(false && "binary unknown tag");
4623     }
4624 
4625     return GetTypeWords(expression -> Type());
4626 }
4627 
4628 
EmitInstanceofExpression(AstInstanceofExpression * expr,bool need_value)4629 int ByteCode::EmitInstanceofExpression(AstInstanceofExpression* expr,
4630                                        bool need_value)
4631 {
4632     TypeSymbol* left_type = expr -> expression -> Type();
4633     TypeSymbol* right_type = expr -> type -> symbol;
4634     if (right_type -> num_dimensions > 255)
4635         semantic.ReportSemError(SemanticError::ARRAY_OVERFLOW, expr -> type);
4636     if (left_type == control.null_type)
4637     {
4638         //
4639         // We know the result: false. But emit the left expression,
4640         // in case of side effects in (expr ? null : null).
4641         //
4642         EmitExpression(expr -> expression, false);
4643         if (need_value)
4644             PutOp(OP_ICONST_0);
4645     }
4646     else if (expr -> expression -> IsConstant() ||
4647              expr -> expression -> BinaryExpressionCast())
4648     {
4649         //
4650         // We know the result: true, since the string literals and string
4651         // concats are non-null and String is a final class.
4652         //
4653         assert(left_type == control.String());
4654         EmitExpression(expr -> expression, false);
4655         if (need_value)
4656             PutOp(OP_ICONST_1);
4657     }
4658     else if ((expr -> expression -> ThisExpressionCast() ||
4659               expr -> expression -> SuperExpressionCast() ||
4660               expr -> expression -> ClassLiteralCast() ||
4661               expr -> expression -> ClassCreationExpressionCast() ||
4662               expr -> expression -> ArrayCreationExpressionCast()) &&
4663              left_type -> IsSubtype(right_type))
4664     {
4665         //
4666         // We know the result: true, since the expression is non-null.
4667         //
4668         EmitExpression(expr -> expression, false);
4669         if (need_value)
4670             PutOp(OP_ICONST_1);
4671     }
4672     else
4673     {
4674         EmitExpression(expr -> expression, need_value);
4675         if (need_value)
4676         {
4677             PutOp(OP_INSTANCEOF);
4678             PutU2(RegisterClass(right_type));
4679         }
4680     }
4681     return need_value ? 1 : 0;
4682 }
4683 
4684 
EmitCastExpression(AstCastExpression * expression,bool need_value)4685 int ByteCode::EmitCastExpression(AstCastExpression* expression,
4686                                  bool need_value)
4687 {
4688     TypeSymbol* dest_type = expression -> Type();
4689     TypeSymbol* source_type = expression -> expression -> Type();
4690     if (dest_type -> num_dimensions > 255 && expression -> type)
4691     {
4692         semantic.ReportSemError(SemanticError::ARRAY_OVERFLOW,
4693                                 expression -> type);
4694     }
4695 
4696     //
4697     // Object downcasts must be emitted, in case of a ClassCastException.
4698     //
4699     EmitExpression(expression -> expression,
4700                    need_value || dest_type -> IsSubtype(source_type));
4701 
4702     if (need_value || dest_type -> IsSubtype(source_type))
4703     {
4704         EmitCast(dest_type, source_type);
4705         if (! need_value)
4706         {
4707             assert(source_type -> IsSubtype(control.Object()));
4708             PutOp(OP_POP);
4709         }
4710     }
4711 
4712     return need_value ? GetTypeWords(dest_type) : 0;
4713 }
4714 
4715 
EmitCast(TypeSymbol * dest_type,TypeSymbol * source_type)4716 void ByteCode::EmitCast(TypeSymbol* dest_type, TypeSymbol* source_type)
4717 {
4718     if (source_type -> IsSubtype(dest_type) ||
4719         source_type == control.null_type)
4720     {
4721         return; // done if nothing to do
4722     }
4723 
4724     if (control.IsSimpleIntegerValueType(source_type))
4725     {
4726         if (dest_type == control.int_type ||
4727             (source_type == control.byte_type &&
4728              dest_type == control.short_type))
4729         {
4730             return; // no conversion needed
4731         }
4732         Opcode op_kind = (dest_type == control.long_type ? OP_I2L
4733                           : dest_type == control.float_type ? OP_I2F
4734                           : dest_type == control.double_type ? OP_I2D
4735                           : dest_type == control.char_type ? OP_I2C
4736                           : dest_type == control.byte_type ? OP_I2B
4737                           : OP_I2S); // short_type
4738         // If the type we wanted to cast to could not be matched then
4739         // the cast is invalid. For example, one might be trying
4740         // to cast an int to a Object.
4741         assert(op_kind != OP_I2S || dest_type == control.short_type);
4742 
4743         PutOp(op_kind);
4744     }
4745     else if (source_type == control.long_type)
4746     {
4747         Opcode op_kind = (dest_type == control.float_type ? OP_L2F
4748                           : dest_type == control.double_type ? OP_L2D
4749                           : OP_L2I);
4750         PutOp(op_kind);
4751 
4752         if (op_kind == OP_L2I && dest_type != control.int_type)
4753         {
4754             assert(control.IsSimpleIntegerValueType(dest_type) &&
4755                    "unsupported conversion");
4756 
4757             PutOp(dest_type == control.char_type ? OP_I2C
4758                   : dest_type == control.byte_type ? OP_I2B
4759                   : OP_I2S); // short_type
4760         }
4761     }
4762     else if (source_type == control.float_type)
4763     {
4764         Opcode op_kind = (dest_type == control.long_type ? OP_F2L
4765                           : dest_type == control.double_type ? OP_F2D
4766                           : OP_F2I);
4767         PutOp(op_kind);
4768 
4769         if (op_kind == OP_F2I && dest_type != control.int_type)
4770         {
4771             assert(control.IsSimpleIntegerValueType(dest_type) &&
4772                    "unsupported conversion");
4773 
4774             PutOp(dest_type == control.char_type ? OP_I2C
4775                   : dest_type == control.byte_type ? OP_I2B
4776                   : OP_I2S); // short_type
4777         }
4778     }
4779     else if (source_type == control.double_type)
4780     {
4781         Opcode op_kind = (dest_type == control.long_type ? OP_D2L
4782                           : dest_type == control.float_type ? OP_D2F
4783                           : OP_D2I);
4784 
4785         PutOp(op_kind);
4786 
4787         if (op_kind == OP_D2I && dest_type != control.int_type)
4788         {
4789             assert(control.IsSimpleIntegerValueType(dest_type) &&
4790                    "unsupported conversion");
4791 
4792             PutOp(dest_type == control.char_type ? OP_I2C
4793                   : dest_type == control.byte_type ? OP_I2B
4794                   : OP_I2S); // short_type
4795         }
4796     }
4797     else
4798     {
4799         PutOp(OP_CHECKCAST);
4800         PutU2(RegisterClass(dest_type));
4801     }
4802 }
4803 
4804 //
4805 // Emits the required check for null in a qualified instance creation,
4806 // super constructor call, or constant instance variable reference, if the
4807 // base expression can possibly be null. It also emits the base expression.
4808 // In the case of anonymous classes, we emit an alternate expression (the
4809 // constructor parameter), after performing the null check on the qualifier
4810 // of the anonymous class instance creation expression.
4811 //
EmitCheckForNull(AstExpression * expression,bool need_value)4812 void ByteCode::EmitCheckForNull(AstExpression* expression, bool need_value)
4813 {
4814     expression = StripNops(expression);
4815 
4816     if (expression -> Type() == control.null_type)
4817     {
4818         //
4819         // It's guaranteed to be null, so cause any side effects, then throw
4820         // the null already on the stack (which will make the VM correctly
4821         // create and throw a NullPointerException). Adjust the stack if
4822         // necessary, since the calling context does not realize that this
4823         // will always complete abruptly.
4824         //
4825         EmitExpression(expression, true);
4826         PutOp(OP_ATHROW);
4827         if (need_value)
4828             ChangeStack(1);
4829         return;
4830     }
4831     VariableSymbol* variable = expression -> symbol -> VariableCast();
4832     if (expression -> ClassCreationExpressionCast() ||
4833         expression -> ThisExpressionCast() ||
4834         expression -> SuperExpressionCast() ||
4835         expression -> ClassLiteralCast() ||
4836         (variable && variable -> ACC_SYNTHETIC() &&
4837          variable -> Identity() == control.this_name_symbol))
4838     {
4839         EmitExpression(expression, need_value);
4840         return;
4841     }
4842     //
4843     // We did not bother checking for other guaranteed non-null conditions:
4844     // IsConstant(), string concats, and ArrayCreationExpressionCast(), since
4845     // none of these can qualify a constructor invocation or a constant
4846     // instance field reference. If we get here, it is uncertain whether the
4847     // expression can be null, so check, using:
4848     //
4849     // ((Object) ref).getClass();
4850     //
4851     // This discarded instance method call will cause the necessary
4852     // NullPointerException if invoked on null; and since it is final in
4853     // Object, we can be certain it has no side-effects.
4854     //
4855     EmitExpression(expression, true);
4856     if (need_value)
4857         PutOp(OP_DUP);
4858     PutOp(OP_INVOKEVIRTUAL);
4859     ChangeStack(1); // for returned value
4860     PutU2(RegisterLibraryMethodref(control.Object_getClassMethod()));
4861     PutOp(OP_POP);
4862 }
4863 
EmitClassCreationExpression(AstClassCreationExpression * expr,bool need_value)4864 int ByteCode::EmitClassCreationExpression(AstClassCreationExpression* expr,
4865                                           bool need_value)
4866 {
4867     if (expr -> resolution_opt)
4868         expr = expr -> resolution_opt;
4869     MethodSymbol* constructor = (MethodSymbol*) expr -> symbol;
4870     TypeSymbol* type = constructor -> containing_type;
4871 
4872     PutOp(OP_NEW);
4873     PutU2(RegisterClass(type));
4874     if (need_value) // save address of new object for constructor
4875         PutOp(OP_DUP);
4876 
4877     //
4878     // Pass enclosing instance along, then real arguments, then shadow
4879     // variables, and finally an extra null argument, as needed.
4880     //
4881     int stack_words = 0;
4882     unsigned i = 0;
4883     if (expr -> base_opt)
4884     {
4885         stack_words++;
4886         EmitCheckForNull(expr -> base_opt);
4887     }
4888     if (type -> Anonymous() && type -> super -> EnclosingInstance())
4889     {
4890         stack_words++;
4891         EmitCheckForNull(expr -> arguments -> Argument(i++));
4892     }
4893     for ( ; i < expr -> arguments -> NumArguments(); i++)
4894         stack_words += EmitExpression(expr -> arguments -> Argument(i));
4895     for (i = 0; i < expr -> arguments -> NumLocalArguments(); i++)
4896         stack_words +=
4897             EmitExpression(expr -> arguments -> LocalArgument(i));
4898     if (expr -> arguments -> NeedsExtraNullArgument())
4899     {
4900         PutOp(OP_ACONST_NULL);
4901         stack_words++;
4902     }
4903 
4904     PutOp(OP_INVOKESPECIAL);
4905     ChangeStack(-stack_words);
4906     PutU2(RegisterMethodref(type, constructor));
4907     return 1;
4908 }
4909 
4910 
EmitConditionalExpression(AstConditionalExpression * expression,bool need_value)4911 int ByteCode::EmitConditionalExpression(AstConditionalExpression* expression,
4912                                         bool need_value)
4913 {
4914     //
4915     // Optimize (true ? a : b) to (a).
4916     // Optimize (false ? a : b) (b).
4917     //
4918     if (expression -> test_expression -> IsConstant())
4919         return EmitExpression((IsZero(expression -> test_expression)
4920                                ? expression -> false_expression
4921                                : expression -> true_expression),
4922                               need_value);
4923     if (expression -> Type() == control.null_type)
4924     {
4925         //
4926         // The null literal has no side effects, but null_expr might.
4927         // Optimize (cond ? null : null) to (cond, null).
4928         // Optimize (cond ? null_expr : null) to (cond && null_expr, null).
4929         // Optimize (cond ? null : null_expr) to (cond || null_expr, null).
4930         //
4931         if (expression -> false_expression -> NullLiteralCast())
4932         {
4933             if (expression -> true_expression -> NullLiteralCast())
4934                 EmitExpression(expression -> test_expression, false);
4935             else
4936             {
4937                 Label lab;
4938                 EmitBranchIfExpression(expression -> test_expression, false,
4939                                        lab);
4940                 EmitExpression(expression -> true_expression, false);
4941                 DefineLabel(lab);
4942                 CompleteLabel(lab);
4943             }
4944             if (need_value)
4945                 PutOp(OP_ACONST_NULL);
4946             return need_value ? 1 : 0;
4947         }
4948         if (expression -> true_expression -> NullLiteralCast())
4949         {
4950             Label lab;
4951             EmitBranchIfExpression(expression -> test_expression, true, lab);
4952             EmitExpression(expression -> false_expression, false);
4953             DefineLabel(lab);
4954             CompleteLabel(lab);
4955             if (need_value)
4956                 PutOp(OP_ACONST_NULL);
4957             return need_value ? 1 : 0;
4958         }
4959     }
4960     else if (expression -> true_expression -> IsConstant())
4961     {
4962         if (expression -> false_expression -> IsConstant())
4963         {
4964             if (! need_value)
4965                 return EmitExpression(expression -> test_expression, false);
4966             if (expression -> true_expression -> value ==
4967                 expression -> false_expression -> value)
4968             {
4969                 //
4970                 // Optimize (cond ? expr : expr) to (cond, expr).
4971                 //
4972                 EmitExpression(expression -> test_expression, false);
4973                 return EmitExpression(expression -> true_expression);
4974             }
4975             if (control.IsSimpleIntegerValueType(expression -> Type()) ||
4976                 expression -> Type() == control.boolean_type)
4977             {
4978                 //
4979                 // Optimize (expr ? 1 : 0) to (expr).
4980                 // Optimize (expr ? value + 1 : value) to (expr + value).
4981                 // Optimize (expr ? value - 1 : value) to (value - expr).
4982                 //
4983                 IntLiteralValue* left = DYNAMIC_CAST<IntLiteralValue*>
4984                     (expression -> true_expression -> value);
4985                 IntLiteralValue* right = DYNAMIC_CAST<IntLiteralValue*>
4986                     (expression -> false_expression -> value);
4987                 if (left -> value == 1 && right -> value == 0)
4988                     return EmitExpression(expression -> test_expression);
4989                 if (left -> value == right -> value + 1)
4990                 {
4991                     EmitExpression(expression -> test_expression);
4992                     EmitExpression(expression -> false_expression);
4993                     PutOp(OP_IADD);
4994                     return 1;
4995                 }
4996                 if (left -> value == right -> value - 1)
4997                 {
4998                     EmitExpression(expression -> false_expression);
4999                     EmitExpression(expression -> test_expression);
5000                     PutOp(OP_ISUB);
5001                     return 1;
5002                 }
5003             }
5004         }
5005         else if ((control.IsSimpleIntegerValueType(expression -> Type()) ||
5006                   expression -> Type() == control.boolean_type) &&
5007                  (IsOne(expression -> true_expression) ||
5008                   IsZero(expression -> true_expression)))
5009         {
5010             //
5011             // Optimize (cond ? 1 : b) to (cond || b)
5012             // Optimize (cond ? 0 : b) to (!cond && b)
5013             //
5014             Label label;
5015             if (need_value)
5016                 PutOp(IsZero(expression -> true_expression)
5017                       ? OP_ICONST_0 : OP_ICONST_1);
5018             EmitBranchIfExpression(expression -> test_expression, true, label);
5019             if (need_value)
5020                 PutOp(OP_POP);
5021             EmitExpression(expression -> false_expression, need_value);
5022             DefineLabel(label);
5023             CompleteLabel(label);
5024             return need_value ? 1 : 0;
5025         }
5026     }
5027     else if ((control.IsSimpleIntegerValueType(expression -> Type()) ||
5028               expression -> Type() == control.boolean_type) &&
5029              (IsOne(expression -> false_expression) ||
5030               IsZero(expression -> false_expression)))
5031     {
5032         //
5033         // Optimize (cond ? a : 0) to (cond && a)
5034         // Optimize (cond ? a : 1) to (!cond || a)
5035         //
5036         Label label;
5037         if (need_value)
5038             PutOp(IsZero(expression -> false_expression)
5039                   ? OP_ICONST_0 : OP_ICONST_1);
5040         EmitBranchIfExpression(expression -> test_expression, false, label);
5041         if (need_value)
5042             PutOp(OP_POP);
5043         EmitExpression(expression -> true_expression, need_value);
5044         DefineLabel(label);
5045         CompleteLabel(label);
5046         return need_value ? 1 : 0;
5047     }
5048     Label lab1,
5049         lab2;
5050     EmitBranchIfExpression(expression -> test_expression, false, lab1);
5051     EmitExpression(expression -> true_expression, need_value);
5052     EmitBranch(OP_GOTO, lab2);
5053     if (need_value) // restore the stack size
5054         ChangeStack(- GetTypeWords(expression -> Type()));
5055     DefineLabel(lab1);
5056     EmitExpression(expression -> false_expression, need_value);
5057     DefineLabel(lab2);
5058     CompleteLabel(lab2);
5059     CompleteLabel(lab1);
5060     return GetTypeWords(expression -> true_expression -> Type());
5061 }
5062 
5063 
EmitFieldAccess(AstFieldAccess * expression,bool need_value)5064 int ByteCode::EmitFieldAccess(AstFieldAccess* expression, bool need_value)
5065 {
5066     if (expression -> resolution_opt)
5067         return LoadVariable(ACCESSED_VAR, expression, need_value);
5068     VariableSymbol* sym = expression -> symbol -> VariableCast();
5069     assert(sym);
5070     return LoadVariable(sym -> ACC_STATIC() ? STATIC_VAR : FIELD_VAR,
5071                         expression, need_value);
5072 }
5073 
5074 
EmitMethodInvocation(AstMethodInvocation * expression,bool need_value)5075 int ByteCode::EmitMethodInvocation(AstMethodInvocation* expression,
5076                                    bool need_value)
5077 {
5078     //
5079     // If the method call was resolved into a call to another method, use the
5080     // resolution expression.
5081     //
5082     AstMethodInvocation* method_call = expression -> resolution_opt
5083         ? expression -> resolution_opt -> MethodInvocationCast() : expression;
5084     assert(method_call);
5085     MethodSymbol* msym = (MethodSymbol*) method_call -> symbol;
5086     AstExpression* base = method_call -> base_opt;
5087     bool is_super = false; // set if super call
5088 
5089     if (msym -> ACC_STATIC())
5090     {
5091         //
5092         // If the access is qualified by an arbitrary base
5093         // expression, evaluate it for side effects.
5094         // Notice that accessor methods, which are always static, might
5095         // access an instance method, in which case the base expression
5096         // will already be evaluated as the first parameter.
5097         //
5098         if (base && (! msym -> accessed_member ||
5099                       msym -> AccessesStaticMember()))
5100         {
5101             EmitExpression(base, false);
5102         }
5103     }
5104     else
5105     {
5106         if (base)
5107         {
5108             //
5109             // Note that field will be marked IsSuperAccess only in synthetic
5110             // accessor methods.  Code that calls Foo.super.bar() in a nested
5111             // class creates an accessor method:
5112             // Foo.access$<num>(Foo $1) { $1.bar(); }
5113             // but must use invokespecial instead of the regular invokevirtual.
5114             //
5115             is_super = base -> SuperExpressionCast() != NULL;
5116             EmitExpression(base);
5117         }
5118         else PutOp(OP_ALOAD_0);
5119     }
5120 
5121     int stack_words = 0; // words on stack needed for arguments
5122     for (unsigned i = 0; i < method_call -> arguments -> NumArguments(); i++)
5123         stack_words += EmitExpression(method_call -> arguments -> Argument(i));
5124 
5125     TypeSymbol* type = MethodTypeResolution(method_call -> base_opt, msym);
5126     PutOp(msym -> ACC_STATIC() ? OP_INVOKESTATIC
5127           : (is_super || msym -> ACC_PRIVATE()) ? OP_INVOKESPECIAL
5128           : type -> ACC_INTERFACE() ? OP_INVOKEINTERFACE
5129           : OP_INVOKEVIRTUAL);
5130     return CompleteCall(msym, stack_words, need_value, type);
5131 }
5132 
5133 
CompleteCall(MethodSymbol * msym,int stack_words,bool need_value,TypeSymbol * base_type)5134 int ByteCode::CompleteCall(MethodSymbol* msym, int stack_words,
5135                            bool need_value, TypeSymbol* base_type)
5136 {
5137     ChangeStack(- stack_words);
5138     TypeSymbol* type = (base_type ? base_type : msym -> containing_type);
5139     PutU2(RegisterMethodref(type, msym));
5140     if (type -> ACC_INTERFACE())
5141     {
5142         PutU1(stack_words + 1);
5143         PutU1(0);
5144     }
5145 
5146     //
5147     // Must account for value returned by method.
5148     //
5149     if (msym -> Type() == control.void_type)
5150         return 0;
5151     bool wide = control.IsDoubleWordType(msym -> Type());
5152     ChangeStack(wide ? 2 : 1);
5153     if (! need_value)
5154     {
5155         PutOp(wide ? OP_POP2 : OP_POP);
5156         return 0;
5157     }
5158     return wide ? 2 : 1;
5159 }
5160 
5161 
5162 //
5163 // Called when expression has been parenthesized; remove parentheses and
5164 // widening casts to expose true structure.
5165 //
StripNops(AstExpression * expr)5166 AstExpression* ByteCode::StripNops(AstExpression* expr)
5167 {
5168     while (! expr -> IsConstant())
5169     {
5170         if (expr -> ParenthesizedExpressionCast())
5171             expr = ((AstParenthesizedExpression*) expr) -> expression;
5172         else if (expr -> CastExpressionCast())
5173         {
5174             AstCastExpression* cast_expr = (AstCastExpression*) expr;
5175             TypeSymbol* cast_type = expr -> Type();
5176             AstExpression* sub_expr = StripNops(cast_expr -> expression);
5177             TypeSymbol* sub_type = sub_expr -> Type();
5178             if (sub_type -> IsSubtype(cast_type) ||
5179                 (sub_type == control.byte_type &&
5180                  (cast_type == control.short_type ||
5181                   cast_type == control.int_type)) ||
5182                 ((sub_type == control.short_type ||
5183                   sub_type == control.char_type) &&
5184                  cast_type == control.int_type) ||
5185                 (sub_type == control.null_type &&
5186                  cast_type -> num_dimensions <= 255))
5187             {
5188                 return sub_expr;
5189             }
5190             else return expr;
5191         }
5192         else return expr;
5193     }
5194 
5195     return expr;
5196 }
5197 
5198 
IsNop(AstBlock * block)5199 bool ByteCode::IsNop(AstBlock* block)
5200 {
5201     for (int i = block -> NumStatements() - 1; i >= 0; i--)
5202     {
5203         Ast* statement = block -> Statement(i);
5204         if (statement -> EmptyStatementCast() ||
5205             statement -> LocalClassStatementCast() ||
5206             (statement -> BlockCast() && IsNop((AstBlock*) statement)))
5207             continue;
5208         if (statement -> kind == Ast::IF)
5209         {
5210             AstIfStatement* ifstat = (AstIfStatement*) statement;
5211             if ((IsOne(ifstat -> expression) &&
5212                  IsNop(ifstat -> true_statement)) ||
5213                 (IsZero(ifstat -> expression) &&
5214                  (! ifstat -> false_statement_opt ||
5215                   IsNop(ifstat -> false_statement_opt))))
5216             {
5217                 continue;
5218             }
5219         }
5220         //
5221         // TODO: Is it worth adding more checks for bypassed code?
5222         //
5223         return false;
5224     }
5225     return true;
5226 }
5227 
5228 
EmitNewArray(unsigned num_dims,const TypeSymbol * type)5229 void ByteCode::EmitNewArray(unsigned num_dims, const TypeSymbol* type)
5230 {
5231     assert(num_dims);
5232     if (num_dims == 1)
5233     {
5234         TypeSymbol* element_type = type -> ArraySubtype();
5235 
5236         if (control.IsPrimitive(element_type))
5237         {
5238             PutOp(OP_NEWARRAY);
5239             PutU1(element_type == control.boolean_type ? 4
5240                   : element_type == control.char_type ? 5
5241                   : element_type == control.float_type ? 6
5242                   : element_type == control.double_type ? 7
5243                   : element_type == control.byte_type ? 8
5244                   : element_type == control.short_type ? 9
5245                   : element_type == control.int_type ? 10
5246                   : 11); // control.long_type
5247         }
5248         else // must be reference type
5249         {
5250             PutOp(OP_ANEWARRAY);
5251             PutU2(RegisterClass(element_type));
5252         }
5253     }
5254     else
5255     {
5256         PutOp(OP_MULTIANEWARRAY);
5257         PutU2(RegisterClass(type));
5258         PutU1(num_dims); // load dims count
5259         ChangeStack(1 - num_dims);
5260     }
5261 }
5262 
5263 
5264 //
5265 // Initial part of array access: ready to either load or store after this.
5266 //
EmitArrayAccessLhs(AstArrayAccess * expression)5267 void ByteCode::EmitArrayAccessLhs(AstArrayAccess* expression)
5268 {
5269     TypeSymbol* base_type = expression -> base -> Type();
5270     AstExpression* base = StripNops(expression -> base);
5271     EmitExpression(base);
5272     if (control.option.target < JikesOption::SDK1_5 &&
5273         IsMultiDimensionalArray(base_type) &&
5274         base -> Type() == control.null_type)
5275     {
5276         //
5277         // Prior to JDK 1.5, VMs incorrectly complained if assigning an array
5278         // type into an element of a null expression (in other words, null
5279         // was not being treated as compatible with a multi-dimensional array
5280         // on the aastore opcode).  The workaround requires a checkcast any
5281         // time null might be assigned to a multi-dimensional local variable
5282         // or directly used as an array access base.
5283         //
5284         PutOp(OP_CHECKCAST);
5285         PutU2(RegisterClass(base_type));
5286     }
5287     EmitExpression(expression -> expression);
5288 }
5289 
5290 //
5291 // POST_UNARY
5292 //
EmitPostUnaryExpression(AstPostUnaryExpression * expression,bool need_value)5293 int ByteCode::EmitPostUnaryExpression(AstPostUnaryExpression* expression,
5294                                       bool need_value)
5295 {
5296     VariableCategory kind = GetVariableKind(expression);
5297 
5298     switch (kind)
5299     {
5300     case LOCAL_VAR:
5301     case STATIC_VAR:
5302         EmitPostUnaryExpressionSimple(kind, expression, need_value);
5303         break;
5304     case ARRAY_VAR:
5305         EmitPostUnaryExpressionArray(expression, need_value);
5306         break;
5307     case FIELD_VAR:
5308         EmitPostUnaryExpressionField(kind, expression, need_value);
5309         break;
5310     case ACCESSED_VAR:
5311         {
5312             VariableSymbol* accessed_member =
5313                 expression -> write_method -> accessed_member -> VariableCast();
5314             if (accessed_member -> ACC_STATIC())
5315                 EmitPostUnaryExpressionSimple(kind, expression, need_value);
5316             else EmitPostUnaryExpressionField(kind, expression, need_value);
5317         }
5318         break;
5319     default:
5320         assert(false && "unknown lhs kind for assignment");
5321     }
5322 
5323     return GetTypeWords(expression -> Type());
5324 }
5325 
5326 
5327 //
5328 // AstExpression* expression;
5329 // POST_UNARY on instance variable
5330 // load value of field, duplicate, do increment or decrement, then store
5331 // back, leaving original value on top of stack.
5332 //
EmitPostUnaryExpressionField(VariableCategory kind,AstPostUnaryExpression * expression,bool need_value)5333 void ByteCode::EmitPostUnaryExpressionField(VariableCategory kind,
5334                                             AstPostUnaryExpression* expression,
5335                                             bool need_value)
5336 {
5337     if (kind == ACCESSED_VAR)
5338         ResolveAccess(expression -> expression); // get address and value
5339     else EmitFieldAccessLhs(expression -> expression);
5340 
5341     TypeSymbol* expression_type = expression -> Type();
5342     if (need_value)
5343         PutOp(control.IsDoubleWordType(expression_type)
5344               ? OP_DUP2_X1 : OP_DUP_X1);
5345 
5346     if (control.IsSimpleIntegerValueType(expression_type))
5347     {
5348         PutOp(OP_ICONST_1);
5349         PutOp(expression -> Tag() == AstPostUnaryExpression::PLUSPLUS
5350               ? OP_IADD : OP_ISUB);
5351         EmitCast(expression_type, control.int_type);
5352     }
5353     else if (expression_type == control.long_type)
5354     {
5355         PutOp(OP_LCONST_1);
5356         PutOp(expression -> Tag() == AstPostUnaryExpression::PLUSPLUS
5357               ? OP_LADD : OP_LSUB);
5358     }
5359     else if (expression_type == control.float_type)
5360     {
5361         PutOp(OP_FCONST_1);
5362         PutOp(expression -> Tag() == AstPostUnaryExpression::PLUSPLUS
5363               ? OP_FADD : OP_FSUB);
5364     }
5365     else if (expression_type == control.double_type)
5366     {
5367         PutOp(OP_DCONST_1); // load 1.0
5368         PutOp(expression -> Tag() == AstPostUnaryExpression::PLUSPLUS
5369               ? OP_DADD : OP_DSUB);
5370     }
5371 
5372     if (kind == ACCESSED_VAR)
5373     {
5374         int stack_words = GetTypeWords(expression_type) + 1;
5375         PutOp(OP_INVOKESTATIC);
5376         CompleteCall(expression -> write_method, stack_words);
5377     }
5378     else // assert(kind == FIELD_VAR)
5379     {
5380         PutOp(OP_PUTFIELD);
5381         if (control.IsDoubleWordType(expression_type))
5382             ChangeStack(-1);
5383 
5384         VariableSymbol* sym = (VariableSymbol*) expression -> symbol;
5385         PutU2(RegisterFieldref(VariableTypeResolution(expression ->
5386                                                       expression, sym), sym));
5387     }
5388 }
5389 
5390 
5391 //
5392 // AstExpression* expression;
5393 // POST_UNARY on local variable
5394 // load value of variable, duplicate, do increment or decrement, then store
5395 // back, leaving original value on top of stack.
5396 //
EmitPostUnaryExpressionSimple(VariableCategory kind,AstPostUnaryExpression * expression,bool need_value)5397 void ByteCode::EmitPostUnaryExpressionSimple(VariableCategory kind,
5398                                              AstPostUnaryExpression* expression,
5399                                              bool need_value)
5400 {
5401     TypeSymbol* expression_type = expression -> Type();
5402     if (kind == LOCAL_VAR && expression_type == control.int_type)
5403     {
5404         // can we use IINC ??
5405         LoadVariable(kind, StripNops(expression -> expression), need_value);
5406         PutOpIINC(expression -> symbol -> VariableCast() -> LocalVariableIndex(),
5407                   expression -> Tag() == AstPostUnaryExpression::PLUSPLUS ? 1 : -1);
5408         return;
5409     }
5410 
5411     // this will also load value needing resolution
5412     LoadVariable(kind, StripNops(expression -> expression));
5413 
5414     if (need_value)
5415         PutOp(control.IsDoubleWordType(expression_type) ? OP_DUP2 : OP_DUP);
5416 
5417     if (control.IsSimpleIntegerValueType(expression_type))
5418     {
5419         PutOp(OP_ICONST_1);
5420         PutOp(expression -> Tag() == AstPostUnaryExpression::PLUSPLUS
5421               ? OP_IADD : OP_ISUB);
5422         EmitCast(expression_type, control.int_type);
5423     }
5424     else if (expression_type == control.long_type)
5425     {
5426         PutOp(OP_LCONST_1);
5427         PutOp(expression -> Tag() == AstPostUnaryExpression::PLUSPLUS
5428               ? OP_LADD : OP_LSUB);
5429     }
5430     else if (expression_type == control.float_type)
5431     {
5432         PutOp(OP_FCONST_1);
5433         PutOp(expression -> Tag() == AstPostUnaryExpression::PLUSPLUS
5434               ? OP_FADD : OP_FSUB);
5435     }
5436     else if (expression_type == control.double_type)
5437     {
5438         PutOp(OP_DCONST_1); // load 1.0
5439         PutOp(expression -> Tag() == AstPostUnaryExpression::PLUSPLUS
5440               ? OP_DADD : OP_DSUB);
5441     }
5442 
5443     if (kind == ACCESSED_VAR)
5444     {
5445          int stack_words = GetTypeWords(expression_type);
5446          PutOp(OP_INVOKESTATIC);
5447          CompleteCall(expression -> write_method, stack_words);
5448     }
5449     else StoreVariable(kind, expression -> expression);
5450 }
5451 
5452 
5453 //
5454 // Post Unary for which operand is array element
5455 // assignment for which lhs is array element
5456 //    AstExpression* expression;
5457 //
EmitPostUnaryExpressionArray(AstPostUnaryExpression * expression,bool need_value)5458 void ByteCode::EmitPostUnaryExpressionArray(AstPostUnaryExpression* expression,
5459                                             bool need_value)
5460 {
5461     //
5462     // JLS2 added ability for parenthesized variable to remain a variable.
5463     //
5464     EmitArrayAccessLhs((AstArrayAccess*) StripNops(expression -> expression));
5465     // lhs must be array access
5466     PutOp(OP_DUP2); // save array base and index for later store
5467 
5468     TypeSymbol* expression_type = expression -> Type();
5469     if (expression_type == control.int_type)
5470     {
5471          PutOp(OP_IALOAD);
5472          if (need_value) // save value below saved array base and index
5473              PutOp(OP_DUP_X2);
5474          PutOp(OP_ICONST_1);
5475          PutOp(expression -> Tag() == AstPostUnaryExpression::PLUSPLUS
5476                ? OP_IADD : OP_ISUB);
5477          PutOp(OP_IASTORE);
5478     }
5479     else if (expression_type == control.byte_type )
5480     {
5481          PutOp(OP_BALOAD);
5482          if (need_value) // save value below saved array base and index
5483              PutOp(OP_DUP_X2);
5484          PutOp(OP_ICONST_1);
5485          PutOp(expression -> Tag() == AstPostUnaryExpression::PLUSPLUS
5486                ? OP_IADD : OP_ISUB);
5487          PutOp(OP_I2B);
5488          PutOp(OP_BASTORE);
5489     }
5490     else if (expression_type == control.char_type )
5491     {
5492          PutOp(OP_CALOAD);
5493          if (need_value) // save value below saved array base and index
5494              PutOp(OP_DUP_X2);
5495          PutOp(OP_ICONST_1);
5496          PutOp(expression -> Tag() == AstPostUnaryExpression::PLUSPLUS
5497                ? OP_IADD : OP_ISUB);
5498          PutOp(OP_I2C);
5499          PutOp(OP_CASTORE);
5500     }
5501     else if (expression_type == control.short_type)
5502     {
5503          PutOp(OP_SALOAD);
5504          if (need_value) // save value below saved array base and index
5505              PutOp(OP_DUP_X2);
5506          PutOp(OP_ICONST_1);
5507          PutOp(expression -> Tag() == AstPostUnaryExpression::PLUSPLUS
5508                ? OP_IADD : OP_ISUB);
5509          PutOp(OP_I2S);
5510          PutOp(OP_SASTORE);
5511     }
5512     else if (expression_type == control.long_type)
5513     {
5514          PutOp(OP_LALOAD);
5515          if (need_value) // save value below saved array base and index
5516              PutOp(OP_DUP2_X2);
5517          PutOp(OP_LCONST_1);
5518          PutOp(expression -> Tag() == AstPostUnaryExpression::PLUSPLUS
5519                ? OP_LADD : OP_LSUB);
5520          PutOp(OP_LASTORE);
5521     }
5522     else if (expression_type == control.float_type)
5523     {
5524          PutOp(OP_FALOAD);
5525          if (need_value) // save value below saved array base and index
5526              PutOp(OP_DUP_X2);
5527          PutOp(OP_FCONST_1);
5528          PutOp(expression -> Tag() == AstPostUnaryExpression::PLUSPLUS
5529                ? OP_FADD : OP_FSUB);
5530          PutOp(OP_FASTORE);
5531     }
5532     else if (expression_type == control.double_type)
5533     {
5534          PutOp(OP_DALOAD);
5535          if (need_value) // save value below saved array base and index
5536              PutOp(OP_DUP2_X2);
5537          PutOp(OP_DCONST_1);
5538          PutOp(expression -> Tag() == AstPostUnaryExpression::PLUSPLUS
5539                ? OP_DADD : OP_DSUB);
5540          PutOp(OP_DASTORE);
5541     }
5542     else assert(false && "unsupported postunary type");
5543 }
5544 
5545 
5546 //
5547 // PRE_UNARY
5548 //
EmitPreUnaryExpression(AstPreUnaryExpression * expression,bool need_value)5549 int ByteCode::EmitPreUnaryExpression(AstPreUnaryExpression* expression,
5550                                      bool need_value)
5551 {
5552     TypeSymbol* type = expression -> Type();
5553     if (expression -> Tag() == AstPreUnaryExpression::PLUSPLUS ||
5554         expression -> Tag() == AstPreUnaryExpression::MINUSMINUS)
5555     {
5556         EmitPreUnaryIncrementExpression(expression, need_value);
5557     }
5558     else // here for ordinary unary operator without side effects.
5559     {
5560         EmitExpression(expression -> expression, need_value);
5561         if (! need_value)
5562             return 0;
5563         switch (expression -> Tag())
5564         {
5565         case AstPreUnaryExpression::PLUS:
5566             // Nothing else to do.
5567             break;
5568         case AstPreUnaryExpression::MINUS:
5569             assert(control.IsNumeric(type) && "unary minus on bad type");
5570             PutOp(control.IsSimpleIntegerValueType(type) ? OP_INEG
5571                   : type == control.long_type ? OP_LNEG
5572                   : type == control.float_type ? OP_FNEG
5573                   : OP_DNEG); // double_type
5574             break;
5575         case AstPreUnaryExpression::TWIDDLE:
5576             if (control.IsSimpleIntegerValueType(type))
5577             {
5578                 PutOp(OP_ICONST_M1); // -1
5579                 PutOp(OP_IXOR);      // exclusive or to get result
5580             }
5581             else if (type == control.long_type)
5582             {
5583                 PutOp(OP_LCONST_1); // make -1
5584                 PutOp(OP_LNEG);
5585                 PutOp(OP_LXOR);     // exclusive or to get result
5586             }
5587             else assert(false && "unary ~ on unsupported type");
5588             break;
5589         case AstPreUnaryExpression::NOT:
5590             assert(type == control.boolean_type);
5591             PutOp(OP_ICONST_1);
5592             PutOp(OP_IXOR); // !(e) <=> (e)^true
5593             break;
5594         default:
5595             assert(false && "unknown preunary tag");
5596         }
5597     }
5598     return GetTypeWords(type);
5599 }
5600 
5601 
5602 //
5603 // PRE_UNARY with side effects (++X or --X)
5604 //
EmitPreUnaryIncrementExpression(AstPreUnaryExpression * expression,bool need_value)5605 void ByteCode::EmitPreUnaryIncrementExpression(AstPreUnaryExpression* expression,
5606                                                bool need_value)
5607 {
5608     VariableCategory kind = GetVariableKind(expression);
5609 
5610     switch (kind)
5611     {
5612     case LOCAL_VAR:
5613     case STATIC_VAR:
5614         EmitPreUnaryIncrementExpressionSimple(kind, expression, need_value);
5615         break;
5616     case ARRAY_VAR:
5617         EmitPreUnaryIncrementExpressionArray(expression, need_value);
5618         break;
5619     case FIELD_VAR:
5620         EmitPreUnaryIncrementExpressionField(kind, expression, need_value);
5621         break;
5622     case ACCESSED_VAR:
5623         {
5624             VariableSymbol* accessed_member =
5625                 expression -> write_method -> accessed_member -> VariableCast();
5626             if (accessed_member -> ACC_STATIC())
5627                 EmitPreUnaryIncrementExpressionSimple(kind, expression,
5628                                                       need_value);
5629             else EmitPreUnaryIncrementExpressionField(kind, expression,
5630                                                       need_value);
5631         }
5632         break;
5633     default:
5634         assert(false && "unknown lhs kind for assignment");
5635     }
5636 }
5637 
5638 
5639 //
5640 // AstExpression* expression;
5641 // PRE_UNARY on name
5642 // load value of variable, do increment or decrement, duplicate, then store
5643 // back, leaving new value on top of stack.
5644 //
EmitPreUnaryIncrementExpressionSimple(VariableCategory kind,AstPreUnaryExpression * expression,bool need_value)5645 void ByteCode::EmitPreUnaryIncrementExpressionSimple(VariableCategory kind,
5646                                                      AstPreUnaryExpression* expression,
5647                                                      bool need_value)
5648 {
5649     TypeSymbol* type = expression -> Type();
5650     if (kind == LOCAL_VAR && type == control.int_type)
5651     {
5652         PutOpIINC(expression -> symbol -> VariableCast() -> LocalVariableIndex(),
5653                   expression -> Tag() == AstPreUnaryExpression::PLUSPLUS ? 1 : -1);
5654         LoadVariable(kind, StripNops(expression -> expression), need_value);
5655         return;
5656     }
5657 
5658     // will also load value if resolution needed
5659     LoadVariable(kind, StripNops(expression -> expression));
5660 
5661     if (control.IsSimpleIntegerValueType(type))
5662     {
5663         PutOp(OP_ICONST_1);
5664         PutOp(expression -> Tag() == AstPreUnaryExpression::PLUSPLUS
5665               ? OP_IADD : OP_ISUB);
5666         EmitCast(type, control.int_type);
5667         if (need_value)
5668             PutOp(OP_DUP);
5669     }
5670     else if (type == control.long_type)
5671     {
5672         PutOp(OP_LCONST_1);
5673         PutOp(expression -> Tag() == AstPreUnaryExpression::PLUSPLUS
5674               ? OP_LADD : OP_LSUB);
5675         if (need_value)
5676             PutOp(OP_DUP2);
5677     }
5678     else if (type == control.float_type)
5679     {
5680         PutOp(OP_FCONST_1);
5681         PutOp(expression -> Tag() == AstPreUnaryExpression::PLUSPLUS
5682               ? OP_FADD : OP_FSUB);
5683         if (need_value)
5684             PutOp(OP_DUP);
5685     }
5686     else if (type == control.double_type)
5687     {
5688         PutOp(OP_DCONST_1); // load 1.0
5689         PutOp(expression -> Tag() == AstPreUnaryExpression::PLUSPLUS
5690               ? OP_DADD : OP_DSUB);
5691         if (need_value)
5692             PutOp(OP_DUP2);
5693     }
5694 
5695     if (kind == ACCESSED_VAR)
5696     {
5697         int stack_words = GetTypeWords(type);
5698         PutOp(OP_INVOKESTATIC);
5699         CompleteCall(expression -> write_method, stack_words);
5700     }
5701     else StoreVariable(kind, expression -> expression);
5702 }
5703 
5704 
5705 //
5706 // Post Unary for which operand is array element
5707 // assignment for which lhs is array element
5708 //    AstExpression* expression;
5709 //
EmitPreUnaryIncrementExpressionArray(AstPreUnaryExpression * expression,bool need_value)5710 void ByteCode::EmitPreUnaryIncrementExpressionArray(AstPreUnaryExpression* expression,
5711                                                     bool need_value)
5712 {
5713     //
5714     // JLS2 added ability for parenthesized variable to remain a variable.
5715     //
5716     // lhs must be array access
5717     EmitArrayAccessLhs((AstArrayAccess*) StripNops(expression -> expression));
5718 
5719     PutOp(OP_DUP2); // save array base and index for later store
5720 
5721     TypeSymbol* type = expression -> Type();
5722     if (type == control.int_type)
5723     {
5724          PutOp(OP_IALOAD);
5725          PutOp(OP_ICONST_1);
5726          PutOp(expression -> Tag() == AstPreUnaryExpression::PLUSPLUS
5727                ? OP_IADD : OP_ISUB);
5728          if (need_value)
5729              PutOp(OP_DUP_X2);
5730          PutOp(OP_IASTORE);
5731     }
5732     else if (type == control.byte_type)
5733     {
5734          PutOp(OP_BALOAD);
5735          PutOp(OP_ICONST_1);
5736          PutOp(expression -> Tag() == AstPreUnaryExpression::PLUSPLUS
5737                ? OP_IADD : OP_ISUB);
5738          PutOp(OP_I2B);
5739          if (need_value)
5740              PutOp(OP_DUP_X2);
5741          PutOp(OP_BASTORE);
5742     }
5743     else if (type == control.char_type)
5744     {
5745          PutOp(OP_CALOAD);
5746          PutOp(OP_ICONST_1);
5747          PutOp(expression -> Tag() == AstPreUnaryExpression::PLUSPLUS
5748                ? OP_IADD : OP_ISUB);
5749          PutOp(OP_I2C);
5750          if (need_value)
5751              PutOp(OP_DUP_X2);
5752          PutOp(OP_CASTORE);
5753     }
5754     else if (type == control.short_type)
5755     {
5756          PutOp(OP_SALOAD);
5757          PutOp(OP_ICONST_1);
5758          PutOp(expression -> Tag() == AstPreUnaryExpression::PLUSPLUS
5759                ? OP_IADD : OP_ISUB);
5760          PutOp(OP_I2S);
5761          if (need_value)
5762              PutOp(OP_DUP_X2);
5763          PutOp(OP_SASTORE);
5764     }
5765     else if (type == control.long_type)
5766     {
5767          PutOp(OP_LALOAD);
5768          PutOp(OP_LCONST_1);
5769          PutOp(expression -> Tag() == AstPreUnaryExpression::PLUSPLUS
5770                ? OP_LADD : OP_LSUB);
5771          if (need_value)
5772              PutOp(OP_DUP2_X2);
5773          PutOp(OP_LASTORE);
5774     }
5775     else if (type == control.float_type)
5776     {
5777          PutOp(OP_FALOAD);
5778          PutOp(OP_FCONST_1);
5779          PutOp(expression -> Tag() == AstPreUnaryExpression::PLUSPLUS
5780                ? OP_FADD : OP_FSUB);
5781          if (need_value)
5782              PutOp(OP_DUP_X2);
5783          PutOp(OP_FASTORE);
5784     }
5785     else if (type == control.double_type)
5786     {
5787          PutOp(OP_DALOAD);
5788          PutOp(OP_DCONST_1);
5789          PutOp(expression -> Tag() == AstPreUnaryExpression::PLUSPLUS
5790                ? OP_DADD : OP_DSUB);
5791          if (need_value)
5792              PutOp(OP_DUP2_X2);
5793          PutOp(OP_DASTORE);
5794     }
5795     else assert(false && "unsupported PreUnary type");
5796 }
5797 
5798 
5799 //
5800 // Pre Unary for which operand is field (instance variable)
5801 // AstExpression* expression;
5802 //
EmitPreUnaryIncrementExpressionField(VariableCategory kind,AstPreUnaryExpression * expression,bool need_value)5803 void ByteCode::EmitPreUnaryIncrementExpressionField(VariableCategory kind,
5804                                                     AstPreUnaryExpression* expression,
5805                                                     bool need_value)
5806 {
5807     if (kind == ACCESSED_VAR)
5808         ResolveAccess(expression -> expression); // get address and value
5809     else
5810         // need to load address of object, obtained from resolution, saving
5811         // a copy on the stack
5812         EmitFieldAccessLhs(expression -> expression);
5813 
5814     TypeSymbol* expression_type = expression -> Type();
5815     if (control.IsSimpleIntegerValueType(expression_type))
5816     {
5817         PutOp(OP_ICONST_1);
5818         PutOp(expression -> Tag() == AstPreUnaryExpression::PLUSPLUS
5819               ? OP_IADD : OP_ISUB);
5820         EmitCast(expression_type, control.int_type);
5821         if (need_value)
5822             PutOp(OP_DUP_X1);
5823     }
5824     else if (expression_type == control.long_type)
5825     {
5826         PutOp(OP_LCONST_1);
5827         PutOp(expression -> Tag() == AstPreUnaryExpression::PLUSPLUS
5828               ? OP_LADD : OP_LSUB);
5829         if (need_value)
5830             PutOp(OP_DUP2_X1);
5831     }
5832     else if (expression_type == control.float_type)
5833     {
5834         PutOp(OP_FCONST_1);
5835         PutOp(expression -> Tag() == AstPreUnaryExpression::PLUSPLUS
5836               ? OP_FADD : OP_FSUB);
5837         if (need_value)
5838             PutOp(OP_DUP_X1);
5839     }
5840     else if (expression_type == control.double_type)
5841     {
5842         PutOp(OP_DCONST_1);
5843         PutOp(expression -> Tag() == AstPreUnaryExpression::PLUSPLUS
5844               ? OP_DADD : OP_DSUB);
5845         if (need_value)
5846             PutOp(OP_DUP2_X1);
5847     }
5848     else assert(false && "unsupported PreUnary type");
5849 
5850     if (kind == ACCESSED_VAR)
5851     {
5852         int stack_words = GetTypeWords(expression_type) + 1;
5853         PutOp(OP_INVOKESTATIC);
5854         CompleteCall(expression -> write_method, stack_words);
5855     }
5856     else
5857     {
5858         PutOp(OP_PUTFIELD);
5859         if (control.IsDoubleWordType(expression_type))
5860             ChangeStack(-1);
5861 
5862         VariableSymbol* sym = (VariableSymbol*) expression -> symbol;
5863         PutU2(RegisterFieldref(VariableTypeResolution(expression ->
5864                                                       expression, sym), sym));
5865     }
5866 }
5867 
5868 
EmitThisInvocation(AstThisCall * this_call)5869 void ByteCode::EmitThisInvocation(AstThisCall* this_call)
5870 {
5871     //
5872     // Pass enclosing instance along, then real arguments.
5873     //
5874     PutOp(OP_ALOAD_0); // load 'this'
5875     int stack_words = 0; // words on stack needed for arguments
5876     if (unit_type -> EnclosingType())
5877         LoadLocal(++stack_words, unit_type -> EnclosingType());
5878     for (unsigned k = 0; k < this_call -> arguments -> NumArguments(); k++)
5879         stack_words += EmitExpression(this_call -> arguments -> Argument(k));
5880 
5881     //
5882     // Now do a transfer of the shadow variables. We do not need to worry
5883     // about an extra null argument, as there are no accessibility issues
5884     // when invoking this().
5885     //
5886     if (shadow_parameter_offset)
5887     {
5888         int offset = shadow_parameter_offset;
5889         for (unsigned i = 0; i < unit_type -> NumConstructorParameters(); i++)
5890         {
5891             VariableSymbol* shadow = unit_type -> ConstructorParameter(i);
5892             LoadLocal(offset, shadow -> Type());
5893             int words = GetTypeWords(shadow -> Type());
5894             offset += words;
5895             stack_words += words;
5896         }
5897     }
5898 
5899     PutOp(OP_INVOKESPECIAL);
5900     ChangeStack(-stack_words);
5901 
5902     PutU2(RegisterMethodref(unit_type, this_call -> symbol));
5903 }
5904 
5905 
EmitSuperInvocation(AstSuperCall * super_call)5906 void ByteCode::EmitSuperInvocation(AstSuperCall* super_call)
5907 {
5908     //
5909     // Pass enclosing instance along, then real arguments, then shadow
5910     // variables, and finally any extra null argument for accessibility
5911     // issues.
5912     //
5913     PutOp(OP_ALOAD_0); // load 'this'
5914     int stack_words = 0; // words on stack needed for arguments
5915     unsigned i;
5916     if (super_call -> base_opt)
5917     {
5918         stack_words++;
5919         if (unit_type -> Anonymous())
5920         {
5921             //
5922             // Special case - the null check was done during the class instance
5923             // creation, so we skip it here.
5924             //
5925             EmitExpression(super_call -> base_opt);
5926         }
5927         else EmitCheckForNull(super_call -> base_opt);
5928     }
5929     for (i = 0; i < super_call -> arguments -> NumArguments(); i++)
5930         stack_words += EmitExpression(super_call -> arguments -> Argument(i));
5931     for (i = 0; i < super_call -> arguments -> NumLocalArguments(); i++)
5932         stack_words +=
5933             EmitExpression(super_call -> arguments -> LocalArgument(i));
5934     if (super_call -> arguments -> NeedsExtraNullArgument())
5935     {
5936         PutOp(OP_ACONST_NULL);
5937         stack_words++;
5938     }
5939 
5940     PutOp(OP_INVOKESPECIAL);
5941     ChangeStack(-stack_words);
5942     PutU2(RegisterMethodref(unit_type -> super, super_call -> symbol));
5943 }
5944 
5945 
5946 //
5947 //  Methods for string concatenation
5948 //
ConcatenateString(AstBinaryExpression * expression,bool need_value)5949 void ByteCode::ConcatenateString(AstBinaryExpression* expression,
5950                                  bool need_value)
5951 {
5952     //
5953     // Generate code to concatenate strings, by generating a string buffer
5954     // and appending the arguments before calling toString, i.e.,
5955     //  s1+s2
5956     // compiles to
5957     //  new StringBuffer().append(s1).append(s2).toString();
5958     // Use recursion to share a single buffer where possible.
5959     // If concatenated string is not needed, we must still perform string
5960     // conversion on all objects, as well as perform side effects of terms.
5961     // In 1.5 and later, StringBuilder was added with better performance.
5962     //
5963     AstExpression* left_expr = StripNops(expression -> left_expression);
5964     if (left_expr -> Type() == control.String() &&
5965         left_expr -> BinaryExpressionCast() &&
5966         ! left_expr -> IsConstant())
5967     {
5968         ConcatenateString((AstBinaryExpression*) left_expr, need_value);
5969     }
5970     else
5971     {
5972         PutOp(OP_NEW);
5973         PutU2(RegisterClass(control.option.target >= JikesOption::SDK1_5
5974                             ? control.StringBuilder()
5975                             : control.StringBuffer()));
5976         PutOp(OP_DUP);
5977         if (left_expr -> IsConstant())
5978         {
5979             //
5980             // Optimizations: if the left term is "", just append the right
5981             // term to an empty StringBuffer. If the left term is not "",
5982             // use new StringBuffer(String) to create a StringBuffer
5983             // that includes the left term. No need to worry about
5984             // new StringBuffer(null) raising a NullPointerException
5985             // since string constants are never null.
5986             //
5987             Utf8LiteralValue* value =
5988                 DYNAMIC_CAST<Utf8LiteralValue*> (left_expr -> value);
5989             if (value -> length == 0 || ! need_value)
5990             {
5991                 PutOp(OP_INVOKESPECIAL);
5992                 PutU2(RegisterLibraryMethodref
5993                       (control.option.target >= JikesOption::SDK1_5
5994                        ? control.StringBuilder_InitMethod()
5995                        : control.StringBuffer_InitMethod()));
5996             }
5997             else
5998             {
5999                 LoadConstantAtIndex(RegisterString(value));
6000                 PutOp(OP_INVOKESPECIAL);
6001                 PutU2(RegisterLibraryMethodref
6002                       (control.option.target >= JikesOption::SDK1_5
6003                        ? control.StringBuilder_InitWithStringMethod()
6004                        : control.StringBuffer_InitWithStringMethod()));
6005                 ChangeStack(-1); // account for the argument
6006             }
6007         }
6008         else
6009         {
6010             PutOp(OP_INVOKESPECIAL);
6011             PutU2(RegisterLibraryMethodref
6012                   (control.option.target >= JikesOption::SDK1_5
6013                    ? control.StringBuilder_InitMethod()
6014                    : control.StringBuffer_InitMethod()));
6015             //
6016             // Don't pass stripped left_expr, or ((int)char)+"" would be
6017             // treated as a char append rather than int append.
6018             //
6019             AppendString(expression -> left_expression, need_value);
6020         }
6021     }
6022 
6023     AppendString(expression -> right_expression, need_value);
6024 }
6025 
6026 
AppendString(AstExpression * expression,bool need_value)6027 void ByteCode::AppendString(AstExpression* expression, bool need_value)
6028 {
6029     //
6030     // Grab the type before reducing no-ops, in the case of ""+(int)char.
6031     //
6032     TypeSymbol* type = expression -> Type();
6033     expression = StripNops(expression);
6034 
6035     if (expression -> IsConstant())
6036     {
6037         Utf8LiteralValue* value =
6038             DYNAMIC_CAST<Utf8LiteralValue*> (expression -> value);
6039         assert(value != NULL);
6040         assert(! control.IsPrimitive(type)); // Bug 2919.
6041         // Optimization: do nothing when appending "", or for unused result.
6042         if (value -> length == 0 || ! need_value)
6043             return;
6044         if (value -> length == 1)
6045         {
6046             // Optimization: append(char) more efficient than append(String)
6047             LoadImmediateInteger(value -> value[0]);
6048             type = control.char_type;
6049         }
6050         else if (value -> length == 2 &&
6051                  (value -> value[0] & 0x00E0) == 0x00C0)
6052         {
6053             // 2-byte string in UTF-8, but still single character.
6054             LoadImmediateInteger(((value -> value[0] & 0x001F) << 6) |
6055                                  (value -> value[1] & 0x003F));
6056             type = control.char_type;
6057         }
6058         else if (value -> length == 3 &&
6059                  (value -> value[0] & 0x00E0) == 0x00E0)
6060         {
6061             // 3-byte string in UTF-8, but still single character.
6062             LoadImmediateInteger(((value -> value[0] & 0x000F) << 12) |
6063                                  ((value -> value[1] & 0x003F) << 6) |
6064                                  (value -> value[2] & 0x003F));
6065             type = control.char_type;
6066         }
6067         else
6068             LoadConstantAtIndex(RegisterString(value));
6069     }
6070     else
6071     {
6072         AstBinaryExpression* binary_expression =
6073             expression -> BinaryExpressionCast();
6074         if (binary_expression && type == control.String())
6075         {
6076             assert(binary_expression -> Tag() == AstBinaryExpression::PLUS);
6077             AppendString(binary_expression -> left_expression, need_value);
6078             AppendString(binary_expression -> right_expression, need_value);
6079             return;
6080         }
6081         if (! need_value && control.IsPrimitive(type))
6082         {
6083             // Optimization: appending non-Object is no-op if result is unused.
6084             EmitExpression(expression, false);
6085             return;
6086         }
6087         EmitExpression(expression);
6088     }
6089 
6090     EmitStringAppendMethod(type);
6091 }
6092 
6093 
EmitStringAppendMethod(TypeSymbol * type)6094 void ByteCode::EmitStringAppendMethod(TypeSymbol* type)
6095 {
6096     //
6097     // Find appropriate append routine to add to string buffer. Do not use
6098     // append(char[]), because that inserts the contents instead of the
6099     // correct char[].toString(). Treating null as a String is slightly more
6100     // efficient than as an Object.
6101     //
6102     MethodSymbol* append_method;
6103     if (control.option.target >= JikesOption::SDK1_5)
6104     {
6105         append_method =
6106             (type == control.char_type
6107              ? control.StringBuilder_append_charMethod()
6108              : type == control.boolean_type
6109              ? control.StringBuilder_append_booleanMethod()
6110              : (type == control.int_type || type == control.short_type ||
6111                 type == control.byte_type)
6112              ? control.StringBuilder_append_intMethod()
6113              : type == control.long_type
6114              ? control.StringBuilder_append_longMethod()
6115              : type == control.float_type
6116              ? control.StringBuilder_append_floatMethod()
6117              : type == control.double_type
6118              ? control.StringBuilder_append_doubleMethod()
6119              : (type == control.String() || type == control.null_type)
6120              ? control.StringBuilder_append_stringMethod()
6121              : IsReferenceType(type)
6122              ? control.StringBuilder_append_objectMethod()
6123              : (MethodSymbol*) NULL); // for assertion
6124     }
6125     else
6126     {
6127         append_method =
6128             (type == control.char_type
6129              ? control.StringBuffer_append_charMethod()
6130              : type == control.boolean_type
6131              ? control.StringBuffer_append_booleanMethod()
6132              : (type == control.int_type || type == control.short_type ||
6133                 type == control.byte_type)
6134              ? control.StringBuffer_append_intMethod()
6135              : type == control.long_type
6136              ? control.StringBuffer_append_longMethod()
6137              : type == control.float_type
6138              ? control.StringBuffer_append_floatMethod()
6139              : type == control.double_type
6140              ? control.StringBuffer_append_doubleMethod()
6141              : (type == control.String() || type == control.null_type)
6142              ? control.StringBuffer_append_stringMethod()
6143              : IsReferenceType(type)
6144              ? control.StringBuffer_append_objectMethod()
6145              : (MethodSymbol*) NULL); // for assertion
6146     }
6147     assert(append_method &&
6148            "unable to find method for string buffer concatenation");
6149     PutOp(OP_INVOKEVIRTUAL);
6150     if (control.IsDoubleWordType(type))
6151         ChangeStack(-1);
6152     PutU2(RegisterLibraryMethodref(append_method));
6153 }
6154 
6155 
6156 #ifdef JIKES_DEBUG
op_trap()6157 static void op_trap()
6158 {
6159     int i = 0; // used for debugger trap
6160     i++;       // avoid compiler warnings about unused variable
6161 }
6162 #endif // JIKES_DEBUG
6163 
6164 
ByteCode(TypeSymbol * type)6165 ByteCode::ByteCode(TypeSymbol* type)
6166     : ClassFile()
6167     , control(type -> semantic_environment -> sem -> control)
6168     , semantic(*type -> semantic_environment -> sem)
6169     , unit_type(type)
6170     , string_overflow(false)
6171     , library_method_not_found(false)
6172     , last_op_goto(false)
6173     , shadow_parameter_offset(0)
6174     , code_attribute(NULL)
6175     , line_number_table_attribute(NULL)
6176     , local_variable_table_attribute(NULL)
6177     , inner_classes_attribute(NULL)
6178     , double_constant_pool_index(NULL)
6179     , integer_constant_pool_index(NULL)
6180     , long_constant_pool_index(NULL)
6181     , float_constant_pool_index(NULL)
6182     , string_constant_pool_index(NULL)
6183     , utf8_constant_pool_index(segment_pool,
6184                                control.Utf8_pool.symbol_pool.Length())
6185     , class_constant_pool_index(segment_pool,
6186                                 control.Utf8_pool.symbol_pool.Length())
6187     , name_and_type_constant_pool_index(NULL)
6188     , fieldref_constant_pool_index(NULL)
6189     , methodref_constant_pool_index(NULL)
6190 {
6191 #ifdef JIKES_DEBUG
6192     if (! control.option.nowrite)
6193         control.class_files_written++;
6194 #endif // JIKES_DEBUG
6195 
6196     //
6197     // For compatibility reasons, protected classes are marked public, and
6198     // private classes are marked default; and no class may be static or
6199     // strictfp. Also, a non-access flag, the super bit, must be set for
6200     // classes but not interfaces. For top-level types, this changes nothing
6201     // except adding the super bit. For nested types, the correct access bits
6202     // are emitted later as part of the InnerClasses attribute. Also, no class
6203     // is marked strictfp.
6204     //
6205     SetFlags(unit_type -> Flags());
6206     if (ACC_PROTECTED())
6207     {
6208         ResetACC_PROTECTED();
6209         SetACC_PUBLIC();
6210     }
6211     else if (ACC_PRIVATE())
6212         ResetACC_PRIVATE();
6213     ResetACC_STATIC();
6214     ResetACC_STRICTFP();
6215     if (! unit_type -> ACC_INTERFACE())
6216         SetACC_SUPER();
6217 
6218     switch (control.option.target)
6219     {
6220     case JikesOption::SDK1_1:
6221         major_version = 45;
6222         minor_version = 3;
6223         break;
6224     case JikesOption::SDK1_2:
6225         major_version = 46;
6226         minor_version = 0;
6227         break;
6228     case JikesOption::SDK1_3:
6229         major_version = 47;
6230         minor_version = 0;
6231         break;
6232     case JikesOption::SDK1_4:
6233     case JikesOption::SDK1_4_2:
6234         major_version = 48;
6235         minor_version = 0;
6236         break;
6237     case JikesOption::SDK1_5:
6238         major_version = 49;
6239         minor_version = 0;
6240         break;
6241     default:
6242         assert(false && "unknown version for target");
6243     }
6244 
6245 #ifdef JIKES_DEBUG
6246     if (control.option.verbose)
6247 	Coutput << "[generating code for class "
6248 		<< unit_type -> fully_qualified_name -> value << " as version "
6249 		<< major_version << '.' << minor_version << ']' << endl;
6250 #endif // JIKES_DEBUG
6251 
6252     this_class = RegisterClass(unit_type);
6253     super_class = (unit_type -> super ? RegisterClass(unit_type -> super) : 0);
6254     for (unsigned k = 0; k < unit_type -> NumInterfaces(); k++)
6255         interfaces.Next() = RegisterClass(unit_type -> Interface(k));
6256 }
6257 
6258 
6259 //
6260 //  Methods for manipulating labels
6261 //
DefineLabel(Label & lab)6262 void ByteCode::DefineLabel(Label& lab)
6263 {
6264     assert(! lab.defined && "duplicate label definition");
6265 
6266     //
6267     // Optimize if previous instruction was unconditional jump to this label.
6268     // However, we cannot perform the optimization if another label was also
6269     // defined at this location. Likewise, if local symbol tables are being
6270     // emitted, this optimization would screw up the symbol table.
6271     //
6272     // TODO: It would be nice to redo the bytecode emitter, to make it a
6273     // two-pass algorithm with straight-forward emission the first time, and
6274     // peephole optimizations the second time. This would be a better way to
6275     // cleanly collapse useless jumps, and could catch several other cases
6276     // that are missed or difficult to detect currently. This would require
6277     // creating labels at the compiled method level, rather than on the
6278     // invocation stack at the compiled statement level; as well as other code
6279     // changes. However, it might also improve inlining (such as in
6280     // try-finally, or in private methods); and might allow us to finally
6281     // implement the -O option as more than a no-op.
6282     //
6283     int index = lab.uses.Length() - 1;
6284     if (last_op_goto && index >= 0 && ! (control.option.g & JikesOption::VARS))
6285     {
6286         unsigned int luse = lab.uses[index].use_offset;
6287         int start = luse - lab.uses[index].op_offset;
6288         if (start == last_op_pc &&
6289             code_attribute -> CodeLength() != last_label_pc)
6290         {
6291 #ifdef JIKES_DEBUG
6292             if (control.option.debug_trace_stack_change)
6293                 Coutput << "removing dead jump: pc " << start << endl;
6294 #endif
6295             code_attribute -> DeleteCode(lab.uses[index].op_offset +
6296                                          lab.uses[index].use_length);
6297             lab.uses.Reset(index);
6298             line_number_table_attribute -> SetMax(start);
6299             last_op_goto = false;
6300         }
6301     }
6302     lab.defined = true;
6303     lab.definition = code_attribute -> CodeLength();
6304     if (lab.uses.Length())
6305         last_label_pc = lab.definition;
6306 }
6307 
6308 
6309 //
6310 // patch all uses to have proper value. This requires that
6311 // all labels be freed at some time.
6312 //
CompleteLabel(Label & lab)6313 void ByteCode::CompleteLabel(Label& lab)
6314 {
6315     if (lab.uses.Length())
6316     {
6317         assert(lab.defined && "label used but with no definition");
6318 
6319         //
6320         // Sanity check - when completing method, make sure nothing jumps out
6321         // of the method. This also collapses two labels that begin on
6322         // the same location, before one is optimized away, as in
6323         // "if (b) <statement> else {}".
6324         //
6325         if (lab.definition > code_attribute -> CodeLength())
6326             lab.definition = code_attribute -> CodeLength();
6327 
6328         //
6329         // patch byte code reference to label to reflect its definition
6330         // as 16-bit signed offset.
6331         //
6332         for (unsigned i = 0; i < lab.uses.Length(); i++)
6333         {
6334             unsigned int luse = lab.uses[i].use_offset;
6335             int start = luse - lab.uses[i].op_offset,
6336                 offset = lab.definition - start;
6337             if (lab.uses[i].use_length == 2) // here if short offset
6338             {
6339                 assert(offset < 32768 && offset >= -32768 &&
6340                        "needed longer branch offset");
6341                 code_attribute -> ResetCode(luse, (offset >> 8) & 0xFF);
6342                 code_attribute -> ResetCode(luse + 1, offset & 0xFF);
6343             }
6344             else if (lab.uses[i].use_length == 4) // here if 4 byte use
6345             {
6346                 code_attribute -> ResetCode(luse, (offset >> 24) & 0xFF);
6347                 code_attribute -> ResetCode(luse + 1, (offset >> 16) & 0xFF);
6348                 code_attribute -> ResetCode(luse + 2, (offset >>  8) & 0xFF);
6349                 code_attribute -> ResetCode(luse + 3, offset & 0xFF);
6350             }
6351             else assert(false &&  "label use length not 2 or 4");
6352         }
6353     }
6354 
6355     //
6356     // reset in case label is used again.
6357     //
6358     lab.Reset();
6359 }
6360 
6361 
UseLabel(Label & lab,int _length,int _op_offset)6362 void ByteCode::UseLabel(Label& lab, int _length, int _op_offset)
6363 {
6364     int lab_index = lab.uses.NextIndex();
6365     lab.uses[lab_index].use_length = _length;
6366     lab.uses[lab_index].op_offset = _op_offset;
6367     lab.uses[lab_index].use_offset = code_attribute -> CodeLength();
6368 
6369     //
6370     // fill next length bytes with zero; will be filled in with proper value
6371     // when label completed
6372     //
6373     for (int i = 0; i < lab.uses[lab_index].use_length; i++)
6374         code_attribute -> AddCode(0);
6375 }
6376 
6377 
LoadLocal(int varno,const TypeSymbol * type)6378 void ByteCode::LoadLocal(int varno, const TypeSymbol* type)
6379 {
6380     if (control.IsSimpleIntegerValueType(type) || type == control.boolean_type)
6381     {
6382          if (varno <= 3)
6383              PutOp((Opcode) (OP_ILOAD_0 + varno)); // Exploit opcode encodings
6384          else PutOpWide(OP_ILOAD, varno);
6385     }
6386     else if (type == control.long_type)
6387     {
6388          if (varno <= 3)
6389              PutOp((Opcode) (OP_LLOAD_0 + varno)); // Exploit opcode encodings
6390          else PutOpWide(OP_LLOAD, varno);
6391     }
6392     else if (type == control.float_type)
6393     {
6394          if (varno <= 3)
6395              PutOp((Opcode) (OP_FLOAD_0 + varno)); // Exploit opcode encodings
6396          else PutOpWide(OP_FLOAD, varno);
6397     }
6398     else if (type == control.double_type)
6399     {
6400          if (varno <= 3)
6401              PutOp((Opcode) (OP_DLOAD_0 + varno)); // Exploit opcode encodings
6402          else PutOpWide(OP_DLOAD, varno);
6403     }
6404     else // assume reference
6405     {
6406          if (varno <= 3)
6407              PutOp((Opcode) (OP_ALOAD_0 + varno)); // Exploit opcode encodings
6408          else PutOpWide(OP_ALOAD, varno);
6409     }
6410 }
6411 
6412 
6413 //
6414 // See if we can load without using LDC; otherwise generate constant pool
6415 // entry if one has not yet been generated.
6416 //
LoadLiteral(LiteralValue * litp,const TypeSymbol * type)6417 void ByteCode::LoadLiteral(LiteralValue* litp, const TypeSymbol* type)
6418 {
6419     if (control.IsSimpleIntegerValueType(type) || type == control.boolean_type)
6420     {
6421         // load literal using literal value
6422         IntLiteralValue* vp = DYNAMIC_CAST<IntLiteralValue*> (litp);
6423         LoadImmediateInteger(vp -> value);
6424     }
6425     else if (type == control.String() || type == control.null_type)
6426     {
6427         // register index as string if this has not yet been done
6428         Utf8LiteralValue* vp = DYNAMIC_CAST<Utf8LiteralValue*> (litp);
6429         LoadConstantAtIndex(RegisterString(vp));
6430     }
6431     else if (type == control.long_type)
6432     {
6433         LongLiteralValue* vp = DYNAMIC_CAST<LongLiteralValue*> (litp);
6434         if (vp -> value == 0)
6435             PutOp(OP_LCONST_0);
6436         else if (vp -> value == 1)
6437             PutOp(OP_LCONST_1);
6438         else if (vp -> value >= -1 && vp -> value <= 5)
6439         {
6440             LoadImmediateInteger(vp -> value.LowWord());
6441             PutOp(OP_I2L);
6442         }
6443         else
6444         {
6445             PutOp(OP_LDC2_W);
6446             PutU2(RegisterLong(vp));
6447         }
6448     }
6449     else if (type == control.float_type)
6450     {
6451         FloatLiteralValue* vp = DYNAMIC_CAST<FloatLiteralValue*> (litp);
6452         IEEEfloat val = vp -> value;
6453         if (val.IsZero())
6454         {
6455             PutOp(OP_FCONST_0);
6456             if (val.IsNegative())
6457                 PutOp(OP_FNEG);
6458         }
6459         else if (val == 1.0f)
6460             PutOp(OP_FCONST_1);
6461         else if (val == 2.0f)
6462             PutOp(OP_FCONST_2);
6463         else if (val == -1.0f)
6464         {
6465             PutOp(OP_FCONST_1);
6466             PutOp(OP_FNEG);
6467         }
6468         else if (val == 3.0f || val == 4.0f || val == 5.0f)
6469         {
6470             LoadImmediateInteger(val.IntValue());
6471             PutOp(OP_I2F);
6472         }
6473         else LoadConstantAtIndex(RegisterFloat(vp));
6474     }
6475     else if (type == control.double_type)
6476     {
6477         DoubleLiteralValue* vp = DYNAMIC_CAST<DoubleLiteralValue*> (litp);
6478         IEEEdouble val = vp -> value;
6479         if (val.IsZero())
6480         {
6481             PutOp(OP_DCONST_0);
6482             if (val.IsNegative())
6483                 PutOp(OP_DNEG);
6484         }
6485         else if (val == 1.0)
6486             PutOp(OP_DCONST_1);
6487         else if (val == -1.0)
6488         {
6489             PutOp(OP_DCONST_1);
6490             PutOp(OP_DNEG);
6491         }
6492         else if (val == 2.0 || val == 3.0 || val == 4.0 || val == 5.0)
6493         {
6494             LoadImmediateInteger(val.IntValue());
6495             PutOp(OP_I2D);
6496         }
6497         else
6498         {
6499              PutOp(OP_LDC2_W);
6500              PutU2(RegisterDouble(vp));
6501         }
6502     }
6503     else assert(false && "unsupported constant kind");
6504 }
6505 
6506 
LoadImmediateInteger(i4 val)6507 void ByteCode::LoadImmediateInteger(i4 val)
6508 {
6509     if (val >= -1 && val <= 5)
6510         PutOp((Opcode) (OP_ICONST_0 + val)); // exploit opcode encoding
6511     else if (val >= -128 && val < 128)
6512     {
6513         PutOp(OP_BIPUSH);
6514         PutU1(val);
6515     }
6516     else if (val >= -32768 && val < 32768)
6517     {
6518         //
6519         // For a short value, look to see if it is already in the constant
6520         // pool. In such a case, ldc is two bytes, while sipush is three, so
6521         // we emit a smaller classfile with no penalty to a good JIT. Note
6522         // that ldc_w does not buy us anything, however.
6523         //
6524         u2 index = FindInteger(control.int_pool.Find(val));
6525         if (index == 0 || index > 255)
6526         {
6527             PutOp(OP_SIPUSH);
6528             PutU2(val);
6529         }
6530         else LoadConstantAtIndex(index);
6531     }
6532     else if (val == 65535)
6533     {
6534         PutOp(OP_ICONST_M1);
6535         PutOp(OP_I2C);
6536     }
6537     // Outside the range of sipush, we must use the constant pool.
6538     else LoadConstantAtIndex(RegisterInteger(control.int_pool.FindOrInsert(val)));
6539 }
6540 
6541 
6542 //
6543 // Call to an access method for a compound operator such as ++, --,
6544 // or "op=".
6545 //
ResolveAccess(AstExpression * p)6546 void ByteCode::ResolveAccess(AstExpression* p)
6547 {
6548     //
6549     // JLS2 added ability for parenthesized variable to remain a variable.
6550     //
6551     p = StripNops(p);
6552 
6553     AstFieldAccess* field = p -> FieldAccessCast();
6554     AstExpression* resolve_expression = field ? field -> resolution_opt
6555         : p -> NameCast() -> resolution_opt;
6556     AstMethodInvocation* read_method =
6557         resolve_expression -> MethodInvocationCast();
6558 
6559     // a read method has exactly one argument: the object in question.
6560     assert(read_method && read_method -> arguments -> NumArguments() == 1);
6561 
6562     int stack_words = EmitExpression(read_method -> arguments -> Argument(0));
6563     PutOp(OP_DUP);
6564     PutOp(OP_INVOKESTATIC);
6565     CompleteCall(read_method -> symbol -> MethodCast(), stack_words);
6566 }
6567 
6568 
LoadVariable(VariableCategory kind,AstExpression * expr,bool need_value)6569 int ByteCode::LoadVariable(VariableCategory kind, AstExpression* expr,
6570                            bool need_value)
6571 {
6572     VariableSymbol* sym = (VariableSymbol*) expr -> symbol;
6573     TypeSymbol* expression_type = expr -> Type();
6574     AstFieldAccess* field_access = expr -> FieldAccessCast();
6575     AstName* name = expr -> NameCast();
6576     AstExpression* base = name ? name -> base_opt : field_access -> base;
6577     assert(field_access || name);
6578     switch (kind)
6579     {
6580     case LOCAL_VAR:
6581         assert(name && ! base);
6582         if (! need_value)
6583             return 0;
6584         if (expr -> IsConstant())
6585             LoadLiteral(expr -> value, expression_type);
6586         else LoadLocal(sym -> LocalVariableIndex(), expression_type);
6587         return GetTypeWords(expression_type);
6588     case ACCESSED_VAR:
6589         {
6590             //
6591             // A resolution is related to either this$0.field or
6592             // this$0.access$(). If need_value is false, and the access is
6593             // static, field access is smart enough to optimize away, but
6594             // method access requires some help.
6595             //
6596             MethodSymbol* method = expr -> symbol -> MethodCast();
6597             if (! need_value && method && method -> AccessesStaticMember())
6598                 return base ? EmitExpression(base, false) : 0;
6599             return EmitExpression((name ? name -> resolution_opt
6600                                    : field_access -> resolution_opt),
6601                                   need_value);
6602         }
6603     case FIELD_VAR:
6604         assert(sym -> IsInitialized() || ! sym -> ACC_FINAL());
6605         if (shadow_parameter_offset && sym -> owner == unit_type &&
6606             (sym -> accessed_local ||
6607              sym -> Identity() == control.this_name_symbol))
6608         {
6609             //
6610             // In a constructor, use the parameter that was passed to the
6611             // constructor rather than the val$ or this$0 field, because the
6612             // field is not yet initialized.
6613             //
6614             if (! sym -> accessed_local)
6615             {
6616                 PutOp(OP_ALOAD_1);
6617                 return 1;
6618             }
6619             int offset = shadow_parameter_offset;
6620             for (unsigned i = 0;
6621                  i < unit_type -> NumConstructorParameters(); i++)
6622             {
6623                 VariableSymbol* shadow = unit_type -> ConstructorParameter(i);
6624                 if (sym == shadow)
6625                 {
6626                     LoadLocal(offset, expression_type);
6627                     return GetTypeWords(expression_type);
6628                 }
6629                 offset += GetTypeWords(shadow -> Type());
6630             }
6631             assert(false && "local variable shadowing is messed up");
6632         }
6633         if (base && base -> Type() -> IsArray())
6634         {
6635             assert(sym -> name_symbol == control.length_name_symbol);
6636             if (base -> ArrayCreationExpressionCast() && ! need_value)
6637             {
6638                 EmitExpression(base, false);
6639                 return 0;
6640             }
6641             EmitExpression(base);
6642             PutOp(OP_ARRAYLENGTH);
6643             if (need_value)
6644                 return 1;
6645             PutOp(OP_POP);
6646             return 0;
6647         }
6648         if (sym -> initial_value)
6649         {
6650             //
6651             // Inline constants without referring to the field. However, we
6652             // must still check for null.
6653             //
6654             if (base)
6655                 EmitCheckForNull(base, false);
6656             if (need_value)
6657             {
6658                 LoadLiteral(sym -> initial_value, expression_type);
6659                 return GetTypeWords(expression_type);
6660             }
6661             return 0;
6662         }
6663         if (base)
6664             EmitExpression(base);
6665         else PutOp(OP_ALOAD_0);
6666         PutOp(OP_GETFIELD);
6667         break;
6668     case STATIC_VAR:
6669         //
6670         // If the access is qualified by an arbitrary base expression,
6671         // evaluate it for side effects. Likewise, volatile fields must be
6672         // loaded because of the memory barrier side effect.
6673         //
6674         if (base)
6675             EmitExpression(base, false);
6676         if (need_value || sym -> ACC_VOLATILE())
6677         {
6678             if (sym -> initial_value)
6679             {
6680                 //
6681                 // Inline any constant. Note that volatile variables can't
6682                 // be final, so they are not constant.
6683                 //
6684                 LoadLiteral(sym -> initial_value, expression_type);
6685                 return GetTypeWords(expression_type);
6686             }
6687             PutOp(OP_GETSTATIC);
6688             break;
6689         }
6690         else return 0;
6691     default:
6692         assert(false && "LoadVariable bad kind");
6693     }
6694     if (control.IsDoubleWordType(expression_type))
6695         ChangeStack(1);
6696     PutU2(RegisterFieldref(VariableTypeResolution(expr, sym), sym));
6697     if (need_value)
6698     {
6699         return GetTypeWords(expression_type);
6700     }
6701     PutOp(control.IsDoubleWordType(expression_type) ? OP_POP2 : OP_POP);
6702     return 0;
6703 }
6704 
6705 
LoadArrayElement(const TypeSymbol * type)6706 int ByteCode::LoadArrayElement(const TypeSymbol* type)
6707 {
6708     PutOp((type == control.byte_type ||
6709            type == control.boolean_type) ? OP_BALOAD
6710           : type == control.short_type ? OP_SALOAD
6711           : type == control.int_type ? OP_IALOAD
6712           : type == control.long_type ? OP_LALOAD
6713           : type == control.char_type ? OP_CALOAD
6714           : type == control.float_type ? OP_FALOAD
6715           : type == control.double_type ? OP_DALOAD
6716           : OP_AALOAD); // assume reference
6717 
6718     return GetTypeWords(type);
6719 }
6720 
6721 
StoreArrayElement(const TypeSymbol * type)6722 void ByteCode::StoreArrayElement(const TypeSymbol* type)
6723 {
6724     PutOp((type == control.byte_type ||
6725            type == control.boolean_type) ? OP_BASTORE
6726           : type == control.short_type ? OP_SASTORE
6727           : type == control.int_type ? OP_IASTORE
6728           : type == control.long_type ? OP_LASTORE
6729           : type == control.char_type ? OP_CASTORE
6730           : type == control.float_type ? OP_FASTORE
6731           : type == control.double_type ? OP_DASTORE
6732           : OP_AASTORE); // assume reference
6733 }
6734 
6735 
6736 //
6737 //  Method to generate field reference
6738 //
StoreField(AstExpression * expression)6739 void ByteCode::StoreField(AstExpression* expression)
6740 {
6741     VariableSymbol* sym = (VariableSymbol*) expression -> symbol;
6742     TypeSymbol* expression_type = expression -> Type();
6743     if (sym -> ACC_STATIC())
6744     {
6745         PutOp(OP_PUTSTATIC);
6746         ChangeStack(1 - GetTypeWords(expression_type));
6747     }
6748     else
6749     {
6750         PutOp(OP_PUTFIELD);
6751         ChangeStack(1 - GetTypeWords(expression_type));
6752     }
6753 
6754     PutU2(RegisterFieldref(VariableTypeResolution(expression, sym), sym));
6755 }
6756 
6757 
StoreLocal(int varno,const TypeSymbol * type)6758 void ByteCode::StoreLocal(int varno, const TypeSymbol* type)
6759 {
6760     if (control.IsSimpleIntegerValueType(type) || type == control.boolean_type)
6761     {
6762          if (varno <= 3)
6763              PutOp((Opcode) (OP_ISTORE_0 + varno)); // Exploit opcode encodings
6764          else PutOpWide(OP_ISTORE, varno);
6765     }
6766     else if (type == control.long_type)
6767     {
6768          if (varno <= 3)
6769              PutOp((Opcode) (OP_LSTORE_0 + varno)); // Exploit opcode encodings
6770          else PutOpWide(OP_LSTORE, varno);
6771     }
6772     else if (type == control.float_type)
6773     {
6774          if (varno <= 3)
6775              PutOp((Opcode) (OP_FSTORE_0 + varno)); // Exploit opcode encodings
6776          else PutOpWide(OP_FSTORE, varno);
6777     }
6778     else if (type == control.double_type)
6779     {
6780          if (varno <= 3)
6781              PutOp((Opcode) (OP_DSTORE_0 + varno)); // Exploit opcode encodings
6782          else PutOpWide(OP_DSTORE, varno);
6783     }
6784     else // assume reference
6785     {
6786          if (varno <= 3)
6787              PutOp((Opcode) (OP_ASTORE_0 + varno)); // Exploit opcode encodings
6788          else PutOpWide(OP_ASTORE, varno);
6789     }
6790 }
6791 
6792 
StoreVariable(VariableCategory kind,AstExpression * expr)6793 void ByteCode::StoreVariable(VariableCategory kind, AstExpression* expr)
6794 {
6795     VariableSymbol* sym = (VariableSymbol*) expr -> symbol;
6796     switch (kind)
6797     {
6798     case LOCAL_VAR:
6799         StoreLocal(sym -> LocalVariableIndex(), sym -> Type());
6800         break;
6801     case FIELD_VAR:
6802     case STATIC_VAR:
6803         {
6804             if (sym -> ACC_STATIC())
6805             {
6806                 PutOp(OP_PUTSTATIC);
6807                 ChangeStack(1 - GetTypeWords(expr -> Type()));
6808             }
6809             else
6810             {
6811                 PutOp(OP_ALOAD_0); // get address of "this"
6812                 PutOp(OP_PUTFIELD);
6813                 ChangeStack(1 - GetTypeWords(expr -> Type()));
6814             }
6815 
6816             PutU2(RegisterFieldref(VariableTypeResolution(expr, sym), sym));
6817         }
6818         break;
6819     default:
6820         assert(false && "StoreVariable bad kind");
6821     }
6822 }
6823 
6824 
6825 //
6826 // Finish off code by writing remaining type-level attributes.
6827 //
FinishCode()6828 void ByteCode::FinishCode()
6829 {
6830     //
6831     // Only output SourceFile attribute if -g:source is enabled.
6832     //
6833     if (control.option.g & JikesOption::SOURCE)
6834         AddAttribute(new SourceFileAttribute
6835                      (RegisterUtf8(control.SourceFile_literal),
6836                       RegisterUtf8(unit_type -> file_symbol ->
6837                                    FileNameLiteral())));
6838     if (unit_type -> IsDeprecated())
6839         AddAttribute(CreateDeprecatedAttribute());
6840     if (unit_type -> ACC_SYNTHETIC() &&
6841         control.option.target < JikesOption::SDK1_5)
6842     {
6843         AddAttribute(CreateSyntheticAttribute());
6844     }
6845     if (unit_type -> owner -> MethodCast())
6846     {
6847         MethodSymbol* enclosing = (MethodSymbol*) unit_type -> owner;
6848         AddAttribute(CreateEnclosingMethodAttribute(enclosing));
6849     }
6850     //
6851     // In case they weren't referenced elsewhere, make sure all nested types
6852     // of this class are listed in the constant pool.  A side effect of
6853     // registering the class is updating the InnerClasses attribute.
6854     //
6855     unsigned i = unit_type -> NumNestedTypes();
6856     while (i--)
6857         RegisterClass(unit_type -> NestedType(i));
6858 }
6859 
6860 
PutOp(Opcode opc)6861 void ByteCode::PutOp(Opcode opc)
6862 {
6863 #ifdef JIKES_DEBUG
6864     if (control.option.debug_trap_op &&
6865         code_attribute -> CodeLength() == (u2) control.option.debug_trap_op)
6866     {
6867         op_trap();
6868     }
6869 
6870     if (control.option.debug_trace_stack_change)
6871     {
6872         const char* opname;
6873         OpDesc(opc, &opname, NULL);
6874         Coutput << "opcode: " << opname << endl;
6875     }
6876 #endif // JIKES_DEBUG
6877 
6878     // save pc at start of operation
6879     last_op_pc = code_attribute -> CodeLength();
6880     code_attribute -> AddCode(opc);
6881     ChangeStack(stack_effect[opc]);
6882     last_op_goto = (opc == OP_GOTO || opc == OP_GOTO_W);
6883 }
6884 
PutOpWide(Opcode opc,u2 var)6885 void ByteCode::PutOpWide(Opcode opc, u2 var)
6886 {
6887     if (var <= 255)  // if can use standard form
6888     {
6889         PutOp(opc);
6890         PutU1(var);
6891     }
6892     else // need wide form
6893     {
6894         PutOp(OP_WIDE);
6895         PutOp(opc);
6896         PutU2(var);
6897     }
6898 }
6899 
PutOpIINC(u2 var,int val)6900 void ByteCode::PutOpIINC(u2 var, int val)
6901 {
6902     if (var <= 255 && (val >= -128 && val <= 127))  // if can use standard form
6903     {
6904         PutOp(OP_IINC);
6905         PutU1(var);
6906         PutU1(val);
6907     }
6908     else // else need wide form
6909     {
6910         PutOp(OP_WIDE);
6911         PutOp(OP_IINC);
6912         PutU2(var);
6913         PutU2(val);
6914     }
6915 }
6916 
ChangeStack(int i)6917 void ByteCode::ChangeStack(int i)
6918 {
6919     stack_depth += i;
6920     assert(stack_depth >= 0);
6921 
6922     if (i > 0 && stack_depth > max_stack)
6923         max_stack = stack_depth;
6924 
6925 #ifdef JIKES_DEBUG
6926     if (control.option.debug_trace_stack_change)
6927         Coutput << "stack change: pc " << last_op_pc << " change " << i
6928                 << "  stack_depth " << stack_depth << "  max_stack: "
6929                 << max_stack << endl;
6930 #endif // JIKES_DEBUG
6931 }
6932 
6933 
6934 #ifdef HAVE_JIKES_NAMESPACE
6935 } // Close namespace Jikes block
6936 #endif
6937 
6938