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