1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
|
#include "stdafx.h"
#include "OS/StackCall.h"
static int *data;
#ifdef GCC
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdangling-pointer"
#endif
int onStack(int val) {
int z = val;
// Note: We need to do an atomic write here, as this is technically undefined behavior.
atomicWrite(data, &z);
return z + 10;
}
#ifdef GCC
#pragma GCC diagnostic pop
#endif
void stackThrow(int on) {
if (on > 0) {
throw on;
}
}
BEGIN_TEST(StackCall, OS) {
onStack(100);
os::Stack s(1024*1024); // Note: ARM64 needs more than 1K of stack for proper exception handling.
int src = 42;
os::FnCall<int, 2> call = os::fnCall().add(src);
int result = os::stackCall(s, address(&onStack), call, false);
CHECK_EQ(result, 52);
CHECK_EQ(*data, 42);
s.clear();
// "data" should be on the allocated stack somewhere.
CHECK_GT(size_t(data), size_t(s.low()));
CHECK_LT(size_t(data), size_t(s.high()));
// Check exceptions.
src = -1;
os::FnCall<void, 2> second = os::fnCall().add(src);
os::stackCall(s, address(&stackThrow), second, false);
#ifndef WINDOWS
// Note: Does not work on Win32, and is currently not needed there. It is used for a workaround
// in the Gui library on Linux.
src = 1;
try {
os::stackCall(s, address(&stackThrow), second, false);
CHECK(false);
} catch (int i) {
CHECK_EQ(i, 1);
}
#endif
CHECK_EQ(os::UThread::current().threadData()->stack.detourTo, (void *)null);
} END_TEST
|