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