home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Programming / jikes-1.02 / src / bytecode.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-05  |  192.8 KB  |  5,356 lines

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