27#include <osl/diagnose.h>
28#include <rtl/string.h>
29#include <rtl/string.hxx>
40void appendU1(std::vector< unsigned char > & stream,
sal_uInt8 data) {
41 stream.push_back(
static_cast< unsigned char >(data));
44void appendU2(std::vector< unsigned char > & stream, sal_uInt16 data) {
45 stream.push_back(
static_cast< unsigned char >(data >> 8));
46 stream.push_back(
static_cast< unsigned char >(data & 0xFF));
49void appendU4(std::vector< unsigned char > & stream, sal_uInt32 data) {
50 stream.push_back(
static_cast< unsigned char >(data >> 24));
51 stream.push_back(
static_cast< unsigned char >((data >> 16) & 0xFF));
52 stream.push_back(
static_cast< unsigned char >((data >> 8) & 0xFF));
53 stream.push_back(
static_cast< unsigned char >(data & 0xFF));
56void appendU8(std::vector< unsigned char > & stream, sal_uInt64 data) {
57 stream.push_back(
static_cast< unsigned char >(data >> 56));
58 stream.push_back(
static_cast< unsigned char >((data >> 48) & 0xFF));
59 stream.push_back(
static_cast< unsigned char >((data >> 40) & 0xFF));
60 stream.push_back(
static_cast< unsigned char >((data >> 32) & 0xFF));
61 stream.push_back(
static_cast< unsigned char >((data >> 24) & 0xFF));
62 stream.push_back(
static_cast< unsigned char >((data >> 16) & 0xFF));
63 stream.push_back(
static_cast< unsigned char >((data >> 8) & 0xFF));
64 stream.push_back(
static_cast< unsigned char >(data & 0xFF));
68 std::vector< unsigned char > & stream,
69 std::vector< unsigned char >
const & data)
74void write(
FileStream & file,
void const * buffer, sal_uInt64 size) {
75 if (!file.write(buffer, size))
79void writeU2(
FileStream & file, sal_uInt16 data) {
80 unsigned char buf[] = {
81 static_cast< unsigned char >(data >> 8),
82 static_cast< unsigned char >(data & 0xFF) };
83 write(file, buf,
sizeof buf);
86void writeU4(
FileStream & file, sal_uInt32 data) {
87 unsigned char buf[] = {
88 static_cast< unsigned char >(data >> 24),
89 static_cast< unsigned char >((data >> 16) & 0xFF),
90 static_cast< unsigned char >((data >> 8) & 0xFF),
91 static_cast< unsigned char >(data & 0xFF) };
92 write(file, buf,
sizeof buf);
95void writeStream(
FileStream & file, std::vector< unsigned char >
const & stream)
97 std::vector< unsigned char >::size_type
n =
stream.size();
99 sizeof (std::vector< unsigned char >::size_type)
100 <=
sizeof (sal_uInt64),
"must be at most equal in size");
105 write(file,
stream.data(),
static_cast< sal_uInt64
>(n));
111ClassFile::Code::~Code() {}
113void ClassFile::Code::instrAastore() {
115 appendU1(m_code, 0x53);
118void ClassFile::Code::instrAconstNull() {
120 appendU1(m_code, 0x01);
123void ClassFile::Code::instrAnewarray(OString
const & type) {
125 appendU1(m_code, 0xBD);
126 appendU2(m_code, m_classFile.addClassInfo(
type));
129void ClassFile::Code::instrAreturn() {
131 appendU1(m_code, 0xB0);
134void ClassFile::Code::instrAthrow() {
136 appendU1(m_code, 0xBF);
139void ClassFile::Code::instrCheckcast(OString
const & type) {
141 appendU1(m_code, 0xC0);
142 appendU2(m_code, m_classFile.addClassInfo(
type));
145void ClassFile::Code::instrDup() {
147 appendU1(m_code, 0x59);
150void ClassFile::Code::instrGetstatic(
151 OString
const & type, OString
const & name,
152 OString
const & descriptor)
155 appendU1(m_code, 0xB2);
156 appendU2(m_code, m_classFile.addFieldrefInfo(
type,
name, descriptor));
161 Branch branch = m_code.size();
162 appendU1(m_code, 0xA6);
169 Branch branch = m_code.size();
170 appendU1(m_code, 0x99);
177 Branch branch = m_code.size();
178 appendU1(m_code, 0xC6);
183void ClassFile::Code::instrInstanceof(OString
const & type) {
185 appendU1(m_code, 0xC1);
186 appendU2(m_code, m_classFile.addClassInfo(
type));
189void ClassFile::Code::instrInvokeinterface(
190 OString
const & type, OString
const & name,
191 OString
const & descriptor,
sal_uInt8 args)
194 appendU1(m_code, 0xB9);
196 m_code, m_classFile.addInterfaceMethodrefInfo(
type,
name, descriptor));
197 appendU1(m_code,
args);
201void ClassFile::Code::instrInvokespecial(
202 OString
const & type, OString
const & name,
203 OString
const & descriptor)
206 appendU1(m_code, 0xB7);
207 appendU2(m_code, m_classFile.addMethodrefInfo(
type,
name, descriptor));
210void ClassFile::Code::instrInvokestatic(
211 OString
const & type, OString
const & name,
212 OString
const & descriptor)
215 appendU1(m_code, 0xB8);
216 appendU2(m_code, m_classFile.addMethodrefInfo(
type,
name, descriptor));
219void ClassFile::Code::instrInvokevirtual(
220 OString
const & type, OString
const & name,
221 OString
const & descriptor)
224 appendU1(m_code, 0xB6);
225 appendU2(m_code, m_classFile.addMethodrefInfo(
type,
name, descriptor));
228void ClassFile::Code::instrLookupswitch(
229 Code const * defaultBlock,
230 std::vector< std::pair< sal_Int32, Code * > >
const & blocks)
235 std::vector< std::pair< sal_Int32, Code * > >::size_type
size = blocks.size();
240 appendU1(m_code, 0xAB);
241 int pad = (pos1 + 1) % 4;
242 for (
int i = 0;
i < pad; ++
i) {
245 Position pos2 = pos1 + 1 + pad + 8 + blocks.size() * 8;
246 appendU4(m_code,
static_cast< sal_uInt32
>(pos2 - pos1));
247 pos2 += defaultBlock->
m_code.size();
248 appendU4(m_code,
static_cast< sal_uInt32
>(
size));
249 for (
const std::pair< sal_Int32, Code * >& pair : blocks)
251 appendU4(m_code,
static_cast< sal_uInt32
>(pair.first));
252 appendU4(m_code,
static_cast< sal_uInt32
>(pos2 - pos1));
254 pos2 += pair.second->m_code.size();
256 appendStream(m_code, defaultBlock->
m_code);
257 for (
const std::pair< sal_Int32, Code * >& pair : blocks)
259 appendStream(m_code, pair.second->m_code);
263void ClassFile::Code::instrNew(OString
const & type) {
265 appendU1(m_code, 0xBB);
266 appendU2(m_code, m_classFile.addClassInfo(
type));
274 appendU1(m_code, 0xBC);
276 0x04, 0x08, 0x09, 0x09, 0x0A, 0x0A, 0x0B, 0x0B, 0x06, 0x07, 0x05 };
277 appendU1(m_code, atypes[
static_cast<int>(sort) - 1]);
280void ClassFile::Code::instrPop() {
282 appendU1(m_code, 0x57);
285void ClassFile::Code::instrPutfield(
286 OString
const & type, OString
const & name,
287 OString
const & descriptor)
290 appendU1(m_code, 0xB5);
291 appendU2(m_code, m_classFile.addFieldrefInfo(
type,
name, descriptor));
294void ClassFile::Code::instrPutstatic(
295 OString
const & type, OString
const & name,
296 OString
const & descriptor)
299 appendU1(m_code, 0xB3);
300 appendU2(m_code, m_classFile.addFieldrefInfo(
type,
name, descriptor));
303void ClassFile::Code::instrReturn() {
305 appendU1(m_code, 0xB1);
308void ClassFile::Code::instrSwap() {
310 appendU1(m_code, 0x5F);
313void ClassFile::Code::instrTableswitch(
314 Code const * defaultBlock, sal_Int32 low,
315 std::vector< std::unique_ptr<Code> >
const & blocks)
321 appendU1(m_code, 0xAA);
322 int pad = (pos1 + 1) % 4;
323 for (
int i = 0;
i < pad; ++
i) {
326 std::vector< Code * >::size_type
size = blocks.size();
328 sal_uInt32 defaultOffset =
static_cast< sal_uInt32
>(pos2 - pos1);
330 appendU4(m_code, defaultOffset);
331 pos2 += defaultBlock->
m_code.size();
332 appendU4(m_code,
static_cast< sal_uInt32
>(low));
333 appendU4(m_code,
static_cast< sal_uInt32
>(low + (
size - 1)));
334 for (std::unique_ptr<Code>
const & pCode : blocks)
336 if (pCode ==
nullptr) {
337 appendU4(m_code, defaultOffset);
339 appendU4(m_code,
static_cast< sal_uInt32
>(pos2 - pos1));
341 pos2 += pCode->m_code.size();
344 appendStream(m_code, defaultBlock->
m_code);
345 for (std::unique_ptr<Code>
const & pCode : blocks)
347 if (pCode !=
nullptr) {
348 appendStream(m_code, pCode->m_code);
353void ClassFile::Code::loadIntegerConstant(sal_Int32 value) {
359 appendU1(m_code, 0x10);
361 }
else if (
value >= -32768 &&
value <= 32767) {
363 appendU1(m_code, 0x11);
364 appendU2(m_code,
static_cast< sal_uInt16
>(
value));
366 ldc(m_classFile.addIntegerInfo(
value));
370void ClassFile::Code::loadStringConstant(OString
const & value) {
371 ldc(m_classFile.addStringInfo(
value));
374void ClassFile::Code::loadLocalInteger(sal_uInt16 index) {
375 accessLocal(
index, 0x1A, 0x15);
378void ClassFile::Code::loadLocalLong(sal_uInt16 index) {
379 accessLocal(
index, 0x1E, 0x16);
382void ClassFile::Code::loadLocalFloat(sal_uInt16 index) {
383 accessLocal(
index, 0x22, 0x17);
386void ClassFile::Code::loadLocalDouble(sal_uInt16 index) {
387 accessLocal(
index, 0x26, 0x18);
390void ClassFile::Code::loadLocalReference(sal_uInt16 index) {
391 accessLocal(
index, 0x2A, 0x19);
394void ClassFile::Code::storeLocalReference(sal_uInt16 index) {
395 accessLocal(
index, 0x4B, 0x3A);
398void ClassFile::Code::branchHere(
Branch branch) {
399 std::vector< unsigned char >::size_type
n = m_code.size();
402 m_code[branch + 1] =
static_cast< sal_uInt8 >(
n >> 8);
403 m_code[branch + 2] =
static_cast< sal_uInt8 >(
n & 0xFF);
406void ClassFile::Code::addException(
409 OSL_ASSERT(
start <
end &&
end <= m_code.size() && handler <= m_code.size());
413 ++m_exceptionTableLength;
414 appendU2(m_exceptionTable,
static_cast< sal_uInt16
>(
start));
416 appendU2(m_exceptionTable,
static_cast< sal_uInt16
>(
end));
418 appendU2(m_exceptionTable,
static_cast< sal_uInt16
>(handler));
420 appendU2(m_exceptionTable, m_classFile.addClassInfo(
type));
424 return m_code.size();
428 : m_classFile(classFile)
431 , m_exceptionTableLength(0)
437 appendU1(m_code, 0x12);
441 appendU1(m_code, 0x13);
442 appendU2(m_code,
index);
452 }
else if (
index <= 0xFF) {
454 appendU1(m_code, normalOp);
458 appendU1(m_code, 0xC4);
459 appendU1(m_code, normalOp);
460 appendU2(m_code,
index);
465 AccessFlags accessFlags, OString
const & thisClass,
466 OString
const & superClass, OString
const & signature):
472 if (!signature.isEmpty()) {
483 return std::unique_ptr<Code>(
new Code(*
this));
508 union {
float floatBytes; sal_uInt32 uint32Bytes; }
bytes;
540 union {
double doubleBytes; sal_uInt64 uint64Bytes; }
bytes;
560 OString
const & descriptor, sal_uInt16 constantValueIndex,
561 OString
const & signature)
567 appendU2(
m_fields,
static_cast< sal_uInt16
>(accessFlags));
572 ((constantValueIndex == 0 ? 0 : 1)
573 + (signature.isEmpty() ? 0 : 1)));
574 if (constantValueIndex != 0) {
577 appendU2(
m_fields, constantValueIndex);
584 OString
const & descriptor,
Code const * code,
585 std::vector< OString >
const & exceptions,
586 OString
const & signature)
592 appendU2(
m_methods,
static_cast< sal_uInt16
>(accessFlags));
595 std::vector< OString >::size_type excs = exceptions.size();
601 ((
code ==
nullptr ? 0 : 1) + (exceptions.empty() ? 0 : 1)
602 + (signature.isEmpty() ? 0 : 1)));
603 if (
code !=
nullptr) {
604 std::vector< unsigned char >::size_type codeSize =
code->m_code.size();
605 std::vector< unsigned char >::size_type exceptionTableSize
606 =
code->m_exceptionTable.size();
608 || (exceptionTableSize
610 -
static_cast< sal_uInt32
>(codeSize))))
617 (2 + 2 + 4 +
static_cast< sal_uInt32
>(codeSize) + 2
618 +
static_cast< sal_uInt32
>(exceptionTableSize) + 2));
621 appendU4(
m_methods,
static_cast< sal_uInt32
>(codeSize));
627 if (!exceptions.empty()) {
631 static_cast< sal_uInt32
>(2 + 2 *
static_cast< sal_uInt32
>(excs)));
632 appendU2(
m_methods,
static_cast< sal_uInt16
>(excs));
633 for (
const OString&
ex : exceptions)
642 writeU4(file, 0xCAFEBABE);
661 OSL_ASSERT(width == 1 || width == 2);
681 for (sal_Int32 j = 0; j <
value.getLength(); ++j) {
693 std::map< sal_uInt16, sal_uInt16 >::iterator
i(
710 std::map< sal_uInt16, sal_uInt16 >::iterator
i(
726 OString
const & type, OString
const & name,
727 OString
const & descriptor)
731 sal_uInt32 key = (
static_cast< sal_uInt32
>(classIndex) << 16)
749 OString
const & type, OString
const & name,
750 OString
const & descriptor)
754 sal_uInt32 key = (
static_cast< sal_uInt32
>(classIndex) << 16)
772 OString
const & type, OString
const & name,
773 OString
const & descriptor)
777 sal_uInt32 key = (
static_cast< sal_uInt32
>(classIndex) << 16)
779 std::map< sal_uInt32, sal_uInt16 >::iterator
i(
796 OString
const & name, OString
const & descriptor)
799 sal_uInt16 descriptorIndex =
addUtf8Info(descriptor);
800 sal_uInt32 key = (
static_cast< sal_uInt32
>(nameIndex) << 16)
802 std::map< sal_uInt32, sal_uInt16 >::iterator
i(
819 std::vector< unsigned char > & stream, OString
const & signature)
821 if (!signature.isEmpty()) {
void accessLocal(sal_uInt16 index, sal_uInt8 fastOp, sal_uInt8 normalOp)
void ldc(sal_uInt16 index)
std::vector< unsignedchar >::size_type Position
std::vector< unsigned char > m_code
std::vector< unsignedchar >::size_type Branch
std::map< double, sal_uInt16 > m_doubleInfos
sal_uInt16 m_interfacesCount
std::map< sal_Int64, sal_uInt16 > m_longInfos
sal_uInt16 m_methodsCount
std::vector< unsigned char > m_constantPool
std::vector< unsigned char > m_attributes
void addField(AccessFlags accessFlags, rtl::OString const &name, rtl::OString const &descriptor, sal_uInt16 constantValueIndex, rtl::OString const &signature)
std::vector< unsigned char > m_methods
std::map< sal_uInt16, sal_uInt16 > m_classInfos
std::map< rtl::OString, sal_uInt16 > m_utf8Infos
std::map< sal_uInt32, sal_uInt16 > m_methodrefInfos
void addMethod(AccessFlags accessFlags, rtl::OString const &name, rtl::OString const &descriptor, Code const *code, std::vector< rtl::OString > const &exceptions, rtl::OString const &signature)
sal_uInt16 addClassInfo(rtl::OString const &type)
sal_uInt16 addMethodrefInfo(rtl::OString const &type, rtl::OString const &name, rtl::OString const &descriptor)
std::map< sal_uInt32, sal_uInt16 > m_interfaceMethodrefInfos
sal_uInt16 addInterfaceMethodrefInfo(rtl::OString const &type, rtl::OString const &name, rtl::OString const &descriptor)
std::map< sal_uInt32, sal_uInt16 > m_nameAndTypeInfos
std::map< sal_uInt32, sal_uInt16 > m_fieldrefInfos
sal_uInt16 m_attributesCount
sal_uInt16 addUtf8Info(rtl::OString const &value)
sal_uInt16 addDoubleInfo(double value)
void appendSignatureAttribute(std::vector< unsigned char > &stream, rtl::OString const &signature)
sal_uInt16 addFieldrefInfo(rtl::OString const &type, rtl::OString const &name, rtl::OString const &descriptor)
sal_uInt16 addFloatInfo(float value)
std::vector< unsigned char > m_fields
sal_uInt16 m_constantPoolCount
sal_uInt16 addLongInfo(sal_Int64 value)
sal_uInt16 addNameAndTypeInfo(rtl::OString const &name, rtl::OString const &descriptor)
std::map< float, sal_uInt16 > m_floatInfos
std::vector< unsigned char > m_interfaces
sal_uInt16 nextConstantPoolIndex(sal_uInt16 width)
sal_uInt16 addStringInfo(rtl::OString const &value)
AccessFlags m_accessFlags
void write(FileStream &file) const
ClassFile(AccessFlags accessFlags, rtl::OString const &thisClass, rtl::OString const &superClass, rtl::OString const &signature)
std::unique_ptr< Code > newCode()
std::map< sal_Int32, sal_uInt16 > m_integerInfos
sal_uInt16 addIntegerInfo(sal_Int32 value)
void addInterface(rtl::OString const &interface)
std::map< sal_uInt16, sal_uInt16 > m_stringInfos
Reference< XOutputStream > stream
Sort
An enumeration of all the sorts of relevant UNOIDL entities.
std::vector< sal_uInt8 > bytes