blocks-recovercpp.C [plain text]
#include <stdio.h>
#include <stdlib.h>
int constructors = 0;
int destructors = 0;
void * _NSConcreteStackBlock[32];
#define CONST const
class TestObject
{
public:
TestObject(CONST TestObject& inObj);
TestObject();
~TestObject();
TestObject& operator=(CONST TestObject& inObj);
int version() CONST { return _version; }
private:
mutable int _version;
};
TestObject::TestObject(CONST TestObject& inObj)
{
++constructors;
_version = inObj._version;
printf("%p (%d) -- TestObject(const TestObject&) called\n", this, _version);
}
TestObject::TestObject()
{
_version = ++constructors;
printf("%p (%d) -- TestObject() called\n", this, _version);
}
TestObject::~TestObject()
{
printf("%p -- ~TestObject() called\n", this);
++destructors;
}
TestObject& TestObject::operator=(CONST TestObject& inObj)
{
printf("%p -- operator= called\n", this);
_version = inObj._version;
return *this;
}
void hack(void *block) {
struct myblock {
void *isa;
int flags;
int reserved;
void (*Block_invoke)(void *);
struct Block_descriptor_1 {
unsigned long int reserved; unsigned long int Block_size;
void (*copyhelper)(void *dst, void *src);
void (*disposehelper)(void *src);
} *descriptor;
long space[32];
} myversion, *mbp = (struct myblock *)block;
printf("flags -> %x\n", mbp->flags);
if (! ((1<<25) & mbp->flags)) {
printf("no copy/dispose helper functions provided!\n");
exit(1);
}
if (! ((1<<26) & mbp->flags)) {
printf("no marking for ctor/dtors present!\n");
exit(1);
}
printf("copyhelper -> %p\n", mbp->descriptor->copyhelper);
mbp->descriptor->copyhelper(&myversion, mbp);
if (constructors != 3) {
printf("copy helper didn't do the constructor part\n");
exit(1);
}
printf("disposehelper -> %p\n", mbp->descriptor->disposehelper);
mbp->descriptor->disposehelper(&myversion);
if (destructors != 1) {
printf("dispose helper didn't do the dispose\n");
exit(1);
}
}
void testRoutine() {
TestObject one;
void (^b)(void) = ^{ printf("my copy of one is %d\n", one.version()); };
hack(b);
}
int main(char *argc, char *argv[]) {
testRoutine();
exit(0);
}