summaryrefslogtreecommitdiff
path: root/codemaker
diff options
context:
space:
mode:
authorNoel Grandin <noel@peralex.com>2014-08-15 16:17:25 +0200
committerNoel Grandin <noel@peralex.com>2014-09-25 13:47:25 +0200
commit83636d2c09802aeeb1b30078022d228d04da21eb (patch)
tree8a0c619e16c1f6b5388939d5da2956f7ef758c19 /codemaker
parentcf49392511e98851174b353782df9eb6bac46f77 (diff)
java: when rethrowing exceptions, store the original cause
so that we get a nice complete stacktrace when it hits the final handler Change-Id: Iec4fcc15a2a25c55f591b5e069dce3d010197a90
Diffstat (limited to 'codemaker')
-rw-r--r--codemaker/source/javamaker/javatype.cxx137
1 files changed, 129 insertions, 8 deletions
diff --git a/codemaker/source/javamaker/javatype.cxx b/codemaker/source/javamaker/javatype.cxx
index 9e08171bb07d..5d026449b0f6 100644
--- a/codemaker/source/javamaker/javatype.cxx
+++ b/codemaker/source/javamaker/javatype.cxx
@@ -1672,6 +1672,8 @@ void handleExceptionType(
i->name, index++);
}
}
+
+ // create default constructor
SAL_WNODEPRECATED_DECLARATIONS_PUSH
std::auto_ptr< ClassFile::Code > code(cf->newCode());
SAL_WNODEPRECATED_DECLARATIONS_POP
@@ -1702,6 +1704,78 @@ void handleExceptionType(
cf->addMethod(
ClassFile::ACC_PUBLIC, "<init>", "()V", code.get(),
std::vector< OString >(), "");
+
+
+ // create (Throwable Cause) constructor
+ code.reset(cf->newCode());
+ code->loadLocalReference(0);
+ code->loadLocalReference(1);
+ code->instrInvokespecial(superClass, "<init>", "(Ljava/lang/Throwable;)V");
+ stack = 0;
+ if (baseRuntimeException) {
+ stack = std::max(
+ stack,
+ addFieldInit(
+ manager, className, "Context", false,
+ "com.sun.star.uno.XInterface", dependencies, code.get()));
+ }
+ for (std::vector< unoidl::ExceptionTypeEntity::Member >::const_iterator i(
+ entity->getDirectMembers().begin());
+ i != entity->getDirectMembers().end(); ++i)
+ {
+ if (!baseException || i != entity->getDirectMembers().begin()) {
+ stack = std::max(
+ stack,
+ addFieldInit(
+ manager, className, i->name, false, i->type, dependencies,
+ code.get()));
+ }
+ }
+ code->instrReturn();
+ code->setMaxStackAndLocals(stack + 2, 2);
+ cf->addMethod(
+ ClassFile::ACC_PUBLIC, "<init>", "(Ljava/lang/Throwable;)V", code.get(),
+ std::vector< OString >(), "");
+
+ // create (Throwable Cause, String Message) constructor
+ code.reset(cf->newCode());
+ code->loadLocalReference(0);
+ if (baseException || baseRuntimeException) {
+ code->loadLocalReference(2);
+ code->loadLocalReference(1);
+ code->instrInvokespecial(superClass, "<init>", "(Ljava/lang/String;Ljava/lang/Throwable;)V");
+ } else {
+ code->loadLocalReference(1);
+ code->loadLocalReference(2);
+ code->instrInvokespecial(superClass, "<init>", "(Ljava/lang/Throwable;Ljava/lang/String;)V");
+ }
+ stack = 0;
+ if (baseRuntimeException) {
+ stack = std::max(
+ stack,
+ addFieldInit(
+ manager, className, "Context", false,
+ "com.sun.star.uno.XInterface", dependencies, code.get()));
+ }
+ for (std::vector< unoidl::ExceptionTypeEntity::Member >::const_iterator i(
+ entity->getDirectMembers().begin());
+ i != entity->getDirectMembers().end(); ++i)
+ {
+ if (!baseException || i != entity->getDirectMembers().begin()) {
+ stack = std::max(
+ stack,
+ addFieldInit(
+ manager, className, i->name, false, i->type, dependencies,
+ code.get()));
+ }
+ }
+ code->instrReturn();
+ code->setMaxStackAndLocals(stack + 3, 3);
+ cf->addMethod(
+ ClassFile::ACC_PUBLIC, "<init>", "(Ljava/lang/Throwable;Ljava/lang/String;)V", code.get(),
+ std::vector< OString >(), "");
+
+ // create (String Message) constructor
code.reset(cf->newCode());
code->loadLocalReference(0);
code->loadLocalReference(1);
@@ -1731,24 +1805,27 @@ void handleExceptionType(
cf->addMethod(
ClassFile::ACC_PUBLIC, "<init>", "(Ljava/lang/String;)V", code.get(),
std::vector< OString >(), "");
- MethodDescriptor desc(manager, dependencies, "void", 0, 0);
+
+
+ // create (String Message, Object Context, T1 m1, ..., Tn mn) constructor
+ MethodDescriptor desc1(manager, dependencies, "void", 0, 0);
code.reset(cf->newCode());
code->loadLocalReference(0);
sal_uInt16 index2 = 1;
- desc.addParameter("string", false, true, 0);
code->loadLocalReference(index2++);
+ desc1.addParameter("string", false, true, 0);
if (!(baseException || baseRuntimeException)) {
addExceptionBaseArguments(
- manager, dependencies, &desc, code.get(), entity->getDirectBase(),
+ manager, dependencies, &desc1, code.get(), entity->getDirectBase(),
&index2);
}
- code->instrInvokespecial(superClass, "<init>", desc.getDescriptor());
+ code->instrInvokespecial(superClass, "<init>", desc1.getDescriptor());
sal_uInt16 maxSize = index2;
if (baseRuntimeException) {
maxSize = std::max(
maxSize,
addDirectArgument(
- manager, dependencies, &desc, code.get(), &index2, className,
+ manager, dependencies, &desc1, code.get(), &index2, className,
"Context", false, "com.sun.star.uno.XInterface"));
}
for (std::vector< unoidl::ExceptionTypeEntity::Member >::const_iterator i(
@@ -1759,7 +1836,7 @@ void handleExceptionType(
maxSize = std::max(
maxSize,
addDirectArgument(
- manager, dependencies, &desc, code.get(), &index2,
+ manager, dependencies, &desc1, code.get(), &index2,
className, codemaker::convertString(i->name), false,
i->type));
}
@@ -1767,8 +1844,52 @@ void handleExceptionType(
code->instrReturn();
code->setMaxStackAndLocals(maxSize, index2);
cf->addMethod(
- ClassFile::ACC_PUBLIC, "<init>", desc.getDescriptor(), code.get(),
- std::vector< OString >(), desc.getSignature());
+ ClassFile::ACC_PUBLIC, "<init>", desc1.getDescriptor(), code.get(),
+ std::vector< OString >(), desc1.getSignature());
+
+ // create (Throwable Cause, String Message, Object Context, T1 m1, ..., Tn mn) constructor
+ MethodDescriptor desc2(manager, dependencies, "void", 0, 0);
+ code.reset(cf->newCode());
+ code->loadLocalReference(0);
+ sal_uInt16 index3 = 1;
+ code->loadLocalReference(index3++);
+ code->loadLocalReference(index3++);
+ // Note that we hack in the java.lang.Throwable parameter further down,
+ // because MethodDescriptor does not know how to handle it.
+ desc2.addParameter("string", false, true, 0);
+ if (!(baseException || baseRuntimeException)) {
+ addExceptionBaseArguments(
+ manager, dependencies, &desc2, code.get(), entity->getDirectBase(),
+ &index3);
+ }
+ code->instrInvokespecial(superClass, "<init>", "(Ljava/lang/Throwable;" + desc2.getDescriptor().copy(1));
+ sal_uInt16 maxSize2 = index3;
+ if (baseRuntimeException) {
+ maxSize2 = std::max(
+ maxSize2,
+ addDirectArgument(
+ manager, dependencies, &desc2, code.get(), &index3, className,
+ "Context", false, "com.sun.star.uno.XInterface"));
+ }
+ for (std::vector< unoidl::ExceptionTypeEntity::Member >::const_iterator i(
+ entity->getDirectMembers().begin());
+ i != entity->getDirectMembers().end(); ++i)
+ {
+ if (!baseException || i != entity->getDirectMembers().begin()) {
+ maxSize2 = std::max(
+ maxSize2,
+ addDirectArgument(
+ manager, dependencies, &desc2, code.get(), &index3,
+ className, codemaker::convertString(i->name), false,
+ i->type));
+ }
+ }
+ code->instrReturn();
+ code->setMaxStackAndLocals(maxSize2, index3);
+ cf->addMethod(
+ ClassFile::ACC_PUBLIC, "<init>", "(Ljava/lang/Throwable;" + desc2.getDescriptor().copy(1), code.get(),
+ std::vector< OString >(), desc2.getSignature());
+
addTypeInfo(className, typeInfo, dependencies, cf.get());
writeClassFile(options, className, *cf.get());
}