home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 20 / AACD20.BIN / AACD / Programming / Jikes / Source / src / bytecode.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-24  |  199.2 KB  |  5,493 lines

  1. // $Id: bytecode.cpp,v 1.54 2001/02/18 23:21:18 mdejong 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://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10.  
  11. #include "bytecode.h"
  12. #include "ast.h"
  13. #include "class.h"
  14. #include "control.h"
  15. #include "semantic.h"
  16. #include "stream.h"
  17. #include "symbol.h"
  18. #include "table.h"
  19.  
  20. /*
  21. //FIXME: need to readdress this include stuff
  22. #ifdef HAVE_IOSTREAM_H
  23. #include <iostream.h>
  24. #endif
  25.  
  26. #ifdef HAVE_WCHAR_H
  27. # include <wchar.h>
  28. #endif
  29.  
  30. #ifdef WIN32_FILE_SYSTEM
  31. #include <windows.h>
  32. #endif
  33. */
  34.  
  35. #ifdef    HAVE_JIKES_NAMESPACE
  36. namespace Jikes {    // Open namespace Jikes block
  37. #endif
  38.  
  39. void ByteCode::CompileClass()
  40. {
  41.     AstClassDeclaration *class_decl = unit_type -> declaration -> ClassDeclarationCast();
  42.     AstClassBody *class_body = (class_decl
  43.                                      ? class_decl -> class_body
  44.                                      : ((AstClassInstanceCreationExpression *) unit_type -> declaration) -> class_body_opt);
  45.  
  46.     //
  47.     // Process static variables.
  48.     //
  49.     Tuple<AstVariableDeclarator *> initialized_static_fields(unit_type -> NumVariableSymbols()); // fields needing code to initialize
  50.     {
  51.         for (int i = 0; i < class_body -> NumClassVariables(); i++)
  52.         {
  53.             AstFieldDeclaration *field_decl = class_body -> ClassVariable(i);
  54.             for (int vi = 0; vi < field_decl -> NumVariableDeclarators(); vi++)
  55.             {
  56.                 AstVariableDeclarator *variable_declarator = field_decl -> VariableDeclarator(vi);
  57.                 VariableSymbol *vsym = variable_declarator -> symbol;
  58.                 DeclareField(vsym);
  59.  
  60.                 //
  61.                 // We need a static constructor-initializer if we encounter at least one class
  62.                 // variable that is declared with an initializer that is not a constant expression.
  63.                 //
  64.                 if (variable_declarator -> variable_initializer_opt)
  65.                 {
  66.                     AstExpression *init = variable_declarator -> variable_initializer_opt -> ExpressionCast();
  67.                     if (! (init && init -> IsConstant()))
  68.                         initialized_static_fields.Next() = variable_declarator;
  69.  
  70.                     //
  71.                     // TODO: there seems to be a contradiction between the language spec and the VM spec.
  72.                     // The language spec seems to require that a variable be initialized (in the class file)
  73.                     // with a "ConstantValue" only if it is static. The VM spec, on the other hand, states
  74.                     // that a static need not be final to be initialized with a ConstantValue.
  75.                     // As of now, we are following the language spec - ergo, this extra test.
  76.                     //
  77.                     else
  78.                     {
  79.                         assert(variable_declarator -> symbol);
  80.                         if (! variable_declarator -> symbol -> ACC_FINAL())
  81.                             initialized_static_fields.Next() = variable_declarator;
  82.                     }
  83.                 }
  84.             }
  85.         }
  86.     }
  87.  
  88.     //
  89.     // Process instance variables.
  90.     //
  91.     Tuple<AstVariableDeclarator *> initialized_instance_fields(unit_type -> NumVariableSymbols()); // fields needing code to init
  92.     {
  93.         for (int i = 0; i < class_body -> NumInstanceVariables(); i++)
  94.         {
  95.             AstFieldDeclaration *field_decl  = class_body -> InstanceVariable(i);
  96.             for (int vi = 0; vi < field_decl -> NumVariableDeclarators(); vi++)
  97.             {
  98.                 AstVariableDeclarator *vd = field_decl -> VariableDeclarator(vi);
  99.                 DeclareField(vd -> symbol);
  100.  
  101.                 //
  102.                 // must set Constant attribute if initial value specified
  103.                 //
  104.                 if (vd -> variable_initializer_opt)
  105.                     initialized_instance_fields.Next() = vd;
  106.             }
  107.         }
  108.     }
  109.  
  110.     //
  111.     // supply needed field declaration for this$0 and any additional local shadow parameters
  112.     //
  113.     {
  114.         for (int i = 0; i < unit_type -> NumConstructorParameters(); i++)
  115.             DeclareField(unit_type -> ConstructorParameter(i));
  116.     }
  117.  
  118.     //
  119.     // supply needed field declaration for enclosing instances (this$n, n > 0) if present
  120.     //
  121.     {
  122.         for (int i = 1; i < unit_type -> NumEnclosingInstances(); i++)
  123.             DeclareField(unit_type -> EnclosingInstance(i));
  124.     }
  125.  
  126.     //
  127.     // supply needed field declarations for "class " identifiers (used for X.class literals) if present
  128.     //
  129.     {
  130.         for (int i = 0; i < unit_type -> NumClassLiterals(); i++)
  131.             DeclareField(unit_type -> ClassLiteral(i));
  132.     }
  133.  
  134.     //
  135.     // compile method bodies
  136.     //
  137.     {
  138.         for (int i = 0; i < class_body -> NumMethods(); i++)
  139.         {
  140.             AstMethodDeclaration *method = class_body -> Method(i);
  141.             if (method -> method_symbol)
  142.             {
  143.                 int method_index = methods.NextIndex(); // index for method
  144.  
  145.                 BeginMethod(method_index, method -> method_symbol);
  146.                 AstBlock *method_block = method -> method_body -> BlockCast();
  147.                 if (method_block) // not an abstract method ?
  148.                     EmitStatement(method_block);
  149.                 EndMethod(method_index, method -> method_symbol);
  150.             }
  151.         }
  152.     }
  153.  
  154.     //
  155.     // NOTE that an abstract class that requires this patch may become out-of-date
  156.     // and cause spurious messages to be emitted if any abstract method inherited
  157.     // from an interface is later removed from that interface.
  158.     //
  159.     if (unit_type -> ACC_ABSTRACT())
  160.     {
  161.         for (int i = 0; i < unit_type -> expanded_method_table -> symbol_pool.Length(); i++)
  162.         {
  163.             MethodShadowSymbol *method_shadow_symbol = unit_type -> expanded_method_table -> symbol_pool[i];
  164.             MethodSymbol *method_symbol = method_shadow_symbol -> method_symbol;
  165.             if (method_symbol -> ACC_ABSTRACT() &&
  166.                 method_symbol -> containing_type != unit_type &&
  167.                 method_symbol -> containing_type -> ACC_INTERFACE())
  168.             {
  169.                 if (! method_symbol -> IsTyped())
  170.                     method_symbol -> ProcessMethodSignature(&this_semantic, class_decl -> identifier_token);
  171.                 method_symbol -> ProcessMethodThrows(&this_semantic, class_decl -> identifier_token);
  172.  
  173.                 int method_index = methods.NextIndex();
  174.  
  175.                 BeginMethod(method_index, method_symbol);
  176.                 EndMethod(method_index, method_symbol);
  177.             }
  178.         }
  179.     }
  180.  
  181.     //
  182.     // compile any private access methods
  183.     //
  184.     {
  185.         for (int i = 0; i < unit_type -> NumPrivateAccessMethods(); i++)
  186.         {
  187.             int method_index = methods.NextIndex(); // index for method
  188.  
  189.             MethodSymbol *method_sym = unit_type -> PrivateAccessMethod(i);
  190.             BeginMethod(method_index, method_sym);
  191.             GenerateAccessMethod(method_sym);
  192.             EndMethod(method_index, method_sym);
  193.         }
  194.     }
  195.  
  196.     //
  197.     //
  198.     //
  199.     MethodSymbol *class_literal_sym = unit_type -> ClassLiteralMethod();
  200.     if (class_literal_sym)
  201.     {
  202.         //
  203.         // Generate the class$ identity method used for class literal-related garbage mumbo-jumbo initialization
  204.         //
  205.         int method_index = methods.NextIndex(); // index for method
  206.         BeginMethod(method_index, class_literal_sym);
  207.         GenerateClassAccessMethod(class_literal_sym);
  208.         EndMethod(method_index, class_literal_sym);
  209.     }
  210.  
  211.     //
  212.     //
  213.     //
  214.     MethodSymbol *block_init_method = unit_type -> block_initializer_method;
  215.     if (block_init_method)
  216.     {
  217.         int method_index = methods.NextIndex(); // index for method
  218.         BeginMethod(method_index, block_init_method);
  219.  
  220.         int fi = 0,
  221.             bi = 0;
  222.         while (fi < initialized_instance_fields.Length() && bi < class_body -> NumBlocks())
  223.         {
  224.             if (initialized_instance_fields[fi] -> LeftToken() < class_body -> Block(bi) -> left_brace_token)
  225.                  InitializeInstanceVariable(initialized_instance_fields[fi++]);
  226.             else EmitStatement(class_body -> Block(bi++));
  227.         }
  228.  
  229.         while (fi < initialized_instance_fields.Length())
  230.             InitializeInstanceVariable(initialized_instance_fields[fi++]);
  231.  
  232.         //
  233.         // compile any initialization blocks
  234.         //
  235.         while (bi < class_body -> NumBlocks())
  236.             EmitStatement(class_body -> Block(bi++));
  237.  
  238.         PutOp(OP_RETURN);
  239.         EndMethod(method_index, block_init_method);
  240.     }
  241.  
  242.     //
  243.     //
  244.     //
  245.     if (unit_type -> NumGeneratedConstructors() == 0)
  246.     {
  247.         if (class_body -> default_constructor)
  248.             CompileConstructor(class_body -> default_constructor, initialized_instance_fields);
  249.         else
  250.         {
  251.             for (int i = 0; i < class_body -> NumConstructors(); i++)
  252.             {
  253.                 AstConstructorDeclaration *constructor = class_body -> Constructor(i);
  254.                 CompileConstructor(constructor, initialized_instance_fields);
  255.             }
  256.  
  257.             for (int k = 0; k < unit_type -> NumPrivateAccessConstructors(); k++)
  258.             {
  259.                 MethodSymbol *constructor_sym = unit_type -> PrivateAccessConstructor(k);
  260.                 AstConstructorDeclaration *constructor =
  261.                        constructor_sym -> method_or_constructor_declaration -> ConstructorDeclarationCast();
  262.                 CompileConstructor(constructor, initialized_instance_fields);
  263.             }
  264.         }
  265.     }
  266.     else
  267.     {
  268.         for (int i = 0; i < unit_type -> NumGeneratedConstructors(); i++)
  269.         {
  270.             MethodSymbol *this_constructor_symbol = unit_type -> GeneratedConstructor(i);
  271.             AstConstructorDeclaration *constructor =
  272.                     this_constructor_symbol -> method_or_constructor_declaration -> ConstructorDeclarationCast();
  273.             AstConstructorBlock *constructor_block = constructor -> constructor_body -> ConstructorBlockCast();
  274.  
  275.             //
  276.             // compile generated constructor
  277.             //
  278.             int method_index = methods.NextIndex(); // index for method
  279.             BeginMethod(method_index, this_constructor_symbol);
  280.  
  281.             assert(constructor_block -> explicit_constructor_invocation_opt);
  282.  
  283.             EmitStatement((AstStatement *) constructor_block -> explicit_constructor_invocation_opt);
  284.  
  285.             for (int si = 0; si < constructor_block -> NumLocalInitStatements(); si++)
  286.                 EmitStatement(constructor_block -> LocalInitStatement(si));
  287.  
  288.             //
  289.             // supply needed field initialization unless constructor
  290.             // starts with explicit 'this' call to another constructor
  291.             //
  292.             if (! (constructor_block -> explicit_constructor_invocation_opt &&
  293.                    constructor_block -> explicit_constructor_invocation_opt -> ThisCallCast()))
  294.             {
  295.                 if (unit_type -> NumEnclosingInstances())
  296.                 {
  297.                     VariableSymbol *this0_parameter = unit_type -> EnclosingInstance(0);
  298.                     PutOp(OP_ALOAD_0); // load address of object on which method is to be invoked
  299.                     LoadLocal(1, this0_parameter -> Type());
  300.                     PutOp(OP_PUTFIELD);
  301.                     PutU2(RegisterFieldref(this0_parameter));
  302.                 }
  303.  
  304.                 if (class_body -> this_block)
  305.                 {
  306.                     AstBlock *block = class_body -> this_block;
  307.                     for (int si = 0; si < block -> NumStatements(); si++)
  308.                         EmitStatement((AstStatement *) block -> Statement(si));
  309.                 }
  310.  
  311.                 if (! unit_type -> block_initializer_method)
  312.                 {
  313.                     int fi = 0,
  314.                         bi = 0;
  315.                     while (fi < initialized_instance_fields.Length() && bi < class_body -> NumBlocks())
  316.                     {
  317.                         if (initialized_instance_fields[fi] -> LeftToken() < class_body -> Block(bi) -> left_brace_token)
  318.                             InitializeInstanceVariable(initialized_instance_fields[fi++]);
  319.                         else
  320.                         {
  321.                             AstBlock *block = class_body -> Block(bi++);
  322.                             for (int si = 0; si < block -> NumStatements(); si++)
  323.                                 EmitStatement((AstStatement *) block -> Statement(si));
  324.                         }
  325.                     }
  326.  
  327.                     while (fi < initialized_instance_fields.Length())
  328.                         InitializeInstanceVariable(initialized_instance_fields[fi++]);
  329.  
  330.                     //
  331.                     // compile any initialization blocks
  332.                     //
  333.                     while (bi < class_body -> NumBlocks())
  334.                     {
  335.                         AstBlock *block = class_body -> Block(bi++);
  336.                         for (int si = 0; si < block -> NumStatements(); si++)
  337.                             EmitStatement((AstStatement *) block -> Statement(si));
  338.                     }
  339.                 }
  340.                 else
  341.                 {
  342.                     //
  343.                     // generate a call to the parameterless function block_initializer_function
  344.                     //
  345.                     PutOp(OP_ALOAD_0); // load address of object on which method is to be invoked
  346.                     PutOp(OP_INVOKENONVIRTUAL);
  347.                     CompleteCall(unit_type -> block_initializer_method, 0);
  348.                 }
  349.             }
  350.  
  351.             EmitStatement(constructor_block -> original_constructor_invocation);
  352.             PutOp(OP_RETURN);
  353.             EndMethod(method_index, this_constructor_symbol);
  354.  
  355.             //
  356.             // compile method associated with generated constructor
  357.             //
  358.             MethodSymbol *local_constructor_symbol = this_constructor_symbol -> LocalConstructor();
  359.             method_index = methods.NextIndex(); // index for method
  360.             BeginMethod(method_index, local_constructor_symbol);  // is constructor
  361.  
  362.             EmitStatement(constructor_block -> block);
  363.  
  364.             EndMethod(method_index, local_constructor_symbol);
  365.         }
  366.     }
  367.  
  368.     //
  369.     // If we need to generate a static initializer...
  370.     //
  371.     if (unit_type -> static_initializer_method)
  372.     {
  373.         assert(class_body -> NumStaticInitializers() > 0 || initialized_static_fields.Length() > 0);
  374.  
  375.         int method_index = methods.NextIndex(); // index for method
  376.         BeginMethod(method_index, unit_type -> static_initializer_method);
  377.  
  378.         //
  379.         // revisit members that are part of class initialization
  380.         //
  381.         int fi = 0,
  382.             bi = 0;
  383.         while (fi < class_body -> NumStaticInitializers() && bi < initialized_static_fields.Length())
  384.         {
  385.             if (class_body -> StaticInitializer(fi) -> static_token < initialized_static_fields[bi] -> LeftToken())
  386.                  EmitStatement(class_body -> StaticInitializer(fi++) -> block);
  387.             else InitializeClassVariable(initialized_static_fields[bi++]);
  388.         }
  389.  
  390.         while (fi < class_body -> NumStaticInitializers())
  391.             EmitStatement(class_body -> StaticInitializer(fi++) -> block);
  392.  
  393.         while (bi < initialized_static_fields.Length())
  394.             InitializeClassVariable(initialized_static_fields[bi++]);
  395.  
  396.         PutOp(OP_RETURN);
  397.         EndMethod(method_index, unit_type -> static_initializer_method);
  398.     }
  399.     else assert(class_body -> NumStaticInitializers() == 0 && initialized_static_fields.Length() == 0);
  400.  
  401.     FinishCode(unit_type);
  402.  
  403.     if (constant_pool.Length() > 65535)
  404.     {
  405.          this_semantic.ReportSemError(SemanticError::CONSTANT_POOL_OVERFLOW,
  406.                                       unit_type -> declaration -> LeftToken(),
  407.                                       unit_type -> declaration -> RightToken(),
  408.                                       unit_type -> ContainingPackage() -> PackageName(),
  409.                                       unit_type -> ExternalName());
  410.     }
  411.  
  412.     if (interfaces.Length() > 65535)
  413.     {
  414.          AstClassDeclaration *class_declaration = unit_type -> declaration -> ClassDeclarationCast();
  415.          AstInterfaceDeclaration *interface_declaration = unit_type -> declaration -> InterfaceDeclarationCast();
  416.          int n = (class_declaration ? class_declaration -> NumInterfaces()
  417.                                     : interface_declaration -> NumInterfaceMemberDeclarations());
  418.          Ast *left = (class_declaration ? (Ast *) class_declaration -> Interface(0)
  419.                                         : interface_declaration -> InterfaceMemberDeclaration(0)),
  420.              *right = (class_declaration ? (Ast *) class_declaration -> Interface(n - 1)
  421.                                          : interface_declaration -> InterfaceMemberDeclaration(n - 1));
  422.  
  423.          this_semantic.ReportSemError(SemanticError::INTERFACES_OVERFLOW,
  424.                                       left -> LeftToken(),
  425.                                       right -> RightToken(),
  426.                                       unit_type -> ContainingPackage() -> PackageName(),
  427.                                       unit_type -> ExternalName());
  428.     }
  429.  
  430.     if (fields.Length() > 65535)
  431.     {
  432.          this_semantic.ReportSemError(SemanticError::FIELDS_OVERFLOW,
  433.                                       unit_type -> declaration -> LeftToken(),
  434.                                       unit_type -> declaration -> RightToken(),
  435.                                       unit_type -> ContainingPackage() -> PackageName(),
  436.                                       unit_type -> ExternalName());
  437.     }
  438.  
  439.     if (methods.Length() > 65535)
  440.     {
  441.          this_semantic.ReportSemError(SemanticError::METHODS_OVERFLOW,
  442.                                       unit_type -> declaration -> LeftToken(),
  443.                                       unit_type -> declaration -> RightToken(),
  444.                                       unit_type -> ContainingPackage() -> PackageName(),
  445.                                       unit_type -> ExternalName());
  446.     }
  447.  
  448.     if (string_overflow)
  449.     {
  450.          this_semantic.ReportSemError(SemanticError::STRING_OVERFLOW,
  451.                                       unit_type -> declaration -> LeftToken(),
  452.                                       unit_type -> declaration -> RightToken(),
  453.                                       unit_type -> ContainingPackage() -> PackageName(),
  454.                                       unit_type -> ExternalName());
  455.     }
  456.  
  457.     if (library_method_not_found)
  458.     {
  459.          this_semantic.ReportSemError(SemanticError::LIBRARY_METHOD_NOT_FOUND,
  460.                                       unit_type -> declaration -> LeftToken(),
  461.                                       unit_type -> declaration -> RightToken(),
  462.                                       unit_type -> ContainingPackage() -> PackageName(),
  463.                                       unit_type -> ExternalName());
  464.     }
  465.  
  466.     if (this_semantic.NumErrors() == 0)
  467.          Write();
  468. #ifdef JIKES_DEBUG
  469.     else if (this_control.option.debug_dump_class)
  470.          PrintCode();
  471. #endif
  472. }
  473.  
  474.  
  475. void ByteCode::CompileInterface()
  476. {
  477.     AstInterfaceDeclaration *interface_decl = unit_type -> declaration -> InterfaceDeclarationCast();
  478.  
  479.     Tuple<AstVariableDeclarator *> initialized_fields(unit_type -> NumVariableSymbols()); // fields needing code to initialize
  480.     {
  481.         for (int i = 0; i < interface_decl -> NumClassVariables(); i++)
  482.         {
  483.             AstFieldDeclaration *field_decl = interface_decl -> ClassVariable(i);
  484.  
  485.             for (int vi = 0; vi < field_decl -> NumVariableDeclarators(); vi++)
  486.             {
  487.                 AstVariableDeclarator *variable_declarator = field_decl -> VariableDeclarator(vi);
  488.                 VariableSymbol *vsym = variable_declarator -> symbol;
  489.  
  490.                 //
  491.                 // We need a static constructor-initializer if we encounter at least one
  492.                 // variable (all variable declared in an interface are implicitly static)
  493.                 // that is declared with an initialization expression that is not a
  494.                 // constant expression.
  495.                 //
  496.                 if (variable_declarator -> variable_initializer_opt)
  497.                 {
  498.                     AstExpression *init = variable_declarator -> variable_initializer_opt -> ExpressionCast();
  499.                     if (! (init && init -> IsConstant()))
  500.                         initialized_fields.Next() = variable_declarator;
  501.                 }
  502.  
  503.                 DeclareField(vsym);
  504.             }
  505.         }
  506.     }
  507.  
  508.     //
  509.     // Process all method members
  510.     //
  511.     {
  512.         for (int i = 0; i < interface_decl -> NumMethods(); i++)
  513.         {
  514.             AstMethodDeclaration *method = interface_decl -> Method(i);
  515.             if (method -> method_symbol)
  516.             {
  517.                 int method_index = methods.NextIndex();
  518.  
  519.                 BeginMethod(method_index, method -> method_symbol);
  520.                 EndMethod(method_index, method -> method_symbol);
  521.             }
  522.         }
  523.     }
  524.  
  525.     //
  526.     // If this interface contained field with initial value
  527.     //
  528.     if (unit_type -> static_initializer_method)
  529.     {
  530.         assert(initialized_fields.Length() > 0);
  531.  
  532.         int method_index = methods.NextIndex(); // index for method
  533.         BeginMethod(method_index, unit_type -> static_initializer_method);
  534.  
  535.         for (int i = 0; i < initialized_fields.Length(); i++)
  536.             InitializeClassVariable(initialized_fields[i]);
  537.  
  538.         PutOp(OP_RETURN);
  539.         EndMethod(method_index, unit_type -> static_initializer_method);
  540.     }
  541.     else assert(initialized_fields.Length() == 0);
  542.  
  543.     FinishCode(unit_type);
  544.  
  545.     if (constant_pool.Length() > 65535)
  546.     {
  547.          this_semantic.ReportSemError(SemanticError::CONSTANT_POOL_OVERFLOW,
  548.                                       unit_type -> declaration -> LeftToken(),
  549.                                       unit_type -> declaration -> RightToken(),
  550.                                       unit_type -> ContainingPackage() -> PackageName(),
  551.                                       unit_type -> ExternalName());
  552.     }
  553.  
  554.     if (this_semantic.NumErrors() == 0)
  555.          Write();
  556. #ifdef JIKES_DEBUG
  557.     else if (this_control.option.debug_dump_class)
  558.          PrintCode();
  559. #endif
  560.  
  561.     return;
  562. }
  563.  
  564.  
  565. //
  566. // initialized_fields is a list of fields needing code to initialize.
  567. //
  568. void ByteCode::CompileConstructor(AstConstructorDeclaration *constructor, Tuple<AstVariableDeclarator *> &initialized_fields)
  569. {
  570.     MethodSymbol *method_symbol = constructor -> constructor_symbol;
  571.     TypeSymbol *type = method_symbol -> containing_type;
  572.     AstClassDeclaration *class_decl = type -> declaration -> ClassDeclarationCast();
  573.     AstClassBody *class_body = (class_decl ? class_decl -> class_body
  574.                                            : ((AstClassInstanceCreationExpression *) type -> declaration) -> class_body_opt);
  575.  
  576.     int method_index = methods.NextIndex(); // index for method
  577.     BeginMethod(method_index, method_symbol);
  578.  
  579.     AstConstructorBlock *constructor_block = constructor -> constructor_body -> ConstructorBlockCast();
  580.     if (constructor_block -> explicit_constructor_invocation_opt)
  581.         EmitStatement((AstStatement *) constructor_block -> explicit_constructor_invocation_opt);
  582.     else
  583.     {
  584.         assert(unit_type == this_control.Object() && "A constructor block without an explicit constructor_invocation");
  585.     }
  586.  
  587.     // supply needed field initialization unless constructor
  588.     // starts with explicit 'this' call to another constructor
  589.     if (! (constructor_block -> explicit_constructor_invocation_opt &&
  590.            constructor_block -> explicit_constructor_invocation_opt -> ThisCallCast()))
  591.     {
  592.         if (type -> NumEnclosingInstances())
  593.         {
  594.             VariableSymbol *this0_parameter = type -> EnclosingInstance(0);
  595.             PutOp(OP_ALOAD_0); // load address of object on which method is to be invoked
  596.             LoadLocal(1, this0_parameter -> Type());
  597.             PutOp(OP_PUTFIELD);
  598.             PutU2(RegisterFieldref(this0_parameter));
  599.         }
  600.  
  601.         if (class_body -> this_block) // compile explicit 'this' call if present
  602.         {
  603.             AstBlock *block = class_body -> this_block;
  604.             for (int si = 0; si < block -> NumStatements(); si++)
  605.                 EmitStatement((AstStatement *) block -> Statement(si));
  606.         }
  607.  
  608.         if (! type -> block_initializer_method)
  609.         {
  610.             int fi = 0,
  611.                 bi = 0;
  612.  
  613.             while (fi < initialized_fields.Length() && bi < class_body -> NumBlocks())
  614.             {
  615.                 if (initialized_fields[fi] -> LeftToken() < class_body -> Block(bi) -> left_brace_token)
  616.                     InitializeInstanceVariable(initialized_fields[fi++]);
  617.                 else
  618.                 {
  619.                     AstBlock *block = class_body -> Block(bi++);
  620.                     for (int si = 0; si < block -> NumStatements(); si++)
  621.                         EmitStatement((AstStatement *) block -> Statement(si));
  622.                 }
  623.             }
  624.  
  625.             while (fi < initialized_fields.Length())
  626.                 InitializeInstanceVariable(initialized_fields[fi++]);
  627.  
  628.             // compile any initialization blocks
  629.             while (bi < class_body -> NumBlocks())
  630.             {
  631.                 AstBlock *block = class_body -> Block(bi++);
  632.                 for (int si = 0; si < block -> NumStatements(); si++)
  633.                     EmitStatement((AstStatement *) block -> Statement(si));
  634.             }
  635.         }
  636.         else // generate a call to the parameterless function block_initializer_function
  637.         {
  638.             PutOp(OP_ALOAD_0); // load address of object on which method is to be invoked
  639.             PutOp(OP_INVOKENONVIRTUAL);
  640.             CompleteCall(type -> block_initializer_method, 0);
  641.         }
  642.     }
  643.  
  644.     EmitStatement(constructor_block -> block);
  645.  
  646.     EndMethod(method_index, method_symbol);
  647.  
  648.     return;
  649. }
  650.  
  651.  
  652. void ByteCode::DeclareField(VariableSymbol *symbol)
  653. {
  654.     int field_index = fields.NextIndex(); // index for field
  655.  
  656.     fields[field_index].SetFlags(symbol -> Flags());
  657.     fields[field_index].SetNameIndex(RegisterUtf8(symbol -> ExternalIdentity() -> Utf8_literal));
  658.     fields[field_index].SetDescriptorIndex(RegisterUtf8(symbol -> Type() -> signature));
  659.  
  660.     AstVariableDeclarator *variable_declarator = symbol -> declarator;
  661.     if (variable_declarator && symbol -> ACC_STATIC()) // a declared static variable (not a generated one!)
  662.     {
  663.         AstExpression *init = (variable_declarator -> variable_initializer_opt
  664.                                                     ? variable_declarator -> variable_initializer_opt -> ExpressionCast()
  665.                                                     : (AstExpression *) NULL);
  666.         LiteralValue *initial_value = (init ? init -> value : (LiteralValue *) NULL);
  667.  
  668.         TypeSymbol *type = symbol -> Type();
  669.         if (initial_value && (type -> Primitive() || (type == this_control.String() && initial_value != this_control.NullValue())))
  670.         {
  671.             //
  672.             // TODO: there seems to be a contradiction between the language spec and the VM spec.
  673.             // The language spec seems to require that a variable be initialized (in the class file)
  674.             // with a "ConstantValue" only if it is static. The VM spec, on the other hand, states
  675.             // that a static need not be final to be initialized with a ConstantValue.
  676.             // As of now, we are following the language spec - ergo, this extra test.
  677.             //
  678.             if (symbol -> ACC_FINAL())
  679.             {
  680.                 u2 index = (this_control.IsSimpleIntegerValueType(type) || type == this_control.boolean_type
  681.                                 ? RegisterInteger((IntLiteralValue *) initial_value)
  682.                                 : type == this_control.String()
  683.                                         ? RegisterString((Utf8LiteralValue *) initial_value)
  684.                                         : type == this_control.float_type
  685.                                                 ? RegisterFloat((FloatLiteralValue *) initial_value)
  686.                                                 : type == this_control.long_type
  687.                                                         ? RegisterLong((LongLiteralValue *) initial_value)
  688.                                                         : RegisterDouble((DoubleLiteralValue *) initial_value));
  689.                 u2 attribute_index = RegisterUtf8(this_control.ConstantValue_literal);
  690.                 fields[field_index].AddAttribute(new ConstantValue_attribute(attribute_index, index));
  691.             }
  692.         }
  693.     }
  694.  
  695.     if (symbol -> IsSynthetic())
  696.         fields[field_index].AddAttribute(CreateSyntheticAttribute());
  697.  
  698.     if (symbol -> IsDeprecated())
  699.         fields[field_index].AddAttribute(CreateDeprecatedAttribute());
  700.  
  701.     return;
  702. }
  703.  
  704.  
  705. //
  706. // Generate code for access method to private member of containing class
  707. //
  708. void ByteCode::GenerateAccessMethod(MethodSymbol *method_symbol)
  709. {
  710.     assert(method_symbol -> ACC_STATIC());
  711.  
  712.     int stack_words = 0,
  713.         argument_offset = 0; // offset to start of argument
  714.  
  715.     //
  716.     // Load the parameters
  717.     //
  718.     for (int i = 0; i < method_symbol -> NumFormalParameters(); i++)
  719.     {
  720.         TypeSymbol *local_type = method_symbol -> FormalParameter(i) -> Type();
  721.         stack_words += GetTypeWords(local_type);
  722.         LoadLocal(argument_offset, local_type);
  723.         argument_offset += GetTypeWords(local_type); // update position in stack
  724.     }
  725.  
  726.     MethodSymbol *method_sym = method_symbol -> accessed_member -> MethodCast();
  727.     if (method_sym)
  728.     {
  729.         PutOp(method_sym -> ACC_STATIC() ? OP_INVOKESTATIC : OP_INVOKENONVIRTUAL);
  730.         CompleteCall(method_sym, stack_words);
  731.     }
  732.     else
  733.     {
  734.         VariableSymbol *field_sym = method_symbol -> accessed_member -> VariableCast();
  735.  
  736.         if (method_symbol -> Type() == this_control.void_type) // writing to a field
  737.         {
  738.             TypeSymbol *parameter_type = method_symbol -> FormalParameter(field_sym -> ACC_STATIC() ? 0 : 1) -> Type();
  739.             PutOp(field_sym -> ACC_STATIC() ? OP_PUTSTATIC : OP_PUTFIELD);
  740.             PutU2(RegisterFieldref(field_sym));
  741.             ChangeStack(this_control.IsDoubleWordType(parameter_type) ? -2 : -1);
  742.         }
  743.         else // reading a field: need method to retrieve value of field
  744.         {
  745.             PutOp(field_sym -> ACC_STATIC() ? OP_GETSTATIC : OP_GETFIELD);
  746.             PutU2(RegisterFieldref(field_sym));
  747.             ChangeStack(this_control.IsDoubleWordType(method_symbol -> Type()) ? 2 : 1);
  748.         }
  749.     }
  750.  
  751.     //
  752.     // Method returns void, generate code for expression-less return statement.
  753.     // Otherwise, call GenerateReturn to generate proper code.
  754.     //
  755.     if (method_symbol -> Type() == this_control.void_type)
  756.          PutOp(OP_RETURN);
  757.     else GenerateReturn(method_symbol -> Type());
  758.  
  759.     //
  760.     // here to emit noop if would otherwise EmitBranch past end
  761.     //
  762.     if (last_label_pc >= code_attribute -> CodeLength())
  763.         PutNop(0);
  764.  
  765.     return;
  766. }
  767.  
  768.  
  769. void ByteCode::BeginMethod(int method_index, MethodSymbol *msym)
  770. {
  771.     assert(msym);
  772.  
  773. #ifdef DUMP
  774. if (this_control.option.g)
  775. {
  776. Coutput << "(51) Generating code for method \"" << msym -> Name()
  777.         << "\" in " << unit_type -> ContainingPackage() -> PackageName() << "/"
  778.         << unit_type -> ExternalName() << "\n";
  779. Coutput.flush();
  780. }
  781. #endif
  782.     MethodInitialization();
  783.  
  784.     methods[method_index].SetNameIndex(RegisterUtf8(msym -> ExternalIdentity() -> Utf8_literal));
  785.     methods[method_index].SetDescriptorIndex(RegisterUtf8(msym -> signature));
  786.     methods[method_index].SetFlags(msym -> Flags());
  787.  
  788.     if (msym -> IsSynthetic())
  789.         methods[method_index].AddAttribute(CreateSyntheticAttribute());
  790.  
  791.     if (msym -> IsDeprecated())
  792.         methods[method_index].AddAttribute(CreateDeprecatedAttribute());
  793.  
  794.     //
  795.     // Generate throws attribute if method throws any exceptions
  796.     //
  797.     if (msym -> NumThrows())
  798.     {
  799.         Exceptions_attribute *exceptions_attribute = new Exceptions_attribute(RegisterUtf8(this_control.Exceptions_literal));
  800.         for (int i = 0; i < msym -> NumThrows(); i++)
  801.             exceptions_attribute -> AddExceptionIndex(RegisterClass(msym -> Throws(i) -> fully_qualified_name));
  802.         methods[method_index].AddAttribute(exceptions_attribute);
  803.     }
  804.  
  805.     //
  806.     // If the method is contained in an interface and it is not a generated static initializer,
  807.     // no further processing ins needed
  808.     //
  809.     if (msym -> containing_type -> ACC_INTERFACE() && msym -> Identity() != this_control.clinit_name_symbol)
  810.         return;
  811.  
  812.     //
  813.     // here if need code and associated attributes.
  814.     //
  815.     if (! (msym -> ACC_ABSTRACT() || msym -> ACC_NATIVE()))
  816.     {
  817.         method_stack = new MethodStack(msym -> max_block_depth, msym -> block_symbol -> max_variable_index);
  818.  
  819.         code_attribute = new Code_attribute(RegisterUtf8(this_control.Code_literal), msym -> block_symbol -> max_variable_index);
  820.  
  821.         line_number = 0;
  822.         line_number_table_attribute = new LineNumberTable_attribute(RegisterUtf8(this_control.LineNumberTable_literal));
  823.  
  824.         local_variable_table_attribute = (this_control.option.g
  825.                                             ? new LocalVariableTable_attribute(RegisterUtf8(this_control.LocalVariableTable_literal))
  826.                                             : (LocalVariableTable_attribute *) NULL);
  827.     }
  828.  
  829.     VariableSymbol *last_parameter = (msym -> NumFormalParameters() ? msym -> FormalParameter(msym -> NumFormalParameters() - 1)
  830.                                                                     : (VariableSymbol *) NULL);
  831.  
  832.     last_parameter_index = (last_parameter ? last_parameter -> LocalVariableIndex() : -1);
  833.  
  834.     int num_parameter_slots = (last_parameter && this_control.IsDoubleWordType(last_parameter -> Type())
  835.                                                ? last_parameter_index + 1
  836.                                                : last_parameter_index);
  837.     if (num_parameter_slots > 255)
  838.     {
  839.         assert(msym -> method_or_constructor_declaration);
  840.  
  841.         AstMethodDeclaration *method_declaration = msym -> method_or_constructor_declaration -> MethodDeclarationCast();
  842.         AstConstructorDeclaration *constructor_declaration = msym -> method_or_constructor_declaration -> ConstructorDeclarationCast();
  843.         AstMethodDeclarator *declarator = (method_declaration ? method_declaration -> method_declarator
  844.                                                               : constructor_declaration -> constructor_declarator);
  845.  
  846.         this_semantic.ReportSemError(SemanticError::PARAMETER_OVERFLOW,
  847.                                      declarator -> left_parenthesis_token,
  848.                                      declarator -> right_parenthesis_token,
  849.                                      msym -> Header(),
  850.                                      unit_type -> ContainingPackage() -> PackageName(),
  851.                                      unit_type -> ExternalName());
  852.     }
  853.  
  854.     return;
  855. }
  856.  
  857.  
  858. void ByteCode::EndMethod(int method_index, MethodSymbol *msym)
  859. {
  860.     assert(msym);
  861.  
  862.     if (! (msym -> ACC_ABSTRACT() || msym -> ACC_NATIVE()))
  863.     {
  864.         //
  865.         // Make sure that no component in the code attribute exceeded its limit.
  866.         //
  867.         if (msym -> block_symbol -> max_variable_index > 65535)
  868.         {
  869.             this_semantic.ReportSemError(SemanticError::LOCAL_VARIABLES_OVERFLOW,
  870.                                          msym -> method_or_constructor_declaration -> LeftToken(),
  871.                                          msym -> method_or_constructor_declaration -> RightToken(),
  872.                                          msym -> Header(),
  873.                                          unit_type -> ContainingPackage() -> PackageName(),
  874.                                          unit_type -> ExternalName());
  875.         }
  876.  
  877.         if (max_stack > 65535)
  878.         {
  879.             this_semantic.ReportSemError(SemanticError::STACK_OVERFLOW,
  880.                                          msym -> method_or_constructor_declaration -> LeftToken(),
  881.                                          msym -> method_or_constructor_declaration -> RightToken(),
  882.                                          msym -> Header(),
  883.                                          unit_type -> ContainingPackage() -> PackageName(),
  884.                                          unit_type -> ExternalName());
  885.         }
  886.  
  887.         if (code_attribute -> CodeLength() > 65535)
  888.         {
  889.             this_semantic.ReportSemError(SemanticError::CODE_OVERFLOW,
  890.                                          msym -> method_or_constructor_declaration -> LeftToken(),
  891.                                          msym -> method_or_constructor_declaration -> RightToken(),
  892.                                          msym -> Header(),
  893.                                          unit_type -> ContainingPackage() -> PackageName(),
  894.                                          unit_type -> ExternalName());
  895.         }
  896.  
  897.         //
  898.         //
  899.         //
  900.         code_attribute -> SetMaxStack(max_stack);
  901.  
  902.         if (last_label_pc >= code_attribute -> CodeLength()) // here to emit noop if would otherwise branch past end
  903.             PutNop(0);
  904.  
  905.         //
  906.         // attribute length:
  907.         // need to review how to make attribute_name and attribute_length
  908.         // only write line number attribute if -O not specified and there
  909.         // are line numbers to write.
  910.         //
  911.         if ((! this_control.option.O) && line_number_table_attribute -> LineNumberTableLength() > 0)
  912.              code_attribute -> AddAttribute(line_number_table_attribute);
  913.         else delete line_number_table_attribute; // line_number_table_attribute not needed, so delete it now
  914.  
  915.         //
  916.         // debug & not dealing with generated accessed method
  917.         //
  918.         if (this_control.option.g && (! msym -> accessed_member) && (msym -> Identity() != this_control.class_name_symbol))
  919.         {
  920.             if (! msym -> ACC_STATIC()) // add 'this' to local variable table
  921.             {
  922.                 local_variable_table_attribute -> AddLocalVariable(0,
  923.                                                                    code_attribute -> CodeLength(),
  924.                                                                    RegisterUtf8(this_control.this_literal),
  925.                                                                    RegisterUtf8(msym -> containing_type -> signature),
  926.                                                                    0);
  927.             }
  928.  
  929.             //
  930.             // For a normal constructor or method.
  931.             //
  932.             for (int i = 0; i < msym -> NumFormalParameters(); i++)
  933.             {
  934.                 VariableSymbol *parameter = msym -> FormalParameter(i);
  935.                 local_variable_table_attribute -> AddLocalVariable(0,
  936.                                                                    code_attribute -> CodeLength(),
  937.                                                                    RegisterUtf8(parameter -> ExternalIdentity() -> Utf8_literal),
  938.                                                                    RegisterUtf8(parameter -> Type() -> signature),
  939.                                                                    parameter -> LocalVariableIndex());
  940.             }
  941.  
  942.             if (local_variable_table_attribute -> LocalVariableTableLength() > 0)
  943.                  code_attribute -> AddAttribute(local_variable_table_attribute);
  944.             else delete local_variable_table_attribute; // local_variable_table_attribute not needed, so delete it now
  945.         } else if (local_variable_table_attribute)// delete if we're dealing w/
  946.       delete local_variable_table_attribute;  // a generated access method.
  947.  
  948.         methods[method_index].AddAttribute(code_attribute);
  949.  
  950.         delete method_stack;
  951.     }
  952.  
  953.     return;
  954. }
  955.  
  956.  
  957. void ByteCode::InitializeClassVariable(AstVariableDeclarator *vd)
  958. {
  959.     assert(vd -> variable_initializer_opt);
  960.  
  961.     AstExpression *expression = vd -> variable_initializer_opt -> ExpressionCast();
  962.     if (expression)
  963.     {
  964.         //
  965.         // TODO: there seems to be a contradiction between the language spec and the VM spec.
  966.         // The language spec seems to require that a variable be initialized (in the class file)
  967.         // with a "ConstantValue" only if it is static. The VM spec, on the other hand, states
  968.         // that a static need not be final to be initialized with a ConstantValue.
  969.         // As of now, we are following the language spec - ergo, this extra test.
  970.         //
  971.         // if (expression -> IsConstant())  // if already initialized
  972.         //
  973.         assert(vd -> symbol);
  974.  
  975.         if (expression -> IsConstant() && vd -> symbol -> ACC_FINAL())  // if already initialized
  976.             return;
  977.         EmitExpression(expression);
  978.     }
  979.     else
  980.     {
  981.         AstArrayInitializer *array_initializer = vd -> variable_initializer_opt -> ArrayInitializerCast();
  982.  
  983.         assert(array_initializer);
  984.  
  985.         InitializeArray(vd -> symbol -> Type(), array_initializer);
  986.     }
  987.  
  988.     PutOp(OP_PUTSTATIC);
  989.     ChangeStack(expression && this_control.IsDoubleWordType(expression -> Type()) ? -2 : -1);
  990.     PutU2(RegisterFieldref(vd -> symbol));
  991.  
  992.     return;
  993. }
  994.  
  995.  
  996. void ByteCode::InitializeInstanceVariable(AstVariableDeclarator *vd)
  997. {
  998.     assert(vd -> variable_initializer_opt); // field needs initialization
  999.  
  1000.     AstExpression *expression = vd -> variable_initializer_opt -> ExpressionCast();
  1001.     if (expression)
  1002.     {
  1003.         PutOp(OP_ALOAD_0); // load 'this'
  1004.         EmitExpression(expression);
  1005.     }
  1006.     else
  1007.     {
  1008.         AstArrayInitializer *array_initializer = vd -> variable_initializer_opt -> ArrayInitializerCast();
  1009.  
  1010.         assert(array_initializer);
  1011.  
  1012.         PutOp(OP_ALOAD_0); // load 'this'
  1013.         InitializeArray(vd -> symbol -> Type(), array_initializer);
  1014.     }
  1015.  
  1016.     PutOp(OP_PUTFIELD);
  1017.     ChangeStack(expression && this_control.IsDoubleWordType(expression -> Type()) ? -2 : -1);
  1018.     PutU2(RegisterFieldref(vd -> symbol));
  1019.  
  1020.     return;
  1021. }
  1022.  
  1023.  
  1024. void ByteCode::InitializeArray(TypeSymbol *type, AstArrayInitializer *array_initializer)
  1025. {
  1026.     TypeSymbol *subtype = type -> ArraySubtype();
  1027.  
  1028.     LoadImmediateInteger(array_initializer -> NumVariableInitializers());
  1029.     EmitNewArray(1, type); // make the array
  1030.     for (int i = 0; i < array_initializer -> NumVariableInitializers(); i++)
  1031.     {
  1032.         Ast *entry = array_initializer -> VariableInitializer(i);
  1033.         PutOp(OP_DUP);
  1034.         LoadImmediateInteger(i);
  1035.         AstExpression *expr = entry -> ExpressionCast();
  1036.         if (expr)
  1037.              EmitExpression(expr);
  1038.         else
  1039.         {
  1040.             assert(entry -> ArrayInitializerCast());
  1041.  
  1042.             InitializeArray(subtype, entry -> ArrayInitializerCast());
  1043.         }
  1044.  
  1045.         StoreArrayElement(subtype);
  1046.     }
  1047.  
  1048.     return;
  1049. }
  1050.  
  1051.  
  1052. //
  1053. // Generate code for local variable declaration.
  1054. //
  1055. void ByteCode::DeclareLocalVariable(AstVariableDeclarator *declarator)
  1056. {
  1057.     if (declarator -> symbol -> initial_value)
  1058.         LoadLiteral(declarator -> symbol -> initial_value, declarator -> symbol -> Type());
  1059.     else if (declarator -> variable_initializer_opt)
  1060.     {
  1061.         AstArrayCreationExpression *ace = declarator -> variable_initializer_opt -> ArrayCreationExpressionCast();
  1062.         if (ace)
  1063.             (void) EmitArrayCreationExpression(ace);
  1064.         else if (declarator -> variable_initializer_opt -> ArrayInitializerCast())
  1065.             InitializeArray(declarator -> symbol -> Type(), declarator -> variable_initializer_opt -> ArrayInitializerCast());
  1066.         else // evaluation as expression
  1067.             EmitExpression(declarator -> variable_initializer_opt -> ExpressionCast());
  1068.     }
  1069.     else return; // if nothing to initialize
  1070.  
  1071.     StoreLocal(declarator -> symbol -> LocalVariableIndex(), declarator -> symbol -> Type());
  1072.  
  1073.     if (this_control.option.g)
  1074.     {
  1075. #ifdef JIKES_DEBUG
  1076.         assert(method_stack -> StartPc(declarator -> symbol) == 0xFFFF); // must be uninitialized
  1077. #endif
  1078. #ifdef DUMP
  1079. Coutput << "(53) Variable \"" << declarator -> symbol -> Name()
  1080.         << "\" numbered " << declarator -> symbol -> LocalVariableIndex()
  1081.         << " was processed\n";
  1082. Coutput.flush();
  1083. #endif
  1084.         method_stack -> StartPc(declarator -> symbol) = code_attribute -> CodeLength();
  1085.     }
  1086.  
  1087.     return;
  1088. }
  1089.  
  1090.  
  1091. //
  1092. // JLS Chapter 13: Blocks and Statements
  1093. //  Statements control the sequence of evaluation of Java programs,
  1094. //  are executed for their effects and do not have values.
  1095. //
  1096. // Processing of loops requires a loop stack, especially to hangle
  1097. // break and continue statements.
  1098. // Loops have three labels, LABEL_BEGIN for start of loop body,
  1099. // LABEL_BREAK to leave the loop, and LABEL_CONTINUE to continue the iteration.
  1100. // Each loop requires a break label; other labels are defined and used
  1101. // as needed.
  1102. // Labels allocated but never used incur no extra cost in the generated
  1103. // byte code, only in additional execution expense during compilation.
  1104. //
  1105. void ByteCode::EmitStatement(AstStatement *statement)
  1106. {
  1107.     if (! statement -> BlockCast())
  1108.     {
  1109.         line_number_table_attribute -> AddLineNumber(code_attribute -> CodeLength(),
  1110.                                                      this_semantic.lex_stream -> Line(statement -> LeftToken()));
  1111.     }
  1112.  
  1113.     if (this_control.option.g)
  1114.     {
  1115.         for (int i = 0; i < statement -> NumDefinedVariables(); i++)
  1116.         {
  1117.             VariableSymbol *variable = statement -> DefinedVariable(i);
  1118. #ifdef JIKES_DEBUG
  1119.             assert(method_stack -> StartPc(variable) == 0xFFFF); // must be uninitialized
  1120. #endif
  1121. #ifdef DUMP
  1122. Coutput << "(55) Variable \"" << variable -> Name()
  1123.         << "\" numbered " << variable -> LocalVariableIndex()
  1124.         << " was processed\n";
  1125. Coutput.flush();
  1126. #endif
  1127.             method_stack -> StartPc(variable) = code_attribute -> CodeLength();
  1128.         }
  1129.     }
  1130.  
  1131.     stack_depth = 0; // stack empty at start of statement
  1132.  
  1133.     switch (statement -> kind)
  1134.     {
  1135.         case Ast::BLOCK: // JLS 14.2
  1136.              EmitBlockStatement((AstBlock *) statement);
  1137.              break;
  1138.         case Ast::LOCAL_VARIABLE_DECLARATION: // JLS 14.3
  1139.              {
  1140.                  AstLocalVariableDeclarationStatement *lvds = statement -> LocalVariableDeclarationStatementCast();
  1141.                  for (int i = 0; i < lvds -> NumVariableDeclarators(); i++)
  1142.                      DeclareLocalVariable(lvds -> VariableDeclarator(i));
  1143.              }
  1144.              break;
  1145.         case Ast::EMPTY_STATEMENT: // JLS 14.5
  1146.              break;
  1147.         case Ast::EXPRESSION_STATEMENT: // JLS 14.7
  1148.              EmitStatementExpression(statement -> ExpressionStatementCast() -> expression);
  1149.              break;
  1150.         case Ast::IF: // JLS 14.8
  1151.              {
  1152.                  AstIfStatement *if_statement = (AstIfStatement *) statement;
  1153.                  if (if_statement -> expression -> IsConstant())
  1154.                  {
  1155.                      IntLiteralValue *if_constant_expr = (IntLiteralValue *) if_statement -> expression -> value;
  1156.  
  1157.                      if (if_constant_expr -> value)
  1158.                           EmitStatement(if_statement -> true_statement);
  1159.                      else if (if_statement -> false_statement_opt) // if there is false part
  1160.                           EmitStatement(if_statement -> false_statement_opt);
  1161.                  }
  1162.                  else if (if_statement -> false_statement_opt) // if true and false parts
  1163.                  {
  1164.                      Label label1,
  1165.                            label2;
  1166.                      EmitBranchIfExpression(if_statement -> expression, false, label1);
  1167.                      stack_depth = 0;
  1168.  
  1169.                      AstStatement *true_statement = if_statement -> true_statement;
  1170.                      EmitStatement(true_statement);
  1171.                      if (true_statement -> can_complete_normally)
  1172.                          EmitBranch(OP_GOTO, label2);
  1173.  
  1174.                      DefineLabel(label1);
  1175.                      EmitStatement(if_statement -> false_statement_opt);
  1176.  
  1177.                      if (true_statement -> can_complete_normally)
  1178.                          DefineLabel(label2);
  1179.  
  1180.                      CompleteLabel(label1);
  1181.                      CompleteLabel(label2);
  1182.                  }
  1183.                  else // if no false part
  1184.                  {
  1185.                      Label label1;
  1186.                      EmitBranchIfExpression(if_statement -> expression, false, label1);
  1187.                      stack_depth = 0;
  1188.                      EmitStatement(if_statement -> true_statement);
  1189.                      DefineLabel(label1);
  1190.                      CompleteLabel(label1);
  1191.                  }
  1192.              }
  1193.              break;
  1194.         case Ast::SWITCH: // JLS 14.9
  1195.              EmitSwitchStatement(statement -> SwitchStatementCast());
  1196.              break;
  1197.         case Ast::SWITCH_BLOCK: // JLS 14.9
  1198.         case Ast::CASE:
  1199.         case Ast::DEFAULT:
  1200.             //
  1201.             // These nodes are handled by SwitchStatement and
  1202.             // are not directly visited
  1203.             //
  1204.             break;
  1205.         case Ast::WHILE: // JLS 14.10
  1206.              {
  1207.                  AstWhileStatement *wp = statement -> WhileStatementCast();
  1208.                  //
  1209.                  // Branch to continuation test. This test is placed after the
  1210.                  // body of the loop we can fall through into it after each
  1211.                  // loop iteration without the need for an additional branch.
  1212.                  //
  1213.                  EmitBranch(OP_GOTO, method_stack -> TopContinueLabel());
  1214.                  Label begin_label;
  1215.                  DefineLabel(begin_label);
  1216.                  EmitStatement(wp -> statement);
  1217.                  DefineLabel(method_stack -> TopContinueLabel());
  1218.                  stack_depth = 0;
  1219.  
  1220.                  //
  1221.                  // Reset the line number before evaluating the expression
  1222.                  //
  1223.                  line_number_table_attribute -> AddLineNumber(code_attribute -> CodeLength(),
  1224.                                                               this_semantic.lex_stream -> Line(wp -> expression -> LeftToken()));
  1225.  
  1226.                  EmitBranchIfExpression(wp -> expression, true, begin_label);
  1227.                  CompleteLabel(begin_label);
  1228.                  CompleteLabel(method_stack -> TopContinueLabel());
  1229.              }
  1230.              break;
  1231.         case Ast::DO: // JLS 14.11
  1232.              {
  1233.                  AstDoStatement *sp = statement -> DoStatementCast();
  1234.                  Label begin_label;
  1235.                  DefineLabel(begin_label);
  1236.                  EmitStatement(sp -> statement);
  1237.                  DefineLabel(method_stack -> TopContinueLabel());
  1238.                  stack_depth = 0;
  1239.  
  1240.                  //
  1241.                  // Reset the line number before evaluating the expression
  1242.                  //
  1243.                  line_number_table_attribute -> AddLineNumber(code_attribute -> CodeLength(),
  1244.                                                               this_semantic.lex_stream -> Line(sp -> expression -> LeftToken()));
  1245.  
  1246.                  EmitBranchIfExpression(sp -> expression, true, begin_label);
  1247.                  CompleteLabel(begin_label);
  1248.                  CompleteLabel(method_stack -> TopContinueLabel());
  1249.              }
  1250.              break;
  1251.         case Ast::FOR: // JLS 14.12
  1252.              {
  1253.                  AstForStatement *for_statement = statement -> ForStatementCast();
  1254.                  for (int i = 0; i < for_statement -> NumForInitStatements(); i++)
  1255.                      EmitStatement(for_statement -> ForInitStatement(i));
  1256.                  Label begin_label,
  1257.                        test_label;
  1258.                  EmitBranch(OP_GOTO, test_label);
  1259.                  DefineLabel(begin_label);
  1260.                  EmitStatement(for_statement -> statement);
  1261.                  DefineLabel(method_stack -> TopContinueLabel());
  1262.                  for (int j = 0; j < for_statement -> NumForUpdateStatements(); j++)
  1263.                      EmitStatement(for_statement -> ForUpdateStatement(j));
  1264.                  DefineLabel(test_label);
  1265.  
  1266.                  AstExpression *end_expr = for_statement -> end_expression_opt;
  1267.                  if (end_expr)
  1268.                  {
  1269.                      stack_depth = 0;
  1270.  
  1271.                      //
  1272.                      // Reset the line number before evaluating the expression
  1273.                      //
  1274.                      line_number_table_attribute -> AddLineNumber(code_attribute -> CodeLength(),
  1275.                                                                   this_semantic.lex_stream -> Line(end_expr -> LeftToken()));
  1276.  
  1277.                      EmitBranchIfExpression(end_expr, true, begin_label);
  1278.                  }
  1279.                  else EmitBranch(OP_GOTO, begin_label);
  1280.  
  1281.                  CompleteLabel(begin_label);
  1282.                  CompleteLabel(test_label);
  1283.                  CompleteLabel(method_stack -> TopContinueLabel());
  1284.              }
  1285.              break;
  1286.         case Ast::BREAK: // JLS 14.13
  1287.              ProcessAbruptExit(statement -> BreakStatementCast() -> nesting_level);
  1288.              EmitBranch(OP_GOTO, method_stack -> BreakLabel(statement -> BreakStatementCast() -> nesting_level));
  1289.              break;
  1290.         case Ast::CONTINUE: // JLS 14.14
  1291.              ProcessAbruptExit(statement -> ContinueStatementCast() -> nesting_level);
  1292.              EmitBranch(OP_GOTO, method_stack -> ContinueLabel(statement -> ContinueStatementCast() -> nesting_level));
  1293.              break;
  1294.         case Ast::RETURN: // JLS 14.15
  1295.              EmitReturnStatement(statement -> ReturnStatementCast());
  1296.              break;
  1297.         case Ast::SUPER_CALL:
  1298.              EmitSuperInvocation((AstSuperCall *) statement);
  1299.              break;
  1300.         case Ast::THIS_CALL:
  1301.              EmitThisInvocation((AstThisCall *) statement);
  1302.              break;
  1303.         case Ast::THROW: // JLS 14.16
  1304.              EmitExpression(statement -> ThrowStatementCast() -> expression);
  1305.              PutOp(OP_ATHROW);
  1306.              break;
  1307.         case Ast::SYNCHRONIZED_STATEMENT: // JLS 14.17
  1308.              EmitSynchronizedStatement(statement -> SynchronizedStatementCast());
  1309.              break;
  1310.         case Ast::TRY: // JLS 14.18
  1311.              EmitTryStatement(statement -> TryStatementCast());
  1312.              break;
  1313.         case Ast::CLASS: // Class Declaration
  1314.         case Ast::INTERFACE: // InterfaceDeclaration
  1315.              //
  1316.              // these are factored out by the front end; and so must be skipped here
  1317.              //
  1318.              break;
  1319.         case Ast::CATCH:   // JLS 14.18
  1320.         case Ast::FINALLY: // JLS 14.18
  1321.              // handled by TryStatement
  1322.         default:
  1323.             assert(false && "unknown statement kind");
  1324.             break;
  1325.     }
  1326.  
  1327.     return;
  1328. }
  1329.  
  1330.  
  1331. void ByteCode::EmitReturnStatement(AstReturnStatement *statement)
  1332. {
  1333.     AstExpression *expression = statement -> expression_opt;
  1334.  
  1335.     if (! expression)
  1336.     {
  1337.         ProcessAbruptExit(method_stack -> NestingLevel(0));
  1338.         PutOp(OP_RETURN);
  1339.     }
  1340.     else
  1341.     {
  1342.         TypeSymbol *type = expression -> Type();
  1343.         assert(type != this_control.void_type);
  1344.  
  1345.         EmitExpression(expression);
  1346.  
  1347.         ProcessAbruptExit(method_stack -> NestingLevel(0), type);
  1348.  
  1349.         GenerateReturn(type);
  1350.     }
  1351.  
  1352.     return;
  1353. }
  1354.  
  1355.  
  1356. void ByteCode::EmitBlockStatement(AstBlock *block)
  1357. {
  1358.     stack_depth = 0; // stack empty at start of statement
  1359.  
  1360.     method_stack -> Push(block);
  1361.  
  1362.     for (int i = 0; i < block -> NumStatements(); i++)
  1363.         EmitStatement((AstStatement *) block -> Statement(i));
  1364.  
  1365.     //
  1366.     // Always define LABEL_BREAK at this point, and complete its definition.
  1367.     //
  1368.     if (IsLabelUsed(method_stack -> TopBreakLabel())) // need define only if used
  1369.         DefineLabel(method_stack -> TopBreakLabel());
  1370.     CompleteLabel(method_stack -> TopBreakLabel());
  1371.  
  1372.     if (this_control.option.g)
  1373.     {
  1374.         for (int i = 0; i < block -> NumLocallyDefinedVariables(); i++)
  1375.         {
  1376.             VariableSymbol *variable = block -> LocallyDefinedVariable(i);
  1377.  
  1378. #ifdef JIKES_DEBUG
  1379.             assert(method_stack -> StartPc(variable) != 0xFFFF);
  1380. #endif
  1381. #ifdef DUMP
  1382. Coutput << "(56) The symbol \"" << variable -> Name()
  1383.         << "\" numbered " << variable -> LocalVariableIndex()
  1384.         << " was released\n";
  1385. Coutput.flush();
  1386. #endif
  1387.             local_variable_table_attribute -> AddLocalVariable(method_stack -> StartPc(variable),
  1388.                                                                code_attribute -> CodeLength(),
  1389.                                                                RegisterUtf8(variable -> ExternalIdentity() -> Utf8_literal),
  1390.                                                                RegisterUtf8(variable -> Type() -> signature),
  1391.                                                                variable -> LocalVariableIndex());
  1392.         }
  1393.     }
  1394.  
  1395.     method_stack -> Pop();
  1396.  
  1397.     return;
  1398. }
  1399.  
  1400.  
  1401. void ByteCode::EmitStatementExpression(AstExpression *expression)
  1402. {
  1403.     switch (expression -> kind)
  1404.     {
  1405.         case Ast::PARENTHESIZED_EXPRESSION:
  1406.              (void) EmitStatementExpression(expression -> ParenthesizedExpressionCast() -> expression);
  1407.              break;
  1408.         case Ast::CALL:
  1409.              {
  1410.                  AstMethodInvocation *method_call = (AstMethodInvocation *) expression;
  1411.                  EmitMethodInvocation(method_call);
  1412.                  if (method_call -> Type() != this_control.void_type)
  1413.                      PutOp(this_control.IsDoubleWordType(method_call -> Type()) ? OP_POP2 : OP_POP); // discard value
  1414.             }
  1415.             break;
  1416.         case Ast::POST_UNARY:
  1417.              (void) EmitPostUnaryExpression((AstPostUnaryExpression *) expression, false);
  1418.              break;
  1419.         case Ast::PRE_UNARY:
  1420.              (void) EmitPreUnaryExpression((AstPreUnaryExpression *) expression, false);
  1421.              break;
  1422.         case Ast::ASSIGNMENT:
  1423.              EmitAssignmentExpression((AstAssignmentExpression *) expression, false);
  1424.              break;
  1425.         case Ast::CLASS_CREATION:
  1426.              (void) EmitClassInstanceCreationExpression((AstClassInstanceCreationExpression *) expression, false);
  1427.              break;
  1428.         default:
  1429.              assert(false && "invalid statement expression kind");
  1430.     }
  1431. }
  1432.  
  1433.  
  1434. //
  1435. // Generate code for switch statement. Good code generation requires
  1436. // detailed knowledge of the target machine. Lacking this, we simply
  1437. // choose between LOOKUPSWITCH and TABLESWITCH by picking that
  1438. // opcode that takes the least number of bytes in the byte code.
  1439. //
  1440. //
  1441. // note that if using table, then must provide slot for every
  1442. // entry in the range low..high, even though the user may not
  1443. // have provided an explicit entry, in which case the default
  1444. // action is to be taken. For example
  1445. // switch (e) {
  1446. //  case 1:2:3: act1; break;
  1447. //  case 5:6:   act2; break;
  1448. //  default: defact; break;
  1449. // }
  1450. // translated as
  1451. // switch (e)
  1452. // switch (e) {
  1453. //  case 1:2:3: act1; break;
  1454. //  case 4: goto defa:
  1455. //  case 5:6:   act2; break;
  1456. //  defa:
  1457. //  default: defact;
  1458. // }
  1459. //
  1460. void ByteCode::EmitSwitchStatement(AstSwitchStatement *switch_statement)
  1461. {
  1462.     AstBlock *switch_block = switch_statement -> switch_block;
  1463.  
  1464.     stack_depth = 0; // stack empty at start of statement
  1465.  
  1466.     //
  1467.     // Use tableswitch if have exact match or size of tableswitch
  1468.     // case is no more than 30 bytes more code than lookup case
  1469.     //
  1470.     bool use_lookup = true; // set if using LOOKUPSWITCH opcode
  1471.     int ncases = switch_statement -> NumCases(),
  1472.         nlabels = ncases,
  1473.         high = 0,
  1474.         low = 0;
  1475.     if (ncases > 0)
  1476.     {
  1477.         low = switch_statement -> Case(0) -> Value();
  1478.         high = switch_statement -> Case(ncases - 1) -> Value();
  1479.  
  1480.         //
  1481.         // want to compute
  1482.         //  (2 + high-low + 1) < (1 + ncases * 2 + 30)
  1483.         // but must guard against overflow, so factor out
  1484.         //  high - low < ncases * 2 + 28
  1485.         // but can't have number of labels < number of cases
  1486.         //
  1487.         LongInt range = LongInt(high) - low + 1;
  1488.         if (range < (ncases * 2 + 28))
  1489.         {
  1490.             use_lookup = false; // use tableswitch
  1491.             nlabels = range.LowWord();
  1492.  
  1493.             assert(range.HighWord() == 0);
  1494.             assert(nlabels >= ncases);
  1495.         }
  1496.     }
  1497.  
  1498.     //
  1499.     // Reset the line number before evaluating the expression
  1500.     //
  1501.     line_number_table_attribute -> AddLineNumber(code_attribute -> CodeLength(),
  1502.                                                  this_semantic.lex_stream -> Line(switch_statement -> expression -> LeftToken()));
  1503.     EmitExpression(switch_statement -> expression);
  1504.  
  1505.     stack_depth = 0;
  1506.     PutOp(use_lookup ? OP_LOOKUPSWITCH : OP_TABLESWITCH);
  1507.     int op_start = last_op_pc; // pc at start of instruction
  1508.  
  1509.     //
  1510.     // supply any needed padding
  1511.     //
  1512.     while(code_attribute -> CodeLength() % 4 != 0)
  1513.         PutNop(0);
  1514.  
  1515.     //
  1516.     // Set up the environment for the switch block.
  1517.     //
  1518.     method_stack -> Push(switch_block);
  1519.  
  1520.     //
  1521.     // Note that if no default clause in switch statement, must allocate
  1522.     // one that corresponds to do nothing and branches to start of next
  1523.     // statement.
  1524.     //
  1525.     Label *case_labels = new Label[(use_lookup ? ncases : nlabels) + 1],
  1526.           default_label;
  1527.     UseLabel(switch_statement -> default_case.switch_block_statement ? default_label : method_stack -> TopBreakLabel(),
  1528.              4,
  1529.              code_attribute -> CodeLength() - op_start);
  1530.  
  1531.     //
  1532.     //
  1533.     //
  1534.     if (use_lookup)
  1535.     {
  1536.         PutU4(ncases);
  1537.  
  1538.         for (int i = 0; i < ncases; i++)
  1539.         {
  1540.             PutU4(switch_statement -> Case(i) -> Value());
  1541.             UseLabel(case_labels[switch_statement -> Case(i) -> index], 4, code_attribute -> CodeLength() - op_start);
  1542.         }
  1543.     }
  1544.     else
  1545.     {
  1546.         bool *has_tag = new bool[nlabels + 1];
  1547.  
  1548.         for (int i = 0; i < nlabels; i++)
  1549.             has_tag[i] = false;
  1550.  
  1551.         PutU4(low);
  1552.         PutU4(high);
  1553.  
  1554.         //
  1555.         // mark cases for which no case tag available, i.e., default cases
  1556.         //
  1557.         for (int j = 0; j < switch_block -> NumStatements(); j++)
  1558.         {
  1559.             AstSwitchBlockStatement *switch_block_statement = (AstSwitchBlockStatement *) switch_block -> Statement(j);
  1560.  
  1561.             //
  1562.             // process labels for this block
  1563.             //
  1564.             for (int li = 0; li < switch_block_statement -> NumSwitchLabels(); li++)
  1565.             {
  1566.                 AstCaseLabel *case_label = switch_block_statement -> SwitchLabel(li) -> CaseLabelCast();
  1567.                 if (case_label)
  1568.                 {
  1569.                     int label_index = switch_statement -> Case(case_label -> map_index) -> Value() - low;
  1570.                     has_tag[label_index] = true;
  1571.                 }
  1572.             }
  1573.         }
  1574.  
  1575.         //
  1576.         // Now emit labels in instruction, using appropriate index
  1577.         //
  1578.         for (int k = 0; k < nlabels; k++)
  1579.         {
  1580.             UseLabel(has_tag[k] ? case_labels[k]
  1581.                                 : switch_statement -> default_case.switch_block_statement
  1582.                                        ? default_label
  1583.                                        : method_stack -> TopBreakLabel(),
  1584.                      4,
  1585.                      code_attribute -> CodeLength() - op_start);
  1586.         }
  1587.  
  1588.         delete [] has_tag;
  1589.     }
  1590.  
  1591.     //
  1592.     // march through switch block statements, compiling blocks in
  1593.     // proper order. We must respect order in which blocks seen
  1594.     // so that blocks lacking a terminal break fall through to the
  1595.     // proper place.
  1596.     //
  1597.     for (int i = 0; i < switch_block -> NumStatements(); i++)
  1598.     {
  1599.         AstSwitchBlockStatement *switch_block_statement = (AstSwitchBlockStatement *) switch_block -> Statement(i);
  1600.  
  1601.         //
  1602.         // process labels for this block
  1603.         //
  1604.         for (int li = 0; li < switch_block_statement -> NumSwitchLabels(); li++)
  1605.         {
  1606.             AstCaseLabel *case_label = switch_block_statement -> SwitchLabel(li) -> CaseLabelCast();
  1607.             if (case_label)
  1608.             {
  1609.                 int map_index = case_label -> map_index;
  1610.  
  1611.                 if (use_lookup)
  1612.                     DefineLabel(case_labels[map_index]);
  1613.                 else
  1614.                 {
  1615.                     //
  1616.                     // TODO: Do this more efficiently ??? !!!
  1617.                     //
  1618.                     for (int di = 0; di < switch_statement -> NumCases(); di++)
  1619.                     {
  1620.                         if (switch_statement -> Case(di) -> index == map_index)
  1621.                         {
  1622.                             int ci = switch_statement -> Case(di) -> Value() - low;
  1623.                             DefineLabel(case_labels[ci]);
  1624.                             break;
  1625.                         }
  1626.                     }
  1627.                 }
  1628.             }
  1629.             else
  1630.             {
  1631.                 assert(switch_block_statement -> SwitchLabel(li) -> DefaultLabelCast());
  1632.                 assert(switch_statement -> default_case.switch_block_statement);
  1633.  
  1634.                 DefineLabel(default_label);
  1635.             }
  1636.         }
  1637.  
  1638.         //
  1639.         // compile code for this case
  1640.         //
  1641.         for (int si = 0; si < switch_block_statement -> NumStatements(); si++)
  1642.             EmitStatement(switch_block_statement -> Statement(si) -> StatementCast());
  1643.  
  1644.         //
  1645.         // If this switch block statement does not terminate normally,
  1646.         // close the range of the locally defined variables here and
  1647.         // reset their StartPc
  1648.         //
  1649.         if (this_control.option.g)
  1650.         {
  1651.             for (int i = 0; i < switch_block_statement -> NumLocallyDefinedVariables(); i++)
  1652.             {
  1653.                 VariableSymbol *variable = switch_block_statement -> LocallyDefinedVariable(i);
  1654.  
  1655. #ifdef JIKES_DEBUG
  1656.                 assert(method_stack -> StartPc(variable) != 0xFFFF);
  1657. #endif
  1658. #ifdef DUMP
  1659. Coutput << "(57) The symbol \"" << variable -> Name()
  1660.         << "\" numbered " << variable -> LocalVariableIndex()
  1661.         << " was released\n";
  1662. Coutput.flush();
  1663. #endif
  1664.                 local_variable_table_attribute -> AddLocalVariable(method_stack -> StartPc(variable),
  1665.                                                                    code_attribute -> CodeLength(),
  1666.                                                                    RegisterUtf8(variable -> ExternalIdentity() -> Utf8_literal),
  1667.                                                                    RegisterUtf8(variable -> Type() -> signature),
  1668.                                                                    variable -> LocalVariableIndex());
  1669. #ifdef JIKES_DEBUG
  1670.                 method_stack -> StartPc(variable) = 0xFFFF;
  1671. #endif
  1672.             }
  1673.         }
  1674.     }
  1675.  
  1676.     //
  1677.     // If the last statement in the switch block terminates normally,
  1678.     // close the range of the locally defined variables that have
  1679.     // been defined but not yet processsed.
  1680.     //
  1681.     if (this_control.option.g)
  1682.     {
  1683.         for (int i = 0; i < switch_block -> NumLocallyDefinedVariables(); i++)
  1684.         {
  1685.             VariableSymbol *variable = switch_block -> LocallyDefinedVariable(i);
  1686.  
  1687. #ifdef JIKES_DEBUG
  1688.             assert(method_stack -> StartPc(variable) != 0xFFFF);
  1689. #endif
  1690. #ifdef DUMP
  1691. Coutput << "(58) The symbol \"" << variable -> Name()
  1692.         << "\" numbered " << variable -> LocalVariableIndex()
  1693.         << " was released\n";
  1694. Coutput.flush();
  1695. #endif
  1696.             local_variable_table_attribute -> AddLocalVariable(method_stack -> StartPc(variable),
  1697.                                                                code_attribute -> CodeLength(),
  1698.                                                                RegisterUtf8(variable -> ExternalIdentity() -> Utf8_literal),
  1699.                                                                RegisterUtf8(variable -> Type() -> signature),
  1700.                                                                variable -> LocalVariableIndex());
  1701.         }
  1702.     }
  1703.  
  1704.     //
  1705.     //
  1706.     //
  1707.     for (int j = 0; j < nlabels; j++)
  1708.     {
  1709.         if ((case_labels[j].uses.Length() > 0) && (! case_labels[j].defined))
  1710.         {
  1711.             case_labels[j].defined = true;
  1712.             case_labels[j].definition = (switch_statement -> default_case.switch_block_statement
  1713.                                                            ? default_label.definition
  1714.                                                            : method_stack -> TopBreakLabel().definition);
  1715.         }
  1716.  
  1717.         CompleteLabel(case_labels[j]);
  1718.     }
  1719.  
  1720.     //
  1721.     // If the switch statement contains a default case, we clean up
  1722.     // the default label here.
  1723.     //
  1724.     if (switch_statement -> default_case.switch_block_statement)
  1725.         CompleteLabel(default_label);
  1726.  
  1727.     //
  1728.     // If this switch statement can be "broken", we define the break label here.
  1729.     //
  1730.     if (IsLabelUsed(method_stack -> TopBreakLabel())) // need define only if used
  1731.     {
  1732.         DefineLabel(method_stack -> TopBreakLabel());
  1733.         CompleteLabel(method_stack -> TopBreakLabel());
  1734.     }
  1735.  
  1736.     delete [] case_labels;
  1737.  
  1738.     method_stack -> Pop();
  1739.  
  1740.     return;
  1741. }
  1742.  
  1743.  
  1744. //
  1745. //  13.18       The try statement
  1746. //
  1747. void ByteCode::EmitTryStatement(AstTryStatement *statement)
  1748. {
  1749.     //
  1750.     // If the finally label in the surrounding block is used by a try statement,
  1751.     // it is cleared after the finally block associated with the try statement
  1752.     // has been processed.
  1753.     //
  1754.     assert(method_stack -> TopFinallyLabel().uses.Length() == 0);
  1755.     assert(method_stack -> TopFinallyLabel().defined == false);
  1756.     assert(method_stack -> TopFinallyLabel().definition == 0);
  1757.  
  1758.     int start_try_block_pc = code_attribute -> CodeLength(); // start pc
  1759.  
  1760.     EmitBlockStatement(statement -> block);
  1761.  
  1762.     //
  1763.     // increment max_stack in case exception thrown while stack at greatest depth
  1764.     //
  1765.     max_stack++;
  1766.  
  1767.     //
  1768.     // The computation of end_try_block_pc, the instruction following the last instruction in the
  1769.     // body of the try block, does not include the code, if any, needed to call a finally block or
  1770.     // skip to the end of the try statement.
  1771.     //
  1772.     int end_try_block_pc = code_attribute -> CodeLength(),
  1773.         special_end_pc = end_try_block_pc; // end_pc for "special" handler
  1774.  
  1775.     Label &finally_label = method_stack -> TopFinallyLabel(), // use the label in the block immediately enclosing try statement.
  1776.           end_label;
  1777.     if (statement -> block -> can_complete_normally)
  1778.     {
  1779.         if (statement -> finally_clause_opt)
  1780.         {
  1781.             //
  1782.             // Call finally block if have finally handler.
  1783.             //
  1784.             PutOp(OP_JSR);
  1785.             UseLabel(finally_label, 2, 1);
  1786.         }
  1787.  
  1788.         EmitBranch(OP_GOTO, end_label);
  1789.     }
  1790.  
  1791.     //
  1792.     // Process catch clauses, but only if try block is not empty.
  1793.     //
  1794.     if (start_try_block_pc != end_try_block_pc)
  1795.     {
  1796.         for (int i = 0; i < statement -> NumCatchClauses(); i++)
  1797.         {
  1798.             int handler_pc = code_attribute -> CodeLength();
  1799.  
  1800.             AstCatchClause *catch_clause = statement -> CatchClause(i);
  1801.             VariableSymbol *parameter_symbol = catch_clause -> parameter_symbol;
  1802.  
  1803.             StoreLocal(parameter_symbol -> LocalVariableIndex(), parameter_symbol -> Type());
  1804.  
  1805.             EmitBlockStatement(catch_clause -> block);
  1806.  
  1807.             if (this_control.option.g)
  1808.             {
  1809.                 local_variable_table_attribute -> AddLocalVariable(handler_pc,
  1810.                                                                    code_attribute -> CodeLength(),
  1811.                                                                    RegisterUtf8(parameter_symbol -> ExternalIdentity() -> Utf8_literal),
  1812.                                                                    RegisterUtf8(parameter_symbol -> Type() -> signature),
  1813.                                                                    parameter_symbol -> LocalVariableIndex());
  1814.             }
  1815.  
  1816.             code_attribute -> AddException(start_try_block_pc,
  1817.                                            end_try_block_pc,
  1818.                                            handler_pc,
  1819.                                            RegisterClass(parameter_symbol -> Type() -> fully_qualified_name));
  1820.  
  1821.             special_end_pc = code_attribute -> CodeLength();
  1822.  
  1823.             if (catch_clause -> block -> can_complete_normally)
  1824.             {
  1825.                 if (statement -> finally_clause_opt)
  1826.                 {
  1827.                     //
  1828.                     // Call finally block if have finally handler.
  1829.                     //
  1830.                     PutOp(OP_JSR);
  1831.                     UseLabel(finally_label, 2, 1);
  1832.                 }
  1833.  
  1834.                 //
  1835.                 // If there are more catch clauses, or a finally clause, then emit branch to
  1836.                 // skip over their code and on to the next statement.
  1837.                 //
  1838.                 if (statement -> finally_clause_opt || i < (statement -> NumCatchClauses() - 1))
  1839.                     EmitBranch(OP_GOTO, end_label);
  1840.             }
  1841.         }
  1842.     }
  1843.  
  1844.     //
  1845.     // If this try statement contains a finally clause, then ...
  1846.     //
  1847.     if (statement -> finally_clause_opt)
  1848.     {
  1849.         int variable_index = method_stack -> TopBlock() -> block_symbol -> try_or_synchronized_variable_index;
  1850.  
  1851.         //
  1852.         // Emit code for "special" handler to make sure finally clause is
  1853.         // invoked in case an otherwise uncaught exception is thrown in the
  1854.         // try block, or an exception is thrown from within a catch block.
  1855.         //
  1856.         // No special handler is needed if the try block is empty.
  1857.         if (start_try_block_pc != end_try_block_pc) // If try-block not empty
  1858.         {
  1859.             code_attribute -> AddException(start_try_block_pc,
  1860.                                            special_end_pc,
  1861.                                            code_attribute -> CodeLength(),
  1862.                                            0);
  1863.             StoreLocal(variable_index, this_control.Object()); // Save exception
  1864.             PutOp(OP_JSR); // Jump to finally block.
  1865.             UseLabel(finally_label, 2, 1);
  1866.             LoadLocal(variable_index, this_control.Object()); // Reload exception,
  1867.             PutOp(OP_ATHROW); // and rethrow it.
  1868.         }
  1869.  
  1870.         //
  1871.         // Generate code for finally clause.
  1872.         //
  1873.         DefineLabel(finally_label);
  1874.         CompleteLabel(finally_label);
  1875.  
  1876.         //
  1877.         // If the finally block can complete normally, save the return address.
  1878.         // Otherwise, we pop the return address from the stack.
  1879.         //
  1880.         if (statement -> finally_clause_opt -> block -> can_complete_normally)
  1881.              StoreLocal(variable_index + 1, this_control.Object());
  1882.         else PutOp(OP_POP);
  1883.  
  1884.         EmitBlockStatement(statement -> finally_clause_opt -> block);
  1885.  
  1886.         //
  1887.         // If a finally block can complete normally, after executing itsbody, we return
  1888.         // to the caller using the return address saved earlier.
  1889.         //
  1890.         if (statement -> finally_clause_opt -> block -> can_complete_normally)
  1891.             PutOpWide(OP_RET, variable_index + 1);
  1892.     }
  1893.  
  1894.     if (IsLabelUsed(end_label))
  1895.         DefineLabel(end_label);
  1896.     CompleteLabel(end_label);
  1897.  
  1898.     return;
  1899. }
  1900.  
  1901.  
  1902. //
  1903. // Exit to block at level lev, freeing monitor locks and invoking finally clauses as appropriate
  1904. //
  1905. void ByteCode::ProcessAbruptExit(int to_lev, TypeSymbol *return_type)
  1906. {
  1907.     for (int i = method_stack -> Size() - 1; i > 0 && method_stack -> NestingLevel(i) != to_lev; i--)
  1908.     {
  1909.         int nesting_level = method_stack -> NestingLevel(i),
  1910.             enclosing_level = method_stack -> NestingLevel(i - 1);
  1911.         AstBlock *block = method_stack -> Block(nesting_level);
  1912.         if (block -> block_tag == AstBlock::TRY_CLAUSE_WITH_FINALLY)
  1913.         {
  1914.             if (return_type)
  1915.             {
  1916.                 Label &finally_label = method_stack -> FinallyLabel(enclosing_level);
  1917.                 int variable_index = method_stack -> Block(enclosing_level) -> block_symbol -> try_or_synchronized_variable_index + 2;
  1918.  
  1919.                 StoreLocal(variable_index, return_type);
  1920.  
  1921.                 PutOp(OP_JSR);
  1922.                 UseLabel(finally_label, 2, 1);
  1923.  
  1924.                 LoadLocal(variable_index, return_type);
  1925.             }
  1926.             else
  1927.             {
  1928.                 PutOp(OP_JSR);
  1929.                 UseLabel(method_stack -> FinallyLabel(enclosing_level), 2, 1);
  1930.             }
  1931.         }
  1932.         else if (block -> block_tag == AstBlock::SYNCHRONIZED)
  1933.         {
  1934.             if (return_type)
  1935.             {
  1936.                 Label &monitor_label = method_stack -> MonitorLabel(enclosing_level);
  1937.                 int variable_index = method_stack -> Block(enclosing_level) -> block_symbol -> try_or_synchronized_variable_index + 2;
  1938.  
  1939.                 StoreLocal(variable_index, return_type);
  1940.  
  1941.                 PutOp(OP_JSR);
  1942.                 UseLabel(monitor_label, 2, 1);
  1943.  
  1944.                 LoadLocal(variable_index, return_type);
  1945.             }
  1946.             else
  1947.             {
  1948.                 PutOp(OP_JSR);
  1949.                 UseLabel(method_stack -> MonitorLabel(enclosing_level), 2, 1);
  1950.             }
  1951.         }
  1952.     }
  1953.  
  1954.     return;
  1955. }
  1956.  
  1957.  
  1958. //
  1959. // java provides a variety of conditional branch instructions, so
  1960. // that a number of operators merit special handling:
  1961. //      constant operand
  1962. //      negation (we eliminate it)
  1963. //      equality
  1964. //      && and || (partial evaluation)
  1965. //      comparisons
  1966. // Other expressions are just evaluated and the appropriate
  1967. // branch emitted.
  1968. //
  1969. void ByteCode::EmitBranchIfExpression(AstExpression *p, bool cond, Label &lab)
  1970. {
  1971.     if (p -> ParenthesizedExpressionCast())
  1972.         p = UnParenthesize(p);
  1973.  
  1974.     if (p -> IsConstant())
  1975.     {
  1976.         if (IsZero(p) != cond)
  1977.             EmitBranch(OP_GOTO, lab);
  1978.         return;
  1979.     }
  1980.  
  1981.     AstPreUnaryExpression *pre = p -> PreUnaryExpressionCast();
  1982.     if (pre) // must be !, though should probably
  1983.     {
  1984.         // branch_if(!e,c,l) => branch_if(e,!c,l)
  1985.         // test opcode
  1986.         // call again with complementary control expression to show
  1987.         // effect of negation
  1988.         assert(pre -> pre_unary_tag == AstPreUnaryExpression::NOT);
  1989.  
  1990.         EmitBranchIfExpression(pre -> expression, (! cond), lab);
  1991.         return;
  1992.     }
  1993.  
  1994.     //
  1995.     // dispose of non-binary expression case by just evaluating
  1996.     // operand and emitting appropiate test.
  1997.     //
  1998.     AstBinaryExpression *bp = p -> BinaryExpressionCast();
  1999.     if (! bp)
  2000.     {
  2001.         EmitExpression(p);
  2002.         EmitBranch((cond ? OP_IFNE : OP_IFEQ), lab);
  2003.         return;
  2004.     }
  2005.  
  2006.     //
  2007.     // Here if binary expression, so extract operands
  2008.     //
  2009.     AstExpression *left = bp -> left_expression;
  2010.     if (left -> ParenthesizedExpressionCast())
  2011.         left = UnParenthesize(left);
  2012.  
  2013.     AstExpression *right = bp -> right_expression;
  2014.     if (right -> ParenthesizedExpressionCast())
  2015.         right = UnParenthesize(right);
  2016.  
  2017.     TypeSymbol *left_type = left -> Type(),
  2018.                *right_type = right -> Type();
  2019.     switch (bp -> binary_tag)
  2020.     {
  2021.         case AstBinaryExpression::INSTANCEOF:
  2022.              {
  2023.                  EmitExpression(left);
  2024.                  PutOp(OP_INSTANCEOF);
  2025.                  TypeSymbol *instanceof_type = bp -> right_expression -> Type();
  2026.                  PutU2(instanceof_type -> num_dimensions > 0 ? RegisterClass(instanceof_type -> signature)
  2027.                                                              : RegisterClass(instanceof_type -> fully_qualified_name));
  2028.  
  2029.                  EmitBranch((cond ? OP_IFNE : OP_IFEQ), lab);
  2030.              }
  2031.              return;
  2032.         case AstBinaryExpression::AND_AND:
  2033.              //
  2034.              // branch_if(a&&b, true, lab) =>
  2035.              // branch_if(a,false,skip);
  2036.              // branch_if(b,true,lab);
  2037.              // skip:
  2038.              // branch_if(a&&b, false, lab) =>
  2039.              // branch_if(a,false,lab);
  2040.              // branch_if(b,false,lab);
  2041.              //
  2042.              if (cond)
  2043.              {
  2044.                  Label skip;
  2045.                  EmitBranchIfExpression(left, false, skip);
  2046.                  EmitBranchIfExpression(right, true, lab);
  2047.                  DefineLabel(skip);
  2048.                  CompleteLabel(skip);
  2049.              }
  2050.              else
  2051.              {
  2052.                  EmitBranchIfExpression(left, false, lab);
  2053.                  EmitBranchIfExpression(right, false, lab);
  2054.              }
  2055.              return;
  2056.         case AstBinaryExpression::OR_OR:
  2057.              //
  2058.              // branch_if(a||b,true,lab) =>
  2059.              // branch_if(a,true,lab);
  2060.              // branch_if(b,true,lab);
  2061.              // branch_if(a||b,false,lab) =>
  2062.              // branch_if(a,true,skip);
  2063.              // branch_if(b,false,lab);
  2064.              // There is additional possibility of one of the operands being
  2065.              // constant that should be dealt with at some point.
  2066.              //
  2067.              if (cond)
  2068.              {
  2069.                  EmitBranchIfExpression(left, true, lab);
  2070.                  EmitBranchIfExpression(right, true, lab);
  2071.              }
  2072.              else
  2073.              {
  2074.                  Label skip;
  2075.                  EmitBranchIfExpression(left, true, skip);
  2076.                  EmitBranchIfExpression(right, false, lab);
  2077.                  DefineLabel(skip);
  2078.                  CompleteLabel(skip);
  2079.              }
  2080.              return;
  2081.         case AstBinaryExpression::EQUAL_EQUAL:
  2082.         case AstBinaryExpression::NOT_EQUAL:
  2083.              //
  2084.              // One of the operands is null.
  2085.              //
  2086.              if (left_type == this_control.null_type || right_type == this_control.null_type)
  2087.              {
  2088.                  if (left_type == this_control.null_type)  // arrange so right operand is null
  2089.                  {
  2090.                      AstExpression *temp = left;
  2091.                      left = right;
  2092.                      right = temp;
  2093.  
  2094.                      left_type = left -> Type();
  2095.                      right_type = right -> Type();
  2096.                  }
  2097.  
  2098.                  EmitExpression(left);
  2099.  
  2100.                  if (bp -> binary_tag == AstBinaryExpression::EQUAL_EQUAL)
  2101.                       EmitBranch(cond ? OP_IFNULL : OP_IFNONNULL, lab);
  2102.                  else EmitBranch(cond ? OP_IFNONNULL : OP_IFNULL, lab);
  2103.  
  2104.                  return;
  2105.              }
  2106.  
  2107.              //
  2108.              // One of the operands is zero.
  2109.              //
  2110.              if (IsZero(left) || IsZero(right))
  2111.              {
  2112.                  if (IsZero(left)) // arrange so right operand is zero
  2113.                  {
  2114.                      AstExpression *temp = left;
  2115.                      left = right;
  2116.                      right = temp;
  2117.  
  2118.                      left_type = left -> Type();
  2119.                      right_type = right -> Type();
  2120.                  }
  2121.  
  2122.                  EmitExpression(left);
  2123.  
  2124.                  if (bp -> binary_tag == AstBinaryExpression::EQUAL_EQUAL)
  2125.                       EmitBranch((cond ? OP_IFEQ : OP_IFNE), lab);
  2126.                  else EmitBranch((cond ? OP_IFNE : OP_IFEQ), lab);
  2127.  
  2128.                  return;
  2129.              }
  2130.  
  2131.              //
  2132.              // both operands are integer
  2133.              //
  2134.              if ((this_control.IsSimpleIntegerValueType(left_type)  || left_type == this_control.boolean_type) &&
  2135.                  (this_control.IsSimpleIntegerValueType(right_type) || right_type == this_control.boolean_type))
  2136.              {
  2137.                  EmitExpression(left);
  2138.                  EmitExpression(right);
  2139.  
  2140.                  if (bp -> binary_tag == AstBinaryExpression::EQUAL_EQUAL)
  2141.                       EmitBranch((cond ? OP_IF_ICMPEQ : OP_IF_ICMPNE), lab);
  2142.                  else EmitBranch((cond ? OP_IF_ICMPNE : OP_IF_ICMPEQ), lab);
  2143.  
  2144.                  return;
  2145.              }
  2146.  
  2147.              //
  2148.              // Both operands are reference types: just do the comparison
  2149.              //
  2150.              if (IsReferenceType(left_type) && IsReferenceType(right_type))
  2151.              {
  2152.                  EmitExpression(left);
  2153.                  EmitExpression(right);
  2154.  
  2155.                  if (bp -> binary_tag == AstBinaryExpression::EQUAL_EQUAL)
  2156.                       EmitBranch((cond ? OP_IF_ACMPEQ : OP_IF_ACMPNE), lab);
  2157.                  else EmitBranch((cond ? OP_IF_ACMPNE : OP_IF_ACMPEQ), lab);
  2158.  
  2159.                  return;
  2160.              }
  2161.  
  2162.              break;
  2163.  
  2164.         default:
  2165.              break;
  2166.     }
  2167.  
  2168.     //
  2169.     // here if not comparison, comparison for non-integral numeric types, or
  2170.     // integral comparison for which no special casing needed.
  2171.     // Begin by dealing with non-comparisons
  2172.     //
  2173.     switch(bp -> binary_tag)
  2174.     {
  2175.         case AstBinaryExpression::LESS:
  2176.         case AstBinaryExpression::LESS_EQUAL:
  2177.         case AstBinaryExpression::GREATER:
  2178.         case AstBinaryExpression::GREATER_EQUAL:
  2179.         case AstBinaryExpression::EQUAL_EQUAL:
  2180.         case AstBinaryExpression::NOT_EQUAL:
  2181.              break; // break to continue comparison processing
  2182.         default:
  2183.              //
  2184.              // not a comparison, get the (necessarily boolean) value
  2185.              // of the expression and branch on the result
  2186.              //
  2187.              EmitExpression(p);
  2188.              EmitBranch(cond ? OP_IFNE : OP_IFEQ, lab);
  2189.              return;
  2190.     }
  2191.  
  2192.     //
  2193.     //
  2194.     //
  2195.     unsigned opcode = 0,
  2196.              op_true,
  2197.              op_false;
  2198.     if (this_control.IsSimpleIntegerValueType(left_type) || left_type == this_control.boolean_type)
  2199.     {
  2200.         //
  2201.         // we have already dealt with EQUAL_EQUAL and NOT_EQUAL for the case
  2202.         // of two integers, but still need to look for comparisons for which
  2203.         // one operand may be zero.
  2204.         //
  2205.         if (IsZero(left))
  2206.         {
  2207.             EmitExpression(right);
  2208.             switch(bp -> binary_tag)
  2209.             {
  2210.                 case AstBinaryExpression::LESS: // if (0 < x) same as  if (x > 0)
  2211.                      op_true = OP_IFGT;
  2212.                      op_false = OP_IFLE;
  2213.                      break;
  2214.                 case AstBinaryExpression::LESS_EQUAL:  // if (0 <= x) same as if (x >= 0)
  2215.                      op_true = OP_IFGE;
  2216.                      op_false = OP_IFLT;
  2217.                      break;
  2218.                 case AstBinaryExpression::GREATER:  // if (0 > x) same as if (x < 0)
  2219.                      op_true = OP_IFLT;
  2220.                      op_false = OP_IFGE;
  2221.                      break;
  2222.                 case AstBinaryExpression::GREATER_EQUAL: // if (0 >= x) same as if (x <= 0)
  2223.                      op_true = OP_IFLE;
  2224.                      op_false = OP_IFGT;
  2225.                      break;
  2226.                 default:
  2227.                     assert(false);
  2228.                     break;
  2229.             }
  2230.         }
  2231.         else if (IsZero(right))
  2232.         {
  2233.             EmitExpression(left);
  2234.  
  2235.             switch(bp -> binary_tag)
  2236.             {
  2237.                 case AstBinaryExpression::LESS:
  2238.                      op_true = OP_IFLT;
  2239.                      op_false = OP_IFGE;
  2240.                      break;
  2241.                 case AstBinaryExpression::LESS_EQUAL:
  2242.                      op_true = OP_IFLE;
  2243.                      op_false = OP_IFGT;
  2244.                      break;
  2245.                 case AstBinaryExpression::GREATER:
  2246.                      op_true = OP_IFGT;
  2247.                      op_false = OP_IFLE;
  2248.                      break;
  2249.                 case AstBinaryExpression::GREATER_EQUAL:
  2250.                      op_true = OP_IFGE;
  2251.                      op_false = OP_IFLT;
  2252.                      break;
  2253.                 default:
  2254.                     assert(false);
  2255.                     break;
  2256.             }
  2257.         }
  2258.         else
  2259.         {
  2260.             EmitExpression(left);
  2261.             EmitExpression(right);
  2262.  
  2263.             switch(bp -> binary_tag)
  2264.             {
  2265.                 case AstBinaryExpression::LESS:
  2266.                      op_true = OP_IF_ICMPLT;
  2267.                      op_false = OP_IF_ICMPGE;
  2268.                      break;
  2269.                 case AstBinaryExpression::LESS_EQUAL:
  2270.                      op_true = OP_IF_ICMPLE;
  2271.                      op_false = OP_IF_ICMPGT;
  2272.                      break;
  2273.                 case AstBinaryExpression::GREATER:
  2274.                      op_true = OP_IF_ICMPGT;
  2275.                      op_false = OP_IF_ICMPLE;
  2276.                      break;
  2277.                 case AstBinaryExpression::GREATER_EQUAL:
  2278.                      op_true = OP_IF_ICMPGE;
  2279.                      op_false = OP_IF_ICMPLT;
  2280.                      break;
  2281.                 default:
  2282.                     assert(false);
  2283.                     break;
  2284.             }
  2285.         }
  2286.     }
  2287.     else if (left_type == this_control.long_type)
  2288.     {
  2289.         EmitExpression(left);
  2290.         EmitExpression(right);
  2291.  
  2292.         opcode = OP_LCMP;
  2293.  
  2294.         //
  2295.         // branch according to result value on stack
  2296.         //
  2297.         switch (bp -> binary_tag)
  2298.         {
  2299.             case AstBinaryExpression::EQUAL_EQUAL:
  2300.                  op_true = OP_IFEQ;
  2301.                  op_false = OP_IFNE;
  2302.                  break;
  2303.             case AstBinaryExpression::NOT_EQUAL:
  2304.                  op_true = OP_IFNE;
  2305.                  op_false = OP_IFEQ;
  2306.                  break;
  2307.             case AstBinaryExpression::LESS:
  2308.                  op_true = OP_IFLT;
  2309.                  op_false = OP_IFGE;
  2310.                  break;
  2311.             case AstBinaryExpression::LESS_EQUAL:
  2312.                  op_true = OP_IFLE;
  2313.                  op_false = OP_IFGT;
  2314.                  break;
  2315.             case AstBinaryExpression::GREATER:
  2316.                  op_true = OP_IFGT;
  2317.                  op_false = OP_IFLE;
  2318.                  break;
  2319.             case AstBinaryExpression::GREATER_EQUAL:
  2320.                  op_true = OP_IFGE;
  2321.                  op_false = OP_IFLT;
  2322.                  break;
  2323.             default:
  2324.                 assert(false);
  2325.                 break;
  2326.         }
  2327.     }
  2328.     else if (left_type == this_control.float_type)
  2329.     {
  2330.         EmitExpression(left);
  2331.         EmitExpression(right);
  2332.  
  2333.         switch (bp -> binary_tag)
  2334.         {
  2335.             case AstBinaryExpression::EQUAL_EQUAL:
  2336.                  opcode = OP_FCMPL;
  2337.                  op_true = OP_IFEQ;
  2338.                  op_false = OP_IFNE;
  2339.                  break;
  2340.             case AstBinaryExpression::NOT_EQUAL:
  2341.                  opcode = OP_FCMPL;
  2342.                  op_true = OP_IFNE;
  2343.                  op_false = OP_IFEQ;
  2344.                  break;
  2345.             case AstBinaryExpression::LESS:
  2346.                  opcode = OP_FCMPG;
  2347.                  op_true = OP_IFLT;
  2348.                  op_false = OP_IFGE;
  2349.                  break;
  2350.             case AstBinaryExpression::LESS_EQUAL:
  2351.                  opcode = OP_FCMPG;
  2352.                  op_true = OP_IFLE;
  2353.                  op_false = OP_IFGT;
  2354.                  break;
  2355.             case AstBinaryExpression::GREATER:
  2356.                  opcode = OP_FCMPL;
  2357.                  op_true = OP_IFGT;
  2358.                  op_false = OP_IFLE;
  2359.                  break;
  2360.             case AstBinaryExpression::GREATER_EQUAL:
  2361.                  opcode = OP_FCMPL;
  2362.                  op_true = OP_IFGE;
  2363.                  op_false = OP_IFLT;
  2364.                  break;
  2365.             default:
  2366.                 assert(false);
  2367.                 break;
  2368.         }
  2369.     }
  2370.     else if (left_type == this_control.double_type)
  2371.     {
  2372.         EmitExpression(left);
  2373.         EmitExpression(right);
  2374.         switch (bp -> binary_tag)
  2375.         {
  2376.             case AstBinaryExpression::EQUAL_EQUAL:
  2377.                  opcode = OP_DCMPL;
  2378.                  op_true = OP_IFEQ;
  2379.                  op_false = OP_IFNE;
  2380.                  break;
  2381.             case AstBinaryExpression::NOT_EQUAL:
  2382.                  opcode = OP_DCMPL;
  2383.                  op_true = OP_IFNE;
  2384.                  op_false = OP_IFEQ;
  2385.                  break;
  2386.             case AstBinaryExpression::LESS:
  2387.                  opcode = OP_DCMPG;
  2388.                  op_true = OP_IFLT;
  2389.                  op_false = OP_IFGE;
  2390.                  break;
  2391.             case AstBinaryExpression::LESS_EQUAL:
  2392.                  opcode = OP_DCMPG;
  2393.                  op_true = OP_IFLE;
  2394.                  op_false = OP_IFGT;
  2395.                  break;
  2396.             case AstBinaryExpression::GREATER:
  2397.                  opcode = OP_DCMPL;
  2398.                  op_true = OP_IFGT;
  2399.                  op_false = OP_IFLE;
  2400.                  break;
  2401.             case AstBinaryExpression::GREATER_EQUAL:
  2402.                  opcode = OP_DCMPL;
  2403.                  op_true = OP_IFGE;
  2404.                  op_false = OP_IFLT;
  2405.                  break;
  2406.             default:
  2407.                 assert(false);
  2408.                 break;
  2409.         }
  2410.     }
  2411.     else assert(false && "comparison of unsupported type");
  2412.  
  2413.     if (opcode)
  2414.         PutOp(opcode); // if need to emit comparison before branch
  2415.  
  2416.     EmitBranch (cond ? op_true : op_false, lab);
  2417.  
  2418.     return;
  2419. }
  2420.  
  2421.  
  2422. void ByteCode::EmitSynchronizedStatement(AstSynchronizedStatement *statement)
  2423. {
  2424.     EmitExpression(statement -> expression);
  2425.  
  2426.     int variable_index = method_stack -> TopBlock() -> block_symbol -> try_or_synchronized_variable_index;
  2427.  
  2428.     StoreLocal(variable_index, this_control.Object()); // save address of object
  2429.     LoadLocal(variable_index, this_control.Object()); // load address of object onto stack
  2430.  
  2431.     PutOp(OP_MONITORENTER); // enter monitor associated with object
  2432.  
  2433.     int start_synchronized_pc = code_attribute -> CodeLength(); // start pc
  2434.  
  2435.     EmitBlockStatement(statement -> block);
  2436.  
  2437.     int end_synchronized_pc = code_attribute -> CodeLength(); // end pc
  2438.  
  2439.     LoadLocal(variable_index, this_control.Object()); // load address of object onto stack
  2440.     PutOp(OP_MONITOREXIT);
  2441.  
  2442.     if (start_synchronized_pc != end_synchronized_pc) // if the synchronized block is not empty.
  2443.     {
  2444.         Label end_label;
  2445.         EmitBranch(OP_GOTO, end_label); // branch around exception handler
  2446.  
  2447.         //
  2448.         // Reach here if any increment. max_stack in case exception thrown while stack at greatest depth
  2449.         //
  2450.         max_stack++;
  2451.         int handler_pc = code_attribute -> CodeLength();
  2452.         LoadLocal(variable_index, this_control.Object()); // load address of object onto stack
  2453.         PutOp(OP_MONITOREXIT);
  2454.         PutOp(OP_ATHROW);
  2455.  
  2456.         code_attribute -> AddException(start_synchronized_pc, handler_pc, handler_pc, 0);
  2457.  
  2458.         DefineLabel(method_stack -> TopMonitorLabel());
  2459.         CompleteLabel(method_stack -> TopMonitorLabel());
  2460.  
  2461.         int loc_index = variable_index + 1; // local variable index to save return  address
  2462.         StoreLocal(loc_index, this_control.Object()); // save return address
  2463.         LoadLocal(variable_index, this_control.Object()); // load address of object onto stack
  2464.         PutOp(OP_MONITOREXIT);
  2465.         PutOpWide(OP_RET, loc_index);  // return using saved address
  2466.  
  2467.         DefineLabel(end_label);
  2468.         CompleteLabel(end_label);
  2469.     }
  2470.  
  2471.     return;
  2472. }
  2473.  
  2474.  
  2475. //
  2476. // JLS is Java Language Specification
  2477. // JVM is Java Virtual Machine
  2478. //
  2479. // Expressions: Chapter 14 of JLS
  2480. //
  2481. int ByteCode::EmitExpression(AstExpression *expression)
  2482. {
  2483.     if (expression -> IsConstant())
  2484.     {
  2485.         LoadLiteral(expression -> value, expression -> Type());
  2486.         return (this_control.IsDoubleWordType(expression -> Type()) ? 2 : 1);
  2487.     }
  2488.  
  2489.     switch (expression -> kind)
  2490.     {
  2491.         case Ast::IDENTIFIER:
  2492.              {
  2493.                  AstSimpleName *simple_name = expression -> SimpleNameCast();
  2494.                  return (simple_name -> resolution_opt ? EmitExpression(simple_name -> resolution_opt)
  2495.                                                        : LoadVariable(GetLhsKind(expression), expression));
  2496.              }
  2497.         case Ast::THIS_EXPRESSION:
  2498.         case Ast::SUPER_EXPRESSION:
  2499.              PutOp(OP_ALOAD_0); // must be use
  2500.              return 1;
  2501.         case Ast::PARENTHESIZED_EXPRESSION:
  2502.              return EmitExpression(((AstParenthesizedExpression *) expression) -> expression);
  2503.         case Ast::CLASS_CREATION:
  2504.              return EmitClassInstanceCreationExpression((AstClassInstanceCreationExpression *) expression, true);
  2505.         case Ast::ARRAY_CREATION:
  2506.              return EmitArrayCreationExpression((AstArrayCreationExpression *) expression);
  2507.         case Ast::DIM:
  2508.              return EmitExpression(expression -> DimExprCast() -> expression);
  2509.         case Ast::DOT:
  2510.              {
  2511.                  AstFieldAccess *field_access = (AstFieldAccess *) expression;
  2512.                  return ((field_access -> IsClassAccess()) && (field_access -> resolution_opt))
  2513.                                                             ? (unit_type -> outermost_type -> ACC_INTERFACE()
  2514.                                                                           ? EmitExpression(field_access -> resolution_opt)
  2515.                                                                           : GenerateClassAccess(field_access))
  2516.                                                             : EmitFieldAccess(field_access);
  2517.              }
  2518.         case Ast::CALL:
  2519.              {
  2520.                  AstMethodInvocation *method_call = expression -> MethodInvocationCast();
  2521.                  EmitMethodInvocation(method_call);
  2522.                  return GetTypeWords(method_call -> Type());
  2523.              }
  2524.         case Ast::ARRAY_ACCESS:             // if seen alone this will be as RHS
  2525.              return EmitArrayAccessRhs((AstArrayAccess *) expression);
  2526.         case Ast::POST_UNARY:
  2527.              return EmitPostUnaryExpression((AstPostUnaryExpression *) expression, true);
  2528.         case Ast::PRE_UNARY:
  2529.              return EmitPreUnaryExpression((AstPreUnaryExpression *) expression, true);
  2530.         case Ast::CAST:
  2531.              {
  2532.                  AstCastExpression *cast_expression = (AstCastExpression *) expression;
  2533.  
  2534.                  //
  2535.                  // only primitive types require casting
  2536.                  //
  2537.                  return (cast_expression -> expression -> Type() -> Primitive()
  2538.                                           ? EmitCastExpression(cast_expression)
  2539.                                           : EmitExpression(cast_expression -> expression));
  2540.              }
  2541.         case Ast::CHECK_AND_CAST:
  2542.              return EmitCastExpression((AstCastExpression *) expression);
  2543.         case Ast::BINARY:
  2544.              return EmitBinaryExpression((AstBinaryExpression *) expression);
  2545.         case Ast::CONDITIONAL:
  2546.              return EmitConditionalExpression((AstConditionalExpression *) expression);
  2547.         case Ast::ASSIGNMENT:
  2548.              return EmitAssignmentExpression((AstAssignmentExpression *) expression, true);
  2549.         default:
  2550.              assert(false && "unknown expression kind");
  2551.              break;
  2552.      }
  2553.  
  2554.      return 0; // even though we will not reach here
  2555. }
  2556.  
  2557.  
  2558. AstExpression *ByteCode::VariableExpressionResolution(AstExpression *expression)
  2559. {
  2560.     AstFieldAccess *field = expression -> FieldAccessCast();
  2561.     AstSimpleName *simple_name = expression -> SimpleNameCast();
  2562.  
  2563.     //
  2564.     // If the expression was resolved, get the resolution
  2565.     //
  2566.     if (field)
  2567.     {
  2568.         if (field -> resolution_opt)
  2569.            expression = field -> resolution_opt;
  2570.     }
  2571.     else if (simple_name)
  2572.     {
  2573.         if (simple_name -> resolution_opt)
  2574.             expression = simple_name -> resolution_opt;
  2575.     }
  2576.  
  2577.     return expression;
  2578. }
  2579.  
  2580.  
  2581. TypeSymbol *ByteCode::VariableTypeResolution(AstExpression *expression, VariableSymbol *sym)
  2582. {
  2583.     expression = VariableExpressionResolution(expression);
  2584.     AstFieldAccess *field = expression -> FieldAccessCast();
  2585.     AstSimpleName *simple_name = expression -> SimpleNameCast();
  2586.     assert(field || simple_name);
  2587.  
  2588.     TypeSymbol *owner_type = sym -> owner -> TypeCast(),
  2589.                *base_type = (field ? field -> base -> Type() : unit_type);
  2590.  
  2591.     // If the real owner of the field is either public or contained in
  2592.     // the same package as the current unit then the type used in the
  2593.     // fieldref should be the owner. Otherwise, the base_type is used.
  2594.     //
  2595.     return (owner_type -> ACC_PUBLIC() || owner_type -> ContainingPackage() == unit_type -> ContainingPackage()
  2596.             ? owner_type
  2597.             : base_type);
  2598.  
  2599. }
  2600.  
  2601.  
  2602. TypeSymbol *ByteCode::MethodTypeResolution(AstExpression *method_name, MethodSymbol *msym)
  2603. {
  2604.     AstFieldAccess *field = method_name -> FieldAccessCast();
  2605.     AstSimpleName *simple_name = method_name -> SimpleNameCast();
  2606.     assert(field || simple_name);
  2607.  
  2608.     TypeSymbol *owner_type = msym -> containing_type,
  2609.                *base_type = (field ? field -> base -> Type()
  2610.                                    : (simple_name -> resolution_opt ? simple_name -> resolution_opt -> Type() : owner_type));
  2611.  
  2612.  
  2613.      //
  2614.      // If the real owner of the method is an array type then Object
  2615.      // is used in the methodref. Otherwise, if the owner is public
  2616.      // or it is contained in the same package as the current unit
  2617.      // then the base_type is used.
  2618.      //
  2619.     return (owner_type -> IsArray()
  2620.             ? this_control.Object()
  2621.             : owner_type -> ACC_PUBLIC() || owner_type -> ContainingPackage() == unit_type -> ContainingPackage()
  2622.             ? owner_type
  2623.             : base_type);
  2624. }
  2625.  
  2626.  
  2627. void ByteCode::EmitFieldAccessLhsBase(AstExpression *expression)
  2628. {
  2629.     expression = VariableExpressionResolution(expression);
  2630.     AstFieldAccess *field = expression -> FieldAccessCast();
  2631.  
  2632.     //
  2633.     // We now have the right expression. Check if it's a field. If so, process base
  2634.     // Otherwise, it must be a simple name...
  2635.     //
  2636.     field = expression -> FieldAccessCast();
  2637.     if (field)
  2638.         EmitExpression(field -> base);
  2639.     else
  2640.     {
  2641.         assert(expression -> SimpleNameCast() && "unexpected AssignmentExpressionField operand base type");
  2642.  
  2643.         PutOp(OP_ALOAD_0); // get address of "this"
  2644.     }
  2645.  
  2646.     return;
  2647. }
  2648.  
  2649.  
  2650. void ByteCode::EmitFieldAccessLhs(AstExpression *expression)
  2651. {
  2652.     EmitFieldAccessLhsBase(expression);
  2653.     PutOp(OP_DUP);     // save base address of field for later store
  2654.     PutOp(OP_GETFIELD);
  2655.     ChangeStack(this_control.IsDoubleWordType(expression -> Type()) ? 1 : 0);
  2656.  
  2657.     VariableSymbol *sym = (VariableSymbol *) expression -> symbol;
  2658.     PutU2(RegisterFieldref(VariableTypeResolution(expression, sym), sym));
  2659.  
  2660.     return;
  2661. }
  2662.  
  2663.  
  2664. //
  2665. // Generate code for access method used to set class literal fields
  2666. //
  2667. void ByteCode::GenerateClassAccessMethod(MethodSymbol *msym)
  2668. {
  2669.     //
  2670.     // The code takes the form:
  2671.     //
  2672.     //  aload_0          load this
  2673.     //  invokestatic     java/lang/Class.forName(String)java/lang/Class
  2674.     //  areturn          return Class object for the class named by string
  2675.     //
  2676.     //  exception handler if forName fails:
  2677.     //
  2678.     //  astore_1         save exception
  2679.     //  new              java.lang.NoClassDefFoundError
  2680.     //  dup              save so can return
  2681.     //  aload_1          recover exception
  2682.     //  invokevirtual    java.lang.Throwable.getMessage() to get error message
  2683.     //  invokenonvirtual <init>     // invoke initializer
  2684.     //  athrow           rethrow the exception
  2685.     //
  2686.     PutOp(OP_ALOAD_0);
  2687.     PutOp(OP_INVOKESTATIC);
  2688.     ChangeStack(-1);
  2689.     PutU2(RegisterLibraryMethodref(this_control.Class_forNameMethod()));
  2690.     ChangeStack(1);
  2691.  
  2692.     PutOp(OP_ARETURN);
  2693.     PutOp(OP_ASTORE_1);
  2694.     PutOp(OP_NEW);
  2695.     PutU2(RegisterClass(this_control.NoClassDefFoundError() -> fully_qualified_name));
  2696.     PutOp(OP_DUP);
  2697.     PutOp(OP_ALOAD_1);
  2698.     PutOp(OP_INVOKEVIRTUAL);
  2699.     ChangeStack(-1);
  2700.     PutU2(RegisterLibraryMethodref(this_control.Throwable_getMessageMethod()));
  2701.     ChangeStack(1);
  2702.  
  2703.     PutOp(OP_INVOKENONVIRTUAL);
  2704.     ChangeStack(-1);
  2705.     PutU2(RegisterLibraryMethodref(this_control.NoClassDefFoundError_InitMethod()));
  2706.  
  2707.     ChangeStack(1);
  2708.     PutOp(OP_ATHROW);
  2709.  
  2710.     max_stack = 3;
  2711.  
  2712.     code_attribute -> AddException(0,
  2713.                                    5,
  2714.                                    5,
  2715.                                    RegisterClass(this_control.ClassNotFoundException() -> fully_qualified_name));
  2716.  
  2717.     return;
  2718. }
  2719.  
  2720.  
  2721. //
  2722. // here to generate code to dymanically initialize the field for a class literal and then return its value
  2723. //
  2724. int ByteCode::GenerateClassAccess(AstFieldAccess *field_access)
  2725. {
  2726.     //
  2727.     // simple case in immediate environment, can use field on both left and right
  2728.     // (TypeSymbol *type)
  2729.     // evaluate X.class literal. If X is a primitive type, this is a predefined field;
  2730.     // otherwise, we must create a new synthetic field to hold the desired result and
  2731.     // initialize it at runtime.
  2732.     // generate
  2733.     // getstatic class_field     load class field
  2734.     // ifnull lab1               branch if not yet set
  2735.     // get class_field           here if set, return value
  2736.     // goto lab2
  2737.     // lab1:                     here to initialize the field
  2738.     // load class_constant       get name of class
  2739.     // invokestatic              invoke generated method to get class_field  desired value
  2740.     // dup                       save value so can return it
  2741.     // put class_field           initialize the field
  2742.     // lab2:
  2743.     //
  2744.     Label lab1,
  2745.           lab2;
  2746.     if (field_access -> symbol -> VariableCast())
  2747.     {
  2748.         u2 field_index = RegisterFieldref(field_access -> symbol -> VariableCast());
  2749.  
  2750.         PutOp(OP_GETSTATIC);
  2751.         PutU2(field_index);
  2752.         ChangeStack(1);
  2753.         EmitBranch(OP_IFNULL, lab1);
  2754.         PutOp(OP_GETSTATIC);
  2755.         PutU2(field_index);
  2756.         ChangeStack(1);
  2757.         EmitBranch(OP_GOTO, lab2);
  2758.         DefineLabel(lab1);
  2759.  
  2760.         //
  2761.         // generate load of constant naming the class
  2762.         //
  2763.         LoadLiteral(field_access -> base -> Type() -> ClassLiteralName(), this_control.String());
  2764.         PutOp(OP_INVOKESTATIC);
  2765.         CompleteCall(unit_type -> outermost_type -> ClassLiteralMethod(), 1);
  2766.         PutOp(OP_DUP);
  2767.         PutOp(OP_PUTSTATIC);
  2768.         PutU2(field_index);
  2769.         ChangeStack(-1);
  2770.     }
  2771.     else // here in nested case, where must invoke access methods for the field
  2772.     {
  2773.         MethodSymbol *read_symbol = field_access -> symbol -> MethodCast(),
  2774.                      *write_symbol = field_access -> resolution_opt -> symbol -> MethodCast();
  2775.  
  2776.         //
  2777.         // need load this for class with method
  2778.         // if the next statement read field_access -> resolution_opt -> symbol = read_method, then
  2779.         // generating code for that expression tree would give us what we want
  2780.         //
  2781.         // TODO: THIS DOES NOT SEEM TO HAVE ANY PURPOSE. BESIDES, IT CHANGES THE INTERMEDIATE REPRESENTATION !!!
  2782.         //
  2783.         //        field_access -> resolution_opt -> symbol = read_symbol;
  2784.         //
  2785.  
  2786.         PutOp(OP_INVOKESTATIC);
  2787.         u2 read_ref = RegisterMethodref(read_symbol -> containing_type -> fully_qualified_name,
  2788.                                         read_symbol -> ExternalIdentity() -> Utf8_literal,
  2789.                                         read_symbol -> signature);
  2790.         PutU2(read_ref);
  2791.         ChangeStack(1);
  2792.  
  2793.         EmitBranch(OP_IFNULL, lab1);
  2794.         PutOp(OP_INVOKESTATIC);
  2795.         PutU2(read_ref);
  2796.         ChangeStack(1);
  2797.         EmitBranch(OP_GOTO, lab2);
  2798.         DefineLabel(lab1);
  2799.  
  2800.         //
  2801.         // generate load of constant naming the class
  2802.         //
  2803.         LoadLiteral(field_access -> base -> Type() -> ClassLiteralName(), this_control.String());
  2804.         PutOp(OP_INVOKESTATIC);
  2805.         CompleteCall(unit_type -> outermost_type -> ClassLiteralMethod(), 1);
  2806.         PutOp(OP_DUP);
  2807.         PutOp(OP_INVOKESTATIC);
  2808.  
  2809.         u2 write_ref = RegisterMethodref(write_symbol -> containing_type -> fully_qualified_name,
  2810.                                          write_symbol -> ExternalIdentity() -> Utf8_literal,
  2811.                                          write_symbol -> signature);
  2812.         PutU2(write_ref);
  2813.         ChangeStack(-1); // to indicate argument popped
  2814.     }
  2815.  
  2816.     DefineLabel(lab2);
  2817.     CompleteLabel(lab1);
  2818.     CompleteLabel(lab2);
  2819.  
  2820.     return 1; // return one-word (reference) result
  2821. }
  2822.  
  2823.  
  2824. //
  2825. // see also OP_MULTINEWARRAY
  2826. //
  2827. int ByteCode::EmitArrayCreationExpression(AstArrayCreationExpression *expression)
  2828. {
  2829.     int num_dims = expression -> NumDimExprs();
  2830.  
  2831.     if (num_dims > 255)
  2832.     {
  2833.         this_semantic.ReportSemError(SemanticError::ARRAY_OVERFLOW,
  2834.                                      expression -> LeftToken(),
  2835.                                      expression -> RightToken());
  2836.     }
  2837.  
  2838.     if (expression -> array_initializer_opt)
  2839.         InitializeArray(expression -> Type(), expression -> array_initializer_opt);
  2840.     else
  2841.     {
  2842.         //
  2843.         // need to push value of dimension(s)
  2844.         //
  2845.         for (int i = 0; i < num_dims; i++)
  2846.             EmitExpression(expression -> DimExpr(i) -> expression);
  2847.  
  2848.         EmitNewArray(num_dims, expression -> Type());
  2849.     }
  2850.  
  2851.     return 1;
  2852. }
  2853.  
  2854.  
  2855. //
  2856. // ASSIGNMENT
  2857. //
  2858. int ByteCode::EmitAssignmentExpression(AstAssignmentExpression *assignment_expression, bool need_value)
  2859. {
  2860.     AstCastExpression *casted_left_hand_side = assignment_expression -> left_hand_side -> CastExpressionCast();
  2861.     AstExpression *left_hand_side = (casted_left_hand_side ? casted_left_hand_side -> expression : assignment_expression -> left_hand_side);
  2862.  
  2863.     TypeSymbol *left_type = left_hand_side -> Type();
  2864.  
  2865.     int kind = GetLhsKind(assignment_expression);
  2866.     VariableSymbol *accessed_member = (assignment_expression -> write_method
  2867.                                                    ? assignment_expression -> write_method -> accessed_member -> VariableCast()
  2868.                                                    : (VariableSymbol *) NULL);
  2869.  
  2870.     if (assignment_expression -> SimpleAssignment())
  2871.     {
  2872.         switch(kind)
  2873.         {
  2874.             case LHS_ARRAY:
  2875.                  EmitArrayAccessLhs(left_hand_side -> ArrayAccessCast()); // lhs must be array access
  2876.                  break;
  2877.             case LHS_FIELD:
  2878.                  EmitFieldAccessLhsBase(left_hand_side); // load base for field access
  2879.                  break;
  2880.             case LHS_METHOD:
  2881.                  if (! accessed_member -> ACC_STATIC()) // need to load address of object, obtained from resolution
  2882.                  {
  2883.                      AstExpression *resolve = (left_hand_side -> FieldAccessCast()
  2884.                                                                ? left_hand_side -> FieldAccessCast() -> resolution_opt
  2885.                                                                : left_hand_side -> SimpleNameCast() -> resolution_opt);
  2886.  
  2887.                      assert(resolve);
  2888.  
  2889.                      AstFieldAccess *field_expression = resolve -> MethodInvocationCast() -> method -> FieldAccessCast();
  2890.  
  2891.                      assert(field_expression);
  2892.  
  2893.                      EmitExpression(field_expression -> base);
  2894.                  }
  2895.                  break;
  2896.             default:
  2897.                  break;
  2898.         }
  2899.  
  2900.         EmitExpression(assignment_expression -> expression);
  2901.     }
  2902.     //
  2903.     // Here for compound assignment. Get the left operand, saving any information necessary to
  2904.     // update its value on the stack below the value.
  2905.     //
  2906.     else
  2907.     {
  2908.         switch(kind)
  2909.         {
  2910.             case LHS_ARRAY:
  2911.                  EmitArrayAccessLhs(left_hand_side -> ArrayAccessCast()); // lhs must be array access
  2912.                  PutOp(OP_DUP2); // save base and index for later store
  2913.  
  2914.                  //
  2915.                  // load current value
  2916.                  //
  2917.                  (void) LoadArrayElement(assignment_expression -> Type());
  2918.                  break;
  2919.             case LHS_FIELD:
  2920.                  EmitFieldAccessLhs(left_hand_side);
  2921.                  break;
  2922.             case LHS_LOCAL:
  2923.                  if ((! casted_left_hand_side) &&
  2924.                      assignment_expression -> Type() == this_control.int_type &&
  2925.                      assignment_expression -> expression -> IsConstant() &&
  2926.                      (assignment_expression -> assignment_tag == AstAssignmentExpression::PLUS_EQUAL ||
  2927.                       assignment_expression -> assignment_tag == AstAssignmentExpression::MINUS_EQUAL))
  2928.                  {
  2929.                      IntLiteralValue *vp = (IntLiteralValue *) assignment_expression -> expression -> value;
  2930.                      int val = (assignment_expression -> assignment_tag == AstAssignmentExpression::MINUS_EQUAL
  2931.                                                                          ? -(vp -> value) // we treat "a -= x" as "a += (-x)"
  2932.                                                                          : vp -> value);
  2933.                      if (val >= -32768 && val < 32768) // if value in range
  2934.                      {
  2935.                          VariableSymbol *sym = (VariableSymbol *) left_hand_side -> symbol;
  2936.                          PutOpIINC(sym -> LocalVariableIndex(), val);
  2937.                          if (need_value)
  2938.                              LoadVariable(LHS_LOCAL, left_hand_side);
  2939.                          return GetTypeWords(assignment_expression -> Type());
  2940.                      }
  2941.                  }
  2942.  
  2943.                  (void) LoadVariable(kind, left_hand_side);
  2944.                  break;
  2945.             case LHS_STATIC:
  2946.                  (void) LoadVariable(kind, left_hand_side);
  2947.                  //
  2948.                  // TODO:
  2949.                  // see if actually need call to ChangeStack, marked CHECK_THIS, in AssigmnentExpression
  2950.                  //
  2951.                  // ChangeStack(this_control.IsDoubleWordType(left_type) ? 1: 0); // CHECK_THIS? Is this really necessary
  2952.                  //
  2953.                  break;
  2954.             case LHS_METHOD:
  2955.                  //
  2956.                  // If we are accessing a static member, get value by invoking appropriate resolution.
  2957.                  // Otherwise, in addition to getting the value, we need to load address of the object,
  2958.                  // obtained from the resolution, saving a copy on the stack.
  2959.                  //
  2960.                  if (accessed_member -> ACC_STATIC())
  2961.                       EmitExpression(left_hand_side);
  2962.                  else ResolveAccess(left_hand_side);
  2963.                  break;
  2964.             default:
  2965.                  break;
  2966.         }
  2967.  
  2968.         //
  2969.         // Here for string concatenation.
  2970.         //
  2971.         if (assignment_expression -> assignment_tag == AstAssignmentExpression::PLUS_EQUAL && left_type == this_control.String())
  2972.         {
  2973.             PutOp(OP_NEW);
  2974.             PutU2(RegisterClass(this_control.StringBuffer() -> fully_qualified_name));
  2975.             PutOp(OP_DUP);
  2976.             PutOp(OP_INVOKENONVIRTUAL);
  2977.             PutU2(RegisterLibraryMethodref(this_control.StringBuffer_InitMethod()));
  2978.             PutOp(OP_SWAP); // swap address if buffer and string to update.
  2979.             EmitStringAppendMethod(this_control.String());
  2980.             AppendString(assignment_expression -> expression);
  2981.  
  2982.             //
  2983.             // convert string buffer to string
  2984.             //
  2985.             PutOp(OP_INVOKEVIRTUAL);
  2986.             PutU2(RegisterLibraryMethodref(this_control.StringBuffer_toStringMethod()));
  2987.             ChangeStack(1); // account for return value
  2988.         }
  2989.         //
  2990.         // Here for operation other than string concatenation. Determine the opcode to use.
  2991.         //
  2992.         else
  2993.         {
  2994.             int opc;
  2995.  
  2996.             TypeSymbol *op_type = (casted_left_hand_side ? casted_left_hand_side -> Type() : assignment_expression -> Type());
  2997.  
  2998.             if (this_control.IsSimpleIntegerValueType(op_type) || op_type == this_control.boolean_type)
  2999.             {
  3000.                 switch (assignment_expression -> assignment_tag)
  3001.                 {
  3002.                     case AstAssignmentExpression::STAR_EQUAL:
  3003.                          opc = OP_IMUL;
  3004.                          break;
  3005.                     case AstAssignmentExpression::SLASH_EQUAL:
  3006.                          opc = OP_IDIV;
  3007.                          break;
  3008.                     case AstAssignmentExpression::MOD_EQUAL:
  3009.                          opc = OP_IREM;
  3010.                          break;
  3011.                     case AstAssignmentExpression::PLUS_EQUAL:
  3012.                          opc = OP_IADD;
  3013.                          break;
  3014.                     case AstAssignmentExpression::MINUS_EQUAL:
  3015.                          opc = OP_ISUB;
  3016.                          break;
  3017.                     case AstAssignmentExpression::LEFT_SHIFT_EQUAL:
  3018.                          opc = OP_ISHL;
  3019.                          break;
  3020.                     case AstAssignmentExpression::RIGHT_SHIFT_EQUAL:
  3021.                          opc = OP_ISHR;
  3022.                          break;
  3023.                     case AstAssignmentExpression::UNSIGNED_RIGHT_SHIFT_EQUAL:
  3024.                          opc = OP_IUSHR;
  3025.                          break;
  3026.                     case AstAssignmentExpression::AND_EQUAL:
  3027.                          opc = OP_IAND;
  3028.                          break;
  3029.                     case AstAssignmentExpression::IOR_EQUAL:
  3030.                          opc = OP_IOR;
  3031.                          break;
  3032.                     case AstAssignmentExpression::XOR_EQUAL:
  3033.                          opc = OP_IXOR;
  3034.                          break;
  3035.                     default:
  3036.                          break;
  3037.                 }
  3038.             }
  3039.             else if (op_type == this_control.long_type)
  3040.             {
  3041.                 switch (assignment_expression -> assignment_tag)
  3042.                 {
  3043.                     case AstAssignmentExpression::STAR_EQUAL:
  3044.                          opc = OP_LMUL;
  3045.                          break;
  3046.                     case AstAssignmentExpression::SLASH_EQUAL:
  3047.                          opc = OP_LDIV;
  3048.                          break;
  3049.                     case AstAssignmentExpression::MOD_EQUAL:
  3050.                          opc = OP_LREM;
  3051.                          break;
  3052.                     case AstAssignmentExpression::PLUS_EQUAL:
  3053.                          opc = OP_LADD;
  3054.                          break;
  3055.                     case AstAssignmentExpression::MINUS_EQUAL:
  3056.                          opc = OP_LSUB;
  3057.                          break;
  3058.                     case AstAssignmentExpression::LEFT_SHIFT_EQUAL:
  3059.                          opc = OP_LSHL;
  3060.                          break;
  3061.                     case AstAssignmentExpression::RIGHT_SHIFT_EQUAL:
  3062.                          opc = OP_LSHR;
  3063.                          break;
  3064.                     case AstAssignmentExpression::UNSIGNED_RIGHT_SHIFT_EQUAL:
  3065.                          opc = OP_LUSHR;
  3066.                          break;
  3067.                     case AstAssignmentExpression::AND_EQUAL:
  3068.                          opc = OP_LAND;
  3069.                          break;
  3070.                     case AstAssignmentExpression::IOR_EQUAL:
  3071.                          opc = OP_LOR;
  3072.                          break;
  3073.                     case AstAssignmentExpression::XOR_EQUAL:
  3074.                          opc = OP_LXOR;
  3075.                          break;
  3076.                     default:
  3077.                          break;
  3078.                 }
  3079.             }
  3080.             else if (op_type == this_control.float_type)
  3081.             {
  3082.                 switch (assignment_expression -> assignment_tag)
  3083.                 {
  3084.                     case AstAssignmentExpression::STAR_EQUAL:
  3085.                          opc = OP_FMUL;
  3086.                          break;
  3087.                     case AstAssignmentExpression::SLASH_EQUAL:
  3088.                          opc = OP_FDIV;
  3089.                          break;
  3090.                     case AstAssignmentExpression::MOD_EQUAL:
  3091.                          opc = OP_FREM;
  3092.                          break;
  3093.                     case AstAssignmentExpression::PLUS_EQUAL:
  3094.                          opc = OP_FADD;
  3095.                          break;
  3096.                     case AstAssignmentExpression::MINUS_EQUAL:
  3097.                          opc = OP_FSUB;
  3098.                          break;
  3099.                     default:
  3100.                          break;
  3101.                 }
  3102.             }
  3103.             else if (op_type == this_control.double_type)
  3104.             {
  3105.                 switch (assignment_expression -> assignment_tag)
  3106.                 {
  3107.                     case AstAssignmentExpression::STAR_EQUAL:
  3108.                          opc = OP_DMUL;
  3109.                          break;
  3110.                     case AstAssignmentExpression::SLASH_EQUAL:
  3111.                          opc = OP_DDIV;
  3112.                          break;
  3113.                     case AstAssignmentExpression::MOD_EQUAL:
  3114.                          opc = OP_DREM;
  3115.                          break;
  3116.                     case AstAssignmentExpression::PLUS_EQUAL:
  3117.                          opc = OP_DADD;
  3118.                          break;
  3119.                     case AstAssignmentExpression::MINUS_EQUAL:
  3120.                          opc = OP_DSUB;
  3121.                          break;
  3122.                     default:
  3123.                          break;
  3124.                 }
  3125.             }
  3126.  
  3127.             //
  3128.             // convert value to desired type if necessary
  3129.             //
  3130.             if (casted_left_hand_side)
  3131.                 EmitCast(casted_left_hand_side -> Type(), left_type);
  3132.  
  3133.             EmitExpression(assignment_expression -> expression);
  3134.  
  3135.             PutOp(opc);
  3136.  
  3137.             if (casted_left_hand_side) // now cast result back to type of result
  3138.                 EmitCast(left_type, casted_left_hand_side -> Type());
  3139.         }
  3140.     }
  3141.  
  3142.     //
  3143.     // Update left operand, saving value of right operand if it is needed.
  3144.     //
  3145.     switch(kind)
  3146.     {
  3147.         case LHS_ARRAY:
  3148.              if (need_value)
  3149.                  PutOp(this_control.IsDoubleWordType(left_type) ? OP_DUP2_X2 : OP_DUP_X2);
  3150.              StoreArrayElement(assignment_expression -> Type());
  3151.              break;
  3152.         case LHS_FIELD:
  3153.              if (need_value)
  3154.                  PutOp(this_control.IsDoubleWordType(left_type) ? OP_DUP2_X1 : OP_DUP_X1);
  3155.              StoreField(left_hand_side);
  3156.              break;
  3157.         case LHS_METHOD:
  3158.              {
  3159.                  if (need_value)
  3160.                  {
  3161.                      if (accessed_member -> ACC_STATIC())
  3162.                           PutOp(this_control.IsDoubleWordType(left_type) ? OP_DUP2 : OP_DUP);
  3163.                      else PutOp(this_control.IsDoubleWordType(left_type) ? OP_DUP2_X1 : OP_DUP_X1);
  3164.                  }
  3165.  
  3166.                  int stack_words = (this_control.IsDoubleWordType(left_type) ? 2 : 1) + (accessed_member -> ACC_STATIC() ? 0 : 1);
  3167.                  PutOp(OP_INVOKESTATIC);
  3168.                  CompleteCall(assignment_expression -> write_method, stack_words);
  3169.              }
  3170.              break;
  3171.         case LHS_LOCAL:
  3172.         case LHS_STATIC:
  3173.             if (need_value)
  3174.                 PutOp(this_control.IsDoubleWordType(left_type) ? OP_DUP2 : OP_DUP);
  3175.             StoreVariable(kind, left_hand_side);
  3176.             break;
  3177.         default:
  3178.             break;
  3179.     }
  3180.  
  3181.     if (this_control.option.g && assignment_expression -> assignment_tag == AstAssignmentExpression::DEFINITE_EQUAL)
  3182.     {
  3183.         VariableSymbol *variable = assignment_expression -> left_hand_side -> symbol -> VariableCast();
  3184.         assert(variable);
  3185. #ifdef JIKES_DEBUG
  3186.         assert(method_stack -> StartPc(variable) == 0xFFFF); // must be uninitialized
  3187. #endif
  3188. #ifdef DUMP
  3189. Coutput << "(59) Variable \"" << variable -> Name()
  3190.         << "\" numbered " << variable -> LocalVariableIndex()
  3191.         << " was processed\n";
  3192. Coutput.flush();
  3193. #endif
  3194.         method_stack -> StartPc(variable) = code_attribute -> CodeLength();
  3195.     }
  3196.  
  3197.     return GetTypeWords(assignment_expression -> Type());
  3198. }
  3199.  
  3200.  
  3201. //
  3202. // BINARY: Similar code patterns are used for the ordered comparisons
  3203. //
  3204. int ByteCode::EmitBinaryExpression(AstBinaryExpression *expression)
  3205. {
  3206.     switch (expression -> binary_tag) // process boolean-results first
  3207.     {
  3208.         case AstBinaryExpression::OR_OR:
  3209.         case AstBinaryExpression::AND_AND:
  3210.         case AstBinaryExpression::LESS:
  3211.         case AstBinaryExpression::LESS_EQUAL:
  3212.         case AstBinaryExpression::GREATER:
  3213.         case AstBinaryExpression::GREATER_EQUAL:
  3214.         case AstBinaryExpression::EQUAL_EQUAL:
  3215.         case AstBinaryExpression::NOT_EQUAL:
  3216.              {
  3217.                  Label lab1,
  3218.                        lab2;
  3219.                  EmitBranchIfExpression(expression, true, lab1);
  3220.                  PutOp(OP_ICONST_0);                // push false
  3221.                  EmitBranch(OP_GOTO, lab2);
  3222.                  DefineLabel(lab1);
  3223.                  PutOp(OP_ICONST_1);                // push false
  3224.                  DefineLabel(lab2);
  3225.                  CompleteLabel(lab1);
  3226.                  CompleteLabel(lab2);
  3227.              }
  3228.              return 1;
  3229.         default:
  3230.              break;
  3231.     }
  3232.  
  3233.     if (expression -> binary_tag == AstBinaryExpression::INSTANCEOF)
  3234.     {
  3235.         TypeSymbol *instanceof_type = expression -> right_expression -> Type();
  3236.         EmitExpression(expression -> left_expression);
  3237.         PutOp(OP_INSTANCEOF);
  3238.         PutU2(instanceof_type -> num_dimensions > 0 ? RegisterClass(instanceof_type -> signature)
  3239.                                                     : RegisterClass(instanceof_type -> fully_qualified_name));
  3240.         return 1;
  3241.     }
  3242.  
  3243.     //
  3244.     // special case string concatenation
  3245.     //
  3246.     if (expression -> binary_tag == AstBinaryExpression::PLUS &&
  3247.         (IsReferenceType(expression -> left_expression -> Type()) || IsReferenceType(expression -> right_expression -> Type())))
  3248.     {
  3249.         ConcatenateString(expression);
  3250.         return 1;
  3251.     }
  3252.  
  3253.     //
  3254.     // Try to simplify if one operand known to be zero.
  3255.     //
  3256.     if (IsZero(expression -> left_expression))
  3257.     {
  3258.         TypeSymbol *right_type = expression -> right_expression -> Type();
  3259.         switch (expression -> binary_tag)
  3260.         {
  3261.             case AstBinaryExpression::PLUS:
  3262.             case AstBinaryExpression::IOR:
  3263.             case AstBinaryExpression::XOR:
  3264.                  EmitExpression(expression -> right_expression);
  3265.                  return GetTypeWords(expression -> Type());
  3266.             case AstBinaryExpression::STAR:
  3267.             case AstBinaryExpression::AND:
  3268.             case AstBinaryExpression::LEFT_SHIFT:
  3269.             case AstBinaryExpression::RIGHT_SHIFT:
  3270.             case AstBinaryExpression::UNSIGNED_RIGHT_SHIFT:
  3271.                  if (this_control.IsSimpleIntegerValueType(right_type) || right_type == this_control.boolean_type)
  3272.                      LoadImmediateInteger(0);
  3273.                  else
  3274.                  {
  3275.                      assert((right_type == this_control.long_type ||
  3276.                              right_type == this_control.float_type ||
  3277.                              right_type == this_control.double_type) && "unexpected type in expression simplification");
  3278.  
  3279.                      PutOp(right_type == this_control.long_type
  3280.                                        ? OP_LCONST_0
  3281.                                        : right_type == this_control.float_type
  3282.                                                      ? OP_FCONST_0
  3283.                                                      : OP_DCONST_0); // double_type
  3284.                  }
  3285.                  return GetTypeWords(right_type);
  3286.             case AstBinaryExpression::MINUS: // 0 - x is negation of x
  3287.                  EmitExpression(expression -> right_expression);
  3288.  
  3289.                  assert((this_control.IsSimpleIntegerValueType(right_type) ||
  3290.                          right_type == this_control.long_type ||
  3291.                          right_type == this_control.float_type ||
  3292.                          right_type == this_control.double_type) && "unexpected type in expression simplification");
  3293.  
  3294.                  PutOp(this_control.IsSimpleIntegerValueType(right_type)
  3295.                            ? OP_INEG
  3296.                            : right_type == this_control.long_type
  3297.                                          ? OP_LNEG
  3298.                                          : right_type == this_control.float_type
  3299.                                                        ? OP_FNEG
  3300.                                                        : OP_DNEG); // double_type
  3301.                  return GetTypeWords(expression -> Type());
  3302.             default:
  3303.                  break;
  3304.         }
  3305.     }
  3306.  
  3307.     if (IsZero(expression -> right_expression))
  3308.     {
  3309.         TypeSymbol *left_type = expression -> left_expression -> Type();
  3310.         switch (expression -> binary_tag)
  3311.         {
  3312.             case AstBinaryExpression::PLUS:
  3313.             case AstBinaryExpression::MINUS:
  3314.             case AstBinaryExpression::IOR:
  3315.             case AstBinaryExpression::XOR:
  3316.             case AstBinaryExpression::LEFT_SHIFT:
  3317.             case AstBinaryExpression::RIGHT_SHIFT:
  3318.             case AstBinaryExpression::UNSIGNED_RIGHT_SHIFT: // here for cases that simplify to the left operand
  3319.                  EmitExpression(expression -> left_expression);
  3320.                  return GetTypeWords(expression -> Type());
  3321.             case AstBinaryExpression::STAR:
  3322.             case AstBinaryExpression::AND: // here for cases that evaluate to zero
  3323.                  if (this_control.IsSimpleIntegerValueType(left_type) || left_type == this_control.boolean_type)
  3324.                       LoadImmediateInteger(0);
  3325.                  else
  3326.                  {
  3327.                      assert((left_type == this_control.long_type ||
  3328.                              left_type == this_control.float_type ||
  3329.                              left_type == this_control.double_type) && "unexpected type in expression simplification");
  3330.  
  3331.                      PutOp(left_type == this_control.long_type
  3332.                                       ? OP_LCONST_0
  3333.                                       : left_type == this_control.float_type
  3334.                                                    ? OP_FCONST_0
  3335.                                                    : OP_DCONST_0); // double_type
  3336.                  }
  3337.                  return GetTypeWords(expression -> Type());
  3338.             default:
  3339.                  break;
  3340.         }
  3341.     }
  3342.  
  3343.     EmitExpression(expression -> left_expression);
  3344.     EmitExpression(expression -> right_expression);
  3345.  
  3346.     TypeSymbol *type = expression -> left_expression -> Type();
  3347.     bool integer_type = (this_control.IsSimpleIntegerValueType(type) || type == this_control.boolean_type);
  3348.     switch (expression -> binary_tag)
  3349.     {
  3350.         case AstBinaryExpression::STAR:
  3351.              PutOp(integer_type ? OP_IMUL
  3352.                                 : type == this_control.long_type
  3353.                                         ? OP_LMUL
  3354.                                         : type == this_control.float_type
  3355.                                                 ? OP_FMUL
  3356.                                                 : OP_DMUL); // double_type
  3357.              break;
  3358.         case AstBinaryExpression::SLASH:
  3359.              PutOp(integer_type ? OP_IDIV
  3360.                                 : type == this_control.long_type
  3361.                                         ? OP_LDIV
  3362.                                         : type == this_control.float_type
  3363.                                                 ? OP_FDIV
  3364.                                                 : OP_DDIV); // double_type
  3365.              break;
  3366.         case AstBinaryExpression::MOD:
  3367.              PutOp(integer_type ? OP_IREM
  3368.                                 : type == this_control.long_type
  3369.                                         ? OP_LREM
  3370.                                         : type == this_control.float_type
  3371.                                                 ? OP_FREM
  3372.                                                 : OP_DREM); // double_type
  3373.              break;
  3374.         case AstBinaryExpression::PLUS:
  3375.              PutOp(integer_type ? OP_IADD
  3376.                                 : type == this_control.long_type
  3377.                                         ? OP_LADD
  3378.                                         : type == this_control.float_type
  3379.                                                 ? OP_FADD
  3380.                                                 : OP_DADD); // double_type
  3381.              break;
  3382.         case AstBinaryExpression::MINUS:
  3383.              PutOp(integer_type ? OP_ISUB
  3384.                                 : type == this_control.long_type
  3385.                                         ? OP_LSUB
  3386.                                         : type == this_control.float_type
  3387.                                                 ? OP_FSUB
  3388.                                                 : OP_DSUB); // double_type
  3389.              break;
  3390.         case AstBinaryExpression::LEFT_SHIFT:
  3391.              PutOp(integer_type ? OP_ISHL : OP_LSHL);
  3392.              break;
  3393.         case AstBinaryExpression::RIGHT_SHIFT:
  3394.              PutOp(integer_type ? OP_ISHR : OP_LSHR);
  3395.              break;
  3396.         case AstBinaryExpression::UNSIGNED_RIGHT_SHIFT:
  3397.              PutOp(integer_type ? OP_IUSHR : OP_LUSHR);
  3398.              break;
  3399.         case AstBinaryExpression::AND:
  3400.              PutOp(integer_type ? OP_IAND : OP_LAND);
  3401.              break;
  3402.         case AstBinaryExpression::XOR:
  3403.              PutOp(integer_type ? OP_IXOR : OP_LXOR);
  3404.              break;
  3405.         case AstBinaryExpression::IOR:
  3406.              PutOp(integer_type ? OP_IOR : OP_LOR);
  3407.              break;
  3408.         default:
  3409.              assert(false && "binary unknown tag");
  3410.     }
  3411.  
  3412.     return GetTypeWords(expression -> Type());
  3413. }
  3414.  
  3415.  
  3416. int ByteCode::EmitCastExpression(AstCastExpression *expression)
  3417. {
  3418.     //
  3419.     // convert from numeric type src to destination type dest
  3420.     //
  3421.     EmitExpression(expression -> expression);
  3422.  
  3423.     TypeSymbol *dest_type = expression -> Type(),
  3424.                *source_type = expression -> expression -> Type();
  3425.     EmitCast(dest_type, source_type);
  3426.  
  3427.     return GetTypeWords(dest_type);
  3428. }
  3429.  
  3430.  
  3431. void ByteCode::EmitCast(TypeSymbol *dest_type, TypeSymbol *source_type)
  3432. {
  3433.     if (dest_type == source_type) // done if nothing to do
  3434.         return;
  3435.  
  3436.     if (this_control.IsSimpleIntegerValueType(source_type))
  3437.     {
  3438.         if (dest_type != this_control.int_type) // no conversion needed
  3439.         {
  3440.             Operators::operators op_kind = (dest_type == this_control.long_type
  3441.                                                        ? OP_I2L
  3442.                                                        : dest_type == this_control.float_type
  3443.                                                                     ? OP_I2F
  3444.                                                                     : dest_type == this_control.double_type
  3445.                                                                                  ? OP_I2D
  3446.                                                                                  : dest_type == this_control.char_type
  3447.                                                                                               ? OP_I2C
  3448.                                                                                               : dest_type == this_control.byte_type
  3449.                                                                                                            ? OP_I2B
  3450.                                                                                                            : OP_I2S); // short_type
  3451.             // If the type we wanted to cast to could not be matched then
  3452.             // the cast is invalid. For example, one might be trying
  3453.             // to cast an int to a Object.
  3454.             assert(op_kind != OP_I2S || dest_type == this_control.short_type);
  3455.  
  3456.             PutOp(op_kind);
  3457.         }
  3458.     }
  3459.     else if (source_type == this_control.long_type)
  3460.     {
  3461.         Operators::operators op_kind = (dest_type == this_control.float_type
  3462.                                                    ? OP_L2F
  3463.                                                    : dest_type == this_control.double_type
  3464.                                                                 ? OP_L2D
  3465.                                                                 : OP_L2I);
  3466.         PutOp(op_kind);
  3467.  
  3468.         if (op_kind == OP_L2I && dest_type != this_control.int_type)
  3469.         {
  3470.             assert(this_control.IsSimpleIntegerValueType(dest_type) && "unsupported conversion");
  3471.  
  3472.             PutOp(dest_type == this_control.char_type
  3473.                              ? OP_I2C
  3474.                              : dest_type == this_control.byte_type
  3475.                                           ? OP_I2B
  3476.                                           : OP_I2S); // short_type
  3477.         }
  3478.     }
  3479.     else if (source_type == this_control.float_type)
  3480.     {
  3481.         Operators::operators op_kind = (dest_type == this_control.long_type
  3482.                                                    ? OP_F2L
  3483.                                                    : dest_type == this_control.double_type
  3484.                                                                 ? OP_F2D
  3485.                                                                 : OP_F2I);
  3486.         PutOp(op_kind);
  3487.  
  3488.         if (op_kind == OP_F2I && dest_type != this_control.int_type)
  3489.         {
  3490.             assert(this_control.IsSimpleIntegerValueType(dest_type) && "unsupported conversion");
  3491.  
  3492.             PutOp(dest_type == this_control.char_type
  3493.                              ? OP_I2C
  3494.                              : dest_type == this_control.byte_type
  3495.                                           ? OP_I2B
  3496.                                           : OP_I2S); // short_type
  3497.         }
  3498.     }
  3499.     else if (source_type == this_control.double_type)
  3500.     {
  3501.         Operators::operators op_kind = (dest_type == this_control.long_type
  3502.                                                    ? OP_D2L
  3503.                                                    : dest_type == this_control.float_type
  3504.                                                                 ? OP_D2F
  3505.                                                                 : OP_D2I);
  3506.  
  3507.         PutOp(op_kind);
  3508.  
  3509.         if (op_kind == OP_D2I && dest_type != this_control.int_type)
  3510.         {
  3511.             assert(this_control.IsSimpleIntegerValueType(dest_type) && "unsupported conversion");
  3512.  
  3513.             PutOp(dest_type == this_control.char_type
  3514.                              ? OP_I2C
  3515.                              : dest_type == this_control.byte_type
  3516.                                           ? OP_I2B
  3517.                                           : OP_I2S); // short_type
  3518.         }
  3519.     }
  3520.     else if (source_type == this_control.null_type)
  3521.          ; // Nothing to do
  3522.     else
  3523.     {
  3524.         //
  3525.         // Generate check cast instruction.
  3526.         //
  3527.         PutOp(OP_CHECKCAST);
  3528.         PutU2(dest_type -> num_dimensions > 0 ? RegisterClass(dest_type -> signature)
  3529.                                               : RegisterClass(dest_type -> fully_qualified_name));
  3530.     }
  3531.  
  3532.     return;
  3533. }
  3534.  
  3535.  
  3536. int ByteCode::EmitClassInstanceCreationExpression(AstClassInstanceCreationExpression *expression, bool need_value)
  3537. {
  3538.     MethodSymbol *constructor = (MethodSymbol *) expression -> class_type -> symbol;
  3539.  
  3540.     PutOp(OP_NEW);
  3541.     PutU2(RegisterClass(expression -> Type() -> fully_qualified_name));
  3542.     if (need_value) // save address of new object for constructor
  3543.         PutOp(OP_DUP);
  3544.  
  3545.     //
  3546.     // call constructor
  3547.     // pass address of object explicitly passed to new if specified.
  3548.     //
  3549.     int stack_words = 0;
  3550.     if (expression -> base_opt)
  3551.     {
  3552.         stack_words += EmitExpression(expression -> base_opt);
  3553.         PutOp(OP_DUP);
  3554.  
  3555.         Label lab1;
  3556.         EmitBranch(OP_IFNONNULL, lab1);
  3557.         PutOp(OP_ACONST_NULL); // need to test for null, raising NullPointerException if so. So just do athrow
  3558.         PutOp(OP_ATHROW);
  3559.         DefineLabel(lab1);
  3560.         CompleteLabel(lab1);
  3561.     }
  3562.  
  3563.     //
  3564.     // Pass all local arguments, if any
  3565.     //
  3566.     for (int i = 0; i < expression -> NumLocalArguments(); i++)
  3567.         stack_words += EmitExpression((AstExpression *) expression -> LocalArgument(i));
  3568.  
  3569.     //
  3570.     // If we are calling a private constructor, pass the extra null argument to the access constructor.
  3571.     //
  3572.     if (expression -> NeedsExtraNullArgument())
  3573.     {
  3574.         PutOp(OP_ACONST_NULL);
  3575.         stack_words += 1;
  3576.     }
  3577.  
  3578.     //
  3579.     // Now, process the real arguments specified in the source.
  3580.     //
  3581.     for (int k = 0; k < expression -> NumArguments(); k++)
  3582.         stack_words += EmitExpression((AstExpression *) expression -> Argument(k));
  3583.  
  3584.     PutOp(OP_INVOKENONVIRTUAL);
  3585.     ChangeStack(-stack_words);
  3586.     PutU2(RegisterMethodref(expression -> Type() -> fully_qualified_name,
  3587.                             this_control.init_name_symbol -> Utf8_literal,
  3588.                             constructor -> signature));
  3589.  
  3590.     return 1;
  3591. }
  3592.  
  3593.  
  3594. int ByteCode::EmitConditionalExpression(AstConditionalExpression *expression)
  3595. {
  3596.     Label lab1,
  3597.           lab2;
  3598.     EmitBranchIfExpression(expression -> test_expression, false, lab1);
  3599.     EmitExpression(expression -> true_expression);
  3600.     EmitBranch(OP_GOTO, lab2);
  3601.     DefineLabel(lab1);
  3602.     EmitExpression(expression -> false_expression);
  3603.     DefineLabel(lab2);
  3604.     CompleteLabel(lab1);
  3605.     CompleteLabel(lab2);
  3606.  
  3607.     return GetTypeWords(expression -> true_expression -> Type());
  3608. }
  3609.  
  3610.  
  3611. int ByteCode::EmitFieldAccess(AstFieldAccess *expression)
  3612. {
  3613.     assert(! expression -> IsConstant());
  3614.  
  3615.     AstExpression *base = expression -> base;
  3616.     VariableSymbol *sym = expression -> symbol -> VariableCast();
  3617.  
  3618.     if (expression -> resolution_opt) // resolve reference to private field in parent
  3619.         return EmitExpression(expression -> resolution_opt);
  3620.  
  3621.     if (base -> Type() -> IsArray() && sym -> ExternalIdentity() == this_control.length_name_symbol)
  3622.     {
  3623.         EmitExpression(base);
  3624.         PutOp(OP_ARRAYLENGTH);
  3625.  
  3626.         return 1;
  3627.     }
  3628.  
  3629.     TypeSymbol *expression_type = expression -> Type();
  3630.     if (sym -> ACC_STATIC())
  3631.     {
  3632.         if (! base -> IsSimpleNameOrFieldAccess()) // if the base expression is an arbitrary expression, evaluate it for side effects.
  3633.         {
  3634.             EmitExpression(base);
  3635.             PutOp(OP_POP);
  3636.         }
  3637.         PutOp(OP_GETSTATIC);
  3638.         ChangeStack(this_control.IsDoubleWordType(expression_type) ? 2 : 1);
  3639.     }
  3640.     else
  3641.     {
  3642.         EmitExpression(base); // get base
  3643.         PutOp(OP_GETFIELD);
  3644.         ChangeStack(this_control.IsDoubleWordType(expression_type) ? 1 : 0);
  3645.     }
  3646.  
  3647.     PutU2(RegisterFieldref(VariableTypeResolution(expression, sym), sym));
  3648.  
  3649.     return GetTypeWords(expression_type);
  3650. }
  3651.  
  3652.  
  3653. void ByteCode::EmitMethodInvocation(AstMethodInvocation *expression)
  3654. {
  3655.     //
  3656.     // If the method call was resolved into a call to another method, use the resolution expression.
  3657.     //
  3658.     AstMethodInvocation *method_call = (expression -> resolution_opt
  3659.                                                     ? expression -> resolution_opt -> MethodInvocationCast()
  3660.                                                     : expression);
  3661.  
  3662.     MethodSymbol *msym = (MethodSymbol *) method_call -> symbol;
  3663.  
  3664.     bool is_super = false; // set if super call
  3665.  
  3666.     AstSimpleName *simple_name = method_call -> method -> SimpleNameCast();
  3667.     if (msym -> ACC_STATIC())
  3668.     {
  3669.         AstFieldAccess *field = expression -> resolution_opt ?
  3670.             (((MethodSymbol *)expression->symbol)->ACC_STATIC() ? expression->method->FieldAccessCast() : NULL)
  3671.             :
  3672.             method_call -> method -> FieldAccessCast()
  3673.             ;
  3674.  
  3675.         
  3676.         if (field)
  3677.         {
  3678.             // JLS 15.11.4.7
  3679.             if (field -> base -> MethodInvocationCast())
  3680.             {
  3681.                 EmitMethodInvocation(field -> base -> MethodInvocationCast());
  3682.                 PutOp(OP_POP); // discard value (only evaluating for side effect)
  3683.             }
  3684.             else if (field -> base -> ClassInstanceCreationExpressionCast())
  3685.             {
  3686.                 (void) EmitClassInstanceCreationExpression(field -> base -> ClassInstanceCreationExpressionCast(), false);
  3687.             }
  3688.             else 
  3689.             {
  3690.             // FIXME : diasbled because it is crashing jikes !
  3691.             // This seems to have been caused by a fix for bug #198
  3692.             //PutOp(EmitExpression(field -> base) == 2 ? OP_POP2 : OP_POP); // discard value
  3693.             }
  3694.         }
  3695.     }
  3696.     else
  3697.     {
  3698.         AstFieldAccess *field = method_call -> method -> FieldAccessCast();
  3699.         if (field)
  3700.         {
  3701.             AstFieldAccess *sub_field_access = field -> base -> FieldAccessCast();
  3702.             is_super = field -> base -> SuperExpressionCast() || (sub_field_access && sub_field_access -> IsSuperAccess());
  3703.  
  3704.             if (field -> base -> MethodInvocationCast())
  3705.                  EmitMethodInvocation(field -> base -> MethodInvocationCast());
  3706.             else EmitExpression(field -> base);
  3707.         }
  3708.         else if (method_call -> method -> SimpleNameCast())
  3709.         {
  3710.             if (simple_name -> resolution_opt) // use resolution if available
  3711.                 EmitExpression(simple_name -> resolution_opt);
  3712.             else // must be field of current object, so load this
  3713.                 PutOp(OP_ALOAD_0);
  3714.         }
  3715.         else assert(false && "unexpected argument to field access");
  3716.     }
  3717.  
  3718.     int stack_words = 0; // words on stack needed for arguments
  3719.     for (int i = 0; i < method_call -> NumArguments(); i++)
  3720.         stack_words += EmitExpression((AstExpression *) method_call -> Argument(i));
  3721.  
  3722.     TypeSymbol *type = MethodTypeResolution(method_call -> method, msym);
  3723.     PutOp(msym -> ACC_STATIC()
  3724.                 ? OP_INVOKESTATIC
  3725.                 : (is_super || msym -> ACC_PRIVATE())
  3726.                              ? OP_INVOKENONVIRTUAL
  3727.                              : type -> ACC_INTERFACE() ? OP_INVOKEINTERFACE : OP_INVOKEVIRTUAL);
  3728.     CompleteCall(msym, stack_words, type);
  3729.  
  3730.     return;
  3731. }
  3732.  
  3733.  
  3734. void ByteCode::CompleteCall(MethodSymbol *msym, int stack_words, TypeSymbol *base_type)
  3735. {
  3736.     ChangeStack(-stack_words);
  3737.  
  3738.     TypeSymbol *type = (base_type ? base_type : msym -> containing_type);
  3739.  
  3740.     PutU2(type -> ACC_INTERFACE() ? RegisterInterfaceMethodref(type -> fully_qualified_name,
  3741.                                                                msym -> ExternalIdentity() -> Utf8_literal,
  3742.                                                                msym -> signature)
  3743.                                   : RegisterMethodref(type -> fully_qualified_name,
  3744.                                                       msym -> ExternalIdentity() -> Utf8_literal,
  3745.                                                       msym -> signature));
  3746.  
  3747.     if (type -> ACC_INTERFACE())
  3748.     {
  3749.         PutU1(stack_words + 1);
  3750.         PutU1(0);
  3751.     }
  3752.  
  3753.     //
  3754.     // must account for value returned by method.
  3755.     //
  3756.     ChangeStack(this_control.IsDoubleWordType(msym -> Type()) ? 2 : msym -> Type() == this_control.void_type ? 0 : 1);
  3757.  
  3758.     return;
  3759. }
  3760.  
  3761.  
  3762. void ByteCode::EmitNewArray(int num_dims, TypeSymbol *type)
  3763. {
  3764.     if (num_dims == 0 || (num_dims == 1 && type -> num_dimensions == num_dims))
  3765.     {
  3766.         TypeSymbol *element_type = type -> ArraySubtype();
  3767.  
  3768.         if (this_control.IsNumeric(element_type) || element_type == this_control.boolean_type) // one-dimensional primitive?
  3769.         {
  3770.             PutOp(OP_NEWARRAY);
  3771.             PutU1(element_type == this_control.boolean_type
  3772.                          ? 4
  3773.                          : element_type == this_control.char_type
  3774.                                   ? 5
  3775.                                   : element_type == this_control.float_type
  3776.                                            ? 6
  3777.                                            : element_type == this_control.double_type
  3778.                                                     ? 7
  3779.                                                     : element_type == this_control.byte_type
  3780.                                                              ? 8
  3781.                                                              : element_type == this_control.short_type
  3782.                                                                       ? 9
  3783.                                                                       : element_type == this_control.int_type
  3784.                                                                                ? 10
  3785.                                                                                : 11); // control.long_type
  3786.         }
  3787.         else // must be reference type
  3788.         {
  3789.             PutOp(OP_ANEWARRAY);
  3790.             PutU2(RegisterClass(element_type -> fully_qualified_name));
  3791.         }
  3792.     }
  3793.     else
  3794.     {
  3795.         PutOp(OP_MULTIANEWARRAY);
  3796.         PutU2(RegisterClass(type -> signature));
  3797.         PutU1(num_dims); // load dims count
  3798.         ChangeStack(num_dims - 1);
  3799.     }
  3800.  
  3801.     return;
  3802. }
  3803.  
  3804.  
  3805. //
  3806. // POST_UNARY
  3807. //
  3808. int ByteCode::EmitPostUnaryExpression(AstPostUnaryExpression *expression, bool need_value)
  3809. {
  3810.     int kind = GetLhsKind(expression);
  3811.  
  3812.     switch(kind)
  3813.     {
  3814.         case LHS_LOCAL:
  3815.         case LHS_STATIC:
  3816.              EmitPostUnaryExpressionSimple(kind, expression, need_value);
  3817.              break;
  3818.         case LHS_ARRAY:
  3819.              EmitPostUnaryExpressionArray(expression, need_value);
  3820.              break;
  3821.         case LHS_FIELD:
  3822.              EmitPostUnaryExpressionField(kind, expression, need_value);
  3823.              break;
  3824.         case LHS_METHOD:
  3825.              {
  3826.                  VariableSymbol *accessed_member = expression -> write_method -> accessed_member -> VariableCast();
  3827.                  if (accessed_member -> ACC_STATIC())
  3828.                       EmitPostUnaryExpressionSimple(kind, expression, need_value);
  3829.                  else EmitPostUnaryExpressionField(kind, expression, need_value);
  3830.              }
  3831.              break;
  3832.         default:
  3833.              assert(false && "unknown lhs kind for assignment");
  3834.     }
  3835.  
  3836.     return GetTypeWords(expression -> Type());
  3837. }
  3838.  
  3839.  
  3840. //
  3841. // AstExpression *expression;
  3842. // POST_UNARY on instance variable
  3843. // load value of field, duplicate, do increment or decrement, then store back, leaving original value
  3844. // on top of stack.
  3845. //
  3846. void ByteCode::EmitPostUnaryExpressionField(int kind, AstPostUnaryExpression *expression, bool need_value)
  3847. {
  3848.     if (kind == LHS_METHOD)
  3849.          ResolveAccess(expression -> expression); // get address and value
  3850.     else EmitFieldAccessLhs(expression -> expression);
  3851.  
  3852.     TypeSymbol *expression_type = expression -> Type();
  3853.     if (need_value)
  3854.         PutOp(this_control.IsDoubleWordType(expression_type) ? OP_DUP2_X1 : OP_DUP_X1);
  3855.  
  3856.     if (this_control.IsSimpleIntegerValueType(expression_type))
  3857.     {
  3858.         PutOp(OP_ICONST_1);
  3859.         PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_IADD : OP_ISUB);
  3860.     }
  3861.     else if (expression_type == this_control.long_type)
  3862.     {
  3863.         PutOp(OP_LCONST_1);
  3864.         PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_LADD : OP_LSUB);
  3865.     }
  3866.     else if (expression_type == this_control.float_type)
  3867.     {
  3868.         PutOp(OP_FCONST_1);
  3869.         PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_FADD : OP_FSUB);
  3870.     }
  3871.     else if (expression_type == this_control.double_type)
  3872.     {
  3873.         PutOp(OP_DCONST_1); // load 1.0
  3874.         PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_DADD : OP_DSUB);
  3875.     }
  3876.  
  3877.     if (kind == LHS_METHOD)
  3878.     {
  3879.         int stack_words = (this_control.IsDoubleWordType(expression_type) ? 2 : 1) + 1;
  3880.         PutOp(OP_INVOKESTATIC);
  3881.         CompleteCall(expression -> write_method, stack_words);
  3882.     }
  3883.     else // assert(kind == LHS_FIELD)
  3884.     {
  3885.         PutOp(OP_PUTFIELD);
  3886.         ChangeStack(this_control.IsDoubleWordType(expression_type) ? -3 : -2);
  3887.  
  3888.         VariableSymbol *sym = (VariableSymbol *) expression -> symbol;
  3889.         PutU2(RegisterFieldref(VariableTypeResolution(expression -> expression, sym), sym));
  3890.     }
  3891.  
  3892.     return;
  3893. }
  3894.  
  3895.  
  3896. //
  3897. // AstExpression *expression;
  3898. // POST_UNARY on local variable
  3899. // load value of variable, duplicate, do increment or decrement, then store back, leaving original value
  3900. // on top of stack.
  3901. //
  3902. void ByteCode::EmitPostUnaryExpressionSimple(int kind, AstPostUnaryExpression *expression, bool need_value)
  3903. {
  3904.     TypeSymbol *expression_type = expression -> Type();
  3905.     if (kind == LHS_LOCAL && expression_type == this_control.int_type) // can we use IINC ??
  3906.     {
  3907.         if (need_value)
  3908.             (void) LoadVariable(kind, expression);
  3909.         PutOpIINC(expression -> symbol -> VariableCast() -> LocalVariableIndex(),
  3910.                   expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? 1 : -1);
  3911.         return;
  3912.     }
  3913.  
  3914.     (void) LoadVariable(kind, expression -> expression); // this will also load value needing resolution
  3915.  
  3916.     if (need_value)
  3917.         PutOp(this_control.IsDoubleWordType(expression_type) ? OP_DUP2 : OP_DUP);
  3918.  
  3919.     if (this_control.IsSimpleIntegerValueType(expression_type))
  3920.     {
  3921.         PutOp(OP_ICONST_1);
  3922.         PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_IADD : OP_ISUB);
  3923.         EmitCast(expression_type, this_control.int_type);
  3924.     }
  3925.     else if (expression_type == this_control.long_type)
  3926.     {
  3927.         PutOp(OP_LCONST_1);
  3928.         PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_LADD : OP_LSUB);
  3929.     }
  3930.     else if (expression_type == this_control.float_type)
  3931.     {
  3932.         PutOp(OP_FCONST_1);
  3933.         PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_FADD : OP_FSUB);
  3934.     }
  3935.     else if (expression_type == this_control.double_type)
  3936.     {
  3937.         PutOp(OP_DCONST_1); // load 1.0
  3938.         PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_DADD : OP_DSUB);
  3939.     }
  3940.  
  3941.     if (kind == LHS_METHOD)
  3942.     {
  3943.          int stack_words = this_control.IsDoubleWordType(expression_type) ? 2 : 1;
  3944.          PutOp(OP_INVOKESTATIC);
  3945.          CompleteCall(expression -> write_method, stack_words);
  3946.     }
  3947.     else StoreVariable(kind, expression -> expression);
  3948.  
  3949.     return;
  3950. }
  3951.  
  3952.  
  3953. //
  3954. // Post Unary for which operand is array element
  3955. // assignment for which lhs is array element
  3956. //    AstExpression *expression;
  3957. //
  3958. void ByteCode::EmitPostUnaryExpressionArray(AstPostUnaryExpression *expression, bool need_value)
  3959. {
  3960.     EmitArrayAccessLhs((AstArrayAccess *) expression -> expression); // lhs must be array access
  3961.     PutOp(OP_DUP2); // save array base and index for later store
  3962.  
  3963.     TypeSymbol *expression_type = expression -> Type();
  3964.     if (expression_type == this_control.int_type)
  3965.     {
  3966.          PutOp(OP_IALOAD);
  3967.          if (need_value) // save value below saved array base and index
  3968.              PutOp(OP_DUP_X2);
  3969.          PutOp(OP_ICONST_1);
  3970.          PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_IADD : OP_ISUB);
  3971.          PutOp(OP_IASTORE);
  3972.     }
  3973.     else if (expression_type == this_control.byte_type )
  3974.     {
  3975.          PutOp(OP_BALOAD);
  3976.          if (need_value) // save value below saved array base and index
  3977.              PutOp(OP_DUP_X2);
  3978.          PutOp(OP_ICONST_1);
  3979.          PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_IADD : OP_ISUB);
  3980.          PutOp(OP_I2B);
  3981.          PutOp(OP_BASTORE);
  3982.     }
  3983.     else if (expression_type == this_control.char_type )
  3984.     {
  3985.          PutOp(OP_CALOAD);
  3986.          if (need_value) // save value below saved array base and index
  3987.              PutOp(OP_DUP_X2);
  3988.          PutOp(OP_ICONST_1);
  3989.          PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_IADD : OP_ISUB);
  3990.          PutOp(OP_I2C);
  3991.          PutOp(OP_CASTORE);
  3992.     }
  3993.     else if (expression_type == this_control.short_type)
  3994.     {
  3995.          PutOp(OP_SALOAD);
  3996.          if (need_value) // save value below saved array base and index
  3997.              PutOp(OP_DUP_X2);
  3998.          PutOp(OP_ICONST_1);
  3999.          PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_IADD : OP_ISUB);
  4000.          PutOp(OP_I2S);
  4001.          PutOp(OP_SASTORE);
  4002.     }
  4003.     else if (expression_type == this_control.long_type)
  4004.     {
  4005.          PutOp(OP_LALOAD);
  4006.          if (need_value) // save value below saved array base and index
  4007.              PutOp(OP_DUP2_X2);
  4008.          PutOp(OP_LCONST_1);
  4009.          PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_LADD : OP_LSUB);
  4010.          PutOp(OP_LASTORE);
  4011.     }
  4012.     else if (expression_type == this_control.float_type)
  4013.     {
  4014.          PutOp(OP_FALOAD);
  4015.          if (need_value) // save value below saved array base and index
  4016.              PutOp(OP_DUP_X2);
  4017.          PutOp(OP_FCONST_1);
  4018.          PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_FADD : OP_FSUB);
  4019.          PutOp(OP_FASTORE);
  4020.     }
  4021.     else if (expression_type == this_control.double_type)
  4022.     {
  4023.          PutOp(OP_DALOAD);
  4024.          if (need_value) // save value below saved array base and index
  4025.              PutOp(OP_DUP2_X2);
  4026.          PutOp(OP_DCONST_1);
  4027.          PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_DADD : OP_DSUB);
  4028.          PutOp(OP_DASTORE);
  4029.     }
  4030.     else assert(false && "unsupported postunary type");
  4031.  
  4032.     return;
  4033. }
  4034.  
  4035.  
  4036. //
  4037. // PRE_UNARY
  4038. //
  4039. int ByteCode::EmitPreUnaryExpression(AstPreUnaryExpression *expression, bool need_value)
  4040. {
  4041.     TypeSymbol *type = expression -> Type();
  4042.     if (expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ||
  4043.         expression -> pre_unary_tag == AstPreUnaryExpression::MINUSMINUS)
  4044.     {
  4045.         EmitPreUnaryIncrementExpression(expression, need_value);
  4046.     }
  4047.     else // here for ordinary unary operator without side effects.
  4048.     {
  4049.         switch (expression -> pre_unary_tag)
  4050.         {
  4051.             case AstPreUnaryExpression::PLUS:
  4052.                  // nothing to do (front-end will have done any needed conversions)
  4053.                  EmitExpression(expression -> expression);
  4054.                  break;
  4055.             case AstPreUnaryExpression::MINUS:
  4056.                  EmitExpression(expression -> expression);
  4057.  
  4058.                  assert((this_control.IsSimpleIntegerValueType(type) ||
  4059.                          type == this_control.long_type ||
  4060.                          type == this_control.float_type ||
  4061.                          type == this_control.double_type) && "unary minus on unsupported type");
  4062.  
  4063.                  PutOp(this_control.IsSimpleIntegerValueType(type)
  4064.                            ? OP_INEG
  4065.                            : type == this_control.long_type
  4066.                                    ? OP_LNEG
  4067.                                    : type == this_control.float_type
  4068.                                            ? OP_FNEG
  4069.                                            : OP_DNEG); // double_type
  4070.                  break;
  4071.             case AstPreUnaryExpression::TWIDDLE:
  4072.                  if (this_control.IsSimpleIntegerValueType(type))
  4073.                  {
  4074.                      EmitExpression(expression -> expression);
  4075.                      PutOp(OP_ICONST_M1); // -1
  4076.                      PutOp(OP_IXOR);      // exclusive or to get result
  4077.                  }
  4078.                  else if (type == this_control.long_type)
  4079.                  {
  4080.                      EmitExpression(expression -> expression);
  4081.                      PutOp(OP_LCONST_1); // make -1
  4082.                      PutOp(OP_LNEG);
  4083.                      PutOp(OP_LXOR);     // exclusive or to get result
  4084.                  }
  4085.                  else assert(false && "unary ~ on unsupported type");
  4086.                  break;
  4087.             case AstPreUnaryExpression::NOT:
  4088.                 assert(type == this_control.boolean_type);
  4089.  
  4090.                 {
  4091.                     Label lab1,
  4092.                           lab2;
  4093.                     EmitExpression(expression -> expression);
  4094.                     EmitBranch(OP_IFEQ, lab1);
  4095.                     PutOp(OP_ICONST_0);       // turn true into false
  4096.                     EmitBranch(OP_GOTO, lab2);
  4097.                     DefineLabel(lab1);
  4098.                     PutOp(OP_ICONST_1);       // here to turn false into true
  4099.                     DefineLabel(lab2);
  4100.                     CompleteLabel(lab1);
  4101.                     CompleteLabel(lab2);
  4102.                 }
  4103.                 break;
  4104.             default:
  4105.                 assert(false && "unknown preunary tag");
  4106.         }
  4107.     }
  4108.  
  4109.     return GetTypeWords(type);
  4110. }
  4111.  
  4112.  
  4113. //
  4114. // PRE_UNARY with side effects (++X or --X)
  4115. //
  4116. void ByteCode::EmitPreUnaryIncrementExpression(AstPreUnaryExpression *expression, bool need_value)
  4117. {
  4118.     int kind = GetLhsKind(expression);
  4119.  
  4120.     switch(kind)
  4121.     {
  4122.         case LHS_LOCAL:
  4123.         case LHS_STATIC:
  4124.              EmitPreUnaryIncrementExpressionSimple(kind, expression, need_value);
  4125.              break;
  4126.         case LHS_ARRAY:
  4127.              EmitPreUnaryIncrementExpressionArray(expression, need_value);
  4128.              break;
  4129.         case LHS_FIELD:
  4130.              EmitPreUnaryIncrementExpressionField(kind, expression, need_value);
  4131.              break;
  4132.         case LHS_METHOD:
  4133.              {
  4134.                  VariableSymbol *accessed_member = expression -> write_method -> accessed_member -> VariableCast();
  4135.                  if (accessed_member -> ACC_STATIC())
  4136.                       EmitPreUnaryIncrementExpressionSimple(kind, expression, need_value);
  4137.                  else EmitPreUnaryIncrementExpressionField(kind, expression, need_value);
  4138.              }
  4139.              break;
  4140.         default:
  4141.              assert(false && "unknown lhs kind for assignment");
  4142.     }
  4143.  
  4144.     return;
  4145. }
  4146.  
  4147.  
  4148. //
  4149. //    AstExpression *expression;
  4150. // POST_UNARY on name
  4151. // load value of variable, do increment or decrement, duplicate, then store back, leaving original value
  4152. // on top of stack.
  4153. //
  4154. void ByteCode::EmitPreUnaryIncrementExpressionSimple(int kind, AstPreUnaryExpression *expression, bool need_value)
  4155. {
  4156.     TypeSymbol *type = expression -> Type();
  4157.     if (kind == LHS_LOCAL && type == this_control.int_type)
  4158.     {
  4159.         PutOpIINC(expression -> symbol -> VariableCast() -> LocalVariableIndex(),
  4160.                   expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? 1 : -1);
  4161.         if (need_value)
  4162.             (void) LoadVariable(kind, expression);
  4163.         return;
  4164.     }
  4165.  
  4166.     (void) LoadVariable(kind, expression -> expression); // will also load value if resolution needed
  4167.  
  4168.     if (this_control.IsSimpleIntegerValueType(type))
  4169.     {
  4170.         PutOp(OP_ICONST_1);
  4171.         PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_IADD : OP_ISUB);
  4172.         EmitCast(type, this_control.int_type);
  4173.         if (need_value)
  4174.             PutOp(OP_DUP);
  4175.     }
  4176.     else if (type == this_control.long_type)
  4177.     {
  4178.         PutOp(OP_LCONST_1);
  4179.         PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_LADD : OP_LSUB);
  4180.         if (need_value)
  4181.             PutOp(OP_DUP2);
  4182.     }
  4183.     else if (type == this_control.float_type)
  4184.     {
  4185.         PutOp(OP_FCONST_1);
  4186.         PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_FADD : OP_FSUB);
  4187.         if (need_value)
  4188.             PutOp(OP_DUP);
  4189.     }
  4190.     else if (type == this_control.double_type)
  4191.     {
  4192.         PutOp(OP_DCONST_1); // load 1.0
  4193.         PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_DADD : OP_DSUB);
  4194.         if (need_value)
  4195.             PutOp(OP_DUP2);
  4196.     }
  4197.  
  4198.     if (kind == LHS_METHOD)
  4199.     {
  4200.         int stack_words = this_control.IsDoubleWordType(type) ? 2 : 1;
  4201.         PutOp(OP_INVOKESTATIC);
  4202.         CompleteCall(expression -> write_method, stack_words);
  4203.     }
  4204.     else StoreVariable(kind, expression -> expression);
  4205.  
  4206.     return;
  4207. }
  4208.  
  4209.  
  4210. //
  4211. // Post Unary for which operand is array element
  4212. // assignment for which lhs is array element
  4213. //    AstExpression *expression;
  4214. //
  4215. void ByteCode::EmitPreUnaryIncrementExpressionArray(AstPreUnaryExpression *expression, bool need_value)
  4216. {
  4217.     EmitArrayAccessLhs((AstArrayAccess *) expression -> expression); // lhs must be array access
  4218.  
  4219.     PutOp(OP_DUP2); // save array base and index for later store
  4220.  
  4221.     TypeSymbol *type = expression -> Type();
  4222.     if (type == this_control.int_type)
  4223.     {
  4224.          PutOp(OP_IALOAD);
  4225.          PutOp(OP_ICONST_1);
  4226.          PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_IADD : OP_ISUB);
  4227.          if (need_value)
  4228.              PutOp(OP_DUP_X2);
  4229.          PutOp(OP_IASTORE);
  4230.     }
  4231.     else if (type == this_control.byte_type)
  4232.     {
  4233.          PutOp(OP_BALOAD);
  4234.          PutOp(OP_ICONST_1);
  4235.          PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_IADD : OP_ISUB);
  4236.          if (need_value)
  4237.              PutOp(OP_DUP_X2);
  4238.          PutOp(OP_I2B);
  4239.          PutOp(OP_BASTORE);
  4240.     }
  4241.     else if (type == this_control.char_type)
  4242.     {
  4243.          PutOp(OP_CALOAD);
  4244.          PutOp(OP_ICONST_1);
  4245.          PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_IADD : OP_ISUB);
  4246.          if (need_value)
  4247.              PutOp(OP_DUP_X2);
  4248.          PutOp(OP_I2C);
  4249.          PutOp(OP_CASTORE);
  4250.     }
  4251.     else if (type == this_control.short_type)
  4252.     {
  4253.          PutOp(OP_SALOAD);
  4254.          PutOp(OP_ICONST_1);
  4255.          PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_IADD : OP_ISUB);
  4256.          if (need_value)
  4257.              PutOp(OP_DUP_X2);
  4258.          PutOp(OP_I2S);
  4259.          PutOp(OP_SASTORE);
  4260.     }
  4261.     else if (type == this_control.long_type)
  4262.     {
  4263.          PutOp(OP_LALOAD);
  4264.          PutOp(OP_LCONST_1);
  4265.          PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_LADD : OP_LSUB);
  4266.          if (need_value)
  4267.              PutOp(OP_DUP2_X2);
  4268.          PutOp(OP_LASTORE);
  4269.     }
  4270.     else if (type == this_control.float_type)
  4271.     {
  4272.          PutOp(OP_FALOAD);
  4273.          PutOp(OP_FCONST_1);
  4274.          PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_FADD : OP_FSUB);
  4275.          if (need_value)
  4276.              PutOp(OP_DUP_X2);
  4277.          PutOp(OP_FASTORE);
  4278.     }
  4279.     else if (type == this_control.double_type)
  4280.     {
  4281.          PutOp(OP_DALOAD);
  4282.          PutOp(OP_DCONST_1);
  4283.          PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_DADD : OP_DSUB);
  4284.          if (need_value)
  4285.              PutOp(OP_DUP2_X2);
  4286.          PutOp(OP_DASTORE);
  4287.     }
  4288.     else assert(false && "unsupported PreUnary type");
  4289.  
  4290.     return;
  4291. }
  4292.  
  4293.  
  4294. //
  4295. // Pre Unary for which operand is field (instance variable)
  4296. // AstExpression *expression;
  4297. //
  4298. void ByteCode::EmitPreUnaryIncrementExpressionField(int kind, AstPreUnaryExpression *expression, bool need_value)
  4299. {
  4300.     if (kind == LHS_METHOD)
  4301.         ResolveAccess(expression -> expression); // get address and value
  4302.     else // need to load address of object, obtained from resolution, saving a copy on the stack
  4303.         EmitFieldAccessLhs(expression -> expression);
  4304.  
  4305.     TypeSymbol *expression_type = expression -> Type();
  4306.     if (this_control.IsSimpleIntegerValueType(expression_type))
  4307.     {
  4308.         PutOp(OP_ICONST_1);
  4309.         PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_IADD : OP_ISUB);
  4310.         EmitCast(expression_type, this_control.int_type);
  4311.         if (need_value)
  4312.             PutOp(OP_DUP_X1);
  4313.     }
  4314.     else if (expression_type == this_control.long_type)
  4315.     {
  4316.         PutOp(OP_LCONST_1);
  4317.         PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_LADD : OP_LSUB);
  4318.         if (need_value)
  4319.             PutOp(OP_DUP2_X1);
  4320.     }
  4321.     else if (expression_type == this_control.float_type)
  4322.     {
  4323.         PutOp(OP_FCONST_1);
  4324.         PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_FADD : OP_FSUB);
  4325.         if (need_value)
  4326.             PutOp(OP_DUP_X1);
  4327.     }
  4328.     else if (expression_type == this_control.double_type)
  4329.     {
  4330.         PutOp(OP_DCONST_1);
  4331.         PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_DADD : OP_DSUB);
  4332.         if (need_value)
  4333.             PutOp(OP_DUP2_X1);
  4334.     }
  4335.     else assert(false && "unsupported PreUnary type");
  4336.  
  4337.     if (kind == LHS_METHOD)
  4338.     {
  4339.         int stack_words = (this_control.IsDoubleWordType(expression_type) ? 2 : 1) + 1;
  4340.         PutOp(OP_INVOKESTATIC);
  4341.         CompleteCall(expression -> write_method, stack_words);
  4342.     }
  4343.     else
  4344.     {
  4345.         PutOp(OP_PUTFIELD);
  4346.         ChangeStack(this_control.IsDoubleWordType(expression_type) ? -3 : -2);
  4347.  
  4348.         VariableSymbol *sym = (VariableSymbol *) expression -> symbol;
  4349.         PutU2(RegisterFieldref(VariableTypeResolution(expression -> expression, sym), sym));
  4350.     }
  4351.  
  4352.     return;
  4353. }
  4354.  
  4355.  
  4356. void ByteCode::EmitThisInvocation(AstThisCall *this_call)
  4357. {
  4358.     //
  4359.     // THIS_CALL
  4360.     //    AstExpression *method;
  4361.     //    AstList *arguments;
  4362.     // A call to another constructor (THIS_CALL) or super constructor (SUPER_CALL)
  4363.     // result in the same sort of generated code, as the semantic analysis
  4364.     // has resolved the proper constructor to be invoked.
  4365.     //
  4366.     PutOp(OP_ALOAD_0); // load 'this'
  4367.  
  4368.     int stack_words = 0; // words on stack needed for arguments
  4369.     if (this_call -> base_opt)
  4370.         stack_words += EmitExpression(this_call -> base_opt);
  4371.  
  4372.     for (int i = 0; i < this_call -> NumLocalArguments(); i++)
  4373.         stack_words += EmitExpression((AstExpression *) this_call -> LocalArgument(i));
  4374.  
  4375.     for (int k = 0; k < this_call -> NumArguments(); k++)
  4376.         stack_words += EmitExpression((AstExpression *) this_call -> Argument(k));
  4377.  
  4378.     PutOp(OP_INVOKENONVIRTUAL);
  4379.     ChangeStack(-stack_words);
  4380.  
  4381.     PutU2(RegisterMethodref(unit_type -> fully_qualified_name,
  4382.                             this_call -> symbol -> ExternalIdentity() -> Utf8_literal,
  4383.                             this_call -> symbol -> signature));
  4384.  
  4385.     return;
  4386. }
  4387.  
  4388.  
  4389. void ByteCode::EmitSuperInvocation(AstSuperCall *super_call)
  4390. {
  4391.     PutOp(OP_ALOAD_0); // load 'this'
  4392.  
  4393.     int stack_words = 0; // words on stack needed for arguments
  4394.     if (super_call -> base_opt)
  4395.         stack_words += EmitExpression(super_call -> base_opt);
  4396.  
  4397.     for (int i = 0; i < super_call -> NumLocalArguments(); i++)
  4398.         stack_words += EmitExpression((AstExpression *) super_call -> LocalArgument(i));
  4399.  
  4400.     if (super_call -> NeedsExtraNullArgument())
  4401.     {
  4402.         PutOp(OP_ACONST_NULL);
  4403.         stack_words += 1;
  4404.     }
  4405.  
  4406.     for (int k = 0; k < super_call -> NumArguments(); k++)
  4407.         stack_words += EmitExpression((AstExpression *) super_call -> Argument(k));
  4408.  
  4409.     PutOp(OP_INVOKENONVIRTUAL);
  4410.     ChangeStack(-stack_words);
  4411.  
  4412.     PutU2(RegisterMethodref(unit_type -> super -> fully_qualified_name,
  4413.                             super_call -> symbol -> ExternalIdentity() -> Utf8_literal,
  4414.                             super_call -> symbol -> signature));
  4415.  
  4416.     return;
  4417. }
  4418.  
  4419.  
  4420. //
  4421. //  Methods for string concatenation
  4422. //
  4423. void ByteCode::ConcatenateString(AstBinaryExpression *expression)
  4424. {
  4425.     //
  4426.     // generate code to concatenate strings, by generating a string buffer and appending the arguments
  4427.     // before calling toString, i.e.,
  4428.     //  s1+s2 compiles to
  4429.     //  new StringBuffer().append(s1).append(s2).toString();
  4430.     // look for sequences of concatenation to use a single buffer where possible
  4431.     //
  4432.     // Call appropriate constructor depending on whether or not first operand is a string.
  4433.     //
  4434.     PutOp(OP_NEW);
  4435.     PutU2(RegisterClass(this_control.StringBuffer() -> fully_qualified_name));
  4436.     PutOp(OP_DUP);
  4437.     if (expression -> left_expression -> IsConstant())
  4438.     {
  4439.         assert(expression -> left_expression -> Type() == this_control.String());
  4440.  
  4441.         EmitExpression(expression -> left_expression);
  4442.         PutOp(OP_INVOKENONVIRTUAL);
  4443.         PutU2(RegisterLibraryMethodref(this_control.StringBuffer_InitWithStringMethod()));
  4444.         ChangeStack(-1);
  4445.     }
  4446.     else
  4447.     {
  4448.         PutOp(OP_INVOKENONVIRTUAL);
  4449.         PutU2(RegisterLibraryMethodref(this_control.StringBuffer_InitMethod()));
  4450.  
  4451.         AppendString(expression -> left_expression);
  4452.     }
  4453.  
  4454.     AppendString(expression -> right_expression);
  4455.  
  4456.     //
  4457.     // convert string buffer to string
  4458.     //
  4459.     PutOp(OP_INVOKEVIRTUAL);
  4460.     PutU2(RegisterLibraryMethodref(this_control.StringBuffer_toStringMethod()));
  4461.     ChangeStack(1); // account for return value
  4462.  
  4463.     return;
  4464. }
  4465.  
  4466.  
  4467. void ByteCode::AppendString(AstExpression *expression)
  4468. {
  4469.     TypeSymbol *type = expression -> Type();
  4470.  
  4471.     if (expression -> IsConstant())
  4472.     {
  4473.         assert(type == this_control.String());
  4474.         LoadConstantAtIndex(RegisterString((Utf8LiteralValue *) expression -> value));
  4475.     }
  4476.     else
  4477.     {
  4478.         AstBinaryExpression *binary_expression = expression -> BinaryExpressionCast();
  4479.         if (binary_expression)
  4480.         {
  4481.             if (binary_expression -> binary_tag == AstBinaryExpression::PLUS &&
  4482.                 (IsReferenceType(binary_expression -> left_expression -> Type()) ||
  4483.                  IsReferenceType(binary_expression -> right_expression -> Type())))
  4484.             {
  4485.                 AppendString(binary_expression -> left_expression);
  4486.                 AppendString(binary_expression -> right_expression);
  4487.  
  4488.                 return;
  4489.             }
  4490.         }
  4491.  
  4492.         if (expression -> ParenthesizedExpressionCast())
  4493.         {
  4494.             AppendString(expression -> ParenthesizedExpressionCast() -> expression);
  4495.             return;
  4496.         }
  4497.  
  4498.         AstCastExpression *cast = expression -> CastExpressionCast();
  4499.         if (cast) // here if cast expression, verify that converting to string
  4500.         {
  4501.             if (cast -> kind == Ast::CAST && cast -> Type() == this_control.String())
  4502.             {
  4503.                 AppendString(cast -> expression);
  4504.                 return;
  4505.             }
  4506.         }
  4507.  
  4508.         EmitExpression(expression);
  4509.     }
  4510.  
  4511.     EmitStringAppendMethod(type);
  4512.  
  4513.     return;
  4514. }
  4515.  
  4516.  
  4517. void ByteCode::EmitStringAppendMethod(TypeSymbol *type)
  4518. {
  4519.     //
  4520.     // Find appropriate append routine to add to string buffer
  4521.     //
  4522.     MethodSymbol *append_method =
  4523.             (type -> num_dimensions == 1 && type -> base_type == this_control.char_type
  4524.                    ? this_control.StringBuffer_append_char_arrayMethod()
  4525.                    : type == this_control.char_type
  4526.                           ? this_control.StringBuffer_append_charMethod()
  4527.                           : type == this_control.boolean_type
  4528.                                  ? this_control.StringBuffer_append_booleanMethod()
  4529.                                  : type == this_control.int_type ||
  4530.                                    type == this_control.short_type ||
  4531.                                    type == this_control.byte_type
  4532.                                         ? this_control.StringBuffer_append_intMethod()
  4533.                                         : type == this_control.long_type
  4534.                                                ? this_control.StringBuffer_append_longMethod()
  4535.                                                : type == this_control.float_type
  4536.                                                       ? this_control.StringBuffer_append_floatMethod()
  4537.                                                       : type == this_control.double_type
  4538.                                                              ? this_control.StringBuffer_append_doubleMethod()
  4539.                                                              : type == this_control.String()
  4540.                                                                     ? this_control.StringBuffer_append_stringMethod()
  4541.                                                                     : IsReferenceType(type)
  4542.                                                                           ? this_control.StringBuffer_append_objectMethod()
  4543.                                                                           : this_control.StringBuffer_InitMethod()); // for assertion
  4544.  
  4545.     assert(append_method != this_control.StringBuffer_InitMethod() && "unable to find method for string buffer concatenation");
  4546.  
  4547.     PutOp(OP_INVOKEVIRTUAL);
  4548.     ChangeStack(this_control.IsDoubleWordType(type) ? -2 : -1);
  4549.     PutU2(RegisterLibraryMethodref(append_method));
  4550.     ChangeStack(1); // account for return value
  4551.  
  4552.     return;
  4553. }
  4554.  
  4555.  
  4556. #ifdef JIKES_DEBUG
  4557. static void op_trap()
  4558. {
  4559.     int i = 0; // used for debugger trap
  4560.     i++;       // avoid compiler warnings about unused variable
  4561. }
  4562. #endif
  4563.  
  4564.  
  4565. ByteCode::ByteCode(TypeSymbol *unit_type) : ClassFile(unit_type),
  4566.                                             this_control(unit_type -> semantic_environment -> sem -> control),
  4567.                                             this_semantic(*unit_type -> semantic_environment -> sem),
  4568.  
  4569.                                             string_overflow(false),
  4570.                                             library_method_not_found(false),
  4571.  
  4572.                                             double_constant_pool_index(NULL),
  4573.                                             integer_constant_pool_index(NULL),
  4574.                                             long_constant_pool_index(NULL),
  4575.                                             float_constant_pool_index(NULL),
  4576.                                             string_constant_pool_index(NULL),
  4577.  
  4578.                                             utf8_constant_pool_index(segment_pool, this_control.Utf8_pool.symbol_pool.Length()),
  4579.                                             class_constant_pool_index(segment_pool, this_control.Utf8_pool.symbol_pool.Length()),
  4580.  
  4581.                                             name_and_type_constant_pool_index(NULL),
  4582.                                             fieldref_constant_pool_index(NULL),
  4583.                                             methodref_constant_pool_index(NULL)
  4584. {
  4585. #ifdef JIKES_DEBUG
  4586.     if (! this_control.option.nowrite)
  4587.         this_control.class_files_written++;
  4588. #endif
  4589.  
  4590.     SetFlags(unit_type -> Flags());
  4591.  
  4592.     //
  4593.     // The flags for 'static' and 'protected' are set only for the inner
  4594.     // classes attribute, not for the class, as described in page 25
  4595.     // of the inner classes document.
  4596.     //
  4597.     if (unit_type -> ACC_PROTECTED())
  4598.     {
  4599.         this -> ResetACC_PROTECTED();
  4600.         this -> SetACC_PUBLIC();
  4601.     }
  4602.     this -> ResetACC_STATIC();
  4603.     this -> ResetACC_PRIVATE();
  4604.     this -> SetACC_SUPER(); // must always set ACC_SUPER for class (cf page 96 of revised JVM Spec)
  4605.  
  4606.     magic = 0xcafebabe;
  4607.     major_version = 45;             // use Sun JDK 1.0 version numbers
  4608.     minor_version = 3;
  4609.     constant_pool.Next() = NULL;
  4610.     this_class = RegisterClass(unit_type -> fully_qualified_name);
  4611.  
  4612.     super_class = (unit_type -> super ? RegisterClass(unit_type -> super -> fully_qualified_name) : 0);
  4613.  
  4614.     for (int k = 0; k < unit_type -> NumInterfaces(); k++)
  4615.         interfaces.Next() = RegisterClass(unit_type -> Interface(k) -> fully_qualified_name);
  4616.  
  4617.     return;
  4618. }
  4619.  
  4620.  
  4621. //
  4622. //  Methods for manipulating labels
  4623. //
  4624. void ByteCode::DefineLabel(Label& lab)
  4625. {
  4626.     assert((! lab.defined) && "duplicate label definition");
  4627.  
  4628.     lab.defined = true;
  4629.     lab.definition = code_attribute -> CodeLength();
  4630.     if (lab.definition > last_label_pc)
  4631.         last_label_pc = lab.definition;
  4632.  
  4633.     return;
  4634. }
  4635.  
  4636.  
  4637. //
  4638. // patch all uses to have proper value. This requires that
  4639. // all labels be freed at some time.
  4640. //
  4641. void ByteCode::CompleteLabel(Label& lab)
  4642. {
  4643.     if (lab.uses.Length() > 0)
  4644.     {
  4645.         assert((lab.defined) && "label used but with no definition");
  4646.  
  4647.         //
  4648.         // patch byte code reference to label to reflect it's definition
  4649.         // as 16-bit signed offset.
  4650.         //
  4651.         for (int i = 0; i < lab.uses.Length(); i++)
  4652.         {
  4653.             unsigned int luse = lab.uses[i].use_offset;
  4654.             int start = luse - lab.uses[i].op_offset,
  4655.                 offset = lab.definition - start;
  4656.             if (lab.uses[i].use_length == 2) // here if short offset
  4657.             {
  4658.                 code_attribute -> ResetCode(luse, (offset >> 8) & 0xFF);
  4659.                 code_attribute -> ResetCode(luse + 1, offset & 0xFF);
  4660.             }
  4661.             else if (lab.uses[i].use_length == 4) // here if 4 byte use
  4662.             {
  4663.                 code_attribute -> ResetCode(luse, (offset >> 24) & 0xFF);
  4664.                 code_attribute -> ResetCode(luse + 1, (offset >> 16) & 0xFF);
  4665.                 code_attribute -> ResetCode(luse + 2, (offset >>  8) & 0xFF);
  4666.                 code_attribute -> ResetCode(luse + 3, offset & 0xFF);
  4667.             }
  4668.             else assert(false &&  "label use length not 2 or 4");
  4669.         }
  4670.     }
  4671.  
  4672.     //
  4673.     // reset in case label is used again.
  4674.     //
  4675.     lab.Reset();
  4676.  
  4677.     return;
  4678. }
  4679.  
  4680.  
  4681. void ByteCode::UseLabel(Label &lab, int _length, int _op_offset)
  4682. {
  4683.     int lab_index = lab.uses.NextIndex();
  4684.     lab.uses[lab_index].use_length = _length;
  4685.     lab.uses[lab_index].op_offset = _op_offset;
  4686.     lab.uses[lab_index].use_offset = code_attribute -> CodeLength();
  4687.  
  4688.     //
  4689.     // fill next length bytes with zero; will be filled in with proper value when label completed
  4690.     //
  4691.     for (int i = 0; i < lab.uses[lab_index].use_length; i++)
  4692.         code_attribute -> AddCode(0);
  4693.  
  4694.     return;
  4695. }
  4696.  
  4697.  
  4698. void ByteCode::LoadLocal(int varno, TypeSymbol *type)
  4699. {
  4700.     if (this_control.IsSimpleIntegerValueType(type) || type == this_control.boolean_type)
  4701.     {
  4702.          if (varno <= 3)
  4703.               PutOp(OP_ILOAD_0 + varno);
  4704.          else PutOpWide(OP_ILOAD, varno);
  4705.     }
  4706.     else if (type == this_control.long_type)
  4707.     {
  4708.          if (varno <= 3)
  4709.               PutOp(OP_LLOAD_0 + varno);
  4710.          else PutOpWide(OP_LLOAD, varno);
  4711.     }
  4712.     else if (type == this_control.float_type)
  4713.     {
  4714.          if (varno <= 3)
  4715.               PutOp(OP_FLOAD_0 + varno);
  4716.          else PutOpWide(OP_FLOAD, varno);
  4717.     }
  4718.     else if (type == this_control.double_type)
  4719.     {
  4720.          if (varno <= 3)
  4721.               PutOp(OP_DLOAD_0 + varno);
  4722.          else PutOpWide(OP_DLOAD, varno);
  4723.     }
  4724.     else // assume reference
  4725.     {
  4726.          if (varno <= 3)
  4727.               PutOp(OP_ALOAD_0 + varno);
  4728.          else PutOpWide(OP_ALOAD, varno);
  4729.     }
  4730.  
  4731.     return;
  4732. }
  4733.  
  4734.  
  4735. //
  4736. // see if can load without using LDC even if have literal index; otherwise generate constant pool entry
  4737. // if one has not yet been generated.
  4738. //
  4739. //
  4740. void ByteCode::LoadLiteral(LiteralValue *litp, TypeSymbol *type)
  4741. {
  4742.     if (litp == this_control.NullValue())
  4743.     {
  4744.         PutOp(OP_ACONST_NULL);
  4745.     }
  4746.     else if (this_control.IsSimpleIntegerValueType(type) || type == this_control.boolean_type) // load literal using literal value
  4747.     {
  4748.         IntLiteralValue *vp = (IntLiteralValue *) litp;
  4749.         int val = vp -> value;
  4750.         if (val >= -32768 && val < 32768) // In this case, we might be able to use an immediate instruction
  4751.              LoadImmediateInteger(val);
  4752.         else LoadConstantAtIndex(RegisterInteger(vp));
  4753.     }
  4754.     else if (type == this_control.String()) // register index as string if this has not yet been done
  4755.     {
  4756.         LoadConstantAtIndex(RegisterString((Utf8LiteralValue *) litp));
  4757.     }
  4758.     else if (type == this_control.long_type)
  4759.     {
  4760.         LongLiteralValue *vp = (LongLiteralValue *) litp;
  4761.         if (vp -> value == 0)
  4762.              PutOp(OP_LCONST_0);
  4763.         else if (vp -> value == 1)
  4764.              PutOp(OP_LCONST_1);
  4765.         else
  4766.         {
  4767.              PutOp(OP_LDC2_W);
  4768.              PutU2(RegisterLong(vp));
  4769.         }
  4770.     }
  4771.     else if (type == this_control.float_type)
  4772.     {
  4773.         FloatLiteralValue *vp = (FloatLiteralValue *) litp;
  4774.         IEEEfloat val = vp -> value;
  4775.         if (val.Word() == 0) // if float 0.0
  4776.              PutOp(OP_FCONST_0);
  4777.         else if (val.Word() == 0x3f800000) // if float 1.0
  4778.              PutOp(OP_FCONST_1);
  4779.         else if (val.Word() == 0x40000000) // if float 2.0
  4780.              PutOp(OP_FCONST_2);
  4781.         else LoadConstantAtIndex(RegisterFloat(vp));
  4782.     }
  4783.     else if (type == this_control.double_type)
  4784.     {
  4785.         DoubleLiteralValue *vp = (DoubleLiteralValue *) litp;
  4786.         IEEEdouble val = vp -> value;
  4787.         if (val.HighWord() == 0 && val.LowWord() == 0)
  4788.              PutOp(OP_DCONST_0);
  4789.         else if (val.HighWord() == 0x3ff00000 && val.LowWord() == 0x00000000) // if double 1.0
  4790.              PutOp(OP_DCONST_1);
  4791.         else
  4792.         {
  4793.              PutOp(OP_LDC2_W);
  4794.              PutU2(RegisterDouble(vp));
  4795.         }
  4796.     }
  4797.     else assert(false && "unsupported constant kind");
  4798.  
  4799.     return;
  4800. }
  4801.  
  4802.  
  4803. void ByteCode::LoadImmediateInteger(int val)
  4804. {
  4805.     if (val >= -1 && val <= 5)
  4806.          PutOp(OP_ICONST_0 + val); // exploit opcode encoding
  4807.     else if (val >= -128 && val < 128)
  4808.     {
  4809.          PutOp(OP_BIPUSH);
  4810.          PutU1(val);
  4811.     }
  4812.     else
  4813.     {
  4814.         //
  4815.         // For a short value, look to see if it is already in the constant pool.
  4816.         // For a value outside the short range, make sure it is entered in the
  4817.         // constant pool.
  4818.         //
  4819.         u2 index = (val >= -32768 && val < 32768 ? FindInteger(this_control.int_pool.Find(val))
  4820.                                                  : RegisterInteger(this_control.int_pool.FindOrInsert(val)));
  4821.         if (index == 0) // a short value that was not previously registered in the constant pool
  4822.         {
  4823.             PutOp(OP_SIPUSH);
  4824.             PutU1(val >> 8);
  4825.             PutU1(val);
  4826.         }
  4827.         else LoadConstantAtIndex(index);
  4828.     }
  4829.  
  4830.     return;
  4831. }
  4832.  
  4833.  
  4834. //
  4835. // Call to an access method for a compound operator such as ++, --,
  4836. // or "op=".
  4837. //
  4838. void ByteCode::ResolveAccess(AstExpression *p)
  4839. {
  4840.     AstFieldAccess *field = p -> FieldAccessCast();
  4841.     AstExpression *resolve_expression = (field ? field -> resolution_opt : p -> SimpleNameCast() -> resolution_opt);
  4842.     AstMethodInvocation *read_method = resolve_expression -> MethodInvocationCast();
  4843.  
  4844.     assert(read_method && read_method -> NumArguments() == 1); // a read method has exactly one argument: the object in question.
  4845.  
  4846.     int stack_words = EmitExpression((AstExpression *) read_method -> Argument(0));
  4847.     PutOp(OP_DUP);
  4848.     PutOp(OP_INVOKESTATIC);
  4849.     CompleteCall(read_method -> symbol -> MethodCast(), stack_words);
  4850.  
  4851.     return;
  4852. }
  4853.  
  4854.  
  4855. int ByteCode::LoadVariable(int kind, AstExpression *expr)
  4856. {
  4857.     VariableSymbol *sym = (VariableSymbol *) expr -> symbol;
  4858.     TypeSymbol *expression_type = expr -> Type();
  4859.     switch (kind)
  4860.     {
  4861.         case LHS_LOCAL:
  4862.              LoadLocal(sym -> LocalVariableIndex(), expression_type);
  4863.              break;
  4864.         case LHS_METHOD:
  4865.              EmitExpression(expr); // will do resolution
  4866.              break;
  4867.         case LHS_FIELD:
  4868.         case LHS_STATIC:
  4869.              {
  4870.                  if (sym -> ACC_STATIC())
  4871.                  {
  4872.                      PutOp(OP_GETSTATIC);
  4873.                      ChangeStack(GetTypeWords(expression_type));
  4874.                  }
  4875.                  else
  4876.                  {
  4877.                      PutOp(OP_ALOAD_0); // get address of "this"
  4878.                      PutOp(OP_GETFIELD);
  4879.                      ChangeStack(GetTypeWords(expression_type) - 1);
  4880.                  }
  4881.  
  4882.                  PutU2(RegisterFieldref(VariableTypeResolution(expr, sym), sym));
  4883.              }
  4884.              break;
  4885.         default:
  4886.              assert(false && "LoadVariable bad kind");
  4887.     }
  4888.  
  4889.     return GetTypeWords(expression_type);
  4890. }
  4891.  
  4892.  
  4893. //
  4894. // load reference from local variable.
  4895. // otherwise will use getstatic or getfield.
  4896. //
  4897. void ByteCode::LoadReference(AstExpression *expression)
  4898. {
  4899.     if (expression -> ParenthesizedExpressionCast())
  4900.         expression = UnParenthesize(expression);
  4901.  
  4902.     VariableSymbol *sym = expression -> symbol -> VariableCast();
  4903.     if (sym && sym -> owner -> MethodCast()) // a local variable ?
  4904.     {
  4905.         int varno = sym -> LocalVariableIndex();
  4906.         LoadLocal(varno, expression -> Type());
  4907.         return;
  4908.     }
  4909.  
  4910.     AstFieldAccess *field_access = expression -> FieldAccessCast();
  4911.     if (field_access)
  4912.     {
  4913.         if (field_access -> resolution_opt) // This field access was resolved... Process the resolution
  4914.         {
  4915.             EmitExpression(field_access -> resolution_opt);
  4916.             return;
  4917.         }
  4918.  
  4919.         if (sym -> ACC_STATIC())
  4920.         {
  4921.             PutOp(OP_GETSTATIC);
  4922.             ChangeStack(1);
  4923.         }
  4924.         else
  4925.         {
  4926.             EmitExpression(field_access -> base);
  4927.             PutOp(OP_GETFIELD);
  4928.             ChangeStack(0);
  4929.         }
  4930.  
  4931.         PutU2(RegisterFieldref(VariableTypeResolution(field_access, sym), sym));
  4932.     }
  4933.     else if (expression -> ArrayAccessCast()) // nested array reference
  4934.     {
  4935.         EmitArrayAccessLhs(expression -> ArrayAccessCast());
  4936.         PutOp(OP_AALOAD);
  4937.     }
  4938.     else // must have expression, the value of which is reference
  4939.         EmitExpression(expression);
  4940.  
  4941.     return;
  4942. }
  4943.  
  4944.  
  4945. int ByteCode::LoadArrayElement(TypeSymbol *type)
  4946. {
  4947.     PutOp(type == this_control.byte_type || type == this_control.boolean_type
  4948.                 ? OP_BALOAD
  4949.                 : type == this_control.short_type
  4950.                         ? OP_SALOAD
  4951.                         : type == this_control.int_type
  4952.                                 ? OP_IALOAD
  4953.                                 : type == this_control.long_type
  4954.                                         ? OP_LALOAD
  4955.                                         : type == this_control.char_type
  4956.                                                 ? OP_CALOAD
  4957.                                                 : type == this_control.float_type
  4958.                                                         ? OP_FALOAD
  4959.                                                         : type == this_control.double_type
  4960.                                                                 ? OP_DALOAD
  4961.                                                                 : OP_AALOAD); // assume reference
  4962.  
  4963.     return GetTypeWords(type);
  4964. }
  4965.  
  4966.  
  4967. void ByteCode::StoreArrayElement(TypeSymbol *type)
  4968. {
  4969.     PutOp(type == this_control.byte_type || type == this_control.boolean_type
  4970.                 ? OP_BASTORE
  4971.                 : type == this_control.short_type
  4972.                         ? OP_SASTORE
  4973.                         : type == this_control.int_type
  4974.                                 ? OP_IASTORE
  4975.                                 : type == this_control.long_type
  4976.                                         ? OP_LASTORE
  4977.                                         : type == this_control.char_type
  4978.                                                 ? OP_CASTORE
  4979.                                                 : type == this_control.float_type
  4980.                                                         ? OP_FASTORE
  4981.                                                         : type == this_control.double_type
  4982.                                                                 ? OP_DASTORE
  4983.                                                                 : OP_AASTORE); // assume reference
  4984.  
  4985.     return;
  4986. }
  4987.  
  4988.  
  4989. //
  4990. //  Method to generate field reference
  4991. //
  4992. void ByteCode::StoreField(AstExpression *expression)
  4993. {
  4994.     VariableSymbol *sym = (VariableSymbol *) expression -> symbol;
  4995.     TypeSymbol *expression_type = expression -> Type();
  4996.     if (sym -> ACC_STATIC())
  4997.     {
  4998.         PutOp(OP_PUTSTATIC);
  4999.         ChangeStack(this_control.IsDoubleWordType(expression_type) ? -2 : -1);
  5000.     }
  5001.     else
  5002.     {
  5003.         PutOp(OP_PUTFIELD);
  5004.         ChangeStack(this_control.IsDoubleWordType(expression_type) ? -3 : -2);
  5005.     }
  5006.  
  5007.     PutU2(RegisterFieldref(VariableTypeResolution(expression, sym), sym));
  5008.  
  5009.     return;
  5010. }
  5011.  
  5012.  
  5013. void ByteCode::StoreLocal(int varno, TypeSymbol *type)
  5014. {
  5015.     if (this_control.IsSimpleIntegerValueType(type) || type == this_control.boolean_type)
  5016.     {
  5017.          if (varno <= 3)
  5018.               PutOp(OP_ISTORE_0 + varno);
  5019.          else PutOpWide(OP_ISTORE, varno);
  5020.     }
  5021.     else if (type == this_control.long_type)
  5022.     {
  5023.          if (varno <= 3)
  5024.               PutOp(OP_LSTORE_0 + varno);
  5025.          else PutOpWide(OP_LSTORE, varno);
  5026.     }
  5027.     else if (type == this_control.float_type)
  5028.     {
  5029.          if (varno <= 3)
  5030.               PutOp(OP_FSTORE_0 + varno);
  5031.          else PutOpWide(OP_FSTORE, varno);
  5032.     }
  5033.     else if (type == this_control.double_type)
  5034.     {
  5035.          if (varno <= 3)
  5036.               PutOp(OP_DSTORE_0 + varno);
  5037.          else PutOpWide(OP_DSTORE, varno);
  5038.     }
  5039.     else // assume reference
  5040.     {
  5041.          if (varno <= 3)
  5042.               PutOp(OP_ASTORE_0 + varno);
  5043.          else PutOpWide(OP_ASTORE, varno);
  5044.     }
  5045.  
  5046.     return;
  5047. }
  5048.  
  5049.  
  5050. void ByteCode::StoreVariable(int kind, AstExpression *expr)
  5051. {
  5052.     VariableSymbol *sym = (VariableSymbol *) expr -> symbol;
  5053.     switch (kind)
  5054.     {
  5055.         case LHS_LOCAL:
  5056.              StoreLocal(sym -> LocalVariableIndex(), sym -> Type());
  5057.              break;
  5058.         case LHS_FIELD:
  5059.         case LHS_STATIC:
  5060.              {
  5061.                  if (sym -> ACC_STATIC())
  5062.                  {
  5063.                      PutOp(OP_PUTSTATIC);
  5064.                      ChangeStack(this_control.IsDoubleWordType(expr -> Type()) ? -2 : -1);
  5065.                  }
  5066.                  else
  5067.                  {
  5068.                      PutOp(OP_ALOAD_0); // get address of "this"
  5069.                      PutOp(OP_PUTFIELD);
  5070.                      ChangeStack(this_control.IsDoubleWordType(expr -> Type()) ? -3 : -2);
  5071.                  }
  5072.  
  5073.                  PutU2(RegisterFieldref(VariableTypeResolution(expr, sym), sym));
  5074.              }
  5075.              break;
  5076.         default:
  5077.             assert(false && "StoreVariable bad kind");
  5078.     }
  5079.  
  5080.     return;
  5081. }
  5082.  
  5083.  
  5084. //
  5085. // finish off code by writing SourceFile attribute
  5086. // and InnerClasses attribute (if appropriate)
  5087. //
  5088. void ByteCode::FinishCode(TypeSymbol *type)
  5089. {
  5090.     attributes.Next() = new SourceFile_attribute(RegisterUtf8(this_control.Sourcefile_literal),
  5091.                                                  RegisterUtf8(type -> file_symbol -> FileNameLiteral()));
  5092.  
  5093.     if (type == NULL)
  5094.         return; // return if interface type
  5095.  
  5096.     if (type -> IsLocal() || type -> IsNested() || type -> NumNestedTypes() > 0) // here to generate InnerClasses attribute
  5097.     {
  5098.         inner_classes_attribute = new InnerClasses_attribute(RegisterUtf8(this_control.InnerClasses_literal));
  5099.  
  5100.         //
  5101.         // need to build chain from this type to its owner all the way to the containing type
  5102.         // and then write that out in reverse order (so containing type comes first),
  5103.         // and then write out an entry for each immediately contained type
  5104.         //
  5105.         Tuple<TypeSymbol *> owners;
  5106.         for (TypeSymbol *t = type; t && t != type -> outermost_type; t = t -> ContainingType())
  5107.             owners.Next() = t;
  5108.  
  5109.         for (int j = owners.Length() - 1; j >= 0; j--)
  5110.         {
  5111.             TypeSymbol *outer = owners[j];
  5112.             inner_classes_attribute -> AddInnerClass(RegisterClass(outer -> fully_qualified_name),
  5113.                                                      outer -> IsLocal()
  5114.                                                             ? 0
  5115.                                                             : RegisterClass(outer -> ContainingType() -> fully_qualified_name),
  5116.                                                      outer -> Anonymous()
  5117.                                                             ? 0
  5118.                                                             : RegisterUtf8(outer -> name_symbol -> Utf8_literal),
  5119.                                                      outer -> Flags());
  5120.         }
  5121.  
  5122.         for (int k = 0; k < type -> NumNestedTypes(); k++)
  5123.         {
  5124.             TypeSymbol *nested = type -> NestedType(k);
  5125.             inner_classes_attribute -> AddInnerClass(RegisterClass(nested -> fully_qualified_name),
  5126.                                                      nested -> IsLocal()
  5127.                                                              ? 0
  5128.                                                              : RegisterClass(nested -> ContainingType() -> fully_qualified_name),
  5129.                                                      nested -> Anonymous()
  5130.                                                              ? 0
  5131.                                                              : RegisterUtf8(nested -> name_symbol -> Utf8_literal),
  5132.                                                      nested -> Flags());
  5133.         }
  5134.  
  5135.         attributes.Next() = inner_classes_attribute;
  5136.     }
  5137.  
  5138.     if (type -> IsDeprecated())
  5139.         attributes.Next() = CreateDeprecatedAttribute();
  5140.  
  5141.     return;
  5142. }
  5143.  
  5144.  
  5145. void ByteCode::PutOp(unsigned char opc)
  5146. {
  5147. #ifdef JIKES_DEBUG
  5148.     if (this_control.option.debug_trap_op > 0 && code_attribute -> CodeLength() == this_control.option.debug_trap_op)
  5149.         op_trap();
  5150.  
  5151.     //
  5152.     // debug trick - force branch on opcode to see what opcode we are compiling
  5153.     //
  5154.     switch (opc)
  5155.     {
  5156.         case OP_NOP: break;
  5157.         case OP_ACONST_NULL: break;
  5158.         case OP_ICONST_M1: break;
  5159.         case OP_ICONST_0: break;
  5160.         case OP_ICONST_1: break;
  5161.         case OP_ICONST_2: break;
  5162.         case OP_ICONST_3: break;
  5163.         case OP_ICONST_4: break;
  5164.         case OP_ICONST_5: break;
  5165.         case OP_LCONST_0: break;
  5166.         case OP_LCONST_1: break;
  5167.         case OP_FCONST_0: break;
  5168.         case OP_FCONST_1: break;
  5169.         case OP_FCONST_2: break;
  5170.         case OP_DCONST_0: break;
  5171.         case OP_DCONST_1: break;
  5172.         case OP_BIPUSH: break;
  5173.         case OP_SIPUSH: break;
  5174.         case OP_LDC: break;
  5175.         case OP_LDC_W: break;
  5176.         case OP_LDC2_W: break;
  5177.         case OP_ILOAD: break;
  5178.         case OP_LLOAD: break;
  5179.         case OP_FLOAD: break;
  5180.         case OP_DLOAD: break;
  5181.         case OP_ALOAD: break;
  5182.         case OP_ILOAD_0: break;
  5183.         case OP_ILOAD_1: break;
  5184.         case OP_ILOAD_2: break;
  5185.         case OP_ILOAD_3: break;
  5186.         case OP_LLOAD_0: break;
  5187.         case OP_LLOAD_1: break;
  5188.         case OP_LLOAD_2: break;
  5189.         case OP_LLOAD_3: break;
  5190.         case OP_FLOAD_0: break;
  5191.         case OP_FLOAD_1: break;
  5192.         case OP_FLOAD_2: break;
  5193.         case OP_FLOAD_3: break;
  5194.         case OP_DLOAD_0: break;
  5195.         case OP_DLOAD_1: break;
  5196.         case OP_DLOAD_2: break;
  5197.         case OP_DLOAD_3: break;
  5198.         case OP_ALOAD_0: break;
  5199.         case OP_ALOAD_1: break;
  5200.         case OP_ALOAD_2: break;
  5201.         case OP_ALOAD_3: break;
  5202.         case OP_IALOAD: break;
  5203.         case OP_LALOAD: break;
  5204.         case OP_FALOAD: break;
  5205.         case OP_DALOAD: break;
  5206.         case OP_AALOAD: break;
  5207.         case OP_BALOAD: break;
  5208.         case OP_CALOAD: break;
  5209.         case OP_SALOAD: break;
  5210.         case OP_ISTORE: break;
  5211.         case OP_LSTORE: break;
  5212.         case OP_FSTORE: break;
  5213.         case OP_DSTORE: break;
  5214.         case OP_ASTORE: break;
  5215.         case OP_ISTORE_0: break;
  5216.         case OP_ISTORE_1: break;
  5217.         case OP_ISTORE_2: break;
  5218.         case OP_ISTORE_3: break;
  5219.         case OP_LSTORE_0: break;
  5220.         case OP_LSTORE_1: break;
  5221.         case OP_LSTORE_2: break;
  5222.         case OP_LSTORE_3: break;
  5223.         case OP_FSTORE_0: break;
  5224.         case OP_FSTORE_1: break;
  5225.         case OP_FSTORE_2: break;
  5226.         case OP_FSTORE_3: break;
  5227.         case OP_DSTORE_0: break;
  5228.         case OP_DSTORE_1: break;
  5229.         case OP_DSTORE_2: break;
  5230.         case OP_DSTORE_3: break;
  5231.         case OP_ASTORE_0: break;
  5232.         case OP_ASTORE_1: break;
  5233.         case OP_ASTORE_2: break;
  5234.         case OP_ASTORE_3: break;
  5235.         case OP_IASTORE: break;
  5236.         case OP_LASTORE: break;
  5237.         case OP_FASTORE: break;
  5238.         case OP_DASTORE: break;
  5239.         case OP_AASTORE: break;
  5240.         case OP_BASTORE: break;
  5241.         case OP_CASTORE: break;
  5242.         case OP_SASTORE: break;
  5243.         case OP_POP: break;
  5244.         case OP_POP2: break;
  5245.         case OP_DUP: break;
  5246.         case OP_DUP_X1: break;
  5247.         case OP_DUP_X2: break;
  5248.         case OP_DUP2: break;
  5249.         case OP_DUP2_X1: break;
  5250.         case OP_DUP2_X2: break;
  5251.         case OP_SWAP: break;
  5252.         case OP_IADD: break;
  5253.         case OP_LADD: break;
  5254.         case OP_FADD: break;
  5255.         case OP_DADD: break;
  5256.         case OP_ISUB: break;
  5257.         case OP_LSUB: break;
  5258.         case OP_FSUB: break;
  5259.         case OP_DSUB: break;
  5260.         case OP_IMUL: break;
  5261.         case OP_LMUL: break;
  5262.         case OP_FMUL: break;
  5263.         case OP_DMUL: break;
  5264.         case OP_IDIV: break;
  5265.         case OP_LDIV: break;
  5266.         case OP_FDIV: break;
  5267.         case OP_DDIV: break;
  5268.         case OP_IREM: break;
  5269.         case OP_LREM: break;
  5270.         case OP_FREM: break;
  5271.         case OP_DREM: break;
  5272.         case OP_INEG: break;
  5273.         case OP_LNEG: break;
  5274.         case OP_FNEG: break;
  5275.         case OP_DNEG: break;
  5276.         case OP_ISHL: break;
  5277.         case OP_LSHL: break;
  5278.         case OP_ISHR: break;
  5279.         case OP_LSHR: break;
  5280.         case OP_IUSHR: break;
  5281.         case OP_LUSHR: break;
  5282.         case OP_IAND: break;
  5283.         case OP_LAND: break;
  5284.         case OP_IOR: break;
  5285.         case OP_LOR: break;
  5286.         case OP_IXOR: break;
  5287.         case OP_LXOR: break;
  5288.         case OP_IINC: break;
  5289.         case OP_I2L: break;
  5290.         case OP_I2F: break;
  5291.         case OP_I2D: break;
  5292.         case OP_L2I: break;
  5293.         case OP_L2F: break;
  5294.         case OP_L2D: break;
  5295.         case OP_F2I: break;
  5296.         case OP_F2L: break;
  5297.         case OP_F2D: break;
  5298.         case OP_D2I: break;
  5299.         case OP_D2L: break;
  5300.         case OP_D2F: break;
  5301.         case OP_I2B: break;
  5302.         case OP_I2C: break;
  5303.         case OP_I2S: break;
  5304.         case OP_LCMP: break;
  5305.         case OP_FCMPL: break;
  5306.         case OP_FCMPG: break;
  5307.         case OP_DCMPL: break;
  5308.         case OP_DCMPG: break;
  5309.         case OP_IFEQ: break;
  5310.         case OP_IFNE: break;
  5311.         case OP_IFLT: break;
  5312.         case OP_IFGE: break;
  5313.         case OP_IFGT: break;
  5314.         case OP_IFLE: break;
  5315.         case OP_IF_ICMPEQ: break;
  5316.         case OP_IF_ICMPNE: break;
  5317.         case OP_IF_ICMPLT: break;
  5318.         case OP_IF_ICMPGE: break;
  5319.         case OP_IF_ICMPGT: break;
  5320.         case OP_IF_ICMPLE: break;
  5321.         case OP_IF_ACMPEQ: break;
  5322.         case OP_IF_ACMPNE: break;
  5323.         case OP_GOTO: break;
  5324.         case OP_JSR: break;
  5325.         case OP_RET: break;
  5326.         case OP_TABLESWITCH: break;
  5327.         case OP_LOOKUPSWITCH: break;
  5328.         case OP_IRETURN: break;
  5329.         case OP_LRETURN: break;
  5330.         case OP_FRETURN: break;
  5331.         case OP_DRETURN: break;
  5332.         case OP_ARETURN: break;
  5333.         case OP_RETURN: break;
  5334.         case OP_GETSTATIC: break;
  5335.         case OP_PUTSTATIC: break;
  5336.         case OP_GETFIELD: break;
  5337.         case OP_PUTFIELD: break;
  5338.         case OP_INVOKEVIRTUAL: break;
  5339.         case OP_INVOKENONVIRTUAL: break;
  5340.         case OP_INVOKESTATIC: break;
  5341.         case OP_INVOKEINTERFACE: break;
  5342.         case OP_XXXUNUSEDXXX: break;
  5343.         case OP_NEW: break;
  5344.         case OP_NEWARRAY: break;
  5345.         case OP_ANEWARRAY: break;
  5346.         case OP_ARRAYLENGTH: break;
  5347.         case OP_ATHROW: break;
  5348.         case OP_CHECKCAST: break;
  5349.         case OP_INSTANCEOF: break;
  5350.         case OP_MONITORENTER: break;
  5351.         case OP_MONITOREXIT: break;
  5352.         case OP_WIDE: break;
  5353.         case OP_MULTIANEWARRAY: break;
  5354.         case OP_IFNULL: break;
  5355.         case OP_IFNONNULL: break;
  5356.         case OP_GOTO_W: break;
  5357.         case OP_JSR_W: break;
  5358.         case OP_SOFTWARE: break;
  5359.         case OP_HARDWARE: break;
  5360.     }
  5361. #endif
  5362.  
  5363.     last_op_pc = code_attribute -> CodeLength(); // save pc at start of operation
  5364.     code_attribute -> AddCode(opc);
  5365.     ChangeStack(stack_effect[opc]);
  5366.  
  5367.     return;
  5368. }
  5369.  
  5370. void ByteCode::PutOpWide(unsigned char opc, u2 var)
  5371. {
  5372.     if (var <= 255)  // if can use standard form
  5373.     {
  5374.         PutOp(opc);
  5375.         PutU1(var);
  5376.     }
  5377.     else // need wide form
  5378.     {
  5379.         PutOp(OP_WIDE);
  5380.         PutOp(opc);
  5381.         PutU2(var);
  5382.     }
  5383.  
  5384.     return;
  5385. }
  5386.  
  5387. void ByteCode::PutOpIINC(u2 var, int val)
  5388. {
  5389.     if (var <= 255 && (val >= -128 && val <= 127))  // if can use standard form
  5390.     {
  5391.         PutOp(OP_IINC);
  5392.         PutU1(var);
  5393.         PutU1(val);
  5394.     }
  5395.     else // else need wide form
  5396.     {
  5397.         PutOp(OP_WIDE);
  5398.         PutOp(OP_IINC);
  5399.         PutU2(var);
  5400.         PutU2(val);
  5401.     }
  5402. }
  5403.  
  5404. void ByteCode::ChangeStack(int i)
  5405. {
  5406.     stack_depth += i;
  5407.     if (stack_depth < 0)
  5408.         stack_depth = 0;
  5409.  
  5410.     if (i > 0 && stack_depth > max_stack)
  5411.         max_stack = stack_depth;
  5412.  
  5413. #ifdef TRACE_STACK_CHANGE
  5414.     Coutput << "stack change: pc "
  5415.             << last_op_pc
  5416.             << " change "
  5417.             << i
  5418.             << "  stack_depth "
  5419.             << stack_depth
  5420.             << "  max_stack: "
  5421.             << max_stack
  5422.             << "\n";
  5423. #endif
  5424.  
  5425.     return;
  5426. }
  5427.  
  5428.  
  5429. #ifdef JIKES_DEBUG
  5430. void ByteCode::PrintCode()
  5431. {
  5432.     Coutput << "magic " << hex << magic << dec
  5433.             << " major_version " << (unsigned) major_version
  5434.             << " minor_version " << (unsigned) minor_version << "\n";
  5435.     AccessFlags::Print();
  5436.     Coutput << "\n"
  5437.             << " this_class " << (unsigned) this_class << "  super_class " << (unsigned) super_class <<"\n"
  5438.             << " constant_pool: " << constant_pool.Length() << "\n";
  5439.  
  5440.     {
  5441.         for (int i = 1; i < constant_pool.Length(); i++)
  5442.         {
  5443.             Coutput << "  " << i << "  ";
  5444.             constant_pool[i] -> Print(constant_pool);
  5445.             if (constant_pool[i] -> Tag() == CONSTANT_Long || constant_pool[i] -> Tag() == CONSTANT_Double)
  5446.                 i++; // skip the next entry for eight-byte constants
  5447.         }
  5448.     }
  5449.  
  5450.     Coutput << "  interfaces " << interfaces.Length() <<": ";
  5451.     {
  5452.         for (int i = 0; i < interfaces.Length(); i++)
  5453.              Coutput << "  " << (int) interfaces[i];
  5454.         Coutput <<"\n";
  5455.     }
  5456.  
  5457.     Coutput << "  fields " << fields.Length() <<": ";
  5458.     {
  5459.         for (int i = 0; i < fields.Length(); i++)
  5460.         {
  5461.             Coutput << "field " << i << "\n";
  5462.             fields[i].Print(constant_pool);
  5463.         }
  5464.     }
  5465.  
  5466.     Coutput << " methods length " << methods.Length() << "\n";
  5467.     {
  5468.         for (int i = 0; i < methods.Length(); i++)
  5469.         {
  5470.             Coutput << "method " << i << "\n";
  5471.             methods[i].Print(constant_pool);
  5472.         }
  5473.     }
  5474.  
  5475.     Coutput << " attributes length " << attributes.Length() << "\n";
  5476.     {
  5477.         for (int i = 0; i < attributes.Length(); i++)
  5478.         {
  5479.             Coutput << "attribute " << i << "\n";
  5480.             attributes[i] -> Print(constant_pool);
  5481.         }
  5482.     }
  5483.     Coutput << "\n";
  5484.  
  5485.     return;
  5486. }
  5487. #endif
  5488.  
  5489. #ifdef    HAVE_JIKES_NAMESPACE
  5490. }            // Close namespace Jikes block
  5491. #endif
  5492.  
  5493.