Main Page | Class Hierarchy | Compound List | File List | Compound Members | File Members | Related Pages

bytecode.cpp

00001 /*
00002  * Copyright (c) 2003, Raymond Bosman
00003  * Copyright (c) 2003, Frederik Holljen
00004  * All Rights Reserved.
00005  *
00006  * See COPYING for licensing.
00007  */
00008 
00009 
00010 #include "bytecode.hpp"
00011 #include "constantpool.hpp"
00012 
00013 #include <iostream>
00014 
00015 namespace ClassEncoder
00016 {
00017 using namespace std;
00018 
00019 /*
00020   byte  // 1-byte signed 2's complement integer
00021   short  // 2-byte signed 2's complement integer
00022   int  // 4-byte signed 2's complement integer
00023   long  // 8-byte signed 2's complement integer
00024   float  // 4-byte IEEE 754 single-precision float
00025   double  // 8-byte IEEE 754 double-precision float
00026   char  // 2-byte unsigned Unicode character
00027 
00028  */
00029 
00031 
00034 ByteCode::ByteCode( ConstantPool *pool )
00035 {
00036     ConstantPoolEntries = pool;
00037     StackSize = 0;
00038     MaxStackSize = 0;
00039 }
00040 
00042 
00045 ByteCode::~ByteCode()
00046 {
00047 }
00048 
00050 
00053 void ByteCode::write( ofstream &stream ) const
00054 {
00055     for( vector<u1>::const_iterator it = Code.begin(); it != Code.end(); ++it )
00056     {
00057         writeu1( stream, *it );
00058     }
00059 }
00060 
00062 
00066 void ByteCode::push( int num )
00067 {
00068     if( num == 0 ) return;
00069     StackSize += num;
00070     if( StackSize > MaxStackSize ) MaxStackSize = StackSize;
00071 }
00072 
00074 
00078 void ByteCode::pop( int num )
00079 {
00080     if( num == 0 ) return;
00081         StackSize -= num;
00082 }
00083 
00084 // PUSH CONSTANTS ONTO THE STACK
00089 
00091 
00095 unsigned int ByteCode::emit_iconst( int number )
00096 {
00097     u2 pos = Code.size();
00098     switch( number )
00099     {
00100         case 0:
00101             Code.push_back( jvm_iconst_0 );
00102             break;
00103         case 1:
00104             Code.push_back( jvm_iconst_1 );
00105             break;
00106         case 2:
00107             Code.push_back( jvm_iconst_2 );
00108             break;
00109         case 3:
00110             Code.push_back( jvm_iconst_3 );
00111             break;
00112         case 4:
00113             Code.push_back( jvm_iconst_4 );
00114             break;
00115         case 5:
00116             Code.push_back( jvm_iconst_5 );
00117             break;
00118         default:
00119             cerr << "Warning: ByteCode::emit_iconst( int ) number above 5 given. Using sipush!\n";
00120             return emit_sipush( number );
00121             break;
00122     }
00123     push();
00124     return pos;
00125 }
00126 
00128 
00132 unsigned int ByteCode::emit_bipush( u1 num )
00133 {
00134     u2 pos = Code.size();
00135     Code.push_back( jvm_bipush );
00136     Code.push_back( num );
00137     push();
00138     return pos;
00139 }
00140 
00142 
00146 unsigned int ByteCode::emit_sipush( u2 num )
00147 {
00148     u2 pos = Code.size();
00149     Code.push_back( jvm_sipush );
00150     Code.push_back( (u1)(num >> 8) );
00151     Code.push_back( (u1)num );
00152     push( );
00153     return pos;
00154 }
00155 
00157 
00161 unsigned int ByteCode::emit_ldc( u1 index )
00162 {
00163     u2 pos = Code.size();
00164     Code.push_back( jvm_ldc );
00165     Code.push_back( index );
00166     return pos;
00167 }
00168 
00170 
00174 unsigned int ByteCode::emit_ldc2( u2 index )
00175 {
00176     u2 pos = Code.size();
00177     Code.push_back( jvm_ldc_w );
00178     Code.push_back( (u1)(index >> 8) );
00179     Code.push_back( (u1)index );
00180     return pos;
00181 }
00183 
00184 
00185 // LOADING LOCALS ON THE STACK
00190 
00191 
00193 
00197 unsigned int ByteCode::emit_iload( u1 vindex )
00198 {
00199     u2 pos = Code.size();
00200     switch( vindex )
00201     {
00202         case 0:
00203             Code.push_back( jvm_iload_0 );
00204             break;
00205         case 1:
00206             Code.push_back( jvm_iload_1 );
00207             break;
00208         case 2:
00209             Code.push_back( jvm_iload_2 );
00210             break;
00211         case 3:
00212             Code.push_back( jvm_iload_3 );
00213             break;
00214         default:
00215             Code.push_back( jvm_iload );
00216             Code.push_back( vindex );
00217     }
00218     push();
00219     return pos;
00220 }
00221 
00223 
00227 unsigned int ByteCode::emit_lload( u1 vindex )
00228 {
00229     u2 pos = Code.size();
00230     switch( vindex )
00231     {
00232         case 0:
00233             Code.push_back( jvm_lload_0 );
00234             break;
00235         case 1:
00236             Code.push_back( jvm_lload_1 );
00237             break;
00238         case 2:
00239             Code.push_back( jvm_lload_2 );
00240             break;
00241         case 3:
00242             Code.push_back( jvm_lload_3 );
00243             break;
00244         default:
00245             Code.push_back( jvm_lload );
00246             Code.push_back( vindex );
00247     }
00248     push( 2 );
00249     return pos;
00250 }
00251 
00253 
00257 unsigned int ByteCode::emit_fload( u1 vindex )
00258 {
00259     u2 pos = Code.size();
00260     switch( vindex )
00261     {
00262         case 0:
00263             Code.push_back( jvm_fload_0 );
00264             break;
00265         case 1:
00266             Code.push_back( jvm_fload_1 );
00267             break;
00268         case 2:
00269             Code.push_back( jvm_fload_2 );
00270             break;
00271         case 3:
00272             Code.push_back( jvm_fload_3 );
00273             break;
00274         default:
00275             Code.push_back( jvm_fload );
00276             Code.push_back( vindex );
00277     }
00278     push( 1 );
00279     return pos;
00280 }
00281 
00283 
00287 unsigned int ByteCode::emit_dload( u1 vindex )
00288 {
00289     u2 pos = Code.size();
00290     switch( vindex )
00291     {
00292         case 0:
00293             Code.push_back( jvm_dload_0 );
00294             break;
00295         case 1:
00296             Code.push_back( jvm_dload_1 );
00297             break;
00298         case 2:
00299             Code.push_back( jvm_dload_2 );
00300             break;
00301         case 3:
00302             Code.push_back( jvm_dload_3 );
00303             break;
00304         default:
00305             Code.push_back( jvm_dload );
00306             Code.push_back( vindex );
00307     }
00308     push( 2 );
00309     return pos;
00310 }
00311 
00313 
00317 unsigned int ByteCode::emit_aload( u1 vindex )
00318 {
00319     u2 pos = Code.size();
00320     switch( vindex )
00321     {
00322         case 0:
00323             Code.push_back( jvm_aload_0 );
00324             break;
00325         case 1:
00326             Code.push_back( jvm_aload_1 );
00327             break;
00328         case 2:
00329             Code.push_back( jvm_aload_2 );
00330             break;
00331         case 3:
00332             Code.push_back( jvm_aload_3 );
00333             break;
00334         default:
00335             Code.push_back( jvm_aload );
00336             Code.push_back( vindex );
00337     }
00338     push( 1 );
00339     return pos;
00340 }
00342 
00343 // STORING STACK TO LOCALS
00348 
00349 
00351 
00355 unsigned int ByteCode::emit_istore( u1 vindex )
00356 {
00357     u2 pos = Code.size();
00358     switch( vindex )
00359     {
00360         case 0:
00361             Code.push_back( jvm_istore_0 );
00362             break;
00363         case 1:
00364             Code.push_back( jvm_istore_1 );
00365             break;
00366         case 2:
00367             Code.push_back( jvm_istore_2 );
00368             break;
00369         case 3:
00370             Code.push_back( jvm_istore_3 );
00371             break;
00372         default:
00373             Code.push_back( jvm_istore );
00374             Code.push_back( vindex );
00375     }
00376     pop( 1 );
00377     return pos;
00378 }
00379 
00381 
00385 unsigned int ByteCode::emit_lstore( u1 vindex )
00386 {
00387     u2 pos = Code.size();
00388     switch( vindex )
00389     {
00390         case 0:
00391             Code.push_back( jvm_lstore_0 );
00392             break;
00393         case 1:
00394             Code.push_back( jvm_lstore_1 );
00395             break;
00396         case 2:
00397             Code.push_back( jvm_lstore_2 );
00398             break;
00399         case 3:
00400             Code.push_back( jvm_lstore_3 );
00401             break;
00402         default:
00403             Code.push_back( jvm_lstore );
00404             Code.push_back( vindex );
00405     }
00406     pop( 2 );
00407     return pos;
00408 }
00409 
00411 
00415 unsigned int ByteCode::emit_fstore( u1 vindex )
00416 {
00417     u2 pos = Code.size();
00418     switch( vindex )
00419     {
00420         case 0:
00421             Code.push_back( jvm_fstore_0 );
00422             break;
00423         case 1:
00424             Code.push_back( jvm_fstore_1 );
00425             break;
00426         case 2:
00427             Code.push_back( jvm_fstore_2 );
00428             break;
00429         case 3:
00430             Code.push_back( jvm_fstore_3 );
00431             break;
00432         default:
00433             Code.push_back( jvm_fstore );
00434             Code.push_back( vindex );
00435     }
00436     pop( 1 );
00437     return pos;
00438 
00439 }
00440 
00442 
00446 unsigned int ByteCode::emit_dstore( u1 vindex )
00447 {
00448     u2 pos = Code.size();
00449     switch( vindex )
00450     {
00451         case 0:
00452             Code.push_back( jvm_dstore_0 );
00453             break;
00454         case 1:
00455             Code.push_back( jvm_dstore_1 );
00456             break;
00457         case 2:
00458             Code.push_back( jvm_dstore_2 );
00459             break;
00460         case 3:
00461             Code.push_back( jvm_dstore_3 );
00462             break;
00463         default:
00464             Code.push_back( jvm_dstore );
00465             Code.push_back( vindex );
00466     }
00467     pop( 2 );
00468     return pos;
00469 }
00470 
00472 
00476 unsigned int ByteCode::emit_astore( u1 vindex )
00477 {
00478     u2 pos = Code.size();
00479     switch( vindex )
00480     {
00481         case 0:
00482             Code.push_back( jvm_astore_0 );
00483             break;
00484         case 1:
00485             Code.push_back( jvm_astore_1 );
00486             break;
00487         case 2:
00488             Code.push_back( jvm_astore_2 );
00489             break;
00490         case 3:
00491             Code.push_back( jvm_astore_3 );
00492             break;
00493         default:
00494             Code.push_back( jvm_astore );
00495             Code.push_back( vindex );
00496     }
00497     pop( 1 );
00498     return pos;
00499 }
00500 
00502 
00507 unsigned int ByteCode::emit_iinc( u1 vindex, u1 value )
00508 {
00509     u2 pos = Code.size();
00510     Code.push_back( jvm_iinc );
00511     Code.push_back( vindex );
00512     Code.push_back( value );
00513     return pos;
00514 }
00516 
00517 
00518 // ARRAY FUNCTIONS
00523 unsigned int ByteCode::emit_newarray( _basic_data_types type )
00524 {
00525     u2 pos = Code.size();
00526     Code.push_back( jvm_newarray );
00527     Code.push_back( type );
00528     pop( 1 );
00529     return pos;
00530 }
00531 
00533 
00541 unsigned int ByteCode::emit_multianewarray( u2 index, u1 dimensions )
00542 {
00543     u2 pos = Code.size();
00544     Code.push_back( jvm_multianewarray );
00545     Code.push_back( (u1)(index >> 8) );
00546     Code.push_back( (u1)index );
00547     Code.push_back( dimensions );
00548     return pos;
00549 }
00550 
00552 
00556 unsigned int ByteCode::emit_multianewarray( const string classType, u1 dimensions )
00557 {
00558     unsigned int classString = ConstantPoolEntries->add( new Utf8_info( classType ) );
00559     unsigned int classref = ConstantPoolEntries->add( new Class_info( classString ) );
00560     return emit_multianewarray( classref, dimensions );
00561 }
00562 
00564 unsigned int ByteCode::emit_iastore()
00565 {
00566     u2 pos = Code.size();
00567     Code.push_back( jvm_iastore );
00568     return pos;
00569 }
00570 
00572 unsigned int ByteCode::emit_lastore()
00573 {
00574     u2 pos = Code.size();
00575     Code.push_back( jvm_lastore );
00576     return pos;
00577 }
00578 
00580 unsigned int ByteCode::emit_fastore()
00581 {
00582     u2 pos = Code.size();
00583     Code.push_back( jvm_fastore );
00584     return pos;
00585 }
00586 
00588 unsigned int ByteCode::emit_dastore()
00589 {
00590     u2 pos = Code.size();
00591     Code.push_back( jvm_dastore );
00592     return pos;
00593 }
00594 
00596 unsigned int ByteCode::emit_aastore()
00597 {
00598     u2 pos = Code.size();
00599     Code.push_back( jvm_aastore );
00600     return pos;
00601 }
00602 
00604 unsigned int ByteCode::emit_bastore()
00605 {
00606     u2 pos = Code.size();
00607     Code.push_back( jvm_bastore );
00608     return pos;
00609 }
00610 
00612 unsigned int ByteCode::emit_castore()
00613 {
00614     u2 pos = Code.size();
00615     Code.push_back( jvm_castore );
00616     return pos;
00617 }
00618 
00620 unsigned int ByteCode::emit_sastore()
00621 {
00622     u2 pos = Code.size();
00623     Code.push_back( jvm_sastore );
00624     return pos;
00625 }
00626 
00628 unsigned int ByteCode::emit_iaload()
00629 {
00630     u2 pos = Code.size();
00631     Code.push_back( jvm_iaload );
00632     return pos;
00633 }
00635 unsigned int ByteCode::emit_laload()
00636 {
00637     u2 pos = Code.size();
00638     Code.push_back( jvm_laload );
00639     return pos;
00640 }
00641 
00643 unsigned int ByteCode::emit_faload()
00644 {
00645     u2 pos = Code.size();
00646     Code.push_back( jvm_faload );
00647     return pos;
00648 }
00649 
00651 unsigned int ByteCode::emit_daload()
00652 {
00653     u2 pos = Code.size();
00654     Code.push_back( jvm_daload );
00655     return pos;
00656 }
00657 
00659 unsigned int ByteCode::emit_aaload()
00660 {
00661     u2 pos = Code.size();
00662     Code.push_back( jvm_aaload );
00663     return pos;
00664 }
00665 
00667 unsigned int ByteCode::emit_baload()
00668 {
00669     u2 pos = Code.size();
00670     Code.push_back( jvm_baload );
00671     return pos;
00672 }
00673 
00675 unsigned int ByteCode::emit_caload()
00676 {
00677     u2 pos = Code.size();
00678     Code.push_back( jvm_caload );
00679     return pos;
00680 }
00681 
00683 unsigned int ByteCode::emit_saload()
00684 {
00685     u2 pos = Code.size();
00686     Code.push_back( jvm_saload );
00687     return pos;
00688 }
00689 
00691 
00692 // STACK INSTRUCTIONS
00697 
00699 
00702 unsigned int ByteCode::emit_pop()
00703 {
00704     u2 pos = Code.size();
00705     pop();
00706     Code.push_back( jvm_pop );
00707     return pos;
00708 }
00709 
00711 
00714 unsigned int ByteCode::emit_pop2()
00715 {
00716     u2 pos = Code.size();
00717     pop( 2 );
00718     Code.push_back( jvm_pop2 );
00719     return pos;
00720 
00721 }
00722 
00724 
00727 unsigned int ByteCode::emit_dup()
00728 {
00729     u2 pos = Code.size();
00730     push();
00731     Code.push_back( jvm_dup );
00732     return pos;
00733 }
00734 
00736 
00739 unsigned int ByteCode::emit_dup2()
00740 {
00741     u2 pos = Code.size();
00742     push( 2 );
00743     Code.push_back( jvm_dup2 );
00744     return pos;
00745 }
00746 
00748 
00751 unsigned int ByteCode::emit_dup_x1()
00752 {
00753     u2 pos = Code.size();
00754     Code.push_back( jvm_dup_x1 );
00755     push( 1 );
00756     return pos;
00757 }
00758 
00760 
00763 unsigned int ByteCode::emit_dup_x2()
00764 {
00765     u2 pos = Code.size();
00766     Code.push_back( jvm_dup_x2 );
00767     push( 1 );
00768     return pos;
00769 }
00770 
00772 
00775 unsigned int ByteCode::emit_swap()
00776 {
00777     u2 pos = Code.size();
00778     Code.push_back( jvm_swap );
00779     return pos;
00780 }
00782 
00783 
00784 // ARITHMETIC INSTRUCTIONS
00785 
00787 
00793 unsigned int ByteCode::emit_arithmetic( _opcode code, unsigned int popVal )
00794 {
00795     u2 pos = Code.size();
00796     Code.push_back( code );
00797     pop( popVal );
00798     return pos;
00799 }
00800 
00801 
00806 
00807 
00809 
00812 unsigned int ByteCode::emit_iadd() // add
00813 {
00814     return emit_arithmetic( jvm_iadd );
00815 }
00816 
00818 
00821 unsigned int ByteCode::emit_ladd()
00822 {
00823     return emit_arithmetic( jvm_ladd, 2 );
00824 }
00825 
00827 
00830 unsigned int ByteCode::emit_fadd()
00831 {
00832     return emit_arithmetic( jvm_fadd, 1 );
00833 }
00834 
00836 
00839 unsigned int ByteCode::emit_dadd()
00840 {
00841     return emit_arithmetic( jvm_dadd, 2 );
00842 }
00843 
00845 
00848 unsigned int ByteCode::emit_isub() // sub
00849 {
00850     return emit_arithmetic( jvm_isub );
00851 }
00852 
00854 
00857 unsigned int ByteCode::emit_lsub()
00858 {
00859     return emit_arithmetic( jvm_lsub, 2 );
00860 }
00861 
00863 
00866 unsigned int ByteCode::emit_fsub()
00867 {
00868     return emit_arithmetic( jvm_fsub, 1 );
00869 }
00870 
00872 
00875 unsigned int ByteCode::emit_dsub()
00876 {
00877     return emit_arithmetic( jvm_dsub, 2 );
00878 }
00879 
00881 
00884 unsigned int ByteCode::emit_imul() // mul
00885 {
00886     return emit_arithmetic( jvm_imul );
00887 }
00888 
00890 
00893 unsigned int ByteCode::emit_lmul()
00894 {
00895     return emit_arithmetic( jvm_lmul, 2 );
00896 }
00897 
00899 
00902 unsigned int ByteCode::emit_fmul()
00903 {
00904     return emit_arithmetic( jvm_dmul, 1 );
00905 }
00906 
00908 
00911 unsigned int ByteCode::emit_dmul()
00912 {
00913     return emit_arithmetic( jvm_dmul, 2 );
00914 }
00915 
00917 
00920 unsigned int ByteCode::emit_idiv()// div
00921 {
00922     return emit_arithmetic( jvm_idiv );
00923 }
00924 
00926 
00929 unsigned int ByteCode::emit_ldiv()
00930 {
00931     return emit_arithmetic( jvm_ldiv, 2 );
00932 }
00933 
00935 
00938 unsigned int ByteCode::emit_fdiv()
00939 {
00940     return emit_arithmetic( jvm_fdiv, 1 );
00941 }
00942 
00944 
00947 unsigned int ByteCode::emit_ddiv()
00948 {
00949     return emit_arithmetic( jvm_ddiv, 2 );
00950 }
00951 
00953 
00956 unsigned int ByteCode::emit_irem() // mod
00957 {
00958     return emit_arithmetic( jvm_irem );
00959 }
00960 
00962 
00965 unsigned int ByteCode::emit_lrem()
00966 {
00967     return emit_arithmetic( jvm_lrem, 2 );
00968 }
00969 
00971 
00974 unsigned int ByteCode::emit_frem()
00975 {
00976     return emit_arithmetic( jvm_frem, 1 );
00977 }
00978 
00980 
00983 unsigned int ByteCode::emit_drem()
00984 {
00985     return emit_arithmetic( jvm_drem, 2 );
00986 }
00987 
00989 
00992 unsigned int ByteCode::emit_ineg()
00993 {
00994     return emit_arithmetic( jvm_ineg, 0 );
00995 }
00996 
00998 
01001 unsigned int ByteCode::emit_lneg()
01002 {
01003     return emit_arithmetic( jvm_lneg, 0 );
01004 }
01005 
01007 
01010 unsigned int ByteCode::emit_fneg()
01011 {
01012     return emit_arithmetic( jvm_fneg, 0 );
01013 }
01014 
01016 
01019 unsigned int ByteCode::emit_dneg()
01020 {
01021     return emit_arithmetic( jvm_dneg, 0 );
01022 }
01024 
01025 // LOGICAL INSTRUCTIONS
01026 
01031 
01033 
01037 unsigned int ByteCode::emit_iand()
01038 {
01039     u2 pos = Code.size();
01040     Code.push_back( jvm_iand );
01041     pop( 2 );
01042     return pos;
01043 }
01044 
01046 
01050 unsigned int ByteCode::emit_ior()
01051 {
01052     u2 pos = Code.size();
01053     Code.push_back( jvm_ior );
01054     pop( 2 );
01055     return pos;
01056 }
01057 
01059 
01063 unsigned int ByteCode::emit_ixor()
01064 {
01065     u2 pos = Code.size();
01066     Code.push_back( jvm_ixor );
01067     pop( 2 );
01068     return pos;
01069 }
01070 
01072 
01073 // CONVERSION OPERATIONS
01074 
01075 // CONTROL TRANSFER
01077 
01084 unsigned int ByteCode::emit_transfer( _opcode code, u2 jump, unsigned int popVal )
01085 {
01086     u2 pos = Code.size();
01087     Code.push_back( code );
01088     // push high bits
01089     Code.push_back( (u1)(jump >> 8) );
01090         // push low bits
01091     Code.push_back( (u1)jump );
01092     pop( popVal );
01093     return pos;
01094 }
01095 
01100 
01102 
01108 void ByteCode::patch( unsigned int instrAddr, u2 jump )
01109 {
01110     Code[instrAddr + 1] = (u1)(jump >> 8);
01111     Code[instrAddr + 2] = (u1)(jump);
01112 }
01113 
01115 
01120 unsigned int ByteCode::emit_ifeq( u2 jump )
01121 {
01122     return emit_transfer( jvm_ifeq, jump );
01123 }
01124 
01126 
01131 unsigned int ByteCode::emit_ifnull( u2 jump )
01132 {
01133     return emit_transfer( jvm_ifnull, jump );
01134 }
01135 
01137 
01142 unsigned int ByteCode::emit_iflt( u2 jump ) // less than
01143 {
01144     return emit_transfer( jvm_iflt, jump );
01145 }
01146 
01148 
01153 unsigned int ByteCode::emit_ifle( u2 jump ) // less or equal
01154 {
01155     return emit_transfer( jvm_ifle, jump );
01156 }
01157 
01159 
01164 unsigned int ByteCode::emit_ifne( u2 jump ) // not equal
01165 {
01166     return emit_transfer( jvm_ifne, jump );
01167 }
01168 
01170 
01175 unsigned int ByteCode::emit_ifnonnull( u2 jump )
01176 {
01177     return emit_transfer( jvm_ifnonnull, jump );
01178 }
01179 
01181 
01186 unsigned int ByteCode::emit_ifgt( u2 jump ) // greater than
01187 {
01188     return emit_transfer( jvm_ifgt, jump );
01189 }
01190 
01192 
01197 unsigned int ByteCode::emit_ifge( u2 jump ) // greater or equal
01198 {
01199     return emit_transfer( jvm_ifge, jump );
01200 }
01201 
01203 
01208 unsigned int ByteCode::emit_if_icmpeq( u2 jump ) // top two stack integers equal
01209 {
01210     return emit_transfer( jvm_if_icmpeq, jump, 2 );
01211 }
01212 
01214 
01219 unsigned int ByteCode::emit_if_icmpne( u2 jump ) // top two stack integers not equal
01220 {
01221     return emit_transfer( jvm_if_icmpne, jump, 2 );
01222 }
01223 
01225 
01230 unsigned int ByteCode::emit_if_icmplt( u2 jump ) // integer stack 2 less than stack 1
01231 {
01232     return emit_transfer( jvm_if_icmplt, jump, 2 );
01233 }
01234 
01236 
01241 unsigned int ByteCode::emit_if_icmpgt( u2 jump ) // integer stack 2 greater than stack 1
01242 {
01243     return emit_transfer( jvm_if_icmpgt, jump, 2 );
01244 }
01245 
01247 
01252 unsigned int ByteCode::emit_if_icmple( u2 jump ) // stack2 less or equal stack 1
01253 {
01254     return emit_transfer( jvm_if_icmple, jump, 2 );
01255 }
01256 
01258 
01263 unsigned int ByteCode::emit_if_icmpge( u2 jump ) // stack 2 greater or equal stack 1
01264 {
01265     return emit_transfer( jvm_if_icmpge, jump, 2 );
01266 }
01267 
01269 
01274 unsigned int ByteCode::emit_goto( u2 jump )
01275 {
01276     return emit_transfer( jvm_goto, jump, 0 );
01277 }
01278 
01280 
01286 unsigned int ByteCode::emit_jsr( u2 jump ) // jump subroutine (ret on stack)
01287 {
01288     u2 pos = Code.size();
01289     Code.push_back( jvm_jsr );
01290     Code.push_back( (u1)(jump >> 8) );
01291     Code.push_back( (u1)jump );
01292     push( );
01293     return pos;
01294 }
01295 
01297 
01302 unsigned int ByteCode::emit_ret( u1 vindex )
01303 {
01304     u2 pos = Code.size();
01305     Code.push_back( jvm_ret );
01306     Code.push_back( vindex );
01307     return pos;
01308 }
01310 
01311 
01312 // MANIPULATING OBJECT FIELDS
01317 
01319 
01323 unsigned int ByteCode::emit_getstatic( u2 index )
01324 {
01325     u2 pos = Code.size();
01326     Code.push_back( jvm_getstatic );
01327     Code.push_back( (u1)(index >> 8) );
01328     Code.push_back( (u1)index );
01329     push();
01330     return pos;
01331 }
01332 
01334 
01342 unsigned int ByteCode::emit_getstatic( const string &className, const string &fieldName, const string &fieldType )
01343 {
01344     unsigned int desc_index = ConstantPoolEntries->add( new Utf8_info( fieldType ) );
01345     unsigned int name_index = ConstantPoolEntries->add( new Utf8_info( fieldName ) );
01346     unsigned int name_and_type_index = ConstantPoolEntries->add( new NameAndType_info(
01347                                                                      name_index,
01348                                                                      desc_index )
01349                                                                  );
01350     unsigned int classString = ConstantPoolEntries->add( new Utf8_info( className ) );
01351     unsigned int classref = ConstantPoolEntries->add( new Class_info( classString ) );
01352     unsigned int fieldref = ConstantPoolEntries->add( new Fieldref_info( classref, name_and_type_index ) );
01353 
01354     return emit_getstatic( fieldref );
01355 }
01357 
01358 
01359 // METHOD INVOCATION
01364 
01366 
01373 unsigned int ByteCode::emit_invokevirtual( u2 index )
01374 {
01375     u2 pos = Code.size();
01376     Code.push_back( jvm_invokevirtual );
01377     Code.push_back( (u1)(index >> 8) );
01378     Code.push_back( (u1)index );
01379     return pos;
01380 }
01381 
01383 
01389 unsigned int ByteCode::emit_invokespecial( u2 index )
01390 {
01391     u2 pos = Code.size();
01392     Code.push_back( jvm_invokespecial );
01393     Code.push_back( (u1)(index >> 8) );
01394     Code.push_back( (u1)index );
01395     return pos;
01396 }
01397 
01399 
01405 unsigned int ByteCode::emit_invokestatic( u2 index )
01406 {
01407     u2 pos = Code.size();
01408     Code.push_back( jvm_invokestatic );
01409     Code.push_back( (u1)(index >> 8) );
01410     Code.push_back( (u1)index );
01411     push(); // TODO.. this is only true if function returns
01412     return pos;
01413 }
01414 
01416 
01422 unsigned int ByteCode::emit_invokeinterface( u2 index, u1 nargs )
01423 {
01424     u2 pos = Code.size();
01425     Code.push_back( jvm_invokeinterface );
01426     Code.push_back( (u1)(index >> 8) );
01427     Code.push_back( (u1)index );
01428     Code.push_back( nargs );
01429     Code.push_back( (u1)0 );
01430     return pos;
01431 }
01432 
01434 
01443 unsigned int ByteCode::emit_invokespecial( const string &object, const string &function, const string &footprint )
01444 {
01445     // methodref
01446       // classref
01447          //"java/lang/Object"
01448       // name_and_type_index
01449         // name_index "<init>"
01450         // descriptor_index "()V"
01451     unsigned int desc_index = ConstantPoolEntries->add( new Utf8_info( footprint ) );
01452     unsigned int name_index = ConstantPoolEntries->add( new Utf8_info( function ) );
01453     unsigned int name_and_type_index = ConstantPoolEntries->add( new NameAndType_info(
01454                                                                      name_index,
01455                                                                      desc_index )
01456                                                                  );
01457     unsigned int classString = ConstantPoolEntries->add( new Utf8_info( object ) );
01458     unsigned int classref = ConstantPoolEntries->add( new Class_info( classString ) );
01459     unsigned int methodref = ConstantPoolEntries->add( new Methodref_info( classref, name_and_type_index ) );
01460 
01461     return emit_invokespecial( methodref );
01462 }
01463 
01465 
01474 unsigned int ByteCode::emit_invokestatic( const string &classType,
01475                                           const string &function, const string &footprint )
01476 {
01477     unsigned int desc_index = ConstantPoolEntries->add( new Utf8_info( footprint ) );
01478     unsigned int name_index = ConstantPoolEntries->add( new Utf8_info( function ) );
01479     unsigned int name_and_type_index = ConstantPoolEntries->add( new NameAndType_info(
01480                                                                      name_index,
01481                                                                      desc_index )
01482                                                                  );
01483     unsigned int classString = ConstantPoolEntries->add( new Utf8_info( classType ) );
01484     unsigned int classref = ConstantPoolEntries->add( new Class_info( classString ) );
01485     unsigned int methodref = ConstantPoolEntries->add( new Methodref_info( classref, name_and_type_index ) );
01486 
01487     return emit_invokestatic( methodref );
01488 
01489 }
01490 
01492 
01501 unsigned int ByteCode::emit_invokevirtual( const string &classType,
01502                                           const string &function, const string &footprint )
01503 {
01504     unsigned int desc_index = ConstantPoolEntries->add( new Utf8_info( footprint ) );
01505     unsigned int name_index = ConstantPoolEntries->add( new Utf8_info( function ) );
01506     unsigned int name_and_type_index = ConstantPoolEntries->add( new NameAndType_info(
01507                                                                      name_index,
01508                                                                      desc_index )
01509                                                                  );
01510     unsigned int classString = ConstantPoolEntries->add( new Utf8_info( classType ) );
01511     unsigned int classref = ConstantPoolEntries->add( new Class_info( classString ) );
01512     unsigned int methodref = ConstantPoolEntries->add( new Methodref_info( classref, name_and_type_index ) );
01513 
01514     return emit_invokevirtual( methodref );
01515 }
01516 
01518 
01529 unsigned int ByteCode::emit_invokeinterface( const string &objectType, const string &function,
01530                                              const string &footprint, u1 nargs )
01531 {
01532     unsigned int desc_index = ConstantPoolEntries->add( new Utf8_info( footprint ) );
01533     unsigned int name_index = ConstantPoolEntries->add( new Utf8_info( function ) );
01534     unsigned int name_and_type_index = ConstantPoolEntries->add( new NameAndType_info(
01535                                                                      name_index,
01536                                                                      desc_index )
01537                                                                  );
01538     unsigned int classString = ConstantPoolEntries->add( new Utf8_info( objectType ) );
01539     unsigned int classref = ConstantPoolEntries->add( new Class_info( classString ) );
01540     unsigned int methodref = ConstantPoolEntries->add(
01541         new InterfaceMethodref_info( classref, name_and_type_index ) );
01542 
01543     return emit_invokeinterface( methodref, nargs );
01544 }
01546 
01547     // MISC OBJECT FUNCTIONS
01552 
01553 
01558 unsigned int ByteCode::emit_new( u2 index )
01559 {
01560     u2 pos = Code.size();
01561     Code.push_back( jvm_new );
01562     Code.push_back( (u1)(index >> 8) );
01563     Code.push_back( (u1)index );
01564     push();
01565     return pos;
01566 }
01568 
01572 unsigned int ByteCode::emit_new( const std::string &classType )
01573 {
01574     u2 classString = ConstantPoolEntries->add( new Utf8_info( classType ) );
01575     u2 classref = ConstantPoolEntries->add( new Class_info( classString ) );
01576     return emit_new( classref );
01577 }
01578 
01580 
01581 // FUNCTION RETURN
01586 
01588 
01591 unsigned int ByteCode::emit_ireturn()
01592 {
01593     u2 pos = Code.size();
01594     Code.push_back( jvm_ireturn );
01595     return pos;
01596 }
01597 
01599 
01602 unsigned int ByteCode::emit_lreturn()
01603 {
01604     u2 pos = Code.size();
01605     Code.push_back( jvm_lreturn );
01606     return pos;
01607 }
01608 
01610 
01613 unsigned int ByteCode::emit_freturn()
01614 {
01615     u2 pos = Code.size();
01616     Code.push_back( jvm_freturn );
01617     return pos;
01618 }
01619 
01621 
01624 unsigned int ByteCode::emit_dreturn()
01625 {
01626     u2 pos = Code.size();
01627     Code.push_back( jvm_dreturn );
01628     return pos;
01629 }
01630 
01632 unsigned int ByteCode::emit_return()
01633 {
01634     u2 pos = Code.size();
01635     Code.push_back( jvm_return );
01636     return pos;
01637 }
01639 
01640 } // end namespace

Generated on Mon Dec 1 14:26:27 2003 for Ck by doxygen 1.3.3