LCOV - code coverage report
Current view: top level - codemaker/source/javamaker - classfile.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 458 484 94.6 %
Date: 2012-08-25 Functions: 68 69 98.6 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 232 418 55.5 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*
       3                 :            :  * This file is part of the LibreOffice project.
       4                 :            :  *
       5                 :            :  * This Source Code Form is subject to the terms of the Mozilla Public
       6                 :            :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7                 :            :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8                 :            :  *
       9                 :            :  * This file incorporates work covered by the following license notice:
      10                 :            :  *
      11                 :            :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12                 :            :  *   contributor license agreements. See the NOTICE file distributed
      13                 :            :  *   with this work for additional information regarding copyright
      14                 :            :  *   ownership. The ASF licenses this file to you under the Apache
      15                 :            :  *   License, Version 2.0 (the "License"); you may not use this file
      16                 :            :  *   except in compliance with the License. You may obtain a copy of
      17                 :            :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18                 :            :  */
      19                 :            : 
      20                 :            : 
      21                 :            : #include "classfile.hxx"
      22                 :            : 
      23                 :            : #include "codemaker/global.hxx"
      24                 :            : #include "codemaker/options.hxx"
      25                 :            : #include "codemaker/unotype.hxx"
      26                 :            : 
      27                 :            : #include "boost/static_assert.hpp"
      28                 :            : #include "osl/diagnose.h"
      29                 :            : #include "rtl/string.h"
      30                 :            : #include "rtl/string.hxx"
      31                 :            : #include "sal/types.h"
      32                 :            : 
      33                 :            : #include <map>
      34                 :            : #include <utility>
      35                 :            : #include <vector>
      36                 :            : 
      37                 :            : using codemaker::javamaker::ClassFile;
      38                 :            : 
      39                 :            : namespace {
      40                 :            : 
      41                 :    3272040 : void appendU1(std::vector< unsigned char > & stream, sal_uInt8 data) {
      42         [ +  - ]:    3272040 :     stream.push_back(static_cast< unsigned char >(data));
      43                 :    3272040 : }
      44                 :            : 
      45                 :     599302 : void appendU2(std::vector< unsigned char > & stream, sal_uInt16 data) {
      46         [ +  - ]:     599302 :     stream.push_back(static_cast< unsigned char >(data >> 8));
      47         [ +  - ]:     599302 :     stream.push_back(static_cast< unsigned char >(data & 0xFF));
      48                 :     599302 : }
      49                 :            : 
      50                 :      47508 : void appendU4(std::vector< unsigned char > & stream, sal_uInt32 data) {
      51         [ +  - ]:      47508 :     stream.push_back(static_cast< unsigned char >(data >> 24));
      52         [ +  - ]:      47508 :     stream.push_back(static_cast< unsigned char >((data >> 16) & 0xFF));
      53         [ +  - ]:      47508 :     stream.push_back(static_cast< unsigned char >((data >> 8) & 0xFF));
      54         [ +  - ]:      47508 :     stream.push_back(static_cast< unsigned char >(data & 0xFF));
      55                 :      47508 : }
      56                 :            : 
      57                 :         58 : void appendU8(std::vector< unsigned char > & stream, sal_uInt64 data) {
      58         [ +  - ]:         58 :     stream.push_back(static_cast< unsigned char >(data >> 56));
      59         [ +  - ]:         58 :     stream.push_back(static_cast< unsigned char >((data >> 48) & 0xFF));
      60         [ +  - ]:         58 :     stream.push_back(static_cast< unsigned char >((data >> 40) & 0xFF));
      61         [ +  - ]:         58 :     stream.push_back(static_cast< unsigned char >((data >> 32) & 0xFF));
      62         [ +  - ]:         58 :     stream.push_back(static_cast< unsigned char >((data >> 24) & 0xFF));
      63         [ +  - ]:         58 :     stream.push_back(static_cast< unsigned char >((data >> 16) & 0xFF));
      64         [ +  - ]:         58 :     stream.push_back(static_cast< unsigned char >((data >> 8) & 0xFF));
      65         [ +  - ]:         58 :     stream.push_back(static_cast< unsigned char >(data & 0xFF));
      66                 :         58 : }
      67                 :            : 
      68                 :      23672 : void appendStream(
      69                 :            :     std::vector< unsigned char > & stream,
      70                 :            :     std::vector< unsigned char > const & data)
      71                 :            : {
      72                 :      23672 :     stream.insert(stream.end(), data.begin(), data.end());
      73                 :      23672 : }
      74                 :            : 
      75                 :      88523 : void write(FileStream & file, void const * buffer, sal_uInt64 size) {
      76         [ -  + ]:      88523 :     if (!file.write(buffer, size)) {
      77                 :            :         throw CannotDumpException(
      78                 :          0 :             rtl::OString(RTL_CONSTASCII_STRINGPARAM("Error writing file")));
      79                 :            :     }
      80                 :      88523 : }
      81                 :            : 
      82                 :      62000 : void writeU2(FileStream & file, sal_uInt16 data) {
      83                 :            :     unsigned char buf[] = {
      84                 :            :         static_cast< unsigned char >(data >> 8),
      85                 :      62000 :         static_cast< unsigned char >(data & 0xFF) };
      86         [ +  - ]:      62000 :     write(file, buf, sizeof buf);
      87                 :      62000 : }
      88                 :            : 
      89                 :       6200 : void writeU4(FileStream & file, sal_uInt32 data) {
      90                 :            :     unsigned char buf[] = {
      91                 :            :         static_cast< unsigned char >(data >> 24),
      92                 :            :         static_cast< unsigned char >((data >> 16) & 0xFF),
      93                 :            :         static_cast< unsigned char >((data >> 8) & 0xFF),
      94                 :       6200 :         static_cast< unsigned char >(data & 0xFF) };
      95         [ +  - ]:       6200 :     write(file, buf, sizeof buf);
      96                 :       6200 : }
      97                 :            : 
      98                 :      31000 : void writeStream(FileStream & file, std::vector< unsigned char > const & stream)
      99                 :            : {
     100                 :      31000 :     std::vector< unsigned char >::size_type n = stream.size();
     101                 :            :     BOOST_STATIC_ASSERT(
     102                 :            :         sizeof (std::vector< unsigned char >::size_type)
     103                 :            :         <= sizeof (sal_uInt64));
     104                 :            :         // both unsigned integral, so sizeof is a practically sufficient
     105                 :            :         // approximation of std::numeric_limits<T1>::max() <=
     106                 :            :         // std::numeric_limits<T2>::max()
     107         [ +  + ]:      31000 :     if (n != 0) {
     108                 :      20323 :         write(file, &stream[0], static_cast< sal_uInt64 >(n));
     109                 :            :     }
     110                 :      31000 : }
     111                 :            : 
     112                 :            : }
     113                 :            : 
     114                 :      13451 : ClassFile::Code::~Code() {}
     115                 :            : 
     116                 :      16957 : void ClassFile::Code::instrAastore() {
     117                 :            :     // aastore:
     118                 :      16957 :     appendU1(m_code, 0x53);
     119                 :      16957 : }
     120                 :            : 
     121                 :        422 : void ClassFile::Code::instrAconstNull() {
     122                 :            :     // aconst_null:
     123                 :        422 :     appendU1(m_code, 0x01);
     124                 :        422 : }
     125                 :            : 
     126                 :       4684 : void ClassFile::Code::instrAnewarray(rtl::OString const & type) {
     127                 :            :     // anewarray <indexbyte1> <indexbyte2>:
     128                 :       4684 :     appendU1(m_code, 0xBD);
     129                 :       4684 :     appendU2(m_code, m_classFile.addClassInfo(type));
     130                 :       4684 : }
     131                 :            : 
     132                 :       4621 : void ClassFile::Code::instrAreturn() {
     133                 :            :     // areturn:
     134                 :       4621 :     appendU1(m_code, 0xB0);
     135                 :       4621 : }
     136                 :            : 
     137                 :        976 : void ClassFile::Code::instrAthrow() {
     138                 :            :     // athrow:
     139                 :        976 :     appendU1(m_code, 0xBF);
     140                 :        976 : }
     141                 :            : 
     142                 :        400 : void ClassFile::Code::instrCheckcast(rtl::OString const & type) {
     143                 :            :     // checkcast <indexbyte1> <indexbyte2>:
     144                 :        400 :     appendU1(m_code, 0xC0);
     145                 :        400 :     appendU2(m_code, m_classFile.addClassInfo(type));
     146                 :        400 : }
     147                 :            : 
     148                 :      39011 : void ClassFile::Code::instrDup() {
     149                 :            :     // dup:
     150                 :      39011 :     appendU1(m_code, 0x59);
     151                 :      39011 : }
     152                 :            : 
     153                 :       4107 : void ClassFile::Code::instrGetstatic(
     154                 :            :     rtl::OString const & type, rtl::OString const & name,
     155                 :            :     rtl::OString const & descriptor)
     156                 :            : {
     157                 :            :     // getstatic <indexbyte1> <indexbyte2>:
     158                 :       4107 :     appendU1(m_code, 0xB2);
     159                 :       4107 :     appendU2(m_code, m_classFile.addFieldrefInfo(type, name, descriptor));
     160                 :       4107 : }
     161                 :            : 
     162                 :         20 : ClassFile::Code::Branch ClassFile::Code::instrIfAcmpne() {
     163                 :            :     // if_acmpne <branchbyte1> <branchbyte2>:
     164                 :         20 :     Branch branch = m_code.size();
     165                 :         20 :     appendU1(m_code, 0xA6);
     166                 :         20 :     appendU2(m_code, 0);
     167                 :         20 :     return branch;
     168                 :            : }
     169                 :            : 
     170                 :         20 : ClassFile::Code::Branch ClassFile::Code::instrIfeq() {
     171                 :            :     // ifeq <branchbyte1> <branchbyte2>:
     172                 :         20 :     Branch branch = m_code.size();
     173                 :         20 :     appendU1(m_code, 0x99);
     174                 :         20 :     appendU2(m_code, 0);
     175                 :         20 :     return branch;
     176                 :            : }
     177                 :            : 
     178                 :        622 : ClassFile::Code::Branch ClassFile::Code::instrIfnull() {
     179                 :            :     // ifnull <branchbyte1> <branchbyte2>:
     180                 :        622 :     Branch branch = m_code.size();
     181                 :        622 :     appendU1(m_code, 0xC6);
     182                 :        622 :     appendU2(m_code, 0);
     183                 :        622 :     return branch;
     184                 :            : }
     185                 :            : 
     186                 :         20 : void ClassFile::Code::instrInstanceof(rtl::OString const & type) {
     187                 :            :     // instanceof <indexbyte1> <indexbyte2>:
     188                 :         20 :     appendU1(m_code, 0xC1);
     189                 :         20 :     appendU2(m_code, m_classFile.addClassInfo(type));
     190                 :         20 : }
     191                 :            : 
     192                 :        681 : void ClassFile::Code::instrInvokeinterface(
     193                 :            :     rtl::OString const & type, rtl::OString const & name,
     194                 :            :     rtl::OString const & descriptor, sal_uInt8 args)
     195                 :            : {
     196                 :            :     // invokeinterface <indexbyte1> <indexbyte2> <nargs> 0:
     197                 :        681 :     appendU1(m_code, 0xB9);
     198                 :            :     appendU2(
     199                 :        681 :         m_code, m_classFile.addInterfaceMethodrefInfo(type, name, descriptor));
     200                 :        681 :     appendU1(m_code, args);
     201                 :        681 :     appendU1(m_code, 0);
     202                 :        681 : }
     203                 :            : 
     204                 :      25084 : void ClassFile::Code::instrInvokespecial(
     205                 :            :     rtl::OString const & type, rtl::OString const & name,
     206                 :            :     rtl::OString const & descriptor)
     207                 :            : {
     208                 :            :     // invokespecial <indexbyte1> <indexbyte2>:
     209                 :      25084 :     appendU1(m_code, 0xB7);
     210                 :      25084 :     appendU2(m_code, m_classFile.addMethodrefInfo(type, name, descriptor));
     211                 :      25084 : }
     212                 :            : 
     213                 :       1041 : void ClassFile::Code::instrInvokestatic(
     214                 :            :     rtl::OString const & type, rtl::OString const & name,
     215                 :            :     rtl::OString const & descriptor)
     216                 :            : {
     217                 :            :     // invokestatic <indexbyte1> <indexbyte2>:
     218                 :       1041 :     appendU1(m_code, 0xB8);
     219                 :       1041 :     appendU2(m_code, m_classFile.addMethodrefInfo(type, name, descriptor));
     220                 :       1041 : }
     221                 :            : 
     222                 :        768 : void ClassFile::Code::instrInvokevirtual(
     223                 :            :     rtl::OString const & type, rtl::OString const & name,
     224                 :            :     rtl::OString const & descriptor)
     225                 :            : {
     226                 :            :     // invokevirtual <indexbyte1> <indexbyte2>:
     227                 :        768 :     appendU1(m_code, 0xB6);
     228                 :        768 :     appendU2(m_code, m_classFile.addMethodrefInfo(type, name, descriptor));
     229                 :        768 : }
     230                 :            : 
     231                 :          2 : void ClassFile::Code::instrLookupswitch(
     232                 :            :     Code const * defaultBlock,
     233                 :            :     std::list< std::pair< sal_Int32, Code * > > const & blocks)
     234                 :            : {
     235                 :            :     // lookupswitch <0--3 byte pad> <defaultbyte1> <defaultbyte2> <defaultbyte3>
     236                 :            :     // <defaultbyte4> <npairs1> <npairs2> <npairs3> <npairs4>
     237                 :            :     // <match--offset pairs...>:
     238                 :          2 :     std::list< std::pair< sal_Int32, Code * > >::size_type size = blocks.size();
     239         [ -  + ]:          2 :     if (size > SAL_MAX_INT32) {
     240                 :            :         throw CannotDumpException(
     241                 :            :             rtl::OString(
     242                 :            :                 RTL_CONSTASCII_STRINGPARAM(
     243                 :          0 :                     "Lookup-switch too large for Java class file format")));
     244                 :            :     }
     245                 :          2 :     Position pos1 = m_code.size();
     246                 :          2 :     appendU1(m_code, 0xAB);
     247                 :          2 :     int pad = (pos1 + 1) % 4;
     248         [ +  + ]:          6 :     {for (int i = 0; i < pad; ++i) {
     249                 :          4 :         appendU1(m_code, 0);
     250                 :            :     }}
     251                 :          2 :     Position pos2 = pos1 + 1 + pad + 8 + blocks.size() * 8; //FIXME: overflow
     252                 :          2 :     appendU4(m_code, static_cast< sal_uInt32 >(pos2 - pos1)); //FIXME: overflow
     253                 :          2 :     pos2 += defaultBlock->m_code.size(); //FIXME: overflow
     254                 :          2 :     appendU4(m_code, static_cast< sal_uInt32 >(size));
     255         [ +  + ]:        152 :     {for (std::list< std::pair< sal_Int32, Code * > >::const_iterator i(
     256                 :          2 :               blocks.begin());
     257                 :         76 :           i != blocks.end(); ++i)
     258                 :            :     {
     259         [ +  - ]:         74 :         appendU4(m_code, static_cast< sal_uInt32 >(i->first));
     260         [ +  - ]:         74 :         appendU4(m_code, static_cast< sal_uInt32 >(pos2 - pos1));
     261                 :            :             //FIXME: overflow
     262                 :         74 :         pos2 += i->second->m_code.size(); //FIXME: overflow
     263                 :            :     }}
     264                 :          2 :     appendStream(m_code, defaultBlock->m_code);
     265         [ +  + ]:        152 :     {for (std::list< std::pair< sal_Int32, Code * > >::const_iterator i(
     266                 :          2 :               blocks.begin());
     267                 :         76 :           i != blocks.end(); ++i)
     268                 :            :     {
     269         [ +  - ]:         74 :         appendStream(m_code, i->second->m_code);
     270                 :            :     }}
     271                 :          2 : }
     272                 :            : 
     273                 :      21392 : void ClassFile::Code::instrNew(rtl::OString const & type) {
     274                 :            :     // new <indexbyte1> <indexbyte2>:
     275                 :      21392 :     appendU1(m_code, 0xBB);
     276                 :      21392 :     appendU2(m_code, m_classFile.addClassInfo(type));
     277                 :      21392 : }
     278                 :            : 
     279                 :         67 : void ClassFile::Code::instrNewarray(codemaker::UnoType::Sort sort) {
     280                 :            :     OSL_ASSERT(
     281                 :            :         sort >= codemaker::UnoType::SORT_BOOLEAN
     282                 :            :         && sort <= codemaker::UnoType::SORT_CHAR);
     283                 :            :     // newarray <atype>:
     284                 :         67 :     appendU1(m_code, 0xBC);
     285                 :            :     static sal_uInt8 const atypes[codemaker::UnoType::SORT_CHAR] = {
     286                 :            :         0x04, 0x08, 0x09, 0x09, 0x0A, 0x0A, 0x0B, 0x0B, 0x06, 0x07, 0x05 };
     287                 :         67 :     appendU1(m_code, atypes[sort - 1]);
     288                 :         67 : }
     289                 :            : 
     290                 :        622 : void ClassFile::Code::instrPop() {
     291                 :            :     // pop:
     292                 :        622 :     appendU1(m_code, 0x57);
     293                 :        622 : }
     294                 :            : 
     295                 :       5378 : void ClassFile::Code::instrPutfield(
     296                 :            :     rtl::OString const & type, rtl::OString const & name,
     297                 :            :     rtl::OString const & descriptor)
     298                 :            : {
     299                 :            :     // putfield <indexbyte1> <indexbyte2>:
     300                 :       5378 :     appendU1(m_code, 0xB5);
     301                 :       5378 :     appendU2(m_code, m_classFile.addFieldrefInfo(type, name, descriptor));
     302                 :       5378 : }
     303                 :            : 
     304                 :       7141 : void ClassFile::Code::instrPutstatic(
     305                 :            :     rtl::OString const & type, rtl::OString const & name,
     306                 :            :     rtl::OString const & descriptor)
     307                 :            : {
     308                 :            :     // putstatic <indexbyte1> <indexbyte2>:
     309                 :       7141 :     appendU1(m_code, 0xB3);
     310                 :       7141 :     appendU2(m_code, m_classFile.addFieldrefInfo(type, name, descriptor));
     311                 :       7141 : }
     312                 :            : 
     313                 :       8421 : void ClassFile::Code::instrReturn() {
     314                 :            :     // return:
     315                 :       8421 :     appendU1(m_code, 0xB1);
     316                 :       8421 : }
     317                 :            : 
     318                 :         20 : void ClassFile::Code::instrSwap() {
     319                 :            :     // swap:
     320                 :         20 :     appendU1(m_code, 0x5F);
     321                 :         20 : }
     322                 :            : 
     323                 :        407 : void ClassFile::Code::instrTableswitch(
     324                 :            :     Code const * defaultBlock, sal_Int32 low,
     325                 :            :     std::list< Code * > const & blocks)
     326                 :            : {
     327                 :            :     // tableswitch <0--3 byte pad> <defaultbyte1> <defaultbyte2> <defaultbyte3>
     328                 :            :     // <defaultbyte4> <lowbyte1> <lowbyte2> <lowbyte3> <lowbyte4> <highbyte1>
     329                 :            :     // <highbyte2> <highbyte3> <highbyte4> <jump offsets...>:
     330                 :        407 :     Position pos1 = m_code.size();
     331                 :        407 :     appendU1(m_code, 0xAA);
     332                 :        407 :     int pad = (pos1 + 1) % 4;
     333         [ +  + ]:       1221 :     {for (int i = 0; i < pad; ++i) {
     334                 :        814 :         appendU1(m_code, 0);
     335                 :            :     }}
     336                 :        407 :     std::list< Code * >::size_type size = blocks.size();
     337                 :        407 :     Position pos2 = pos1 + 1 + pad + 12 + size * 4; //FIXME: overflow
     338                 :        407 :     sal_uInt32 defaultOffset = static_cast< sal_uInt32 >(pos2 - pos1);
     339                 :            :         //FIXME: overflow
     340                 :        407 :     appendU4(m_code, defaultOffset);
     341                 :        407 :     pos2 += defaultBlock->m_code.size(); //FIXME: overflow
     342                 :        407 :     appendU4(m_code, static_cast< sal_uInt32 >(low));
     343                 :        407 :     appendU4(m_code, static_cast< sal_uInt32 >(low + (size - 1)));
     344         [ +  + ]:       6324 :     {for (std::list< Code * >::const_iterator i(blocks.begin());
     345                 :       3162 :           i != blocks.end(); ++i)
     346                 :            :     {
     347         [ +  + ]:       2755 :         if (*i == 0) {
     348         [ +  - ]:          8 :             appendU4(m_code, defaultOffset);
     349                 :            :         } else {
     350         [ +  - ]:       2747 :             appendU4(m_code, static_cast< sal_uInt32 >(pos2 - pos1));
     351                 :            :                 //FIXME: overflow
     352                 :       2747 :             pos2 += (*i)->m_code.size(); //FIXME: overflow
     353                 :            :         }
     354                 :            :     }}
     355                 :        407 :     appendStream(m_code, defaultBlock->m_code);
     356         [ +  + ]:       6324 :     {for (std::list< Code * >::const_iterator i(blocks.begin());
     357                 :       3162 :           i != blocks.end(); ++i)
     358                 :            :     {
     359         [ +  + ]:       2755 :         if (*i != 0) {
     360         [ +  - ]:       2747 :             appendStream(m_code, (*i)->m_code);
     361                 :            :         }
     362                 :            :     }}
     363                 :        407 : }
     364                 :            : 
     365                 :      57830 : void ClassFile::Code::loadIntegerConstant(sal_Int32 value) {
     366 [ +  + ][ +  + ]:      57830 :     if (value >= -1 && value <= 5) {
     367                 :            :         // iconst_<i>:
     368                 :      45230 :         appendU1(m_code, static_cast< sal_uInt8 >(0x02 + value + 1));
     369 [ +  + ][ +  + ]:      12600 :     } else if (value >= -128 && value <= 127) {
     370                 :            :         // bipush <byte>:
     371                 :      11914 :         appendU1(m_code, 0x10);
     372                 :      11914 :         appendU1(m_code, static_cast< sal_uInt8 >(value));
     373 [ +  - ][ +  + ]:        686 :     } else if (value >= -32768 && value <= 32767) {
     374                 :            :         // sipush <byte1> <byte2>:
     375                 :        656 :         appendU1(m_code, 0x11);
     376                 :        656 :         appendU2(m_code, static_cast< sal_uInt16 >(value));
     377                 :            :     } else {
     378                 :         30 :         ldc(m_classFile.addIntegerInfo(value));
     379                 :            :     }
     380                 :      57830 : }
     381                 :            : 
     382                 :      20003 : void ClassFile::Code::loadStringConstant(rtl::OString const & value) {
     383                 :      20003 :     ldc(m_classFile.addStringInfo(value));
     384                 :      20003 : }
     385                 :            : 
     386                 :       2546 : void ClassFile::Code::loadLocalInteger(sal_uInt16 index) {
     387                 :       2546 :     accessLocal(index, 0x1A, 0x15); // iload_<n>, iload
     388                 :       2546 : }
     389                 :            : 
     390                 :         60 : void ClassFile::Code::loadLocalLong(sal_uInt16 index) {
     391                 :         60 :     accessLocal(index, 0x1E, 0x16); // load_<n>, load
     392                 :         60 : }
     393                 :            : 
     394                 :         32 : void ClassFile::Code::loadLocalFloat(sal_uInt16 index) {
     395                 :         32 :     accessLocal(index, 0x22, 0x17); // load_<n>, load
     396                 :         32 : }
     397                 :            : 
     398                 :        225 : void ClassFile::Code::loadLocalDouble(sal_uInt16 index) {
     399                 :        225 :     accessLocal(index, 0x26, 0x18); // load_<n>, load
     400                 :        225 : }
     401                 :            : 
     402                 :      16093 : void ClassFile::Code::loadLocalReference(sal_uInt16 index) {
     403                 :      16093 :     accessLocal(index, 0x2A, 0x19); // aload_<n>, aload
     404                 :      16093 : }
     405                 :            : 
     406                 :        354 : void ClassFile::Code::storeLocalReference(sal_uInt16 index) {
     407                 :        354 :     accessLocal(index, 0x4B, 0x3A); // astore_<n>, astore
     408                 :        354 : }
     409                 :            : 
     410                 :        662 : void ClassFile::Code::branchHere(Branch branch) {
     411                 :        662 :     std::vector< unsigned char >::size_type n = m_code.size();
     412                 :            :     OSL_ASSERT(n > branch && n - branch <= SAL_MAX_INT16);
     413                 :        662 :     n -= branch;
     414                 :        662 :     m_code[branch + 1] = static_cast< sal_uInt8 >(n >> 8);
     415                 :        662 :     m_code[branch + 2] = static_cast< sal_uInt8 >(n & 0xFF);
     416                 :        662 : }
     417                 :            : 
     418                 :        426 : void ClassFile::Code::addException(
     419                 :            :     Position start, Position end, Position handler, rtl::OString const & type)
     420                 :            : {
     421                 :            :     OSL_ASSERT(start < end && end <= m_code.size() && handler <= m_code.size());
     422         [ -  + ]:        426 :     if (m_exceptionTableLength == SAL_MAX_UINT16) {
     423                 :            :         throw CannotDumpException(
     424                 :            :             rtl::OString(
     425                 :            :                 RTL_CONSTASCII_STRINGPARAM(
     426                 :          0 :                     "Too many exception handlers for Java class file format")));
     427                 :            :     }
     428                 :        426 :     ++m_exceptionTableLength;
     429                 :        426 :     appendU2(m_exceptionTable, static_cast< sal_uInt16 >(start));
     430                 :            :         //FIXME: overflow
     431                 :        426 :     appendU2(m_exceptionTable, static_cast< sal_uInt16 >(end));
     432                 :            :         //FIXME: overflow
     433                 :        426 :     appendU2(m_exceptionTable, static_cast< sal_uInt16 >(handler));
     434                 :            :         //FIXME: overflow
     435                 :        426 :     appendU2(m_exceptionTable, m_classFile.addClassInfo(type));
     436                 :        426 : }
     437                 :            : 
     438                 :       1428 : ClassFile::Code::Position ClassFile::Code::getPosition() const {
     439                 :       1428 :     return m_code.size();
     440                 :            : }
     441                 :            : 
     442                 :      13451 : ClassFile::Code::Code(ClassFile & classFile):
     443         [ +  - ]:      13451 :     m_classFile(classFile), m_exceptionTableLength(0)
     444                 :      13451 : {}
     445                 :            : 
     446                 :      20033 : void ClassFile::Code::ldc(sal_uInt16 index) {
     447         [ +  + ]:      20033 :     if (index <= 0xFF) {
     448                 :            :         // ldc <index>:
     449                 :      19814 :         appendU1(m_code, 0x12);
     450                 :      19814 :         appendU1(m_code, static_cast< sal_uInt8 >(index));
     451                 :            :     } else {
     452                 :            :         // ldc_w <indexbyte1> <indexbyte2>:
     453                 :        219 :         appendU1(m_code, 0x13);
     454                 :        219 :         appendU2(m_code, index);
     455                 :            :     }
     456                 :      20033 : }
     457                 :            : 
     458                 :      19310 : void ClassFile::Code::accessLocal(
     459                 :            :     sal_uInt16 index, sal_uInt8 fastOp, sal_uInt8 normalOp)
     460                 :            : {
     461         [ +  + ]:      19310 :     if (index <= 3) {
     462                 :            :         // ...load/store_<n>:
     463                 :      17486 :         appendU1(m_code, static_cast< sal_uInt8 >(fastOp + index));
     464         [ +  - ]:       1824 :     } else if (index <= 0xFF) {
     465                 :            :         // ...load/store <index>:
     466                 :       1824 :         appendU1(m_code, normalOp);
     467                 :       1824 :         appendU1(m_code, static_cast< sal_uInt8 >(index));
     468                 :            :     } else {
     469                 :            :         // wide ...load/store <indexbyte1> <indexbyte2>:
     470                 :          0 :         appendU1(m_code, 0xC4);
     471                 :          0 :         appendU1(m_code, normalOp);
     472                 :          0 :         appendU2(m_code, index);
     473                 :            :     }
     474                 :      19310 : }
     475                 :            : 
     476                 :       6200 : ClassFile::ClassFile(
     477                 :            :     AccessFlags accessFlags, rtl::OString const & thisClass,
     478                 :            :     rtl::OString const & superClass, rtl::OString const & signature):
     479                 :            :     m_constantPoolCount(1), m_accessFlags(accessFlags), m_interfacesCount(0),
     480 [ +  - ][ +  - ]:       6200 :     m_fieldsCount(0), m_methodsCount(0), m_attributesCount(0)
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     481                 :            : {
     482         [ +  - ]:       6200 :     m_thisClass = addClassInfo(thisClass);
     483         [ +  - ]:       6200 :     m_superClass = addClassInfo(superClass);
     484         [ +  + ]:       6200 :     if (!signature.isEmpty()) {
     485                 :         10 :         ++m_attributesCount;
     486                 :            :         appendU2(
     487                 :            :             m_attributes,
     488 [ +  - ][ +  - ]:         10 :             addUtf8Info(rtl::OString(RTL_CONSTASCII_STRINGPARAM("Signature"))));
     489         [ +  - ]:         10 :         appendU4(m_attributes, 2);
     490 [ +  - ][ +  - ]:         10 :         appendU2(m_attributes, addUtf8Info(signature));
     491                 :            :     }
     492                 :       6200 : }
     493                 :            : 
     494                 :       6200 : ClassFile::~ClassFile() {}
     495                 :            : 
     496                 :      13451 : ClassFile::Code * ClassFile::newCode() {
     497         [ +  - ]:      13451 :     return new Code(*this);
     498                 :            : }
     499                 :            : 
     500                 :       9381 : sal_uInt16 ClassFile::addIntegerInfo(sal_Int32 value) {
     501         [ +  - ]:       9381 :     std::map< sal_Int32, sal_uInt16 >::iterator i(m_integerInfos.find(value));
     502 [ +  - ][ +  + ]:       9381 :     if (i != m_integerInfos.end()) {
     503         [ +  - ]:        138 :         return i->second;
     504                 :            :     }
     505         [ +  - ]:       9243 :     sal_uInt16 index = nextConstantPoolIndex(1);
     506         [ +  - ]:       9243 :     appendU1(m_constantPool, 3);
     507         [ +  - ]:       9243 :     appendU4(m_constantPool, static_cast< sal_uInt32 >(value));
     508                 :       9243 :     if (!m_integerInfos.insert(
     509 [ +  - ][ +  - ]:       9243 :             std::map< sal_Int32, sal_uInt16 >::value_type(value, index)).second)
     510                 :            :     {
     511                 :            :         OSL_ASSERT(false);
     512                 :            :     }
     513                 :       9381 :     return index;
     514                 :            : }
     515                 :            : 
     516                 :         40 : sal_uInt16 ClassFile::addFloatInfo(float value) {
     517         [ +  - ]:         40 :     std::map< float, sal_uInt16 >::iterator i(m_floatInfos.find(value));
     518 [ +  - ][ -  + ]:         40 :     if (i != m_floatInfos.end()) {
     519         [ #  # ]:          0 :         return i->second;
     520                 :            :     }
     521         [ +  - ]:         40 :     sal_uInt16 index = nextConstantPoolIndex(1);
     522         [ +  - ]:         40 :     appendU1(m_constantPool, 4);
     523                 :            :     union { float floatBytes; sal_uInt32 uint32Bytes; } bytes;
     524                 :         40 :     bytes.floatBytes = value;
     525         [ +  - ]:         40 :     appendU4(m_constantPool, bytes.uint32Bytes);
     526                 :         40 :     if (!m_floatInfos.insert(
     527 [ +  - ][ +  - ]:         40 :             std::map< float, sal_uInt16 >::value_type(value, index)).second)
     528                 :            :     {
     529                 :            :         OSL_ASSERT(false);
     530                 :            :     }
     531                 :         40 :     return index;
     532                 :            : }
     533                 :            : 
     534                 :         58 : sal_uInt16 ClassFile::addLongInfo(sal_Int64 value) {
     535         [ +  - ]:         58 :     std::map< sal_Int64, sal_uInt16 >::iterator i(m_longInfos.find(value));
     536 [ +  - ][ -  + ]:         58 :     if (i != m_longInfos.end()) {
     537         [ #  # ]:          0 :         return i->second;
     538                 :            :     }
     539         [ +  - ]:         58 :     sal_uInt16 index = nextConstantPoolIndex(2);
     540         [ +  - ]:         58 :     appendU1(m_constantPool, 5);
     541         [ +  - ]:         58 :     appendU8(m_constantPool, static_cast< sal_uInt64 >(value));
     542                 :         58 :     if (!m_longInfos.insert(
     543 [ +  - ][ +  - ]:         58 :             std::map< sal_Int64, sal_uInt16 >::value_type(value, index)).second)
     544                 :            :     {
     545                 :            :         OSL_ASSERT(false);
     546                 :            :     }
     547                 :         58 :     return index;
     548                 :            : }
     549                 :            : 
     550                 :          0 : sal_uInt16 ClassFile::addDoubleInfo(double value) {
     551         [ #  # ]:          0 :     std::map< double, sal_uInt16 >::iterator i(m_doubleInfos.find(value));
     552 [ #  # ][ #  # ]:          0 :     if (i != m_doubleInfos.end()) {
     553         [ #  # ]:          0 :         return i->second;
     554                 :            :     }
     555         [ #  # ]:          0 :     sal_uInt16 index = nextConstantPoolIndex(2);
     556         [ #  # ]:          0 :     appendU1(m_constantPool, 6);
     557                 :            :     union { double doubleBytes; sal_uInt64 uint64Bytes; } bytes;
     558                 :          0 :     bytes.doubleBytes = value;
     559         [ #  # ]:          0 :     appendU8(m_constantPool, bytes.uint64Bytes);
     560                 :          0 :     if (!m_doubleInfos.insert(
     561 [ #  # ][ #  # ]:          0 :             std::map< double, sal_uInt16 >::value_type(value, index)).second)
     562                 :            :     {
     563                 :            :         OSL_ASSERT(false);
     564                 :            :     }
     565                 :          0 :     return index;
     566                 :            : }
     567                 :            : 
     568                 :       3586 : void ClassFile::addInterface(rtl::OString const & interface) {
     569         [ -  + ]:       3586 :     if (m_interfacesCount == SAL_MAX_UINT16) {
     570                 :            :         throw CannotDumpException(
     571                 :            :             rtl::OString(
     572                 :            :                 RTL_CONSTASCII_STRINGPARAM(
     573                 :          0 :                     "Too many interfaces for Java class file format")));
     574                 :            :     }
     575                 :       3586 :     ++m_interfacesCount;
     576                 :       3586 :     appendU2(m_interfaces, addClassInfo(interface));
     577                 :       3586 : }
     578                 :            : 
     579                 :      20160 : void ClassFile::addField(
     580                 :            :     AccessFlags accessFlags, rtl::OString const & name,
     581                 :            :     rtl::OString const & descriptor, sal_uInt16 constantValueIndex,
     582                 :            :     rtl::OString const & signature)
     583                 :            : {
     584         [ -  + ]:      20160 :     if (m_fieldsCount == SAL_MAX_UINT16) {
     585                 :            :         throw CannotDumpException(
     586                 :            :             rtl::OString(
     587                 :            :                 RTL_CONSTASCII_STRINGPARAM(
     588                 :          0 :                     "Too many fields for Java class file format")));
     589                 :            :     }
     590                 :      20160 :     ++m_fieldsCount;
     591                 :      20160 :     appendU2(m_fields, static_cast< sal_uInt16 >(accessFlags));
     592                 :      20160 :     appendU2(m_fields, addUtf8Info(name));
     593                 :      20160 :     appendU2(m_fields, addUtf8Info(descriptor));
     594                 :            :     appendU2(
     595                 :            :         m_fields,
     596                 :            :         ((constantValueIndex == 0 ? 0 : 1)
     597         [ +  + ]:      20160 :          + (signature.isEmpty() ? 0 : 1)));
     598         [ +  + ]:      20160 :     if (constantValueIndex != 0) {
     599                 :            :         appendU2(
     600                 :            :             m_fields,
     601                 :            :             addUtf8Info(
     602 [ +  - ][ +  - ]:       9449 :                 rtl::OString(RTL_CONSTASCII_STRINGPARAM("ConstantValue"))));
     603                 :       9449 :         appendU4(m_fields, 2);
     604                 :       9449 :         appendU2(m_fields, constantValueIndex);
     605                 :            :     }
     606                 :      20160 :     appendSignatureAttribute(m_fields, signature);
     607                 :      20160 : }
     608                 :            : 
     609                 :      23615 : void ClassFile::addMethod(
     610                 :            :     AccessFlags accessFlags, rtl::OString const & name,
     611                 :            :     rtl::OString const & descriptor, Code const * code,
     612                 :            :     std::vector< rtl::OString > const & exceptions,
     613                 :            :     rtl::OString const & signature)
     614                 :            : {
     615         [ -  + ]:      23615 :     if (m_methodsCount == SAL_MAX_UINT16) {
     616                 :            :         throw CannotDumpException(
     617                 :            :             rtl::OString(
     618                 :            :                 RTL_CONSTASCII_STRINGPARAM(
     619                 :          0 :                     "Too many methods for Java class file format")));
     620                 :            :     }
     621                 :      23615 :     ++m_methodsCount;
     622                 :      23615 :     appendU2(m_methods, static_cast< sal_uInt16 >(accessFlags));
     623                 :      23615 :     appendU2(m_methods, addUtf8Info(name));
     624                 :      23615 :     appendU2(m_methods, addUtf8Info(descriptor));
     625                 :      23615 :     std::vector< rtl::OString >::size_type excs = exceptions.size();
     626         [ -  + ]:      23615 :     if (excs > SAL_MAX_UINT16) {
     627                 :            :         throw CannotDumpException(
     628                 :            :             rtl::OString(
     629                 :            :                 RTL_CONSTASCII_STRINGPARAM(
     630                 :            :                     "Too many exception specifications for Java class file"
     631                 :          0 :                     " format")));
     632                 :            :     }
     633                 :            :     appendU2(
     634                 :            :         m_methods,
     635                 :      23615 :         ((code == 0 ? 0 : 1) + (exceptions.empty() ? 0 : 1)
     636 [ +  + ][ +  + ]:      23615 :          + (signature.isEmpty() ? 0 : 1)));
     637         [ +  + ]:      23615 :     if (code != 0) {
     638                 :      10221 :         std::vector< unsigned char >::size_type codeSize = code->m_code.size();
     639                 :            :         std::vector< unsigned char >::size_type exceptionTableSize
     640                 :      10221 :             = code->m_exceptionTable.size();
     641 [ -  + ][ +  - ]:      10221 :         if (codeSize > SAL_MAX_UINT32 - (2 + 2 + 4 + 2 + 2)
     642                 :            :             || (exceptionTableSize
     643                 :            :                 > (SAL_MAX_UINT32 - (2 + 2 + 4 + 2 + 2)
     644                 :            :                    - static_cast< sal_uInt32 >(codeSize))))
     645                 :            :         {
     646                 :            :             throw CannotDumpException(
     647                 :            :                 rtl::OString(
     648                 :            :                     RTL_CONSTASCII_STRINGPARAM(
     649                 :          0 :                         "Code block is too big for Java class file format")));
     650                 :            :         }
     651                 :            :         appendU2(
     652                 :            :             m_methods,
     653 [ +  - ][ +  - ]:      10221 :             addUtf8Info(rtl::OString(RTL_CONSTASCII_STRINGPARAM("Code"))));
     654                 :            :         appendU4(
     655                 :            :             m_methods,
     656                 :            :             (2 + 2 + 4 + static_cast< sal_uInt32 >(codeSize) + 2
     657                 :      10221 :              + static_cast< sal_uInt32 >(exceptionTableSize) + 2));
     658                 :      10221 :         appendU2(m_methods, code->m_maxStack);
     659                 :      10221 :         appendU2(m_methods, code->m_maxLocals);
     660                 :      10221 :         appendU4(m_methods, static_cast< sal_uInt32 >(codeSize));
     661                 :      10221 :         appendStream(m_methods, code->m_code);
     662                 :      10221 :         appendU2(m_methods, code->m_exceptionTableLength);
     663                 :      10221 :         appendStream(m_methods, code->m_exceptionTable);
     664                 :      10221 :         appendU2(m_methods, 0);
     665                 :            :     }
     666         [ +  + ]:      23615 :     if (!exceptions.empty()) {
     667                 :            :         appendU2(
     668                 :            :             m_methods,
     669                 :            :             addUtf8Info(
     670 [ +  - ][ +  - ]:       4115 :                 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Exceptions"))));
     671                 :            :         appendU4(
     672                 :            :             m_methods,
     673                 :       4115 :             static_cast< sal_uInt32 >(2 + 2 * static_cast< sal_uInt32 >(excs)));
     674                 :       4115 :         appendU2(m_methods, static_cast< sal_uInt16 >(excs));
     675 [ +  - ][ +  + ]:      19780 :         for (std::vector< rtl::OString >::const_iterator i(exceptions.begin());
     676                 :       9890 :              i != exceptions.end(); ++i)
     677                 :            :         {
     678 [ +  - ][ +  - ]:       5775 :             appendU2(m_methods, addClassInfo(*i));
     679                 :            :         }
     680                 :            :     }
     681                 :      23615 :     appendSignatureAttribute(m_methods, signature);
     682                 :      23615 : }
     683                 :            : 
     684                 :       6200 : void ClassFile::write(FileStream & file) const {
     685                 :       6200 :     writeU4(file, 0xCAFEBABE);
     686                 :       6200 :     writeU2(file, 0);
     687                 :       6200 :     writeU2(file, 49); // class file version of JRE 1.5
     688                 :       6200 :     writeU2(file, m_constantPoolCount);
     689                 :       6200 :     writeStream(file, m_constantPool);
     690                 :       6200 :     writeU2(file, static_cast< sal_uInt16 >(m_accessFlags));
     691                 :       6200 :     writeU2(file, m_thisClass);
     692                 :       6200 :     writeU2(file, m_superClass);
     693                 :       6200 :     writeU2(file, m_interfacesCount);
     694                 :       6200 :     writeStream(file, m_interfaces);
     695                 :       6200 :     writeU2(file, m_fieldsCount);
     696                 :       6200 :     writeStream(file, m_fields);
     697                 :       6200 :     writeU2(file, m_methodsCount);
     698                 :       6200 :     writeStream(file, m_methods);
     699                 :       6200 :     writeU2(file, m_attributesCount);
     700                 :       6200 :     writeStream(file, m_attributes);
     701                 :       6200 : }
     702                 :            : 
     703                 :     227419 : sal_uInt16 ClassFile::nextConstantPoolIndex(sal_uInt16 width) {
     704                 :            :     OSL_ASSERT(width == 1 || width == 2);
     705         [ -  + ]:     227419 :     if (m_constantPoolCount > SAL_MAX_UINT16 - width) {
     706                 :            :         throw CannotDumpException(
     707                 :            :             rtl::OString(
     708                 :            :                 RTL_CONSTASCII_STRINGPARAM(
     709                 :            :                     "Too many constant pool items for Java class file"
     710                 :          0 :                     " format")));
     711                 :            :     }
     712                 :     227419 :     sal_uInt16 index = m_constantPoolCount;
     713                 :     227419 :     m_constantPoolCount = m_constantPoolCount + width;
     714                 :     227419 :     return index;
     715                 :            : }
     716                 :            : 
     717                 :     312803 : sal_uInt16 ClassFile::addUtf8Info(rtl::OString const & value) {
     718         [ +  - ]:     312803 :     std::map< rtl::OString, sal_uInt16 >::iterator i(m_utf8Infos.find(value));
     719         [ +  + ]:     312803 :     if (i != m_utf8Infos.end()) {
     720                 :     188669 :         return i->second;
     721                 :            :     }
     722         [ -  + ]:     124134 :     if (value.getLength() > SAL_MAX_UINT16) {
     723                 :            :         throw CannotDumpException(
     724                 :            :             rtl::OString(
     725                 :            :                 RTL_CONSTASCII_STRINGPARAM(
     726                 :          0 :                     "UTF-8 string too long for Java class file format")));
     727                 :            :     }
     728         [ +  - ]:     124134 :     sal_uInt16 index = nextConstantPoolIndex(1);
     729         [ +  - ]:     124134 :     appendU1(m_constantPool, 1);
     730         [ +  - ]:     124134 :     appendU2(m_constantPool, static_cast< sal_uInt16 >(value.getLength()));
     731         [ +  + ]:    2892929 :     for (sal_Int32 j = 0; j < value.getLength(); ++j) {
     732         [ +  - ]:    2768795 :         appendU1(m_constantPool, static_cast< sal_uInt8 >(value[j]));
     733                 :            :     }
     734                 :     124134 :     if (!m_utf8Infos.insert(
     735                 :            :             std::map< rtl::OString, sal_uInt16 >::value_type(value, index)).
     736 [ +  - ][ +  - ]:     124134 :         second)
     737                 :            :     {
     738                 :            :         OSL_ASSERT(false);
     739                 :            :     }
     740                 :     312803 :     return index;
     741                 :            : }
     742                 :            : 
     743                 :      92883 : sal_uInt16 ClassFile::addClassInfo(rtl::OString const & type) {
     744         [ +  - ]:      92883 :     sal_uInt16 nameIndex = addUtf8Info(type);
     745                 :            :     std::map< sal_uInt16, sal_uInt16 >::iterator i(
     746         [ +  - ]:      92883 :         m_classInfos.find(nameIndex));
     747 [ +  - ][ +  + ]:      92883 :     if (i != m_classInfos.end()) {
     748         [ +  - ]:      61963 :         return i->second;
     749                 :            :     }
     750         [ +  - ]:      30920 :     sal_uInt16 index = nextConstantPoolIndex(1);
     751         [ +  - ]:      30920 :     appendU1(m_constantPool, 7);
     752         [ +  - ]:      30920 :     appendU2(m_constantPool, nameIndex);
     753                 :      30920 :     if (!m_classInfos.insert(
     754                 :            :             std::map< sal_uInt16, sal_uInt16 >::value_type(nameIndex, index)).
     755 [ +  - ][ +  - ]:      30920 :         second)
     756                 :            :     {
     757                 :            :         OSL_ASSERT(false);
     758                 :            :     }
     759                 :      92883 :     return index;
     760                 :            : }
     761                 :            : 
     762                 :      20003 : sal_uInt16 ClassFile::addStringInfo(rtl::OString const & value) {
     763         [ +  - ]:      20003 :     sal_uInt16 stringIndex = addUtf8Info(value);
     764                 :            :     std::map< sal_uInt16, sal_uInt16 >::iterator i(
     765         [ +  - ]:      20003 :         m_stringInfos.find(stringIndex));
     766 [ +  - ][ +  + ]:      20003 :     if (i != m_stringInfos.end()) {
     767         [ +  - ]:       1390 :         return i->second;
     768                 :            :     }
     769         [ +  - ]:      18613 :     sal_uInt16 index = nextConstantPoolIndex(1);
     770         [ +  - ]:      18613 :     appendU1(m_constantPool, 8);
     771         [ +  - ]:      18613 :     appendU2(m_constantPool, stringIndex);
     772                 :      18613 :     if (!m_stringInfos.insert(
     773                 :            :             std::map< sal_uInt16, sal_uInt16 >::value_type(stringIndex, index)).
     774 [ +  - ][ +  - ]:      18613 :         second)
     775                 :            :     {
     776                 :            :         OSL_ASSERT(false);
     777                 :            :     }
     778                 :      20003 :     return index;
     779                 :            : }
     780                 :            : 
     781                 :      16626 : sal_uInt16 ClassFile::addFieldrefInfo(
     782                 :            :     rtl::OString const & type, rtl::OString const & name,
     783                 :            :     rtl::OString const & descriptor)
     784                 :            : {
     785         [ +  - ]:      16626 :     sal_uInt16 classIndex = addClassInfo(type);
     786         [ +  - ]:      16626 :     sal_uInt16 nameAndTypeIndex = addNameAndTypeInfo(name, descriptor);
     787                 :            :     sal_uInt32 key = (static_cast< sal_uInt32 >(classIndex) << 16)
     788                 :      16626 :         | nameAndTypeIndex;
     789         [ +  - ]:      16626 :     std::map< sal_uInt32, sal_uInt16 >::iterator i(m_fieldrefInfos.find(key));
     790 [ +  - ][ +  + ]:      16626 :     if (i != m_fieldrefInfos.end()) {
     791         [ +  - ]:       5274 :         return i->second;
     792                 :            :     }
     793         [ +  - ]:      11352 :     sal_uInt16 index = nextConstantPoolIndex(1);
     794         [ +  - ]:      11352 :     appendU1(m_constantPool, 9);
     795         [ +  - ]:      11352 :     appendU2(m_constantPool, classIndex);
     796         [ +  - ]:      11352 :     appendU2(m_constantPool, nameAndTypeIndex);
     797                 :      11352 :     if (!m_fieldrefInfos.insert(
     798 [ +  - ][ +  - ]:      11352 :             std::map< sal_uInt32, sal_uInt16 >::value_type(key, index)).second)
     799                 :            :     {
     800                 :            :         OSL_ASSERT(false);
     801                 :            :     }
     802                 :      16626 :     return index;
     803                 :            : }
     804                 :            : 
     805                 :      26893 : sal_uInt16 ClassFile::addMethodrefInfo(
     806                 :            :     rtl::OString const & type, rtl::OString const & name,
     807                 :            :     rtl::OString const & descriptor)
     808                 :            : {
     809         [ +  - ]:      26893 :     sal_uInt16 classIndex = addClassInfo(type);
     810         [ +  - ]:      26893 :     sal_uInt16 nameAndTypeIndex = addNameAndTypeInfo(name, descriptor);
     811                 :            :     sal_uInt32 key = (static_cast< sal_uInt32 >(classIndex) << 16)
     812                 :      26893 :         | nameAndTypeIndex;
     813         [ +  - ]:      26893 :     std::map< sal_uInt32, sal_uInt16 >::iterator i(m_methodrefInfos.find(key));
     814 [ +  - ][ +  + ]:      26893 :     if (i != m_methodrefInfos.end()) {
     815         [ +  - ]:      16314 :         return i->second;
     816                 :            :     }
     817         [ +  - ]:      10579 :     sal_uInt16 index = nextConstantPoolIndex(1);
     818         [ +  - ]:      10579 :     appendU1(m_constantPool, 10);
     819         [ +  - ]:      10579 :     appendU2(m_constantPool, classIndex);
     820         [ +  - ]:      10579 :     appendU2(m_constantPool, nameAndTypeIndex);
     821                 :      10579 :     if (!m_methodrefInfos.insert(
     822 [ +  - ][ +  - ]:      10579 :             std::map< sal_uInt32, sal_uInt16 >::value_type(key, index)).second)
     823                 :            :     {
     824                 :            :         OSL_ASSERT(false);
     825                 :            :     }
     826                 :      26893 :     return index;
     827                 :            : }
     828                 :            : 
     829                 :        681 : sal_uInt16 ClassFile::addInterfaceMethodrefInfo(
     830                 :            :     rtl::OString const & type, rtl::OString const & name,
     831                 :            :     rtl::OString const & descriptor)
     832                 :            : {
     833         [ +  - ]:        681 :     sal_uInt16 classIndex = addClassInfo(type);
     834         [ +  - ]:        681 :     sal_uInt16 nameAndTypeIndex = addNameAndTypeInfo(name, descriptor);
     835                 :            :     sal_uInt32 key = (static_cast< sal_uInt32 >(classIndex) << 16)
     836                 :        681 :         | nameAndTypeIndex;
     837                 :            :     std::map< sal_uInt32, sal_uInt16 >::iterator i(
     838         [ +  - ]:        681 :         m_interfaceMethodrefInfos.find(key));
     839 [ +  - ][ +  + ]:        681 :     if (i != m_interfaceMethodrefInfos.end()) {
     840         [ +  - ]:         59 :         return i->second;
     841                 :            :     }
     842         [ +  - ]:        622 :     sal_uInt16 index = nextConstantPoolIndex(1);
     843         [ +  - ]:        622 :     appendU1(m_constantPool, 11);
     844         [ +  - ]:        622 :     appendU2(m_constantPool, classIndex);
     845         [ +  - ]:        622 :     appendU2(m_constantPool, nameAndTypeIndex);
     846                 :        622 :     if (!m_interfaceMethodrefInfos.insert(
     847 [ +  - ][ +  - ]:        622 :             std::map< sal_uInt32, sal_uInt16 >::value_type(key, index)).second)
     848                 :            :     {
     849                 :            :         OSL_ASSERT(false);
     850                 :            :     }
     851                 :        681 :     return index;
     852                 :            : }
     853                 :            : 
     854                 :      44200 : sal_uInt16 ClassFile::addNameAndTypeInfo(
     855                 :            :     rtl::OString const & name, rtl::OString const & descriptor)
     856                 :            : {
     857         [ +  - ]:      44200 :     sal_uInt16 nameIndex = addUtf8Info(name);
     858         [ +  - ]:      44200 :     sal_uInt16 descriptorIndex = addUtf8Info(descriptor);
     859                 :            :     sal_uInt32 key = (static_cast< sal_uInt32 >(nameIndex) << 16)
     860                 :      44200 :         | descriptorIndex;
     861                 :            :     std::map< sal_uInt32, sal_uInt16 >::iterator i(
     862         [ +  - ]:      44200 :         m_nameAndTypeInfos.find(key));
     863 [ +  - ][ +  + ]:      44200 :     if (i != m_nameAndTypeInfos.end()) {
     864         [ +  - ]:      22342 :         return i->second;
     865                 :            :     }
     866         [ +  - ]:      21858 :     sal_uInt16 index = nextConstantPoolIndex(1);
     867         [ +  - ]:      21858 :     appendU1(m_constantPool, 12);
     868         [ +  - ]:      21858 :     appendU2(m_constantPool, nameIndex);
     869         [ +  - ]:      21858 :     appendU2(m_constantPool, descriptorIndex);
     870                 :      21858 :     if (!m_nameAndTypeInfos.insert(
     871 [ +  - ][ +  - ]:      21858 :             std::map< sal_uInt32, sal_uInt16 >::value_type(key, index)).second)
     872                 :            :     {
     873                 :            :         OSL_ASSERT(false);
     874                 :            :     }
     875                 :      44200 :     return index;
     876                 :            : }
     877                 :            : 
     878                 :      43775 : void ClassFile::appendSignatureAttribute(
     879                 :            :     std::vector< unsigned char > & stream, rtl::OString const & signature)
     880                 :            : {
     881         [ +  + ]:      43775 :     if (!signature.isEmpty()) {
     882                 :            :         appendU2(
     883                 :            :             stream,
     884 [ +  - ][ +  - ]:         81 :             addUtf8Info(rtl::OString(RTL_CONSTASCII_STRINGPARAM("Signature"))));
     885                 :         81 :         appendU4(stream, 2);
     886                 :         81 :         appendU2(stream, addUtf8Info(signature));
     887                 :            :     }
     888                 :      43775 : }
     889                 :            : 
     890                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10