aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormax99x <max99x@gmail.com>2011-09-15 18:08:25 +0300
committermax99x <max99x@gmail.com>2011-09-15 18:08:25 +0300
commit76c15819b22aca811e70127d82e146afa33036f4 (patch)
tree2ddfabe609c907a3729e716407e8d1156bbff43c
parenta39cbaf4f3d6da7122a83697d29e4ff3fc71ddfb (diff)
Fixed unbound calling of destructor in exception handler; updated test.
-rw-r--r--src/library.js16
-rw-r--r--tests/exceptions/output.txt22
-rw-r--r--tests/exceptions/typed.cpp20
3 files changed, 28 insertions, 30 deletions
diff --git a/src/library.js b/src/library.js
index 156c1c25..a628e323 100644
--- a/src/library.js
+++ b/src/library.js
@@ -4044,18 +4044,20 @@ LibraryManager.library = {
}
// Clear state flag.
__THREW__ = false;
- // Free ptr if it isn't null.
- if ({{{ makeGetValue('_llvm_eh_exception.buf', '0', 'void*') }}}) {
- ___cxa_free_exception({{{ makeGetValue('_llvm_eh_exception.buf', '0', 'void*') }}});
- {{{ makeSetValue('_llvm_eh_exception.buf', '0', '0', 'void*') }}}
- }
// Clear type.
{{{ makeSetValue('_llvm_eh_exception.buf', '4', '0', 'void*') }}}
// Call destructor if one is registered then clear it.
- if ({{{ makeGetValue('_llvm_eh_exception.buf', '8', 'void*') }}}) {
- FUNCTION_TABLE[{{{ makeGetValue('_llvm_eh_exception.buf', '8', 'void*') }}}]();
+ var ptr = {{{ makeGetValue('_llvm_eh_exception.buf', '0', 'void*') }}};
+ var destructor = {{{ makeGetValue('_llvm_eh_exception.buf', '8', 'void*') }}};
+ if (destructor) {
+ FUNCTION_TABLE[destructor](ptr);
{{{ makeSetValue('_llvm_eh_exception.buf', '8', '0', 'i32') }}}
}
+ // Free ptr if it isn't null.
+ if (ptr) {
+ ___cxa_free_exception(ptr);
+ {{{ makeSetValue('_llvm_eh_exception.buf', '0', '0', 'void*') }}}
+ }
},
__cxa_get_exception_ptr__deps: ['llvm_eh_exception'],
__cxa_get_exception_ptr: function(ptr) {
diff --git a/tests/exceptions/output.txt b/tests/exceptions/output.txt
index 9f6961e3..2db8345e 100644
--- a/tests/exceptions/output.txt
+++ b/tests/exceptions/output.txt
@@ -1,8 +1,6 @@
*CREATING A FOO
*CREATING A BAR
*CREATING A QUUX
-*CREATING A QUUX
-*CREATING A CHILD
start
@@ -10,25 +8,25 @@ start
*COPYING A FOO
*COPYING A FOO
outer catch foo: 11
-*DESTROYING A FOO
-*DESTROYING A FOO
+*DESTROYING A FOO (11)
+*DESTROYING A FOO (11)
throwing ExBarInstance
*COPYING A BAR
*COPYING A BAR
inner re-throw: 22
-*DESTROYING A BAR
+*DESTROYING A BAR (22)
outer catch bar-ref: 22
-*DESTROYING A BAR
+*DESTROYING A BAR (22)
throwing ExQuuxInstance
*COPYING A QUUX
*COPYING A QUUX
inner catch quux: 33
-*DESTROYING A QUUX
-*DESTROYING A QUUX
+*DESTROYING A QUUX (33)
+*DESTROYING A QUUX (33)
@@ -47,8 +45,6 @@ outer catch-all
end
-*DESTROYING A CHILD
-*DESTROYING A QUUX
-*DESTROYING A QUUX
-*DESTROYING A BAR
-*DESTROYING A FOO
+*DESTROYING A QUUX (33)
+*DESTROYING A BAR (22)
+*DESTROYING A FOO (11)
diff --git a/tests/exceptions/typed.cpp b/tests/exceptions/typed.cpp
index dd509bdf..29bf548a 100644
--- a/tests/exceptions/typed.cpp
+++ b/tests/exceptions/typed.cpp
@@ -5,29 +5,29 @@ public:
int x;
ExFoo(int x) { this->x = x; printf("*CREATING A FOO\n"); }
ExFoo(const ExFoo& other) { x=other.x; printf("*COPYING A FOO\n"); }
- ~ExFoo() { printf("*DESTROYING A FOO\n"); }
+ ~ExFoo() { printf("*DESTROYING A FOO (%d)\n", x); }
} ExFooInstance(11);
class ExBar {
public:
int x;
ExBar(int x) { this->x = x; printf("*CREATING A BAR\n"); }
ExBar(const ExBar& other) { x=other.x; printf("*COPYING A BAR\n"); }
- ~ExBar() { printf("*DESTROYING A BAR\n"); }
+ ~ExBar() { printf("*DESTROYING A BAR (%d)\n", x); }
} ExBarInstance(22);
class ExQuux {
public:
int x;
ExQuux(int x) { this->x = x; printf("*CREATING A QUUX\n"); }
ExQuux(const ExQuux& other) { x=other.x; printf("*COPYING A QUUX\n"); }
- ~ExQuux() { printf("*DESTROYING A QUUX\n"); }
+ ~ExQuux() { printf("*DESTROYING A QUUX (%d)\n", x); }
} ExQuuxInstance(33);
-class ExChild : public ExQuux {
-public:
- int x;
- ExChild(int x) : ExQuux(x) { this->x = x; printf("*CREATING A CHILD\n"); }
- ExChild(const ExChild& other) : ExQuux(x) { x=other.x; printf("*COPYING CHILD\n"); }
- ~ExChild() { printf("*DESTROYING A CHILD\n"); }
-} ExChildInstance(44);
+// NOTE: Throwing pointers and polymorphic matching not supported.
+// class ExChild : public ExQuux {
+// public:
+// ExChild(int x) : ExQuux(x) { printf("*CREATING A CHILD\n"); }
+// ExChild(const ExChild& other) : ExQuux(x) { x=other.x; printf("*COPYING CHILD\n"); }
+// ~ExChild() { printf("*DESTROYING A CHILD (%d)\n", x); }
+// } ExChildInstance(44);
void magic(int which) {
try {