initial commit
This commit is contained in:
commit
3d7202a915
|
@ -0,0 +1,581 @@
|
|||
#ifndef AS_GEN_WRAPPER_H
|
||||
#define AS_GEN_WRAPPER_H
|
||||
|
||||
#ifndef ANGELSCRIPT_H
|
||||
// Avoid having to inform include path if header is already include before
|
||||
#include <angelscript.h>
|
||||
#endif
|
||||
|
||||
#include <new>
|
||||
|
||||
namespace gw {
|
||||
|
||||
template <typename T> class Proxy {
|
||||
public:
|
||||
T value;
|
||||
Proxy(T value) : value(value) {}
|
||||
static T cast(void * ptr) {
|
||||
return reinterpret_cast<Proxy<T> *>(&ptr)->value;
|
||||
}
|
||||
private:
|
||||
Proxy(const Proxy &);
|
||||
Proxy & operator=(const Proxy &);
|
||||
};
|
||||
|
||||
template <typename T> struct Wrapper {};
|
||||
template <typename T> struct ObjFirst {};
|
||||
template <typename T> struct ObjLast {};
|
||||
template <typename T> struct Constructor {};
|
||||
|
||||
template <typename T>
|
||||
void destroy(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
static_cast<T *>(gen->GetObject())->~T();
|
||||
}
|
||||
template <>
|
||||
struct Wrapper<void (*)(void)> {
|
||||
template <void (*fp)(void)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * /*gen*/) {
|
||||
((fp)());
|
||||
}
|
||||
};
|
||||
template <typename R>
|
||||
struct Wrapper<R (*)(void)> {
|
||||
template <R (*fp)(void)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)());
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct Wrapper<void (T::*)(void)> {
|
||||
template <void (T::*fp)(void)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((static_cast<T *>(gen->GetObject())->*fp)());
|
||||
}
|
||||
};
|
||||
template <typename T, typename R>
|
||||
struct Wrapper<R (T::*)(void)> {
|
||||
template <R (T::*fp)(void)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)());
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct Wrapper<void (T::*)(void) const> {
|
||||
template <void (T::*fp)(void) const>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((static_cast<T *>(gen->GetObject())->*fp)());
|
||||
}
|
||||
};
|
||||
template <typename T, typename R>
|
||||
struct Wrapper<R (T::*)(void) const> {
|
||||
template <R (T::*fp)(void) const>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)());
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct ObjFirst<void (*)(T)> {
|
||||
template <void (*fp)(T)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
Proxy<T>::cast(gen->GetObject())));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R>
|
||||
struct ObjFirst<R (*)(T)> {
|
||||
template <R (*fp)(T)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
Proxy<T>::cast(gen->GetObject())));
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct ObjLast<void (*)(T)> {
|
||||
template <void (*fp)(T)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
Proxy<T>::cast(gen->GetObject())));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R>
|
||||
struct ObjLast<R (*)(T)> {
|
||||
template <R (*fp)(T)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
Proxy<T>::cast(gen->GetObject())));
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct Constructor <T ()> {
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetObject()) T();
|
||||
}
|
||||
};
|
||||
template <typename A0>
|
||||
struct Wrapper<void (*)(A0)> {
|
||||
template <void (*fp)(A0)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
|
||||
}
|
||||
};
|
||||
template <typename R, typename A0>
|
||||
struct Wrapper<R (*)(A0)> {
|
||||
template <R (*fp)(A0)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0>
|
||||
struct Wrapper<void (T::*)(A0)> {
|
||||
template <void (T::*fp)(A0)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0>
|
||||
struct Wrapper<R (T::*)(A0)> {
|
||||
template <R (T::*fp)(A0)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0>
|
||||
struct Wrapper<void (T::*)(A0) const> {
|
||||
template <void (T::*fp)(A0) const>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0>
|
||||
struct Wrapper<R (T::*)(A0) const> {
|
||||
template <R (T::*fp)(A0) const>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0>
|
||||
struct ObjFirst<void (*)(T, A0)> {
|
||||
template <void (*fp)(T, A0)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
Proxy<T>::cast(gen->GetObject()),
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0>
|
||||
struct ObjFirst<R (*)(T, A0)> {
|
||||
template <R (*fp)(T, A0)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
Proxy<T>::cast(gen->GetObject()),
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0>
|
||||
struct ObjLast<void (*)(A0, T)> {
|
||||
template <void (*fp)(A0, T)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
Proxy<T>::cast(gen->GetObject())));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0>
|
||||
struct ObjLast<R (*)(A0, T)> {
|
||||
template <R (*fp)(A0, T)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
Proxy<T>::cast(gen->GetObject())));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0>
|
||||
struct Constructor <T (A0)> {
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetObject()) T(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value);
|
||||
}
|
||||
};
|
||||
template <typename A0, typename A1>
|
||||
struct Wrapper<void (*)(A0, A1)> {
|
||||
template <void (*fp)(A0, A1)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
|
||||
}
|
||||
};
|
||||
template <typename R, typename A0, typename A1>
|
||||
struct Wrapper<R (*)(A0, A1)> {
|
||||
template <R (*fp)(A0, A1)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1>
|
||||
struct Wrapper<void (T::*)(A0, A1)> {
|
||||
template <void (T::*fp)(A0, A1)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0, typename A1>
|
||||
struct Wrapper<R (T::*)(A0, A1)> {
|
||||
template <R (T::*fp)(A0, A1)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1>
|
||||
struct Wrapper<void (T::*)(A0, A1) const> {
|
||||
template <void (T::*fp)(A0, A1) const>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0, typename A1>
|
||||
struct Wrapper<R (T::*)(A0, A1) const> {
|
||||
template <R (T::*fp)(A0, A1) const>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1>
|
||||
struct ObjFirst<void (*)(T, A0, A1)> {
|
||||
template <void (*fp)(T, A0, A1)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
Proxy<T>::cast(gen->GetObject()),
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0, typename A1>
|
||||
struct ObjFirst<R (*)(T, A0, A1)> {
|
||||
template <R (*fp)(T, A0, A1)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
Proxy<T>::cast(gen->GetObject()),
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1>
|
||||
struct ObjLast<void (*)(A0, A1, T)> {
|
||||
template <void (*fp)(A0, A1, T)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
Proxy<T>::cast(gen->GetObject())));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0, typename A1>
|
||||
struct ObjLast<R (*)(A0, A1, T)> {
|
||||
template <R (*fp)(A0, A1, T)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
Proxy<T>::cast(gen->GetObject())));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1>
|
||||
struct Constructor <T (A0, A1)> {
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetObject()) T(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value);
|
||||
}
|
||||
};
|
||||
template <typename A0, typename A1, typename A2>
|
||||
struct Wrapper<void (*)(A0, A1, A2)> {
|
||||
template <void (*fp)(A0, A1, A2)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
|
||||
}
|
||||
};
|
||||
template <typename R, typename A0, typename A1, typename A2>
|
||||
struct Wrapper<R (*)(A0, A1, A2)> {
|
||||
template <R (*fp)(A0, A1, A2)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1, typename A2>
|
||||
struct Wrapper<void (T::*)(A0, A1, A2)> {
|
||||
template <void (T::*fp)(A0, A1, A2)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0, typename A1, typename A2>
|
||||
struct Wrapper<R (T::*)(A0, A1, A2)> {
|
||||
template <R (T::*fp)(A0, A1, A2)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1, typename A2>
|
||||
struct Wrapper<void (T::*)(A0, A1, A2) const> {
|
||||
template <void (T::*fp)(A0, A1, A2) const>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0, typename A1, typename A2>
|
||||
struct Wrapper<R (T::*)(A0, A1, A2) const> {
|
||||
template <R (T::*fp)(A0, A1, A2) const>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1, typename A2>
|
||||
struct ObjFirst<void (*)(T, A0, A1, A2)> {
|
||||
template <void (*fp)(T, A0, A1, A2)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
Proxy<T>::cast(gen->GetObject()),
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0, typename A1, typename A2>
|
||||
struct ObjFirst<R (*)(T, A0, A1, A2)> {
|
||||
template <R (*fp)(T, A0, A1, A2)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
Proxy<T>::cast(gen->GetObject()),
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1, typename A2>
|
||||
struct ObjLast<void (*)(A0, A1, A2, T)> {
|
||||
template <void (*fp)(A0, A1, A2, T)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
Proxy<T>::cast(gen->GetObject())));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0, typename A1, typename A2>
|
||||
struct ObjLast<R (*)(A0, A1, A2, T)> {
|
||||
template <R (*fp)(A0, A1, A2, T)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
Proxy<T>::cast(gen->GetObject())));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1, typename A2>
|
||||
struct Constructor <T (A0, A1, A2)> {
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetObject()) T(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value);
|
||||
}
|
||||
};
|
||||
template <typename A0, typename A1, typename A2, typename A3>
|
||||
struct Wrapper<void (*)(A0, A1, A2, A3)> {
|
||||
template <void (*fp)(A0, A1, A2, A3)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
|
||||
}
|
||||
};
|
||||
template <typename R, typename A0, typename A1, typename A2, typename A3>
|
||||
struct Wrapper<R (*)(A0, A1, A2, A3)> {
|
||||
template <R (*fp)(A0, A1, A2, A3)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1, typename A2, typename A3>
|
||||
struct Wrapper<void (T::*)(A0, A1, A2, A3)> {
|
||||
template <void (T::*fp)(A0, A1, A2, A3)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
|
||||
struct Wrapper<R (T::*)(A0, A1, A2, A3)> {
|
||||
template <R (T::*fp)(A0, A1, A2, A3)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1, typename A2, typename A3>
|
||||
struct Wrapper<void (T::*)(A0, A1, A2, A3) const> {
|
||||
template <void (T::*fp)(A0, A1, A2, A3) const>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
|
||||
struct Wrapper<R (T::*)(A0, A1, A2, A3) const> {
|
||||
template <R (T::*fp)(A0, A1, A2, A3) const>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1, typename A2, typename A3>
|
||||
struct ObjFirst<void (*)(T, A0, A1, A2, A3)> {
|
||||
template <void (*fp)(T, A0, A1, A2, A3)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
Proxy<T>::cast(gen->GetObject()),
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
|
||||
struct ObjFirst<R (*)(T, A0, A1, A2, A3)> {
|
||||
template <R (*fp)(T, A0, A1, A2, A3)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
Proxy<T>::cast(gen->GetObject()),
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1, typename A2, typename A3>
|
||||
struct ObjLast<void (*)(A0, A1, A2, A3, T)> {
|
||||
template <void (*fp)(A0, A1, A2, A3, T)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value,
|
||||
Proxy<T>::cast(gen->GetObject())));
|
||||
}
|
||||
};
|
||||
template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
|
||||
struct ObjLast<R (*)(A0, A1, A2, A3, T)> {
|
||||
template <R (*fp)(A0, A1, A2, A3, T)>
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value,
|
||||
Proxy<T>::cast(gen->GetObject())));
|
||||
}
|
||||
};
|
||||
template <typename T, typename A0, typename A1, typename A2, typename A3>
|
||||
struct Constructor <T (A0, A1, A2, A3)> {
|
||||
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
|
||||
new (gen->GetObject()) T(
|
||||
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
|
||||
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
|
||||
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
|
||||
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value);
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct Id {
|
||||
template <T fn_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr f(void) { return asFUNCTION(&Wrapper<T>::template f<fn_ptr>); }
|
||||
template <T fn_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr of(void) { return asFUNCTION(&ObjFirst<T>::template f<fn_ptr>); }
|
||||
template <T fn_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr ol(void) { return asFUNCTION(&ObjLast<T>::template f<fn_ptr>); }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
Id<T> id(T /*fn_ptr*/) { return Id<T>(); }
|
||||
|
||||
// On some versions of GNUC it is necessary to use the template keyword as disambiguator,
|
||||
// on others the template keyword gives an error, hence the need for the following define.
|
||||
// MSVC on the other hand seems to accept both with or without the template keyword.
|
||||
#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))
|
||||
// GNUC 4.4.3 doesn't need the template keyword, and
|
||||
// hopefully upcoming versions won't need it either
|
||||
#define TMPL template
|
||||
#else
|
||||
#define TMPL
|
||||
#endif
|
||||
|
||||
#define WRAP_FN(name) (::gw::id(name).TMPL f< name >())
|
||||
#define WRAP_MFN(ClassType, name) (::gw::id(&ClassType::name).TMPL f< &ClassType::name >())
|
||||
#define WRAP_OBJ_FIRST(name) (::gw::id(name).TMPL of< name >())
|
||||
#define WRAP_OBJ_LAST(name) (::gw::id(name).TMPL ol< name >())
|
||||
|
||||
#define WRAP_FN_PR(name, Parameters, ReturnType) asFUNCTION((::gw::Wrapper<ReturnType (*)Parameters>::TMPL f< name >))
|
||||
#define WRAP_MFN_PR(ClassType, name, Parameters, ReturnType) asFUNCTION((::gw::Wrapper<ReturnType (ClassType::*)Parameters>::TMPL f< &ClassType::name >))
|
||||
#define WRAP_OBJ_FIRST_PR(name, Parameters, ReturnType) asFUNCTION((::gw::ObjFirst<ReturnType (*)Parameters>::TMPL f< name >))
|
||||
#define WRAP_OBJ_LAST_PR(name, Parameters, ReturnType) asFUNCTION((::gw::ObjLast<ReturnType (*)Parameters>::TMPL f< name >))
|
||||
|
||||
#define WRAP_CON(ClassType, Parameters) asFUNCTION((::gw::Constructor<ClassType Parameters>::f))
|
||||
#define WRAP_DES(ClassType) asFUNCTION((::gw::destroy<ClassType>))
|
||||
|
||||
|
||||
} // end namespace gw
|
||||
|
||||
#endif
|
|
@ -0,0 +1,166 @@
|
|||
//
|
||||
// This generator creates a header file that implements automatic
|
||||
// wrapper functions for the generic calling convention.
|
||||
//
|
||||
// Originally implemented by George Yohng from 4Front Technologies in 2009-03-11
|
||||
// Modifications by Pierre Fortin in order to add constructor wrapper generation
|
||||
//
|
||||
// A completely new implementation of automatic wrapper functions was
|
||||
// implemented by SiCrane at GameDev.net in 2011-12-18. The generator was
|
||||
// adapted from Python to C++ by Andreas.
|
||||
//
|
||||
// ref: http://www.gamedev.net/topic/617111-more-angelscript-binding-wrappers/
|
||||
//
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
// Generate templates for up to this number of function parameters
|
||||
const int max_args = 4;
|
||||
|
||||
using namespace std;
|
||||
|
||||
void PrintTemplate(const char *base, const char *typeNameList, const char *retType, const char *objType, const char *isConst, const char *newExpr, const char *objExpr, const char *argList1, const char *argList2, const char *wrapName);
|
||||
void PrintConstructor(const char *comma, const char *typeNameList, const char *typeList, const char *argList);
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("#ifndef AS_GEN_WRAPPER_H\n"
|
||||
"#define AS_GEN_WRAPPER_H\n"
|
||||
"\n"
|
||||
"#ifndef ANGELSCRIPT_H\n"
|
||||
"// Avoid having to inform include path if header is already include before\n"
|
||||
"#include <angelscript.h>\n"
|
||||
"#endif\n"
|
||||
"#include <new>\n"
|
||||
"\n"
|
||||
"namespace gw {\n"
|
||||
"\n"
|
||||
"template <typename T> class Proxy {\n"
|
||||
" public:\n"
|
||||
" T value;\n"
|
||||
" Proxy(T value) : value(value) {}\n"
|
||||
" static T cast(void * ptr) {\n"
|
||||
" return reinterpret_cast<Proxy<T> *>(&ptr)->value;\n"
|
||||
" }\n"
|
||||
" private:\n"
|
||||
" Proxy(const Proxy &);\n"
|
||||
" Proxy & operator=(const Proxy &);\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"template <typename T> struct Wrapper {};\n"
|
||||
"template <typename T> struct ObjFirst {};\n"
|
||||
"template <typename T> struct ObjLast {};\n"
|
||||
"template <typename T> struct Constructor {};\n"
|
||||
"\n"
|
||||
"template <typename T>\n"
|
||||
"void destroy(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {\n"
|
||||
" static_cast<T *>(gen->GetObject())->~T();\n"
|
||||
"}\n");
|
||||
|
||||
string typename_list = "typename A0";
|
||||
string type_list = "A0";
|
||||
string arg_list = "\n static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value";
|
||||
string new_exp = "new (gen->GetAddressOfReturnLocation()) Proxy<R>";
|
||||
string obj_exp = "static_cast<T *>(gen->GetObject())->*";
|
||||
string obj_arg_exp = "\n Proxy<T>::cast(gen->GetObject())";
|
||||
|
||||
PrintTemplate("", "", "void", "", "", "", "", "void", "", "Wrapper");
|
||||
PrintTemplate("typename R", "", "R", "", "", new_exp.c_str(), "", "void", "", "Wrapper");
|
||||
PrintTemplate("typename T", "", "void", "T::", "", "", obj_exp.c_str(), "void", "", "Wrapper");
|
||||
PrintTemplate("typename T, typename R", "", "R", "T::", "", new_exp.c_str(), obj_exp.c_str(), "void", "", "Wrapper");
|
||||
PrintTemplate("typename T", "", "void", "T::", " const", "", obj_exp.c_str(), "void", "", "Wrapper");
|
||||
PrintTemplate("typename T, typename R", "", "R", "T::", " const", new_exp.c_str(), obj_exp.c_str(), "void", "", "Wrapper");
|
||||
|
||||
PrintTemplate("typename T", "", "void", "", "", "", "", "T", obj_arg_exp.c_str(), "ObjFirst");
|
||||
PrintTemplate("typename T, typename R", "", "R", "", "", new_exp.c_str(), "", "T", obj_arg_exp.c_str(), "ObjFirst");
|
||||
PrintTemplate("typename T", "", "void", "", "", "", "", "T", obj_arg_exp.c_str(), "ObjLast");
|
||||
PrintTemplate("typename T, typename R", "", "R", "", "", new_exp.c_str(), "", "T", obj_arg_exp.c_str(), "ObjLast");
|
||||
|
||||
PrintConstructor("", "", "", "");
|
||||
|
||||
for( int i = 0; i < max_args; i++ )
|
||||
{
|
||||
PrintTemplate("", typename_list.c_str(), "void", "", "", "", "", type_list.c_str(), arg_list.c_str(), "Wrapper");
|
||||
PrintTemplate("typename R, ", typename_list.c_str(), "R", "", "", new_exp.c_str(), "", type_list.c_str(), arg_list.c_str(), "Wrapper");
|
||||
PrintTemplate("typename T, ", typename_list.c_str(), "void", "T::", "", "", obj_exp.c_str(), type_list.c_str(), arg_list.c_str(), "Wrapper");
|
||||
PrintTemplate("typename T, typename R, ", typename_list.c_str(), "R", "T::", "", new_exp.c_str(), obj_exp.c_str(), type_list.c_str(), arg_list.c_str(), "Wrapper");
|
||||
PrintTemplate("typename T, ", typename_list.c_str(), "void", "T::", " const", "", obj_exp.c_str(), type_list.c_str(), arg_list.c_str(), "Wrapper");
|
||||
PrintTemplate("typename T, typename R, ", typename_list.c_str(), "R", "T::", " const", new_exp.c_str(), obj_exp.c_str(), type_list.c_str(), arg_list.c_str(), "Wrapper");
|
||||
|
||||
PrintTemplate("typename T, ", typename_list.c_str(), "void", "", "", "", "", ("T, " + type_list).c_str(), (obj_arg_exp + "," + arg_list).c_str(), "ObjFirst");
|
||||
PrintTemplate("typename T, typename R, ", typename_list.c_str(), "R", "", "", new_exp.c_str(), "", ("T, " + type_list).c_str(), (obj_arg_exp + "," + arg_list).c_str(), "ObjFirst");
|
||||
PrintTemplate("typename T, ", typename_list.c_str(), "void", "", "", "", "", (type_list + ", T").c_str(), (arg_list + "," + obj_arg_exp).c_str(), "ObjLast");
|
||||
PrintTemplate("typename T, typename R, ", typename_list.c_str(), "R", "", "", new_exp.c_str(), "", (type_list + ", T").c_str(), (arg_list + "," + obj_arg_exp).c_str(), "ObjLast");
|
||||
|
||||
PrintConstructor(", ", typename_list.c_str(), type_list.c_str(), arg_list.c_str());
|
||||
|
||||
char buf[5];
|
||||
sprintf(buf, "%d", i + 1);
|
||||
typename_list += ", typename A" + string(buf);
|
||||
type_list += ", A" + string(buf);
|
||||
arg_list += ",\n static_cast<Proxy <A" + string(buf) + "> *>(gen->GetAddressOfArg(" + string(buf) + "))->value";
|
||||
}
|
||||
|
||||
printf("template <typename T>\n"
|
||||
"struct Id {\n"
|
||||
" template <T fn_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr f(void) { return asFUNCTION(&Wrapper<T>::template f<fn_ptr>); }\n"
|
||||
" template <T fn_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr of(void) { return asFUNCTION(&ObjFirst<T>::template f<fn_ptr>); }\n"
|
||||
" template <T fn_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr ol(void) { return asFUNCTION(&ObjLast<T>::template f<fn_ptr>); }\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"template <typename T>\n"
|
||||
"Id<T> id(T fn_ptr) { return Id<T>(); }\n"
|
||||
"\n"
|
||||
"// On some versions of GNUC it is necessary to use the template keyword as disambiguator,\n"
|
||||
"// on others the template keyword gives an error, hence the need for the following define.\n"
|
||||
"// MSVC on the other hand seems to accept both with or without the template keyword.\n"
|
||||
"#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))\n"
|
||||
" // GNUC 4.4.3 doesn't need the template keyword, and\n"
|
||||
" // hopefully upcoming versions won't need it either\n"
|
||||
" #define TMPL template\n"
|
||||
"#else\n"
|
||||
" #define TMPL\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"#define WRAP_FN(name) (::gw::id(name).TMPL f< name >())\n"
|
||||
"#define WRAP_MFN(ClassType, name) (::gw::id(&ClassType::name).TMPL f< &ClassType::name >())\n"
|
||||
"#define WRAP_OBJ_FIRST(name) (::gw::id(name).TMPL of< name >())\n"
|
||||
"#define WRAP_OBJ_LAST(name) (::gw::id(name).TMPL ol< name >())\n"
|
||||
"\n"
|
||||
"#define WRAP_FN_PR(name, Parameters, ReturnType) asFUNCTION((::gw::Wrapper<ReturnType (*)Parameters>::TMPL f< name >))\n"
|
||||
"#define WRAP_MFN_PR(ClassType, name, Parameters, ReturnType) asFUNCTION((::gw::Wrapper<ReturnType (ClassType::*)Parameters>::TMPL f< &ClassType::name >))\n"
|
||||
"#define WRAP_OBJ_FIRST_PR(name, Parameters, ReturnType) asFUNCTION((::gw::ObjFirst<ReturnType (*)Parameters>::TMPL f< name >))\n"
|
||||
"#define WRAP_OBJ_LAST_PR(name, Parameters, ReturnType) asFUNCTION((::gw::ObjLast<ReturnType (*)Parameters>::TMPL f< name >))\n"
|
||||
"\n"
|
||||
"#define WRAP_CON(ClassType, Parameters) asFUNCTION((::gw::Constructor<ClassType Parameters>::f))\n"
|
||||
"#define WRAP_DES(ClassType) asFUNCTION((::gw::destroy<ClassType>))\n"
|
||||
"\n"
|
||||
"} // end namespace gw\n"
|
||||
"\n"
|
||||
"#endif\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PrintTemplate(const char *base, const char *typeNameList, const char *retType, const char *objType, const char *isConst, const char *newExpr, const char *objExpr, const char *argList1, const char *argList2, const char *wrapName)
|
||||
{
|
||||
printf("template <%s%s>\n", base, typeNameList);
|
||||
printf("struct %s<%s (%s*)(%s)%s> {\n", wrapName, retType, objType, argList1, isConst);
|
||||
printf(" template <%s (%s*fp)(%s)%s>\n", retType, objType, argList1, isConst);
|
||||
printf(" static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {\n");
|
||||
printf(" %s((%sfp)(%s));\n", newExpr, objExpr, argList2);
|
||||
printf(" }\n");
|
||||
printf("};\n");
|
||||
}
|
||||
|
||||
void PrintConstructor(const char *comma, const char *typeNameList, const char *typeList, const char *argList)
|
||||
{
|
||||
printf("template <typename T%s%s>\n", comma, typeNameList);
|
||||
printf("struct Constructor <T (%s)> {\n", typeList);
|
||||
printf(" static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {\n");
|
||||
printf(" new (gen->GetObject()) T(%s);\n", argList);
|
||||
printf(" }\n");
|
||||
printf("};\n");
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "generator", "generator.vcproj", "{086A2F1A-01B1-4EB3-A8FA-0926FF10E953}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{086A2F1A-01B1-4EB3-A8FA-0926FF10E953}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{086A2F1A-01B1-4EB3-A8FA-0926FF10E953}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{086A2F1A-01B1-4EB3-A8FA-0926FF10E953}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{086A2F1A-01B1-4EB3-A8FA-0926FF10E953}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,236 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Name="generator"
|
||||
ProjectGUID="{086A2F1A-01B1-4EB3-A8FA-0926FF10E953}"
|
||||
TargetFrameworkVersion="0"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\Debug"
|
||||
IntermediateDirectory=".\Debug"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TypeLibraryName=".\Debug/generator.tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
PrecompiledHeaderFile=".\Debug/generator.pch"
|
||||
AssemblerListingLocation=".\Debug/"
|
||||
ObjectFile=".\Debug/"
|
||||
ProgramDataBaseFileName=".\Debug/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile=".\Debug/generator.exe"
|
||||
LinkIncremental="2"
|
||||
SuppressStartupBanner="true"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile=".\Debug/generator.pdb"
|
||||
SubSystem="1"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/generator.bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\Release"
|
||||
IntermediateDirectory=".\Release"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TypeLibraryName=".\Release/generator.tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\Release/generator.pch"
|
||||
AssemblerListingLocation=".\Release/"
|
||||
ObjectFile=".\Release/"
|
||||
ProgramDataBaseFileName=".\Release/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile=".\Release/generator.exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
ProgramDatabaseFile=".\Release/generator.pdb"
|
||||
SubSystem="1"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Release/generator.bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
>
|
||||
<File
|
||||
RelativePath="generateheader.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
|
@ -0,0 +1,401 @@
|
|||
#include <assert.h>
|
||||
#include <string>
|
||||
|
||||
#include "contextmgr.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
// TODO: Should have a pool of free asIScriptContext so that new contexts
|
||||
// won't be allocated every time. The application must not keep
|
||||
// its own references, instead it must tell the context manager
|
||||
// that it is using the context. Otherwise the context manager may
|
||||
// think it can reuse the context too early.
|
||||
|
||||
// TODO: Need to have a callback for when scripts finishes, so that the
|
||||
// application can receive return values.
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
// The id for the context manager user data.
|
||||
// The add-ons have reserved the numbers 1000
|
||||
// through 1999 for this purpose, so we should be fine.
|
||||
const asPWORD CONTEXT_MGR = 1002;
|
||||
|
||||
struct SContextInfo
|
||||
{
|
||||
asUINT sleepUntil;
|
||||
vector<asIScriptContext*> coRoutines;
|
||||
asUINT currentCoRoutine;
|
||||
asIScriptContext * keepCtxAfterExecution;
|
||||
};
|
||||
|
||||
static void ScriptSleep(asUINT milliSeconds)
|
||||
{
|
||||
// Get a pointer to the context that is currently being executed
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
if( ctx )
|
||||
{
|
||||
// Get the context manager from the user data
|
||||
CContextMgr *ctxMgr = reinterpret_cast<CContextMgr*>(ctx->GetUserData(CONTEXT_MGR));
|
||||
if( ctxMgr )
|
||||
{
|
||||
// Suspend its execution. The VM will continue until the current
|
||||
// statement is finished and then return from the Execute() method
|
||||
ctx->Suspend();
|
||||
|
||||
// Tell the context manager when the context is to continue execution
|
||||
ctxMgr->SetSleeping(ctx, milliSeconds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ScriptYield()
|
||||
{
|
||||
// Get a pointer to the context that is currently being executed
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
if( ctx )
|
||||
{
|
||||
// Get the context manager from the user data
|
||||
CContextMgr *ctxMgr = reinterpret_cast<CContextMgr*>(ctx->GetUserData(CONTEXT_MGR));
|
||||
if( ctxMgr )
|
||||
{
|
||||
// Let the context manager know that it should run the next co-routine
|
||||
ctxMgr->NextCoRoutine();
|
||||
|
||||
// The current context must be suspended so that VM will return from
|
||||
// the Execute() method where the context manager will continue.
|
||||
ctx->Suspend();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptCreateCoRoutine(asIScriptFunction *func, CScriptDictionary *arg)
|
||||
{
|
||||
if( func == 0 )
|
||||
return;
|
||||
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
if( ctx )
|
||||
{
|
||||
// Get the context manager from the user data
|
||||
CContextMgr *ctxMgr = reinterpret_cast<CContextMgr*>(ctx->GetUserData(CONTEXT_MGR));
|
||||
if( ctxMgr )
|
||||
{
|
||||
// Create a new context for the co-routine
|
||||
asIScriptContext *coctx = ctxMgr->AddContextForCoRoutine(ctx, func);
|
||||
|
||||
// Pass the argument to the context
|
||||
coctx->SetArgObject(0, arg);
|
||||
|
||||
// The context manager will call Execute() on the context when it is time
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef AS_MAX_PORTABILITY
|
||||
void ScriptYield_generic(asIScriptGeneric *)
|
||||
{
|
||||
ScriptYield();
|
||||
}
|
||||
|
||||
void ScriptCreateCoRoutine_generic(asIScriptGeneric *gen)
|
||||
{
|
||||
asIScriptFunction *func = reinterpret_cast<asIScriptFunction*>(gen->GetArgAddress(0));
|
||||
CScriptDictionary *dict = reinterpret_cast<CScriptDictionary*>(gen->GetArgAddress(1));
|
||||
ScriptCreateCoRoutine(func, dict);
|
||||
}
|
||||
#endif
|
||||
|
||||
CContextMgr::CContextMgr()
|
||||
{
|
||||
m_getTimeFunc = 0;
|
||||
m_currentThread = 0;
|
||||
|
||||
m_numExecutions = 0;
|
||||
m_numGCObjectsCreated = 0;
|
||||
m_numGCObjectsDestroyed = 0;
|
||||
}
|
||||
|
||||
CContextMgr::~CContextMgr()
|
||||
{
|
||||
asUINT n;
|
||||
|
||||
// Free the memory
|
||||
for( n = 0; n < m_threads.size(); n++ )
|
||||
{
|
||||
if( m_threads[n] )
|
||||
{
|
||||
for( asUINT c = 0; c < m_threads[n]->coRoutines.size(); c++ )
|
||||
{
|
||||
asIScriptContext *ctx = m_threads[n]->coRoutines[c];
|
||||
if( ctx )
|
||||
{
|
||||
// Return the context to the engine (and possible context pool configured in it)
|
||||
ctx->GetEngine()->ReturnContext(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
delete m_threads[n];
|
||||
}
|
||||
}
|
||||
|
||||
for( n = 0; n < m_freeThreads.size(); n++ )
|
||||
{
|
||||
if( m_freeThreads[n] )
|
||||
{
|
||||
assert( m_freeThreads[n]->coRoutines.size() == 0 );
|
||||
|
||||
delete m_freeThreads[n];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int CContextMgr::ExecuteScripts()
|
||||
{
|
||||
// TODO: Should have an optional time out for this function. If not all scripts executed before the
|
||||
// time out, the next time the function is called the loop should continue
|
||||
// where it left off.
|
||||
|
||||
// TODO: There should be a time out per thread as well. If a thread executes for too
|
||||
// long, it should be aborted. A group of co-routines count as a single thread.
|
||||
|
||||
// Check if the system time is higher than the time set for the contexts
|
||||
asUINT time = m_getTimeFunc ? m_getTimeFunc() : asUINT(-1);
|
||||
for( m_currentThread = 0; m_currentThread < m_threads.size(); m_currentThread++ )
|
||||
{
|
||||
SContextInfo *thread = m_threads[m_currentThread];
|
||||
if( thread->sleepUntil < time )
|
||||
{
|
||||
int currentCoRoutine = thread->currentCoRoutine;
|
||||
|
||||
// Gather some statistics from the GC
|
||||
asIScriptEngine *engine = thread->coRoutines[currentCoRoutine]->GetEngine();
|
||||
asUINT gcSize1, gcSize2, gcSize3;
|
||||
engine->GetGCStatistics(&gcSize1);
|
||||
|
||||
// Execute the script for this thread and co-routine
|
||||
int r = thread->coRoutines[currentCoRoutine]->Execute();
|
||||
|
||||
// Determine how many new objects were created in the GC
|
||||
engine->GetGCStatistics(&gcSize2);
|
||||
m_numGCObjectsCreated += gcSize2 - gcSize1;
|
||||
m_numExecutions++;
|
||||
|
||||
if( r != asEXECUTION_SUSPENDED )
|
||||
{
|
||||
// The context has terminated execution (for one reason or other)
|
||||
// Unless the application has requested to keep the context we'll return it to the pool now
|
||||
if( thread->keepCtxAfterExecution != thread->coRoutines[currentCoRoutine] )
|
||||
engine->ReturnContext(thread->coRoutines[currentCoRoutine]);
|
||||
thread->coRoutines[currentCoRoutine] = 0;
|
||||
|
||||
thread->coRoutines.erase(thread->coRoutines.begin() + thread->currentCoRoutine);
|
||||
if( thread->currentCoRoutine >= thread->coRoutines.size() )
|
||||
thread->currentCoRoutine = 0;
|
||||
|
||||
// If this was the last co-routine terminate the thread
|
||||
if( thread->coRoutines.size() == 0 )
|
||||
{
|
||||
m_freeThreads.push_back(thread);
|
||||
m_threads.erase(m_threads.begin() + m_currentThread);
|
||||
m_currentThread--;
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy all known garbage if any new objects were created
|
||||
if( gcSize2 > gcSize1 )
|
||||
{
|
||||
engine->GarbageCollect(asGC_FULL_CYCLE | asGC_DESTROY_GARBAGE);
|
||||
|
||||
// Determine how many objects were destroyed
|
||||
engine->GetGCStatistics(&gcSize3);
|
||||
m_numGCObjectsDestroyed += gcSize3 - gcSize2;
|
||||
}
|
||||
|
||||
// TODO: If more objects are created per execution than destroyed on average
|
||||
// then it may be necessary to run more iterations of the detection of
|
||||
// cyclic references. At the startup of an application there is usually
|
||||
// a lot of objects created that will live on through out the application
|
||||
// so the average number of objects created per execution will be higher
|
||||
// than the number of destroyed objects in the beginning, but afterwards
|
||||
// it usually levels out to be more or less equal.
|
||||
|
||||
// Just run an incremental step for detecting cyclic references
|
||||
engine->GarbageCollect(asGC_ONE_STEP | asGC_DETECT_GARBAGE);
|
||||
}
|
||||
}
|
||||
|
||||
return int(m_threads.size());
|
||||
}
|
||||
|
||||
void CContextMgr::DoneWithContext(asIScriptContext *ctx)
|
||||
{
|
||||
ctx->GetEngine()->ReturnContext(ctx);
|
||||
}
|
||||
|
||||
void CContextMgr::NextCoRoutine()
|
||||
{
|
||||
m_threads[m_currentThread]->currentCoRoutine++;
|
||||
if( m_threads[m_currentThread]->currentCoRoutine >= m_threads[m_currentThread]->coRoutines.size() )
|
||||
m_threads[m_currentThread]->currentCoRoutine = 0;
|
||||
}
|
||||
|
||||
void CContextMgr::AbortAll()
|
||||
{
|
||||
// Abort all contexts and release them. The script engine will make
|
||||
// sure that all resources held by the scripts are properly released.
|
||||
|
||||
for( asUINT n = 0; n < m_threads.size(); n++ )
|
||||
{
|
||||
for( asUINT c = 0; c < m_threads[n]->coRoutines.size(); c++ )
|
||||
{
|
||||
asIScriptContext *ctx = m_threads[n]->coRoutines[c];
|
||||
if( ctx )
|
||||
{
|
||||
ctx->Abort();
|
||||
ctx->GetEngine()->ReturnContext(ctx);
|
||||
ctx = 0;
|
||||
}
|
||||
}
|
||||
m_threads[n]->coRoutines.resize(0);
|
||||
|
||||
m_freeThreads.push_back(m_threads[n]);
|
||||
}
|
||||
|
||||
m_threads.resize(0);
|
||||
|
||||
m_currentThread = 0;
|
||||
}
|
||||
|
||||
asIScriptContext *CContextMgr::AddContext(asIScriptEngine *engine, asIScriptFunction *func, bool keepCtxAfterExec)
|
||||
{
|
||||
// Use RequestContext instead of CreateContext so we can take
|
||||
// advantage of possible context pooling configured with the engine
|
||||
asIScriptContext *ctx = engine->RequestContext();
|
||||
if( ctx == 0 )
|
||||
return 0;
|
||||
|
||||
// Prepare it to execute the function
|
||||
int r = ctx->Prepare(func);
|
||||
if( r < 0 )
|
||||
{
|
||||
engine->ReturnContext(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set the context manager as user data with the context so it
|
||||
// can be retrieved by the functions registered with the engine
|
||||
ctx->SetUserData(this, CONTEXT_MGR);
|
||||
|
||||
// Add the context to the list for execution
|
||||
SContextInfo *info = 0;
|
||||
if( m_freeThreads.size() > 0 )
|
||||
{
|
||||
info = *m_freeThreads.rbegin();
|
||||
m_freeThreads.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
info = new SContextInfo;
|
||||
}
|
||||
|
||||
info->coRoutines.push_back(ctx);
|
||||
info->currentCoRoutine = 0;
|
||||
info->sleepUntil = 0;
|
||||
info->keepCtxAfterExecution = keepCtxAfterExec ? ctx : 0;
|
||||
m_threads.push_back(info);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
asIScriptContext *CContextMgr::AddContextForCoRoutine(asIScriptContext *currCtx, asIScriptFunction *func)
|
||||
{
|
||||
asIScriptEngine *engine = currCtx->GetEngine();
|
||||
asIScriptContext *coctx = engine->RequestContext();
|
||||
if( coctx == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Prepare the context
|
||||
int r = coctx->Prepare(func);
|
||||
if( r < 0 )
|
||||
{
|
||||
// Couldn't prepare the context
|
||||
engine->ReturnContext(coctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set the context manager as user data with the context so it
|
||||
// can be retrieved by the functions registered with the engine
|
||||
coctx->SetUserData(this, CONTEXT_MGR);
|
||||
|
||||
// Find the current context thread info
|
||||
// TODO: Start with the current thread so that we can find the group faster
|
||||
for( asUINT n = 0; n < m_threads.size(); n++ )
|
||||
{
|
||||
if( m_threads[n]->coRoutines[m_threads[n]->currentCoRoutine] == currCtx )
|
||||
{
|
||||
// Add the coRoutine to the list
|
||||
m_threads[n]->coRoutines.push_back(coctx);
|
||||
}
|
||||
}
|
||||
|
||||
return coctx;
|
||||
}
|
||||
|
||||
void CContextMgr::SetSleeping(asIScriptContext *ctx, asUINT milliSeconds)
|
||||
{
|
||||
assert( m_getTimeFunc != 0 );
|
||||
|
||||
// Find the context and update the timeStamp
|
||||
// for when the context is to be continued
|
||||
|
||||
// TODO: Start with the current thread
|
||||
|
||||
for( asUINT n = 0; n < m_threads.size(); n++ )
|
||||
{
|
||||
if( m_threads[n]->coRoutines[m_threads[n]->currentCoRoutine] == ctx )
|
||||
{
|
||||
m_threads[n]->sleepUntil = (m_getTimeFunc ? m_getTimeFunc() : 0) + milliSeconds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CContextMgr::RegisterThreadSupport(asIScriptEngine *engine)
|
||||
{
|
||||
int r;
|
||||
|
||||
// Must set the get time callback function for this to work
|
||||
assert( m_getTimeFunc != 0 );
|
||||
|
||||
// Register the sleep function
|
||||
r = engine->RegisterGlobalFunction("void sleep(uint)", asFUNCTION(ScriptSleep), asCALL_CDECL); assert( r >= 0 );
|
||||
|
||||
// TODO: Add support for spawning new threads, waiting for signals, etc
|
||||
}
|
||||
|
||||
void CContextMgr::RegisterCoRoutineSupport(asIScriptEngine *engine)
|
||||
{
|
||||
int r;
|
||||
|
||||
// The dictionary add-on must have been registered already
|
||||
assert( engine->GetTypeInfoByDecl("dictionary") );
|
||||
|
||||
#ifndef AS_MAX_PORTABILITY
|
||||
r = engine->RegisterGlobalFunction("void yield()", asFUNCTION(ScriptYield), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterFuncdef("void coroutine(dictionary@)");
|
||||
r = engine->RegisterGlobalFunction("void createCoRoutine(coroutine @+, dictionary @+)", asFUNCTION(ScriptCreateCoRoutine), asCALL_CDECL); assert( r >= 0 );
|
||||
#else
|
||||
r = engine->RegisterGlobalFunction("void yield()", asFUNCTION(ScriptYield_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterFuncdef("void coroutine(dictionary@)");
|
||||
r = engine->RegisterGlobalFunction("void createCoRoutine(coroutine @+, dictionary @+)", asFUNCTION(ScriptCreateCoRoutine_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
void CContextMgr::SetGetTimeCallback(TIMEFUNC_t func)
|
||||
{
|
||||
m_getTimeFunc = func;
|
||||
}
|
||||
|
||||
END_AS_NAMESPACE
|
|
@ -0,0 +1,99 @@
|
|||
#ifndef CONTEXTMGR_H
|
||||
#define CONTEXTMGR_H
|
||||
|
||||
// The context manager simplifies the management of multiple concurrent scripts
|
||||
|
||||
// More than one context manager can be used, if you wish to control different
|
||||
// groups of scripts separately, e.g. game object scripts, and GUI scripts.
|
||||
|
||||
// OBSERVATION: This class is currently not thread safe.
|
||||
|
||||
#ifndef ANGELSCRIPT_H
|
||||
// Avoid having to inform include path if header is already include before
|
||||
#include <angelscript.h>
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
class CScriptDictionary;
|
||||
|
||||
// The internal structure for holding contexts
|
||||
struct SContextInfo;
|
||||
|
||||
// The signature of the get time callback function
|
||||
typedef asUINT (*TIMEFUNC_t)();
|
||||
|
||||
class CContextMgr
|
||||
{
|
||||
public:
|
||||
CContextMgr();
|
||||
~CContextMgr();
|
||||
|
||||
// Set the function that the manager will use to obtain the time in milliseconds
|
||||
void SetGetTimeCallback(TIMEFUNC_t func);
|
||||
|
||||
// Registers the following:
|
||||
//
|
||||
// void sleep(uint milliseconds)
|
||||
//
|
||||
// The application must set the get time callback for this to work
|
||||
void RegisterThreadSupport(asIScriptEngine *engine);
|
||||
|
||||
// Registers the following:
|
||||
//
|
||||
// funcdef void coroutine(dictionary@)
|
||||
// void createCoRoutine(coroutine @func, dictionary @args)
|
||||
// void yield()
|
||||
void RegisterCoRoutineSupport(asIScriptEngine *engine);
|
||||
|
||||
// Create a new context, prepare it with the function id, then return
|
||||
// it so that the application can pass the argument values. The context
|
||||
// will be released by the manager after the execution has completed.
|
||||
// Set keepCtxAfterExecution to true if the application needs to retrieve
|
||||
// information from the context after it the script has finished.
|
||||
asIScriptContext *AddContext(asIScriptEngine *engine, asIScriptFunction *func, bool keepCtxAfterExecution = false);
|
||||
|
||||
// If the context was kept after the execution, this method must be
|
||||
// called when the application is done with the context so it can be
|
||||
// returned to the pool for reuse.
|
||||
void DoneWithContext(asIScriptContext *ctx);
|
||||
|
||||
// Create a new context, prepare it with the function id, then return
|
||||
// it so that the application can pass the argument values. The context
|
||||
// will be added as a co-routine in the same thread as the currCtx.
|
||||
asIScriptContext *AddContextForCoRoutine(asIScriptContext *currCtx, asIScriptFunction *func);
|
||||
|
||||
// Execute each script that is not currently sleeping. The function returns after
|
||||
// each script has been executed once. The application should call this function
|
||||
// for each iteration of the message pump, or game loop, or whatever.
|
||||
// Returns the number of scripts still in execution.
|
||||
int ExecuteScripts();
|
||||
|
||||
// Put a script to sleep for a while
|
||||
void SetSleeping(asIScriptContext *ctx, asUINT milliSeconds);
|
||||
|
||||
// Switch the execution to the next co-routine in the group.
|
||||
// Returns true if the switch was successful.
|
||||
void NextCoRoutine();
|
||||
|
||||
// Abort all scripts
|
||||
void AbortAll();
|
||||
|
||||
protected:
|
||||
std::vector<SContextInfo*> m_threads;
|
||||
std::vector<SContextInfo*> m_freeThreads;
|
||||
asUINT m_currentThread;
|
||||
TIMEFUNC_t m_getTimeFunc;
|
||||
|
||||
// Statistics for Garbage Collection
|
||||
asUINT m_numExecutions;
|
||||
asUINT m_numGCObjectsCreated;
|
||||
asUINT m_numGCObjectsDestroyed;
|
||||
};
|
||||
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,270 @@
|
|||
#include "datetime.h"
|
||||
#include "../autowrapper/aswrappedcall.h"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <new>
|
||||
|
||||
using namespace std;
|
||||
using namespace std::chrono;
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
// TODO: Allow setting the timezone to use
|
||||
|
||||
static tm time_point_to_tm(const std::chrono::time_point<std::chrono::system_clock> &tp)
|
||||
{
|
||||
time_t t = system_clock::to_time_t(tp);
|
||||
tm local;
|
||||
|
||||
// Use the universal timezone
|
||||
#ifdef _MSC_VER
|
||||
gmtime_s(&local, &t);
|
||||
#else
|
||||
local = *gmtime(&t);
|
||||
#endif
|
||||
return local;
|
||||
}
|
||||
|
||||
// Returns true if successful. Doesn't modify tp if not successful
|
||||
static bool tm_to_time_point(const tm &_tm, std::chrono::time_point<std::chrono::system_clock> &tp)
|
||||
{
|
||||
tm localTm = _tm;
|
||||
|
||||
// Do not rely on timezone, as it is not portable
|
||||
// ref: https://stackoverflow.com/questions/38298261/why-there-is-no-inverse-function-for-gmtime-in-libc
|
||||
// ref: https://stackoverflow.com/questions/8558919/mktime-and-tm-isdst
|
||||
localTm.tm_isdst = -1; // Always use current settings, so mktime doesn't modify the time for daylight savings
|
||||
time_t t = mktime(&localTm);
|
||||
if (t == -1)
|
||||
return false;
|
||||
|
||||
// Adjust the time_t since epoch with the difference of the local timezone to the universal timezone
|
||||
t += (mktime(localtime(&t)) - mktime(gmtime(&t)));
|
||||
|
||||
// Verify if the members were modified, indicating an out-of-range value in input
|
||||
if (localTm.tm_year != _tm.tm_year ||
|
||||
localTm.tm_mon != _tm.tm_mon ||
|
||||
localTm.tm_mday != _tm.tm_mday ||
|
||||
localTm.tm_hour != _tm.tm_hour ||
|
||||
localTm.tm_min != _tm.tm_min ||
|
||||
localTm.tm_sec != _tm.tm_sec)
|
||||
return false;
|
||||
|
||||
tp = system_clock::from_time_t(t);
|
||||
return true;
|
||||
}
|
||||
|
||||
CDateTime::CDateTime() : tp(std::chrono::system_clock::now())
|
||||
{
|
||||
}
|
||||
|
||||
CDateTime::CDateTime(const CDateTime &o) : tp(o.tp)
|
||||
{
|
||||
}
|
||||
|
||||
CDateTime &CDateTime::operator=(const CDateTime &o)
|
||||
{
|
||||
tp = o.tp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
asUINT CDateTime::getYear() const
|
||||
{
|
||||
tm local = time_point_to_tm(tp);
|
||||
return local.tm_year + 1900;
|
||||
}
|
||||
|
||||
asUINT CDateTime::getMonth() const
|
||||
{
|
||||
tm local = time_point_to_tm(tp);
|
||||
return local.tm_mon + 1;
|
||||
}
|
||||
|
||||
asUINT CDateTime::getDay() const
|
||||
{
|
||||
tm local = time_point_to_tm(tp);
|
||||
return local.tm_mday;
|
||||
}
|
||||
|
||||
asUINT CDateTime::getHour() const
|
||||
{
|
||||
tm local = time_point_to_tm(tp);
|
||||
return local.tm_hour;
|
||||
}
|
||||
|
||||
asUINT CDateTime::getMinute() const
|
||||
{
|
||||
tm local = time_point_to_tm(tp);
|
||||
return local.tm_min;
|
||||
}
|
||||
|
||||
asUINT CDateTime::getSecond() const
|
||||
{
|
||||
tm local = time_point_to_tm(tp);
|
||||
return local.tm_sec;
|
||||
}
|
||||
|
||||
bool CDateTime::setDate(asUINT year, asUINT month, asUINT day)
|
||||
{
|
||||
tm local = time_point_to_tm(tp);
|
||||
local.tm_year = int(year) - 1900;
|
||||
local.tm_mon = month - 1;
|
||||
local.tm_mday = day;
|
||||
|
||||
return tm_to_time_point(local, tp);
|
||||
}
|
||||
|
||||
bool CDateTime::setTime(asUINT hour, asUINT minute, asUINT second)
|
||||
{
|
||||
tm local = time_point_to_tm(tp);
|
||||
local.tm_hour = hour;
|
||||
local.tm_min = minute;
|
||||
local.tm_sec = second;
|
||||
|
||||
return tm_to_time_point(local, tp);
|
||||
}
|
||||
|
||||
CDateTime::CDateTime(asUINT year, asUINT month, asUINT day, asUINT hour, asUINT minute, asUINT second)
|
||||
{
|
||||
tp = std::chrono::system_clock::now();
|
||||
setDate(year, month, day);
|
||||
setTime(hour, minute, second);
|
||||
}
|
||||
|
||||
asINT64 CDateTime::operator-(const CDateTime &dt) const
|
||||
{
|
||||
return (tp - dt.tp).count() / std::chrono::system_clock::period::den * std::chrono::system_clock::period::num;
|
||||
}
|
||||
|
||||
CDateTime CDateTime::operator+(asINT64 seconds) const
|
||||
{
|
||||
CDateTime dt(*this);
|
||||
dt.tp += std::chrono::system_clock::duration(seconds * std::chrono::system_clock::period::den / std::chrono::system_clock::period::num);
|
||||
return dt;
|
||||
}
|
||||
|
||||
CDateTime &CDateTime::operator+=(asINT64 seconds)
|
||||
{
|
||||
tp += std::chrono::system_clock::duration(seconds * std::chrono::system_clock::period::den / std::chrono::system_clock::period::num);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CDateTime operator+(asINT64 seconds, const CDateTime &other)
|
||||
{
|
||||
return other + seconds;
|
||||
}
|
||||
|
||||
CDateTime CDateTime::operator-(asINT64 seconds) const
|
||||
{
|
||||
return *this + -seconds;
|
||||
}
|
||||
|
||||
CDateTime &CDateTime::operator-=(asINT64 seconds)
|
||||
{
|
||||
return *this += -seconds;
|
||||
}
|
||||
|
||||
CDateTime operator-(asINT64 seconds, const CDateTime &other)
|
||||
{
|
||||
return other + -seconds;
|
||||
}
|
||||
|
||||
bool CDateTime::operator==(const CDateTime &other) const
|
||||
{
|
||||
return tp == other.tp;
|
||||
}
|
||||
|
||||
bool CDateTime::operator<(const CDateTime &other) const
|
||||
{
|
||||
return tp < other.tp;
|
||||
}
|
||||
|
||||
static int opCmp(const CDateTime &a, const CDateTime &b)
|
||||
{
|
||||
if (a < b) return -1;
|
||||
if (a == b) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void Construct(CDateTime *mem)
|
||||
{
|
||||
new(mem) CDateTime();
|
||||
}
|
||||
|
||||
static void ConstructCopy(CDateTime *mem, const CDateTime &o)
|
||||
{
|
||||
new(mem) CDateTime(o);
|
||||
}
|
||||
|
||||
static void ConstructSet(CDateTime *mem, asUINT year, asUINT month, asUINT day, asUINT hour, asUINT minute, asUINT second)
|
||||
{
|
||||
new(mem) CDateTime(year, month, day, hour, minute, second);
|
||||
}
|
||||
|
||||
static void ConstructSet_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CDateTime *date = (CDateTime*)gen->GetObject();
|
||||
asUINT year = *(asUINT*)gen->GetAddressOfArg(0);
|
||||
asUINT month = *(asUINT*)gen->GetAddressOfArg(1);
|
||||
asUINT day = *(asUINT*)gen->GetAddressOfArg(2);
|
||||
asUINT hour = *(asUINT*)gen->GetAddressOfArg(3);
|
||||
asUINT minute = *(asUINT*)gen->GetAddressOfArg(4);
|
||||
asUINT second = *(asUINT*)gen->GetAddressOfArg(5);
|
||||
ConstructSet(date, year, month, day, hour, minute, second);
|
||||
}
|
||||
|
||||
void RegisterScriptDateTime(asIScriptEngine *engine)
|
||||
{
|
||||
int r = engine->RegisterObjectType("datetime", sizeof(CDateTime), asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<CDateTime>()); assert(r >= 0);
|
||||
|
||||
if(strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY")==0)
|
||||
{
|
||||
r = engine->RegisterObjectBehaviour("datetime", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(Construct), asCALL_CDECL_OBJLAST); assert(r >= 0);
|
||||
r = engine->RegisterObjectBehaviour("datetime", asBEHAVE_CONSTRUCT, "void f(const datetime &in)", asFUNCTION(ConstructCopy), asCALL_CDECL_OBJFIRST); assert(r >= 0);
|
||||
r = engine->RegisterObjectBehaviour("datetime", asBEHAVE_CONSTRUCT, "void f(uint, uint, uint, uint = 0, uint = 0, uint = 0)", asFUNCTION(ConstructSet), asCALL_CDECL_OBJFIRST); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "datetime &opAssign(const datetime &in)", asMETHOD(CDateTime, operator=), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "uint get_year() const property", asMETHOD(CDateTime, getYear), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "uint get_month() const property", asMETHOD(CDateTime, getMonth), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "uint get_day() const property", asMETHOD(CDateTime, getDay), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "uint get_hour() const property", asMETHOD(CDateTime, getHour), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "uint get_minute() const property", asMETHOD(CDateTime, getMinute), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "uint get_second() const property", asMETHOD(CDateTime, getSecond), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "bool setDate(uint year, uint month, uint day)", asMETHOD(CDateTime, setDate), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "bool setTime(uint hour, uint minute, uint second)", asMETHOD(CDateTime, setTime), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "int64 opSub(const datetime &in) const", asMETHODPR(CDateTime, operator-, (const CDateTime &other) const, asINT64), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "datetime opAdd(int64 seconds) const", asMETHOD(CDateTime, operator+), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "datetime opAdd_r(int64 seconds) const", asFUNCTIONPR(operator+, (asINT64 seconds, const CDateTime &other), CDateTime), asCALL_CDECL_OBJLAST); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "datetime &opAddAssign(int64 seconds)", asMETHOD(CDateTime, operator+=), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "datetime opSub(int64 seconds) const", asMETHODPR(CDateTime, operator-, (asINT64) const, CDateTime), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "datetime opSub_r(int64 seconds) const", asFUNCTIONPR(operator-, (asINT64 seconds, const CDateTime &other), CDateTime), asCALL_CDECL_OBJLAST); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "datetime &opSubAssign(int64 seconds)", asMETHOD(CDateTime, operator-=), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "bool opEquals(const datetime &in) const", asMETHODPR(CDateTime, operator==, (const CDateTime &other) const, bool), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "int opCmp(const datetime &in) const", asFUNCTION(opCmp), asCALL_CDECL_OBJFIRST); assert(r >= 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
r = engine->RegisterObjectBehaviour("datetime", asBEHAVE_CONSTRUCT, "void f()", WRAP_OBJ_LAST(Construct), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectBehaviour("datetime", asBEHAVE_CONSTRUCT, "void f(const datetime &in)", WRAP_OBJ_FIRST(ConstructCopy), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectBehaviour("datetime", asBEHAVE_CONSTRUCT, "void f(uint, uint, uint, uint = 0, uint = 0, uint = 0)", asFUNCTION(ConstructSet_Generic), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "datetime &opAssign(const datetime &in)", WRAP_MFN(CDateTime, operator=), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "uint get_year() const property", WRAP_MFN(CDateTime, getYear), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "uint get_month() const property", WRAP_MFN(CDateTime, getMonth), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "uint get_day() const property", WRAP_MFN(CDateTime, getDay), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "uint get_hour() const property", WRAP_MFN(CDateTime, getHour), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "uint get_minute() const property", WRAP_MFN(CDateTime, getMinute), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "uint get_second() const property", WRAP_MFN(CDateTime, getSecond), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "bool setDate(uint year, uint month, uint day)", WRAP_MFN(CDateTime, setDate), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "bool setTime(uint hour, uint minute, uint second)", WRAP_MFN(CDateTime, setTime), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "int64 opSub(const datetime &in) const", WRAP_MFN_PR(CDateTime, operator-, (const CDateTime &other) const, asINT64), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "datetime opAdd(int64 seconds) const", WRAP_MFN(CDateTime, operator+), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "datetime opAdd_r(int64 seconds) const", WRAP_OBJ_LAST_PR(operator+, (asINT64 seconds, const CDateTime &other), CDateTime), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "datetime &opAddAssign(int64 seconds)", WRAP_MFN(CDateTime, operator+=), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "datetime opSub(int64 seconds) const", WRAP_MFN_PR(CDateTime, operator-, (asINT64) const, CDateTime), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "datetime opSub_r(int64 seconds) const", WRAP_OBJ_LAST_PR(operator-, (asINT64 seconds, const CDateTime &other), CDateTime), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "datetime &opSubAssign(int64 seconds)", WRAP_MFN(CDateTime, operator-=), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "bool opEquals(const datetime &in) const", WRAP_MFN_PR(CDateTime, operator==, (const CDateTime &other) const, bool), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("datetime", "int opCmp(const datetime &in) const", WRAP_OBJ_FIRST(opCmp), asCALL_GENERIC); assert(r >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
END_AS_NAMESPACE
|
|
@ -0,0 +1,61 @@
|
|||
#ifndef SCRIPTDATETIME_H
|
||||
#define SCRIPTDATETIME_H
|
||||
|
||||
#ifndef ANGELSCRIPT_H
|
||||
// Avoid having to inform include path if header is already include before
|
||||
#include <angelscript.h>
|
||||
#endif
|
||||
|
||||
#ifdef AS_CAN_USE_CPP11
|
||||
#include <chrono>
|
||||
#else
|
||||
#error Sorry, this requires C++11 which your compiler doesnt appear to support
|
||||
#endif
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
class CDateTime
|
||||
{
|
||||
public:
|
||||
// Constructors
|
||||
CDateTime();
|
||||
CDateTime(const CDateTime &other);
|
||||
CDateTime(asUINT year, asUINT month, asUINT day, asUINT hour, asUINT minute, asUINT second);
|
||||
|
||||
// Copy the stored value from another any object
|
||||
CDateTime &operator=(const CDateTime &other);
|
||||
|
||||
// Accessors
|
||||
asUINT getYear() const;
|
||||
asUINT getMonth() const;
|
||||
asUINT getDay() const;
|
||||
asUINT getHour() const;
|
||||
asUINT getMinute() const;
|
||||
asUINT getSecond() const;
|
||||
|
||||
// Setters
|
||||
// Returns true if valid
|
||||
bool setDate(asUINT year, asUINT month, asUINT day);
|
||||
bool setTime(asUINT hour, asUINT minute, asUINT second);
|
||||
|
||||
// Operators
|
||||
// Return difference in seconds
|
||||
asINT64 operator-(const CDateTime &other) const;
|
||||
CDateTime operator+(asINT64 seconds) const;
|
||||
friend CDateTime operator+(asINT64 seconds, const CDateTime &other);
|
||||
CDateTime & operator+=(asINT64 seconds);
|
||||
CDateTime operator-(asINT64 seconds) const;
|
||||
friend CDateTime operator-(asINT64 seconds, const CDateTime &other);
|
||||
CDateTime & operator-=(asINT64 seconds);
|
||||
bool operator==(const CDateTime &other) const;
|
||||
bool operator<(const CDateTime &other) const;
|
||||
|
||||
protected:
|
||||
std::chrono::system_clock::time_point tp;
|
||||
};
|
||||
|
||||
void RegisterScriptDateTime(asIScriptEngine *engine);
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,852 @@
|
|||
#include "debugger.h"
|
||||
#include <iostream> // cout
|
||||
#include <sstream> // stringstream
|
||||
#include <stdlib.h> // atoi
|
||||
#include <assert.h> // assert
|
||||
|
||||
using namespace std;
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
CDebugger::CDebugger()
|
||||
{
|
||||
m_action = CONTINUE;
|
||||
m_lastFunction = 0;
|
||||
m_engine = 0;
|
||||
}
|
||||
|
||||
CDebugger::~CDebugger()
|
||||
{
|
||||
SetEngine(0);
|
||||
}
|
||||
|
||||
string CDebugger::ToString(void *value, asUINT typeId, int expandMembers, asIScriptEngine *engine)
|
||||
{
|
||||
if( value == 0 )
|
||||
return "<null>";
|
||||
|
||||
// If no engine pointer was provided use the default
|
||||
if( engine == 0 )
|
||||
engine = m_engine;
|
||||
|
||||
stringstream s;
|
||||
if( typeId == asTYPEID_VOID )
|
||||
return "<void>";
|
||||
else if( typeId == asTYPEID_BOOL )
|
||||
return *(bool*)value ? "true" : "false";
|
||||
else if( typeId == asTYPEID_INT8 )
|
||||
s << (int)*(signed char*)value;
|
||||
else if( typeId == asTYPEID_INT16 )
|
||||
s << (int)*(signed short*)value;
|
||||
else if( typeId == asTYPEID_INT32 )
|
||||
s << *(signed int*)value;
|
||||
else if( typeId == asTYPEID_INT64 )
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1200
|
||||
s << "{...}"; // MSVC6 doesn't like the << operator for 64bit integer
|
||||
#else
|
||||
s << *(asINT64*)value;
|
||||
#endif
|
||||
else if( typeId == asTYPEID_UINT8 )
|
||||
s << (unsigned int)*(unsigned char*)value;
|
||||
else if( typeId == asTYPEID_UINT16 )
|
||||
s << (unsigned int)*(unsigned short*)value;
|
||||
else if( typeId == asTYPEID_UINT32 )
|
||||
s << *(unsigned int*)value;
|
||||
else if( typeId == asTYPEID_UINT64 )
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1200
|
||||
s << "{...}"; // MSVC6 doesn't like the << operator for 64bit integer
|
||||
#else
|
||||
s << *(asQWORD*)value;
|
||||
#endif
|
||||
else if( typeId == asTYPEID_FLOAT )
|
||||
s << *(float*)value;
|
||||
else if( typeId == asTYPEID_DOUBLE )
|
||||
s << *(double*)value;
|
||||
else if( (typeId & asTYPEID_MASK_OBJECT) == 0 )
|
||||
{
|
||||
// The type is an enum
|
||||
s << *(asUINT*)value;
|
||||
|
||||
// Check if the value matches one of the defined enums
|
||||
if( engine )
|
||||
{
|
||||
asITypeInfo *t = engine->GetTypeInfoById(typeId);
|
||||
for( int n = t->GetEnumValueCount(); n-- > 0; )
|
||||
{
|
||||
int enumVal;
|
||||
const char *enumName = t->GetEnumValueByIndex(n, &enumVal);
|
||||
if( enumVal == *(int*)value )
|
||||
{
|
||||
s << ", " << enumName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( typeId & asTYPEID_SCRIPTOBJECT )
|
||||
{
|
||||
// Dereference handles, so we can see what it points to
|
||||
if( typeId & asTYPEID_OBJHANDLE )
|
||||
value = *(void**)value;
|
||||
|
||||
asIScriptObject *obj = (asIScriptObject *)value;
|
||||
|
||||
// Print the address of the object
|
||||
s << "{" << obj << "}";
|
||||
|
||||
// Print the members
|
||||
if( obj && expandMembers > 0 )
|
||||
{
|
||||
asITypeInfo *type = obj->GetObjectType();
|
||||
for( asUINT n = 0; n < obj->GetPropertyCount(); n++ )
|
||||
{
|
||||
if( n == 0 )
|
||||
s << " ";
|
||||
else
|
||||
s << ", ";
|
||||
|
||||
s << type->GetPropertyDeclaration(n) << " = " << ToString(obj->GetAddressOfProperty(n), obj->GetPropertyTypeId(n), expandMembers - 1, type->GetEngine());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Dereference handles, so we can see what it points to
|
||||
if( typeId & asTYPEID_OBJHANDLE )
|
||||
value = *(void**)value;
|
||||
|
||||
// Print the address for reference types so it will be
|
||||
// possible to see when handles point to the same object
|
||||
if( engine )
|
||||
{
|
||||
asITypeInfo *type = engine->GetTypeInfoById(typeId);
|
||||
if( type->GetFlags() & asOBJ_REF )
|
||||
s << "{" << value << "}";
|
||||
|
||||
if( value )
|
||||
{
|
||||
// Check if there is a registered to-string callback
|
||||
map<const asITypeInfo*, ToStringCallback>::iterator it = m_toStringCallbacks.find(type);
|
||||
if( it == m_toStringCallbacks.end() )
|
||||
{
|
||||
// If the type is a template instance, there might be a
|
||||
// to-string callback for the generic template type
|
||||
if( type->GetFlags() & asOBJ_TEMPLATE )
|
||||
{
|
||||
asITypeInfo *tmplType = engine->GetTypeInfoByName(type->GetName());
|
||||
it = m_toStringCallbacks.find(tmplType);
|
||||
}
|
||||
}
|
||||
|
||||
if( it != m_toStringCallbacks.end() )
|
||||
{
|
||||
if( type->GetFlags() & asOBJ_REF )
|
||||
s << " ";
|
||||
|
||||
// Invoke the callback to get the string representation of this type
|
||||
string str = it->second(value, expandMembers, this);
|
||||
s << str;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
s << "{no engine}";
|
||||
}
|
||||
|
||||
return s.str();
|
||||
}
|
||||
|
||||
void CDebugger::RegisterToStringCallback(const asITypeInfo *ot, ToStringCallback callback)
|
||||
{
|
||||
if( m_toStringCallbacks.find(ot) == m_toStringCallbacks.end() )
|
||||
m_toStringCallbacks.insert(map<const asITypeInfo*, ToStringCallback>::value_type(ot, callback));
|
||||
}
|
||||
|
||||
void CDebugger::LineCallback(asIScriptContext *ctx)
|
||||
{
|
||||
assert( ctx );
|
||||
|
||||
// This should never happen, but it doesn't hurt to validate it
|
||||
if( ctx == 0 )
|
||||
return;
|
||||
|
||||
// By default we ignore callbacks when the context is not active.
|
||||
// An application might override this to for example disconnect the
|
||||
// debugger as the execution finished.
|
||||
if( ctx->GetState() != asEXECUTION_ACTIVE )
|
||||
return;
|
||||
|
||||
if( m_action == CONTINUE )
|
||||
{
|
||||
if( !CheckBreakPoint(ctx) )
|
||||
return;
|
||||
}
|
||||
else if( m_action == STEP_OVER )
|
||||
{
|
||||
if( ctx->GetCallstackSize() > m_lastCommandAtStackLevel )
|
||||
{
|
||||
if( !CheckBreakPoint(ctx) )
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if( m_action == STEP_OUT )
|
||||
{
|
||||
if( ctx->GetCallstackSize() >= m_lastCommandAtStackLevel )
|
||||
{
|
||||
if( !CheckBreakPoint(ctx) )
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if( m_action == STEP_INTO )
|
||||
{
|
||||
CheckBreakPoint(ctx);
|
||||
|
||||
// Always break, but we call the check break point anyway
|
||||
// to tell user when break point has been reached
|
||||
}
|
||||
|
||||
stringstream s;
|
||||
const char *file = 0;
|
||||
int lineNbr = ctx->GetLineNumber(0, 0, &file);
|
||||
s << (file ? file : "{unnamed}") << ":" << lineNbr << "; " << ctx->GetFunction()->GetDeclaration() << endl;
|
||||
Output(s.str());
|
||||
|
||||
TakeCommands(ctx);
|
||||
}
|
||||
|
||||
bool CDebugger::CheckBreakPoint(asIScriptContext *ctx)
|
||||
{
|
||||
if( ctx == 0 )
|
||||
return false;
|
||||
|
||||
// TODO: Should cache the break points in a function by checking which possible break points
|
||||
// can be hit when entering a function. If there are no break points in the current function
|
||||
// then there is no need to check every line.
|
||||
|
||||
const char *tmp = 0;
|
||||
int lineNbr = ctx->GetLineNumber(0, 0, &tmp);
|
||||
|
||||
// Consider just filename, not the full path
|
||||
string file = tmp ? tmp : "";
|
||||
size_t r = file.find_last_of("\\/");
|
||||
if( r != string::npos )
|
||||
file = file.substr(r+1);
|
||||
|
||||
// Did we move into a new function?
|
||||
asIScriptFunction *func = ctx->GetFunction();
|
||||
if( m_lastFunction != func )
|
||||
{
|
||||
// Check if any breakpoints need adjusting
|
||||
for( size_t n = 0; n < m_breakPoints.size(); n++ )
|
||||
{
|
||||
// We need to check for a breakpoint at entering the function
|
||||
if( m_breakPoints[n].func )
|
||||
{
|
||||
if( m_breakPoints[n].name == func->GetName() )
|
||||
{
|
||||
stringstream s;
|
||||
s << "Entering function '" << m_breakPoints[n].name << "'. Transforming it into break point" << endl;
|
||||
Output(s.str());
|
||||
|
||||
// Transform the function breakpoint into a file breakpoint
|
||||
m_breakPoints[n].name = file;
|
||||
m_breakPoints[n].lineNbr = lineNbr;
|
||||
m_breakPoints[n].func = false;
|
||||
m_breakPoints[n].needsAdjusting = false;
|
||||
}
|
||||
}
|
||||
// Check if a given breakpoint fall on a line with code or else adjust it to the next line
|
||||
else if( m_breakPoints[n].needsAdjusting &&
|
||||
m_breakPoints[n].name == file )
|
||||
{
|
||||
int line = func->FindNextLineWithCode(m_breakPoints[n].lineNbr);
|
||||
if( line >= 0 )
|
||||
{
|
||||
m_breakPoints[n].needsAdjusting = false;
|
||||
if( line != m_breakPoints[n].lineNbr )
|
||||
{
|
||||
stringstream s;
|
||||
s << "Moving break point " << n << " in file '" << file << "' to next line with code at line " << line << endl;
|
||||
Output(s.str());
|
||||
|
||||
// Move the breakpoint to the next line
|
||||
m_breakPoints[n].lineNbr = line;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_lastFunction = func;
|
||||
|
||||
// Determine if there is a breakpoint at the current line
|
||||
for( size_t n = 0; n < m_breakPoints.size(); n++ )
|
||||
{
|
||||
// TODO: do case-less comparison for file name
|
||||
|
||||
// Should we break?
|
||||
if( !m_breakPoints[n].func &&
|
||||
m_breakPoints[n].lineNbr == lineNbr &&
|
||||
m_breakPoints[n].name == file )
|
||||
{
|
||||
stringstream s;
|
||||
s << "Reached break point " << n << " in file '" << file << "' at line " << lineNbr << endl;
|
||||
Output(s.str());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CDebugger::TakeCommands(asIScriptContext *ctx)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
char buf[512];
|
||||
|
||||
Output("[dbg]> ");
|
||||
cin.getline(buf, 512);
|
||||
|
||||
if( InterpretCommand(string(buf), ctx) )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool CDebugger::InterpretCommand(const string &cmd, asIScriptContext *ctx)
|
||||
{
|
||||
if( cmd.length() == 0 ) return true;
|
||||
|
||||
switch( cmd[0] )
|
||||
{
|
||||
case 'c':
|
||||
m_action = CONTINUE;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
m_action = STEP_INTO;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
m_action = STEP_OVER;
|
||||
m_lastCommandAtStackLevel = ctx ? ctx->GetCallstackSize() : 1;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
m_action = STEP_OUT;
|
||||
m_lastCommandAtStackLevel = ctx ? ctx->GetCallstackSize() : 0;
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
{
|
||||
// Set break point
|
||||
size_t p = cmd.find_first_not_of(" \t", 1);
|
||||
size_t div = cmd.find(':');
|
||||
if( div != string::npos && div > 2 && p > 1 )
|
||||
{
|
||||
string file = cmd.substr(2, div-2);
|
||||
string line = cmd.substr(div+1);
|
||||
|
||||
int nbr = atoi(line.c_str());
|
||||
|
||||
AddFileBreakPoint(file, nbr);
|
||||
}
|
||||
else if( div == string::npos && p != string::npos && p > 1 )
|
||||
{
|
||||
string func = cmd.substr(p);
|
||||
|
||||
AddFuncBreakPoint(func);
|
||||
}
|
||||
else
|
||||
{
|
||||
Output("Incorrect format for setting break point, expected one of:\n"
|
||||
" b <file name>:<line number>\n"
|
||||
" b <function name>\n");
|
||||
}
|
||||
}
|
||||
// take more commands
|
||||
return false;
|
||||
|
||||
case 'r':
|
||||
{
|
||||
// Remove break point
|
||||
size_t p = cmd.find_first_not_of(" \t", 1);
|
||||
if( cmd.length() > 2 && p != string::npos && p > 1 )
|
||||
{
|
||||
string br = cmd.substr(2);
|
||||
if( br == "all" )
|
||||
{
|
||||
m_breakPoints.clear();
|
||||
Output("All break points have been removed\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
int nbr = atoi(br.c_str());
|
||||
if( nbr >= 0 && nbr < (int)m_breakPoints.size() )
|
||||
m_breakPoints.erase(m_breakPoints.begin()+nbr);
|
||||
ListBreakPoints();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Output("Incorrect format for removing break points, expected:\n"
|
||||
" r <all|number of break point>\n");
|
||||
}
|
||||
}
|
||||
// take more commands
|
||||
return false;
|
||||
|
||||
case 'l':
|
||||
{
|
||||
// List something
|
||||
bool printHelp = false;
|
||||
size_t p = cmd.find_first_not_of(" \t", 1);
|
||||
if( p != string::npos && p > 1 )
|
||||
{
|
||||
if( cmd[p] == 'b' )
|
||||
{
|
||||
ListBreakPoints();
|
||||
}
|
||||
else if( cmd[p] == 'v' )
|
||||
{
|
||||
ListLocalVariables(ctx);
|
||||
}
|
||||
else if( cmd[p] == 'g' )
|
||||
{
|
||||
ListGlobalVariables(ctx);
|
||||
}
|
||||
else if( cmd[p] == 'm' )
|
||||
{
|
||||
ListMemberProperties(ctx);
|
||||
}
|
||||
else if( cmd[p] == 's' )
|
||||
{
|
||||
ListStatistics(ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
Output("Unknown list option.\n");
|
||||
printHelp = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Output("Incorrect format for list command.\n");
|
||||
printHelp = true;
|
||||
}
|
||||
|
||||
if( printHelp )
|
||||
{
|
||||
Output("Expected format: \n"
|
||||
" l <list option>\n"
|
||||
"Available options: \n"
|
||||
" b - breakpoints\n"
|
||||
" v - local variables\n"
|
||||
" m - member properties\n"
|
||||
" g - global variables\n"
|
||||
" s - statistics\n");
|
||||
}
|
||||
}
|
||||
// take more commands
|
||||
return false;
|
||||
|
||||
case 'h':
|
||||
PrintHelp();
|
||||
// take more commands
|
||||
return false;
|
||||
|
||||
case 'p':
|
||||
{
|
||||
// Print a value
|
||||
size_t p = cmd.find_first_not_of(" \t", 1);
|
||||
if( p != string::npos && p > 1 )
|
||||
{
|
||||
PrintValue(cmd.substr(p), ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
Output("Incorrect format for print, expected:\n"
|
||||
" p <expression>\n");
|
||||
}
|
||||
}
|
||||
// take more commands
|
||||
return false;
|
||||
|
||||
case 'w':
|
||||
// Where am I?
|
||||
PrintCallstack(ctx);
|
||||
// take more commands
|
||||
return false;
|
||||
|
||||
case 'a':
|
||||
// abort the execution
|
||||
if( ctx == 0 )
|
||||
{
|
||||
Output("No script is running\n");
|
||||
return false;
|
||||
}
|
||||
ctx->Abort();
|
||||
break;
|
||||
|
||||
default:
|
||||
Output("Unknown command\n");
|
||||
// take more commands
|
||||
return false;
|
||||
}
|
||||
|
||||
// Continue execution
|
||||
return true;
|
||||
}
|
||||
|
||||
void CDebugger::PrintValue(const std::string &expr, asIScriptContext *ctx)
|
||||
{
|
||||
if( ctx == 0 )
|
||||
{
|
||||
Output("No script is running\n");
|
||||
return;
|
||||
}
|
||||
|
||||
asIScriptEngine *engine = ctx->GetEngine();
|
||||
|
||||
// Tokenize the input string to get the variable scope and name
|
||||
asUINT len = 0;
|
||||
string scope;
|
||||
string name;
|
||||
string str = expr;
|
||||
asETokenClass t = engine->ParseToken(str.c_str(), 0, &len);
|
||||
while( t == asTC_IDENTIFIER || (t == asTC_KEYWORD && len == 2 && str.compare(0, 2, "::") == 0) )
|
||||
{
|
||||
if( t == asTC_KEYWORD )
|
||||
{
|
||||
if( scope == "" && name == "" )
|
||||
scope = "::"; // global scope
|
||||
else if( scope == "::" || scope == "" )
|
||||
scope = name; // namespace
|
||||
else
|
||||
scope += "::" + name; // nested namespace
|
||||
name = "";
|
||||
}
|
||||
else if( t == asTC_IDENTIFIER )
|
||||
name.assign(str.c_str(), len);
|
||||
|
||||
// Skip the parsed token and get the next one
|
||||
str = str.substr(len);
|
||||
t = engine->ParseToken(str.c_str(), 0, &len);
|
||||
}
|
||||
|
||||
if( name.size() )
|
||||
{
|
||||
// Find the variable
|
||||
void *ptr = 0;
|
||||
int typeId = 0;
|
||||
|
||||
asIScriptFunction *func = ctx->GetFunction();
|
||||
if( !func ) return;
|
||||
|
||||
// skip local variables if a scope was informed
|
||||
if( scope == "" )
|
||||
{
|
||||
// We start from the end, in case the same name is reused in different scopes
|
||||
for( asUINT n = func->GetVarCount(); n-- > 0; )
|
||||
{
|
||||
if( ctx->IsVarInScope(n) && name == ctx->GetVarName(n) )
|
||||
{
|
||||
ptr = ctx->GetAddressOfVar(n);
|
||||
typeId = ctx->GetVarTypeId(n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Look for class members, if we're in a class method
|
||||
if( !ptr && func->GetObjectType() )
|
||||
{
|
||||
if( name == "this" )
|
||||
{
|
||||
ptr = ctx->GetThisPointer();
|
||||
typeId = ctx->GetThisTypeId();
|
||||
}
|
||||
else
|
||||
{
|
||||
asITypeInfo *type = engine->GetTypeInfoById(ctx->GetThisTypeId());
|
||||
for( asUINT n = 0; n < type->GetPropertyCount(); n++ )
|
||||
{
|
||||
const char *propName = 0;
|
||||
int offset = 0;
|
||||
bool isReference = 0;
|
||||
int compositeOffset = 0;
|
||||
bool isCompositeIndirect = false;
|
||||
type->GetProperty(n, &propName, &typeId, 0, 0, &offset, &isReference, 0, &compositeOffset, &isCompositeIndirect);
|
||||
if( name == propName )
|
||||
{
|
||||
ptr = (void*)(((asBYTE*)ctx->GetThisPointer())+compositeOffset);
|
||||
if (isCompositeIndirect) ptr = *(void**)ptr;
|
||||
ptr = (void*)(((asBYTE*)ptr) + offset);
|
||||
if( isReference ) ptr = *(void**)ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Look for global variables
|
||||
if( !ptr )
|
||||
{
|
||||
if( scope == "" )
|
||||
{
|
||||
// If no explicit scope was informed then use the namespace of the current function by default
|
||||
scope = func->GetNamespace();
|
||||
}
|
||||
else if( scope == "::" )
|
||||
{
|
||||
// The global namespace will be empty
|
||||
scope = "";
|
||||
}
|
||||
|
||||
asIScriptModule *mod = func->GetModule();
|
||||
if( mod )
|
||||
{
|
||||
for( asUINT n = 0; n < mod->GetGlobalVarCount(); n++ )
|
||||
{
|
||||
const char *varName = 0, *nameSpace = 0;
|
||||
mod->GetGlobalVar(n, &varName, &nameSpace, &typeId);
|
||||
|
||||
// Check if both name and namespace match
|
||||
if( name == varName && scope == nameSpace )
|
||||
{
|
||||
ptr = mod->GetAddressOfGlobalVar(n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( ptr )
|
||||
{
|
||||
// TODO: If there is a . after the identifier, check for members
|
||||
// TODO: If there is a [ after the identifier try to call the 'opIndex(expr) const' method
|
||||
if( str != "" )
|
||||
{
|
||||
Output("Invalid expression. Expression doesn't end after symbol\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
stringstream s;
|
||||
// TODO: Allow user to set if members should be expanded
|
||||
// Expand members by default to 3 recursive levels only
|
||||
s << ToString(ptr, typeId, 3, engine) << endl;
|
||||
Output(s.str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Output("Invalid expression. No matching symbol\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Output("Invalid expression. Expected identifier\n");
|
||||
}
|
||||
}
|
||||
|
||||
void CDebugger::ListBreakPoints()
|
||||
{
|
||||
// List all break points
|
||||
stringstream s;
|
||||
for( size_t b = 0; b < m_breakPoints.size(); b++ )
|
||||
if( m_breakPoints[b].func )
|
||||
s << b << " - " << m_breakPoints[b].name << endl;
|
||||
else
|
||||
s << b << " - " << m_breakPoints[b].name << ":" << m_breakPoints[b].lineNbr << endl;
|
||||
Output(s.str());
|
||||
}
|
||||
|
||||
void CDebugger::ListMemberProperties(asIScriptContext *ctx)
|
||||
{
|
||||
if( ctx == 0 )
|
||||
{
|
||||
Output("No script is running\n");
|
||||
return;
|
||||
}
|
||||
|
||||
void *ptr = ctx->GetThisPointer();
|
||||
if( ptr )
|
||||
{
|
||||
stringstream s;
|
||||
// TODO: Allow user to define if members should be expanded or not
|
||||
// Expand members by default to 3 recursive levels only
|
||||
s << "this = " << ToString(ptr, ctx->GetThisTypeId(), 3, ctx->GetEngine()) << endl;
|
||||
Output(s.str());
|
||||
}
|
||||
}
|
||||
|
||||
void CDebugger::ListLocalVariables(asIScriptContext *ctx)
|
||||
{
|
||||
if( ctx == 0 )
|
||||
{
|
||||
Output("No script is running\n");
|
||||
return;
|
||||
}
|
||||
|
||||
asIScriptFunction *func = ctx->GetFunction();
|
||||
if( !func ) return;
|
||||
|
||||
stringstream s;
|
||||
for( asUINT n = 0; n < func->GetVarCount(); n++ )
|
||||
{
|
||||
if( ctx->IsVarInScope(n) )
|
||||
{
|
||||
// TODO: Allow user to set if members should be expanded or not
|
||||
// Expand members by default to 3 recursive levels only
|
||||
s << func->GetVarDecl(n) << " = " << ToString(ctx->GetAddressOfVar(n), ctx->GetVarTypeId(n), 3, ctx->GetEngine()) << endl;
|
||||
}
|
||||
}
|
||||
Output(s.str());
|
||||
}
|
||||
|
||||
void CDebugger::ListGlobalVariables(asIScriptContext *ctx)
|
||||
{
|
||||
if( ctx == 0 )
|
||||
{
|
||||
Output("No script is running\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine the current module from the function
|
||||
asIScriptFunction *func = ctx->GetFunction();
|
||||
if( !func ) return;
|
||||
|
||||
asIScriptModule *mod = func->GetModule();
|
||||
if( !mod ) return;
|
||||
|
||||
stringstream s;
|
||||
for( asUINT n = 0; n < mod->GetGlobalVarCount(); n++ )
|
||||
{
|
||||
int typeId = 0;
|
||||
mod->GetGlobalVar(n, 0, 0, &typeId);
|
||||
// TODO: Allow user to set how many recursive expansions should be done
|
||||
// Expand members by default to 3 recursive levels only
|
||||
s << mod->GetGlobalVarDeclaration(n) << " = " << ToString(mod->GetAddressOfGlobalVar(n), typeId, 3, ctx->GetEngine()) << endl;
|
||||
}
|
||||
Output(s.str());
|
||||
}
|
||||
|
||||
void CDebugger::ListStatistics(asIScriptContext *ctx)
|
||||
{
|
||||
if( ctx == 0 )
|
||||
{
|
||||
Output("No script is running\n");
|
||||
return;
|
||||
}
|
||||
|
||||
asIScriptEngine *engine = ctx->GetEngine();
|
||||
|
||||
asUINT gcCurrSize, gcTotalDestr, gcTotalDet, gcNewObjects, gcTotalNewDestr;
|
||||
engine->GetGCStatistics(&gcCurrSize, &gcTotalDestr, &gcTotalDet, &gcNewObjects, &gcTotalNewDestr);
|
||||
|
||||
stringstream s;
|
||||
s << "Garbage collector:" << endl;
|
||||
s << " current size: " << gcCurrSize << endl;
|
||||
s << " total destroyed: " << gcTotalDestr << endl;
|
||||
s << " total detected: " << gcTotalDet << endl;
|
||||
s << " new objects: " << gcNewObjects << endl;
|
||||
s << " new objects destroyed: " << gcTotalNewDestr << endl;
|
||||
|
||||
Output(s.str());
|
||||
}
|
||||
|
||||
void CDebugger::PrintCallstack(asIScriptContext *ctx)
|
||||
{
|
||||
if( ctx == 0 )
|
||||
{
|
||||
Output("No script is running\n");
|
||||
return;
|
||||
}
|
||||
|
||||
stringstream s;
|
||||
const char *file = 0;
|
||||
int lineNbr = 0;
|
||||
for( asUINT n = 0; n < ctx->GetCallstackSize(); n++ )
|
||||
{
|
||||
lineNbr = ctx->GetLineNumber(n, 0, &file);
|
||||
s << (file ? file : "{unnamed}") << ":" << lineNbr << "; " << ctx->GetFunction(n)->GetDeclaration() << endl;
|
||||
}
|
||||
Output(s.str());
|
||||
}
|
||||
|
||||
void CDebugger::AddFuncBreakPoint(const string &func)
|
||||
{
|
||||
// Trim the function name
|
||||
size_t b = func.find_first_not_of(" \t");
|
||||
size_t e = func.find_last_not_of(" \t");
|
||||
string actual = func.substr(b, e != string::npos ? e-b+1 : string::npos);
|
||||
|
||||
stringstream s;
|
||||
s << "Adding deferred break point for function '" << actual << "'" << endl;
|
||||
Output(s.str());
|
||||
|
||||
BreakPoint bp(actual, 0, true);
|
||||
m_breakPoints.push_back(bp);
|
||||
}
|
||||
|
||||
void CDebugger::AddFileBreakPoint(const string &file, int lineNbr)
|
||||
{
|
||||
// Store just file name, not entire path
|
||||
size_t r = file.find_last_of("\\/");
|
||||
string actual;
|
||||
if( r != string::npos )
|
||||
actual = file.substr(r+1);
|
||||
else
|
||||
actual = file;
|
||||
|
||||
// Trim the file name
|
||||
size_t b = actual.find_first_not_of(" \t");
|
||||
size_t e = actual.find_last_not_of(" \t");
|
||||
actual = actual.substr(b, e != string::npos ? e-b+1 : string::npos);
|
||||
|
||||
stringstream s;
|
||||
s << "Setting break point in file '" << actual << "' at line " << lineNbr << endl;
|
||||
Output(s.str());
|
||||
|
||||
BreakPoint bp(actual, lineNbr, false);
|
||||
m_breakPoints.push_back(bp);
|
||||
}
|
||||
|
||||
void CDebugger::PrintHelp()
|
||||
{
|
||||
Output(" c - Continue\n"
|
||||
" s - Step into\n"
|
||||
" n - Next step\n"
|
||||
" o - Step out\n"
|
||||
" b - Set break point\n"
|
||||
" l - List various things\n"
|
||||
" r - Remove break point\n"
|
||||
" p - Print value\n"
|
||||
" w - Where am I?\n"
|
||||
" a - Abort execution\n"
|
||||
" h - Print this help text\n");
|
||||
}
|
||||
|
||||
void CDebugger::Output(const string &str)
|
||||
{
|
||||
// By default we just output to stdout
|
||||
cout << str;
|
||||
}
|
||||
|
||||
void CDebugger::SetEngine(asIScriptEngine *engine)
|
||||
{
|
||||
if( m_engine != engine )
|
||||
{
|
||||
if( m_engine )
|
||||
m_engine->Release();
|
||||
m_engine = engine;
|
||||
if( m_engine )
|
||||
m_engine->AddRef();
|
||||
}
|
||||
}
|
||||
|
||||
asIScriptEngine *CDebugger::GetEngine()
|
||||
{
|
||||
return m_engine;
|
||||
}
|
||||
|
||||
END_AS_NAMESPACE
|
|
@ -0,0 +1,87 @@
|
|||
#ifndef DEBUGGER_H
|
||||
#define DEBUGGER_H
|
||||
|
||||
#ifndef ANGELSCRIPT_H
|
||||
// Avoid having to inform include path if header is already include before
|
||||
#include <angelscript.h>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
class CDebugger
|
||||
{
|
||||
public:
|
||||
CDebugger();
|
||||
virtual ~CDebugger();
|
||||
|
||||
// Register callbacks to handle to-string conversions of application types
|
||||
// The expandMembersLevel is a counter for how many recursive levels the members should be expanded.
|
||||
// If the object that is being converted to a string has members of its own the callback should call
|
||||
// the debugger's ToString passing in expandMembersLevel - 1.
|
||||
typedef std::string (*ToStringCallback)(void *obj, int expandMembersLevel, CDebugger *dbg);
|
||||
virtual void RegisterToStringCallback(const asITypeInfo *ti, ToStringCallback callback);
|
||||
|
||||
// User interaction
|
||||
virtual void TakeCommands(asIScriptContext *ctx);
|
||||
virtual void Output(const std::string &str);
|
||||
|
||||
// Line callback invoked by context
|
||||
virtual void LineCallback(asIScriptContext *ctx);
|
||||
|
||||
// Commands
|
||||
virtual void PrintHelp();
|
||||
virtual void AddFileBreakPoint(const std::string &file, int lineNbr);
|
||||
virtual void AddFuncBreakPoint(const std::string &func);
|
||||
virtual void ListBreakPoints();
|
||||
virtual void ListLocalVariables(asIScriptContext *ctx);
|
||||
virtual void ListGlobalVariables(asIScriptContext *ctx);
|
||||
virtual void ListMemberProperties(asIScriptContext *ctx);
|
||||
virtual void ListStatistics(asIScriptContext *ctx);
|
||||
virtual void PrintCallstack(asIScriptContext *ctx);
|
||||
virtual void PrintValue(const std::string &expr, asIScriptContext *ctx);
|
||||
|
||||
// Helpers
|
||||
virtual bool InterpretCommand(const std::string &cmd, asIScriptContext *ctx);
|
||||
virtual bool CheckBreakPoint(asIScriptContext *ctx);
|
||||
virtual std::string ToString(void *value, asUINT typeId, int expandMembersLevel, asIScriptEngine *engine);
|
||||
|
||||
// Optionally set the engine pointer in the debugger so it can be retrieved
|
||||
// by callbacks that need it. This will hold a reference to the engine.
|
||||
virtual void SetEngine(asIScriptEngine *engine);
|
||||
virtual asIScriptEngine *GetEngine();
|
||||
|
||||
protected:
|
||||
enum DebugAction
|
||||
{
|
||||
CONTINUE, // continue until next break point
|
||||
STEP_INTO, // stop at next instruction
|
||||
STEP_OVER, // stop at next instruction, skipping called functions
|
||||
STEP_OUT // run until returning from current function
|
||||
};
|
||||
DebugAction m_action;
|
||||
asUINT m_lastCommandAtStackLevel;
|
||||
asIScriptFunction *m_lastFunction;
|
||||
|
||||
struct BreakPoint
|
||||
{
|
||||
BreakPoint(std::string f, int n, bool _func) : name(f), lineNbr(n), func(_func), needsAdjusting(true) {}
|
||||
std::string name;
|
||||
int lineNbr;
|
||||
bool func;
|
||||
bool needsAdjusting;
|
||||
};
|
||||
std::vector<BreakPoint> m_breakPoints;
|
||||
|
||||
asIScriptEngine *m_engine;
|
||||
|
||||
// Registered callbacks for converting types to strings
|
||||
std::map<const asITypeInfo*, ToStringCallback> m_toStringCallbacks;
|
||||
};
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,490 @@
|
|||
#include "scriptany.h"
|
||||
#include <new>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
// We'll use the generic interface for the factories as we need the engine pointer
|
||||
static void ScriptAnyFactory_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
asIScriptEngine *engine = gen->GetEngine();
|
||||
|
||||
*(CScriptAny**)gen->GetAddressOfReturnLocation() = new CScriptAny(engine);
|
||||
}
|
||||
|
||||
static void ScriptAnyFactory2_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
asIScriptEngine *engine = gen->GetEngine();
|
||||
void *ref = (void*)gen->GetArgAddress(0);
|
||||
int refType = gen->GetArgTypeId(0);
|
||||
|
||||
*(CScriptAny**)gen->GetAddressOfReturnLocation() = new CScriptAny(ref,refType,engine);
|
||||
}
|
||||
|
||||
static CScriptAny &ScriptAnyAssignment(CScriptAny *other, CScriptAny *self)
|
||||
{
|
||||
return *self = *other;
|
||||
}
|
||||
|
||||
static void ScriptAnyAssignment_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptAny *other = (CScriptAny*)gen->GetArgObject(0);
|
||||
CScriptAny *self = (CScriptAny*)gen->GetObject();
|
||||
|
||||
*self = *other;
|
||||
|
||||
gen->SetReturnObject(self);
|
||||
}
|
||||
|
||||
static void ScriptAny_Store_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
void *ref = (void*)gen->GetArgAddress(0);
|
||||
int refTypeId = gen->GetArgTypeId(0);
|
||||
CScriptAny *self = (CScriptAny*)gen->GetObject();
|
||||
|
||||
self->Store(ref, refTypeId);
|
||||
}
|
||||
|
||||
static void ScriptAny_StoreInt_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
asINT64 *ref = (asINT64*)gen->GetArgAddress(0);
|
||||
CScriptAny *self = (CScriptAny*)gen->GetObject();
|
||||
|
||||
self->Store(*ref);
|
||||
}
|
||||
|
||||
static void ScriptAny_StoreFlt_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
double *ref = (double*)gen->GetArgAddress(0);
|
||||
CScriptAny *self = (CScriptAny*)gen->GetObject();
|
||||
|
||||
self->Store(*ref);
|
||||
}
|
||||
|
||||
static void ScriptAny_Retrieve_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
void *ref = (void*)gen->GetArgAddress(0);
|
||||
int refTypeId = gen->GetArgTypeId(0);
|
||||
CScriptAny *self = (CScriptAny*)gen->GetObject();
|
||||
|
||||
*(bool*)gen->GetAddressOfReturnLocation() = self->Retrieve(ref, refTypeId);
|
||||
}
|
||||
|
||||
static void ScriptAny_RetrieveInt_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
asINT64 *ref = (asINT64*)gen->GetArgAddress(0);
|
||||
CScriptAny *self = (CScriptAny*)gen->GetObject();
|
||||
|
||||
*(bool*)gen->GetAddressOfReturnLocation() = self->Retrieve(*ref);
|
||||
}
|
||||
|
||||
static void ScriptAny_RetrieveFlt_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
double *ref = (double*)gen->GetArgAddress(0);
|
||||
CScriptAny *self = (CScriptAny*)gen->GetObject();
|
||||
|
||||
*(bool*)gen->GetAddressOfReturnLocation() = self->Retrieve(*ref);
|
||||
}
|
||||
|
||||
static void ScriptAny_AddRef_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptAny *self = (CScriptAny*)gen->GetObject();
|
||||
self->AddRef();
|
||||
}
|
||||
|
||||
static void ScriptAny_Release_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptAny *self = (CScriptAny*)gen->GetObject();
|
||||
self->Release();
|
||||
}
|
||||
|
||||
static void ScriptAny_GetRefCount_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptAny *self = (CScriptAny*)gen->GetObject();
|
||||
*(int*)gen->GetAddressOfReturnLocation() = self->GetRefCount();
|
||||
}
|
||||
|
||||
static void ScriptAny_SetFlag_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptAny *self = (CScriptAny*)gen->GetObject();
|
||||
self->SetFlag();
|
||||
}
|
||||
|
||||
static void ScriptAny_GetFlag_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptAny *self = (CScriptAny*)gen->GetObject();
|
||||
*(bool*)gen->GetAddressOfReturnLocation() = self->GetFlag();
|
||||
}
|
||||
|
||||
static void ScriptAny_EnumReferences_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptAny *self = (CScriptAny*)gen->GetObject();
|
||||
asIScriptEngine *engine = *(asIScriptEngine**)gen->GetAddressOfArg(0);
|
||||
self->EnumReferences(engine);
|
||||
}
|
||||
|
||||
static void ScriptAny_ReleaseAllHandles_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptAny *self = (CScriptAny*)gen->GetObject();
|
||||
asIScriptEngine *engine = *(asIScriptEngine**)gen->GetAddressOfArg(0);
|
||||
self->ReleaseAllHandles(engine);
|
||||
}
|
||||
|
||||
void RegisterScriptAny(asIScriptEngine *engine)
|
||||
{
|
||||
if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
|
||||
RegisterScriptAny_Generic(engine);
|
||||
else
|
||||
RegisterScriptAny_Native(engine);
|
||||
}
|
||||
|
||||
void RegisterScriptAny_Native(asIScriptEngine *engine)
|
||||
{
|
||||
int r;
|
||||
r = engine->RegisterObjectType("any", sizeof(CScriptAny), asOBJ_REF | asOBJ_GC); assert( r >= 0 );
|
||||
|
||||
// We'll use the generic interface for the constructor as we need the engine pointer
|
||||
r = engine->RegisterObjectBehaviour("any", asBEHAVE_FACTORY, "any@ f()", asFUNCTION(ScriptAnyFactory_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("any", asBEHAVE_FACTORY, "any@ f(?&in) explicit", asFUNCTION(ScriptAnyFactory2_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("any", asBEHAVE_FACTORY, "any@ f(const int64&in) explicit", asFUNCTION(ScriptAnyFactory2_Generic), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectBehaviour("any", asBEHAVE_FACTORY, "any@ f(const double&in) explicit", asFUNCTION(ScriptAnyFactory2_Generic), asCALL_GENERIC); assert(r >= 0);
|
||||
|
||||
r = engine->RegisterObjectBehaviour("any", asBEHAVE_ADDREF, "void f()", asMETHOD(CScriptAny,AddRef), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("any", asBEHAVE_RELEASE, "void f()", asMETHOD(CScriptAny,Release), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("any", "any &opAssign(any&in)", asFUNCTION(ScriptAnyAssignment), asCALL_CDECL_OBJLAST); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("any", "void store(?&in)", asMETHODPR(CScriptAny,Store,(void*,int),void), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("any", "void store(const int64&in)", asMETHODPR(CScriptAny,Store,(asINT64&),void), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("any", "void store(const double&in)", asMETHODPR(CScriptAny,Store,(double&),void), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("any", "bool retrieve(?&out)", asMETHODPR(CScriptAny,Retrieve,(void*,int) const,bool), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("any", "bool retrieve(int64&out)", asMETHODPR(CScriptAny,Retrieve,(asINT64&) const,bool), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("any", "bool retrieve(double&out)", asMETHODPR(CScriptAny,Retrieve,(double&) const,bool), asCALL_THISCALL); assert( r >= 0 );
|
||||
|
||||
// Register GC behaviours
|
||||
r = engine->RegisterObjectBehaviour("any", asBEHAVE_GETREFCOUNT, "int f()", asMETHOD(CScriptAny,GetRefCount), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("any", asBEHAVE_SETGCFLAG, "void f()", asMETHOD(CScriptAny,SetFlag), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("any", asBEHAVE_GETGCFLAG, "bool f()", asMETHOD(CScriptAny,GetFlag), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("any", asBEHAVE_ENUMREFS, "void f(int&in)", asMETHOD(CScriptAny,EnumReferences), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("any", asBEHAVE_RELEASEREFS, "void f(int&in)", asMETHOD(CScriptAny,ReleaseAllHandles), asCALL_THISCALL); assert( r >= 0 );
|
||||
}
|
||||
|
||||
void RegisterScriptAny_Generic(asIScriptEngine *engine)
|
||||
{
|
||||
int r;
|
||||
r = engine->RegisterObjectType("any", sizeof(CScriptAny), asOBJ_REF | asOBJ_GC); assert( r >= 0 );
|
||||
|
||||
// We'll use the generic interface for the constructor as we need the engine pointer
|
||||
r = engine->RegisterObjectBehaviour("any", asBEHAVE_FACTORY, "any@ f()", asFUNCTION(ScriptAnyFactory_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("any", asBEHAVE_FACTORY, "any@ f(?&in) explicit", asFUNCTION(ScriptAnyFactory2_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("any", asBEHAVE_FACTORY, "any@ f(const int64&in) explicit", asFUNCTION(ScriptAnyFactory2_Generic), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectBehaviour("any", asBEHAVE_FACTORY, "any@ f(const double&in) explicit", asFUNCTION(ScriptAnyFactory2_Generic), asCALL_GENERIC); assert(r >= 0);
|
||||
|
||||
r = engine->RegisterObjectBehaviour("any", asBEHAVE_ADDREF, "void f()", asFUNCTION(ScriptAny_AddRef_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("any", asBEHAVE_RELEASE, "void f()", asFUNCTION(ScriptAny_Release_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("any", "any &opAssign(any&in)", asFUNCTION(ScriptAnyAssignment_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("any", "void store(?&in)", asFUNCTION(ScriptAny_Store_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("any", "void store(const int64&in)", asFUNCTION(ScriptAny_StoreInt_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("any", "void store(const double&in)", asFUNCTION(ScriptAny_StoreFlt_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("any", "bool retrieve(?&out) const", asFUNCTION(ScriptAny_Retrieve_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("any", "bool retrieve(int64&out) const", asFUNCTION(ScriptAny_RetrieveInt_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("any", "bool retrieve(double&out) const", asFUNCTION(ScriptAny_RetrieveFlt_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
|
||||
// Register GC behaviours
|
||||
r = engine->RegisterObjectBehaviour("any", asBEHAVE_GETREFCOUNT, "int f()", asFUNCTION(ScriptAny_GetRefCount_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("any", asBEHAVE_SETGCFLAG, "void f()", asFUNCTION(ScriptAny_SetFlag_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("any", asBEHAVE_GETGCFLAG, "bool f()", asFUNCTION(ScriptAny_GetFlag_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("any", asBEHAVE_ENUMREFS, "void f(int&in)", asFUNCTION(ScriptAny_EnumReferences_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("any", asBEHAVE_RELEASEREFS, "void f(int&in)", asFUNCTION(ScriptAny_ReleaseAllHandles_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
}
|
||||
|
||||
|
||||
CScriptAny &CScriptAny::operator=(const CScriptAny &other)
|
||||
{
|
||||
// Hold on to the object type reference so it isn't destroyed too early
|
||||
if( (other.value.typeId & asTYPEID_MASK_OBJECT) )
|
||||
{
|
||||
asITypeInfo *ti = engine->GetTypeInfoById(other.value.typeId);
|
||||
if( ti )
|
||||
ti->AddRef();
|
||||
}
|
||||
|
||||
FreeObject();
|
||||
|
||||
value.typeId = other.value.typeId;
|
||||
if( value.typeId & asTYPEID_OBJHANDLE )
|
||||
{
|
||||
// For handles, copy the pointer and increment the reference count
|
||||
value.valueObj = other.value.valueObj;
|
||||
engine->AddRefScriptObject(value.valueObj, engine->GetTypeInfoById(value.typeId));
|
||||
}
|
||||
else if( value.typeId & asTYPEID_MASK_OBJECT )
|
||||
{
|
||||
// Create a copy of the object
|
||||
value.valueObj = engine->CreateScriptObjectCopy(other.value.valueObj, engine->GetTypeInfoById(value.typeId));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Primitives can be copied directly
|
||||
value.valueInt = other.value.valueInt;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
int CScriptAny::CopyFrom(const CScriptAny *other)
|
||||
{
|
||||
if( other == 0 ) return asINVALID_ARG;
|
||||
|
||||
*this = *(CScriptAny*)other;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CScriptAny::CScriptAny(asIScriptEngine *engine)
|
||||
{
|
||||
this->engine = engine;
|
||||
refCount = 1;
|
||||
gcFlag = false;
|
||||
|
||||
value.typeId = 0;
|
||||
value.valueInt = 0;
|
||||
|
||||
// Notify the garbage collector of this object
|
||||
engine->NotifyGarbageCollectorOfNewObject(this, engine->GetTypeInfoByName("any"));
|
||||
}
|
||||
|
||||
CScriptAny::CScriptAny(void *ref, int refTypeId, asIScriptEngine *engine)
|
||||
{
|
||||
this->engine = engine;
|
||||
refCount = 1;
|
||||
gcFlag = false;
|
||||
|
||||
value.typeId = 0;
|
||||
value.valueInt = 0;
|
||||
|
||||
// Notify the garbage collector of this object
|
||||
engine->NotifyGarbageCollectorOfNewObject(this, engine->GetTypeInfoByName("any"));
|
||||
|
||||
Store(ref, refTypeId);
|
||||
}
|
||||
|
||||
CScriptAny::~CScriptAny()
|
||||
{
|
||||
FreeObject();
|
||||
}
|
||||
|
||||
void CScriptAny::Store(void *ref, int refTypeId)
|
||||
{
|
||||
// This method is not expected to be used for primitive types, except for bool, int64, or double
|
||||
assert( refTypeId > asTYPEID_DOUBLE || refTypeId == asTYPEID_VOID || refTypeId == asTYPEID_BOOL || refTypeId == asTYPEID_INT64 || refTypeId == asTYPEID_DOUBLE );
|
||||
|
||||
// Hold on to the object type reference so it isn't destroyed too early
|
||||
if( (refTypeId & asTYPEID_MASK_OBJECT) )
|
||||
{
|
||||
asITypeInfo *ti = engine->GetTypeInfoById(refTypeId);
|
||||
if( ti )
|
||||
ti->AddRef();
|
||||
}
|
||||
|
||||
FreeObject();
|
||||
|
||||
value.typeId = refTypeId;
|
||||
if( value.typeId & asTYPEID_OBJHANDLE )
|
||||
{
|
||||
// We're receiving a reference to the handle, so we need to dereference it
|
||||
value.valueObj = *(void**)ref;
|
||||
engine->AddRefScriptObject(value.valueObj, engine->GetTypeInfoById(value.typeId));
|
||||
}
|
||||
else if( value.typeId & asTYPEID_MASK_OBJECT )
|
||||
{
|
||||
// Create a copy of the object
|
||||
value.valueObj = engine->CreateScriptObjectCopy(ref, engine->GetTypeInfoById(value.typeId));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Primitives can be copied directly
|
||||
value.valueInt = 0;
|
||||
|
||||
// Copy the primitive value
|
||||
// We receive a pointer to the value.
|
||||
int size = engine->GetSizeOfPrimitiveType(value.typeId);
|
||||
memcpy(&value.valueInt, ref, size);
|
||||
}
|
||||
}
|
||||
|
||||
void CScriptAny::Store(double &ref)
|
||||
{
|
||||
Store(&ref, asTYPEID_DOUBLE);
|
||||
}
|
||||
|
||||
void CScriptAny::Store(asINT64 &ref)
|
||||
{
|
||||
Store(&ref, asTYPEID_INT64);
|
||||
}
|
||||
|
||||
|
||||
bool CScriptAny::Retrieve(void *ref, int refTypeId) const
|
||||
{
|
||||
// This method is not expected to be used for primitive types, except for bool, int64, or double
|
||||
assert( refTypeId > asTYPEID_DOUBLE || refTypeId == asTYPEID_BOOL || refTypeId == asTYPEID_INT64 || refTypeId == asTYPEID_DOUBLE );
|
||||
|
||||
if( refTypeId & asTYPEID_OBJHANDLE )
|
||||
{
|
||||
// Is the handle type compatible with the stored value?
|
||||
|
||||
// A handle can be retrieved if the stored type is a handle of same or compatible type
|
||||
// or if the stored type is an object that implements the interface that the handle refer to.
|
||||
if( (value.typeId & asTYPEID_MASK_OBJECT) )
|
||||
{
|
||||
// Don't allow the retrieval if the stored handle is to a const object but not the wanted handle
|
||||
if( (value.typeId & asTYPEID_HANDLETOCONST) && !(refTypeId & asTYPEID_HANDLETOCONST) )
|
||||
return false;
|
||||
|
||||
// RefCastObject will increment the refCount of the returned pointer if successful
|
||||
engine->RefCastObject(value.valueObj, engine->GetTypeInfoById(value.typeId), engine->GetTypeInfoById(refTypeId), reinterpret_cast<void**>(ref));
|
||||
if( *(asPWORD*)ref == 0 )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if( refTypeId & asTYPEID_MASK_OBJECT )
|
||||
{
|
||||
// Is the object type compatible with the stored value?
|
||||
|
||||
// Copy the object into the given reference
|
||||
if( value.typeId == refTypeId )
|
||||
{
|
||||
engine->AssignScriptObject(ref, value.valueObj, engine->GetTypeInfoById(value.typeId));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Is the primitive type compatible with the stored value?
|
||||
|
||||
if( value.typeId == refTypeId )
|
||||
{
|
||||
int size = engine->GetSizeOfPrimitiveType(refTypeId);
|
||||
memcpy(ref, &value.valueInt, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
// We know all numbers are stored as either int64 or double, since we register overloaded functions for those
|
||||
if( value.typeId == asTYPEID_INT64 && refTypeId == asTYPEID_DOUBLE )
|
||||
{
|
||||
*(double*)ref = double(value.valueInt);
|
||||
return true;
|
||||
}
|
||||
else if( value.typeId == asTYPEID_DOUBLE && refTypeId == asTYPEID_INT64 )
|
||||
{
|
||||
*(asINT64*)ref = asINT64(value.valueFlt);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CScriptAny::Retrieve(asINT64 &outValue) const
|
||||
{
|
||||
return Retrieve(&outValue, asTYPEID_INT64);
|
||||
}
|
||||
|
||||
bool CScriptAny::Retrieve(double &outValue) const
|
||||
{
|
||||
return Retrieve(&outValue, asTYPEID_DOUBLE);
|
||||
}
|
||||
|
||||
int CScriptAny::GetTypeId() const
|
||||
{
|
||||
return value.typeId;
|
||||
}
|
||||
|
||||
void CScriptAny::FreeObject()
|
||||
{
|
||||
// If it is a handle or a ref counted object, call release
|
||||
if( value.typeId & asTYPEID_MASK_OBJECT )
|
||||
{
|
||||
// Let the engine release the object
|
||||
asITypeInfo *ti = engine->GetTypeInfoById(value.typeId);
|
||||
engine->ReleaseScriptObject(value.valueObj, ti);
|
||||
|
||||
// Release the object type info
|
||||
if( ti )
|
||||
ti->Release();
|
||||
|
||||
value.valueObj = 0;
|
||||
value.typeId = 0;
|
||||
}
|
||||
|
||||
// For primitives, there's nothing to do
|
||||
}
|
||||
|
||||
|
||||
void CScriptAny::EnumReferences(asIScriptEngine *inEngine)
|
||||
{
|
||||
// If we're holding a reference, we'll notify the garbage collector of it
|
||||
if (value.valueObj && (value.typeId & asTYPEID_MASK_OBJECT))
|
||||
{
|
||||
asITypeInfo *subType = engine->GetTypeInfoById(value.typeId);
|
||||
if ((subType->GetFlags() & asOBJ_REF))
|
||||
{
|
||||
inEngine->GCEnumCallback(value.valueObj);
|
||||
}
|
||||
else if ((subType->GetFlags() & asOBJ_VALUE) && (subType->GetFlags() & asOBJ_GC))
|
||||
{
|
||||
// For value types we need to forward the enum callback
|
||||
// to the object so it can decide what to do
|
||||
engine->ForwardGCEnumReferences(value.valueObj, subType);
|
||||
}
|
||||
|
||||
// The object type itself is also garbage collected
|
||||
asITypeInfo *ti = inEngine->GetTypeInfoById(value.typeId);
|
||||
if (ti)
|
||||
inEngine->GCEnumCallback(ti);
|
||||
}
|
||||
}
|
||||
|
||||
void CScriptAny::ReleaseAllHandles(asIScriptEngine * /*engine*/)
|
||||
{
|
||||
FreeObject();
|
||||
}
|
||||
|
||||
int CScriptAny::AddRef() const
|
||||
{
|
||||
// Increase counter and clear flag set by GC
|
||||
gcFlag = false;
|
||||
return asAtomicInc(refCount);
|
||||
}
|
||||
|
||||
int CScriptAny::Release() const
|
||||
{
|
||||
// Decrease the ref counter
|
||||
gcFlag = false;
|
||||
if( asAtomicDec(refCount) == 0 )
|
||||
{
|
||||
// Delete this object as no more references to it exists
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return refCount;
|
||||
}
|
||||
|
||||
int CScriptAny::GetRefCount()
|
||||
{
|
||||
return refCount;
|
||||
}
|
||||
|
||||
void CScriptAny::SetFlag()
|
||||
{
|
||||
gcFlag = true;
|
||||
}
|
||||
|
||||
bool CScriptAny::GetFlag()
|
||||
{
|
||||
return gcFlag;
|
||||
}
|
||||
|
||||
|
||||
END_AS_NAMESPACE
|
|
@ -0,0 +1,76 @@
|
|||
#ifndef SCRIPTANY_H
|
||||
#define SCRIPTANY_H
|
||||
|
||||
#ifndef ANGELSCRIPT_H
|
||||
// Avoid having to inform include path if header is already include before
|
||||
#include <angelscript.h>
|
||||
#endif
|
||||
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
class CScriptAny
|
||||
{
|
||||
public:
|
||||
// Constructors
|
||||
CScriptAny(asIScriptEngine *engine);
|
||||
CScriptAny(void *ref, int refTypeId, asIScriptEngine *engine);
|
||||
|
||||
// Memory management
|
||||
int AddRef() const;
|
||||
int Release() const;
|
||||
|
||||
// Copy the stored value from another any object
|
||||
CScriptAny &operator=(const CScriptAny&);
|
||||
int CopyFrom(const CScriptAny *other);
|
||||
|
||||
// Store the value, either as variable type, integer number, or real number
|
||||
void Store(void *ref, int refTypeId);
|
||||
void Store(asINT64 &value);
|
||||
void Store(double &value);
|
||||
|
||||
// Retrieve the stored value, either as variable type, integer number, or real number
|
||||
bool Retrieve(void *ref, int refTypeId) const;
|
||||
bool Retrieve(asINT64 &value) const;
|
||||
bool Retrieve(double &value) const;
|
||||
|
||||
// Get the type id of the stored value
|
||||
int GetTypeId() const;
|
||||
|
||||
// GC methods
|
||||
int GetRefCount();
|
||||
void SetFlag();
|
||||
bool GetFlag();
|
||||
void EnumReferences(asIScriptEngine *engine);
|
||||
void ReleaseAllHandles(asIScriptEngine *engine);
|
||||
|
||||
protected:
|
||||
virtual ~CScriptAny();
|
||||
void FreeObject();
|
||||
|
||||
mutable int refCount;
|
||||
mutable bool gcFlag;
|
||||
asIScriptEngine *engine;
|
||||
|
||||
// The structure for holding the values
|
||||
struct valueStruct
|
||||
{
|
||||
union
|
||||
{
|
||||
asINT64 valueInt;
|
||||
double valueFlt;
|
||||
void *valueObj;
|
||||
};
|
||||
int typeId;
|
||||
};
|
||||
|
||||
valueStruct value;
|
||||
};
|
||||
|
||||
void RegisterScriptAny(asIScriptEngine *engine);
|
||||
void RegisterScriptAny_Native(asIScriptEngine *engine);
|
||||
void RegisterScriptAny_Generic(asIScriptEngine *engine);
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,142 @@
|
|||
#ifndef SCRIPTARRAY_H
|
||||
#define SCRIPTARRAY_H
|
||||
|
||||
#ifndef ANGELSCRIPT_H
|
||||
// Avoid having to inform include path if header is already include before
|
||||
#include <angelscript.h>
|
||||
#endif
|
||||
|
||||
// Sometimes it may be desired to use the same method names as used by C++ STL.
|
||||
// This may for example reduce time when converting code from script to C++ or
|
||||
// back.
|
||||
//
|
||||
// 0 = off
|
||||
// 1 = on
|
||||
#ifndef AS_USE_STLNAMES
|
||||
#define AS_USE_STLNAMES 0
|
||||
#endif
|
||||
|
||||
// Some prefer to use property accessors to get/set the length of the array
|
||||
// This option registers the accessors instead of the method length()
|
||||
#ifndef AS_USE_ACCESSORS
|
||||
#define AS_USE_ACCESSORS 0
|
||||
#endif
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
struct SArrayBuffer;
|
||||
struct SArrayCache;
|
||||
|
||||
class CScriptArray
|
||||
{
|
||||
public:
|
||||
// Set the memory functions that should be used by all CScriptArrays
|
||||
static void SetMemoryFunctions(asALLOCFUNC_t allocFunc, asFREEFUNC_t freeFunc);
|
||||
|
||||
// Factory functions
|
||||
static CScriptArray *Create(asITypeInfo *ot);
|
||||
static CScriptArray *Create(asITypeInfo *ot, asUINT length);
|
||||
static CScriptArray *Create(asITypeInfo *ot, asUINT length, void *defaultValue);
|
||||
static CScriptArray *Create(asITypeInfo *ot, void *listBuffer);
|
||||
|
||||
// Memory management
|
||||
void AddRef() const;
|
||||
void Release() const;
|
||||
|
||||
// Type information
|
||||
asITypeInfo *GetArrayObjectType() const;
|
||||
int GetArrayTypeId() const;
|
||||
int GetElementTypeId() const;
|
||||
|
||||
// Get the current size
|
||||
asUINT GetSize() const;
|
||||
|
||||
// Returns true if the array is empty
|
||||
bool IsEmpty() const;
|
||||
|
||||
// Pre-allocates memory for elements
|
||||
void Reserve(asUINT maxElements);
|
||||
|
||||
// Resize the array
|
||||
void Resize(asUINT numElements);
|
||||
|
||||
// Get a pointer to an element. Returns 0 if out of bounds
|
||||
void *At(asUINT index);
|
||||
const void *At(asUINT index) const;
|
||||
|
||||
// Set value of an element.
|
||||
// The value arg should be a pointer to the value that will be copied to the element.
|
||||
// Remember, if the array holds handles the value parameter should be the
|
||||
// address of the handle. The refCount of the object will also be incremented
|
||||
void SetValue(asUINT index, void *value);
|
||||
|
||||
// Copy the contents of one array to another (only if the types are the same)
|
||||
CScriptArray &operator=(const CScriptArray&);
|
||||
|
||||
// Compare two arrays
|
||||
bool operator==(const CScriptArray &) const;
|
||||
|
||||
// Array manipulation
|
||||
void InsertAt(asUINT index, void *value);
|
||||
void InsertAt(asUINT index, const CScriptArray &arr);
|
||||
void InsertLast(void *value);
|
||||
void RemoveAt(asUINT index);
|
||||
void RemoveLast();
|
||||
void RemoveRange(asUINT start, asUINT count);
|
||||
void SortAsc();
|
||||
void SortDesc();
|
||||
void SortAsc(asUINT startAt, asUINT count);
|
||||
void SortDesc(asUINT startAt, asUINT count);
|
||||
void Sort(asUINT startAt, asUINT count, bool asc);
|
||||
void Sort(asIScriptFunction *less, asUINT startAt, asUINT count);
|
||||
void Reverse();
|
||||
int Find(void *value) const;
|
||||
int Find(asUINT startAt, void *value) const;
|
||||
int FindByRef(void *ref) const;
|
||||
int FindByRef(asUINT startAt, void *ref) const;
|
||||
|
||||
// Return the address of internal buffer for direct manipulation of elements
|
||||
void *GetBuffer();
|
||||
|
||||
// GC methods
|
||||
int GetRefCount();
|
||||
void SetFlag();
|
||||
bool GetFlag();
|
||||
void EnumReferences(asIScriptEngine *engine);
|
||||
void ReleaseAllHandles(asIScriptEngine *engine);
|
||||
|
||||
protected:
|
||||
mutable int refCount;
|
||||
mutable bool gcFlag;
|
||||
asITypeInfo *objType;
|
||||
SArrayBuffer *buffer;
|
||||
int elementSize;
|
||||
int subTypeId;
|
||||
|
||||
// Constructors
|
||||
CScriptArray(asITypeInfo *ot, void *initBuf); // Called from script when initialized with list
|
||||
CScriptArray(asUINT length, asITypeInfo *ot);
|
||||
CScriptArray(asUINT length, void *defVal, asITypeInfo *ot);
|
||||
CScriptArray(const CScriptArray &other);
|
||||
virtual ~CScriptArray();
|
||||
|
||||
bool Less(const void *a, const void *b, bool asc);
|
||||
void *GetArrayItemPointer(int index);
|
||||
void *GetDataPointer(void *buffer);
|
||||
void Copy(void *dst, void *src);
|
||||
void Precache();
|
||||
bool CheckMaxSize(asUINT numElements);
|
||||
void Resize(int delta, asUINT at);
|
||||
void CreateBuffer(SArrayBuffer **buf, asUINT numElements);
|
||||
void DeleteBuffer(SArrayBuffer *buf);
|
||||
void CopyBuffer(SArrayBuffer *dst, SArrayBuffer *src);
|
||||
void Construct(SArrayBuffer *buf, asUINT start, asUINT end);
|
||||
void Destruct(SArrayBuffer *buf, asUINT start, asUINT end);
|
||||
bool Equals(const void *a, const void *b, asIScriptContext *ctx, SArrayCache *cache) const;
|
||||
};
|
||||
|
||||
void RegisterScriptArray(asIScriptEngine *engine, bool defaultArray);
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,216 @@
|
|||
#ifndef SCRIPTBUILDER_H
|
||||
#define SCRIPTBUILDER_H
|
||||
|
||||
//---------------------------
|
||||
// Compilation settings
|
||||
//
|
||||
|
||||
// Set this flag to turn on/off metadata processing
|
||||
// 0 = off
|
||||
// 1 = on
|
||||
#ifndef AS_PROCESS_METADATA
|
||||
#define AS_PROCESS_METADATA 1
|
||||
#endif
|
||||
|
||||
// TODO: Implement flags for turning on/off include directives and conditional programming
|
||||
|
||||
|
||||
|
||||
//---------------------------
|
||||
// Declaration
|
||||
//
|
||||
|
||||
#ifndef ANGELSCRIPT_H
|
||||
// Avoid having to inform include path if header is already include before
|
||||
#include <angelscript.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1200
|
||||
// disable the annoying warnings on MSVC 6
|
||||
#pragma warning (disable:4786)
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <string.h> // _strcmpi
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
class CScriptBuilder;
|
||||
|
||||
// This callback will be called for each #include directive encountered by the
|
||||
// builder. The callback should call the AddSectionFromFile or AddSectionFromMemory
|
||||
// to add the included section to the script. If the include cannot be resolved
|
||||
// then the function should return a negative value to abort the compilation.
|
||||
typedef int (*INCLUDECALLBACK_t)(const char *include, const char *from, CScriptBuilder *builder, void *userParam);
|
||||
|
||||
// This callback will be called for each #pragma directive encountered by the builder.
|
||||
// The application can interpret the pragmaText and decide what do to based on that.
|
||||
// If the callback returns a negative value the builder will report an error and abort the compilation.
|
||||
typedef int(*PRAGMACALLBACK_t)(const std::string &pragmaText, CScriptBuilder &builder, void *userParam);
|
||||
|
||||
// Helper class for loading and pre-processing script files to
|
||||
// support include directives and metadata declarations
|
||||
class CScriptBuilder
|
||||
{
|
||||
public:
|
||||
CScriptBuilder();
|
||||
|
||||
// Start a new module
|
||||
int StartNewModule(asIScriptEngine *engine, const char *moduleName);
|
||||
|
||||
// Load a script section from a file on disk
|
||||
// Returns 1 if the file was included
|
||||
// 0 if the file had already been included before
|
||||
// <0 on error
|
||||
int AddSectionFromFile(const char *filename);
|
||||
|
||||
// Load a script section from memory
|
||||
// Returns 1 if the section was included
|
||||
// 0 if a section with the same name had already been included before
|
||||
// <0 on error
|
||||
int AddSectionFromMemory(const char *sectionName,
|
||||
const char *scriptCode,
|
||||
unsigned int scriptLength = 0,
|
||||
int lineOffset = 0);
|
||||
|
||||
// Build the added script sections
|
||||
int BuildModule();
|
||||
|
||||
// Returns the engine
|
||||
asIScriptEngine *GetEngine();
|
||||
|
||||
// Returns the current module
|
||||
asIScriptModule *GetModule();
|
||||
|
||||
// Register the callback for resolving include directive
|
||||
void SetIncludeCallback(INCLUDECALLBACK_t callback, void *userParam);
|
||||
|
||||
// Register the callback for resolving pragma directive
|
||||
void SetPragmaCallback(PRAGMACALLBACK_t callback, void *userParam);
|
||||
|
||||
// Add a pre-processor define for conditional compilation
|
||||
void DefineWord(const char *word);
|
||||
|
||||
// Enumerate included script sections
|
||||
unsigned int GetSectionCount() const;
|
||||
std::string GetSectionName(unsigned int idx) const;
|
||||
|
||||
#if AS_PROCESS_METADATA == 1
|
||||
// Get metadata declared for classes, interfaces, and enums
|
||||
std::vector<std::string> GetMetadataForType(int typeId);
|
||||
|
||||
// Get metadata declared for functions
|
||||
std::vector<std::string> GetMetadataForFunc(asIScriptFunction *func);
|
||||
|
||||
// Get metadata declared for global variables
|
||||
std::vector<std::string> GetMetadataForVar(int varIdx);
|
||||
|
||||
// Get metadata declared for class variables
|
||||
std::vector<std::string> GetMetadataForTypeProperty(int typeId, int varIdx);
|
||||
|
||||
// Get metadata declared for class methods
|
||||
std::vector<std::string> GetMetadataForTypeMethod(int typeId, asIScriptFunction *method);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void ClearAll();
|
||||
int Build();
|
||||
int ProcessScriptSection(const char *script, unsigned int length, const char *sectionname, int lineOffset);
|
||||
int LoadScriptSection(const char *filename);
|
||||
bool IncludeIfNotAlreadyIncluded(const char *filename);
|
||||
|
||||
int SkipStatement(int pos);
|
||||
|
||||
int ExcludeCode(int start);
|
||||
void OverwriteCode(int start, int len);
|
||||
|
||||
asIScriptEngine *engine;
|
||||
asIScriptModule *module;
|
||||
std::string modifiedScript;
|
||||
|
||||
INCLUDECALLBACK_t includeCallback;
|
||||
void *includeParam;
|
||||
|
||||
PRAGMACALLBACK_t pragmaCallback;
|
||||
void *pragmaParam;
|
||||
|
||||
#if AS_PROCESS_METADATA == 1
|
||||
int ExtractMetadata(int pos, std::vector<std::string> &outMetadata);
|
||||
int ExtractDeclaration(int pos, std::string &outName, std::string &outDeclaration, int &outType);
|
||||
|
||||
enum METADATATYPE
|
||||
{
|
||||
MDT_TYPE = 1,
|
||||
MDT_FUNC = 2,
|
||||
MDT_VAR = 3,
|
||||
MDT_VIRTPROP = 4,
|
||||
MDT_FUNC_OR_VAR = 5
|
||||
};
|
||||
|
||||
// Temporary structure for storing metadata and declaration
|
||||
struct SMetadataDecl
|
||||
{
|
||||
SMetadataDecl(std::vector<std::string> m, std::string n, std::string d, int t, std::string c, std::string ns) : metadata(m), name(n), declaration(d), type(t), parentClass(c), nameSpace(ns) {}
|
||||
std::vector<std::string> metadata;
|
||||
std::string name;
|
||||
std::string declaration;
|
||||
int type;
|
||||
std::string parentClass;
|
||||
std::string nameSpace;
|
||||
};
|
||||
std::vector<SMetadataDecl> foundDeclarations;
|
||||
std::string currentClass;
|
||||
std::string currentNamespace;
|
||||
|
||||
// Storage of metadata for global declarations
|
||||
std::map<int, std::vector<std::string> > typeMetadataMap;
|
||||
std::map<int, std::vector<std::string> > funcMetadataMap;
|
||||
std::map<int, std::vector<std::string> > varMetadataMap;
|
||||
|
||||
// Storage of metadata for class member declarations
|
||||
struct SClassMetadata
|
||||
{
|
||||
SClassMetadata(const std::string& aName) : className(aName) {}
|
||||
std::string className;
|
||||
std::map<int, std::vector<std::string> > funcMetadataMap;
|
||||
std::map<int, std::vector<std::string> > varMetadataMap;
|
||||
};
|
||||
std::map<int, SClassMetadata> classMetadataMap;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
// On Windows the filenames are case insensitive so the comparisons to
|
||||
// avoid duplicate includes must also be case insensitive. True case insensitive
|
||||
// is not easy as it must be language aware, but a simple implementation such
|
||||
// as strcmpi should suffice in almost all cases.
|
||||
//
|
||||
// ref: http://www.gotw.ca/gotw/029.htm
|
||||
// ref: https://msdn.microsoft.com/en-us/library/windows/desktop/dd317761(v=vs.85).aspx
|
||||
// ref: http://site.icu-project.org/
|
||||
|
||||
// TODO: Strings by default are treated as UTF8 encoded. If the application choses to
|
||||
// use a different encoding, the comparison algorithm should be adjusted as well
|
||||
|
||||
struct ci_less
|
||||
{
|
||||
bool operator()(const std::string &a, const std::string &b) const
|
||||
{
|
||||
return _stricmp(a.c_str(), b.c_str()) < 0;
|
||||
}
|
||||
};
|
||||
std::set<std::string, ci_less> includedScripts;
|
||||
#else
|
||||
std::set<std::string> includedScripts;
|
||||
#endif
|
||||
|
||||
std::set<std::string> definedWords;
|
||||
};
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,240 @@
|
|||
#ifndef SCRIPTDICTIONARY_H
|
||||
#define SCRIPTDICTIONARY_H
|
||||
|
||||
// The dictionary class relies on the script string object, thus the script
|
||||
// string type must be registered with the engine before registering the
|
||||
// dictionary type
|
||||
|
||||
#ifndef ANGELSCRIPT_H
|
||||
// Avoid having to inform include path if header is already include before
|
||||
#include <angelscript.h>
|
||||
#endif
|
||||
|
||||
// By default the CScriptDictionary use the std::string for the keys.
|
||||
// If the application uses a custom string type, then this typedef
|
||||
// can be changed accordingly.
|
||||
#include <string>
|
||||
typedef std::string dictKey_t;
|
||||
|
||||
// Forward declare CScriptDictValue so we can typedef the internal map type
|
||||
BEGIN_AS_NAMESPACE
|
||||
class CScriptDictValue;
|
||||
END_AS_NAMESPACE
|
||||
|
||||
// C++11 introduced the std::unordered_map which is a hash map which is
|
||||
// is generally more performatic for lookups than the std::map which is a
|
||||
// binary tree.
|
||||
// TODO: memory: The map allocator should use the asAllocMem and asFreeMem
|
||||
#if AS_CAN_USE_CPP11
|
||||
#include <unordered_map>
|
||||
typedef std::unordered_map<dictKey_t, AS_NAMESPACE_QUALIFIER CScriptDictValue> dictMap_t;
|
||||
#else
|
||||
#include <map>
|
||||
typedef std::map<dictKey_t, AS_NAMESPACE_QUALIFIER CScriptDictValue> dictMap_t;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// Turn off annoying warnings about truncated symbol names
|
||||
#pragma warning (disable:4786)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
// Sometimes it may be desired to use the same method names as used by C++ STL.
|
||||
// This may for example reduce time when converting code from script to C++ or
|
||||
// back.
|
||||
//
|
||||
// 0 = off
|
||||
// 1 = on
|
||||
|
||||
#ifndef AS_USE_STLNAMES
|
||||
#define AS_USE_STLNAMES 0
|
||||
#endif
|
||||
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
class CScriptArray;
|
||||
class CScriptDictionary;
|
||||
|
||||
class CScriptDictValue
|
||||
{
|
||||
public:
|
||||
// This class must not be declared as local variable in C++, because it needs
|
||||
// to receive the script engine pointer in all operations. The engine pointer
|
||||
// is not kept as member in order to keep the size down
|
||||
CScriptDictValue();
|
||||
CScriptDictValue(asIScriptEngine *engine, void *value, int typeId);
|
||||
|
||||
// Destructor must not be called without first calling FreeValue, otherwise a memory leak will occur
|
||||
~CScriptDictValue();
|
||||
|
||||
// Replace the stored value
|
||||
void Set(asIScriptEngine *engine, void *value, int typeId);
|
||||
void Set(asIScriptEngine *engine, const asINT64 &value);
|
||||
void Set(asIScriptEngine *engine, const double &value);
|
||||
void Set(asIScriptEngine *engine, CScriptDictValue &value);
|
||||
|
||||
// Gets the stored value. Returns false if the value isn't compatible with the informed typeId
|
||||
bool Get(asIScriptEngine *engine, void *value, int typeId) const;
|
||||
bool Get(asIScriptEngine *engine, asINT64 &value) const;
|
||||
bool Get(asIScriptEngine *engine, double &value) const;
|
||||
|
||||
// Returns the address of the stored value for inspection
|
||||
const void *GetAddressOfValue() const;
|
||||
|
||||
// Returns the type id of the stored value
|
||||
int GetTypeId() const;
|
||||
|
||||
// Free the stored value
|
||||
void FreeValue(asIScriptEngine *engine);
|
||||
|
||||
// GC callback
|
||||
void EnumReferences(asIScriptEngine *engine);
|
||||
|
||||
protected:
|
||||
friend class CScriptDictionary;
|
||||
|
||||
union
|
||||
{
|
||||
asINT64 m_valueInt;
|
||||
double m_valueFlt;
|
||||
void *m_valueObj;
|
||||
};
|
||||
int m_typeId;
|
||||
};
|
||||
|
||||
class CScriptDictionary
|
||||
{
|
||||
public:
|
||||
// Factory functions
|
||||
static CScriptDictionary *Create(asIScriptEngine *engine);
|
||||
|
||||
// Called from the script to instantiate a dictionary from an initialization list
|
||||
static CScriptDictionary *Create(asBYTE *buffer);
|
||||
|
||||
// Reference counting
|
||||
void AddRef() const;
|
||||
void Release() const;
|
||||
|
||||
// Reassign the dictionary
|
||||
CScriptDictionary &operator =(const CScriptDictionary &other);
|
||||
|
||||
// Sets a key/value pair
|
||||
void Set(const dictKey_t &key, void *value, int typeId);
|
||||
void Set(const dictKey_t &key, const asINT64 &value);
|
||||
void Set(const dictKey_t &key, const double &value);
|
||||
|
||||
// Gets the stored value. Returns false if the value isn't compatible with the informed typeId
|
||||
bool Get(const dictKey_t &key, void *value, int typeId) const;
|
||||
bool Get(const dictKey_t &key, asINT64 &value) const;
|
||||
bool Get(const dictKey_t &key, double &value) const;
|
||||
|
||||
// Index accessors. If the dictionary is not const it inserts the value if it doesn't already exist
|
||||
// If the dictionary is const then a script exception is set if it doesn't exist and a null pointer is returned
|
||||
CScriptDictValue *operator[](const dictKey_t &key);
|
||||
const CScriptDictValue *operator[](const dictKey_t &key) const;
|
||||
|
||||
// Returns the type id of the stored value, or negative if it doesn't exist
|
||||
int GetTypeId(const dictKey_t &key) const;
|
||||
|
||||
// Returns true if the key is set
|
||||
bool Exists(const dictKey_t &key) const;
|
||||
|
||||
// Returns true if there are no key/value pairs in the dictionary
|
||||
bool IsEmpty() const;
|
||||
|
||||
// Returns the number of key/value pairs in the dictionary
|
||||
asUINT GetSize() const;
|
||||
|
||||
// Deletes the key
|
||||
bool Delete(const dictKey_t &key);
|
||||
|
||||
// Deletes all keys
|
||||
void DeleteAll();
|
||||
|
||||
// Get an array of all keys
|
||||
CScriptArray *GetKeys() const;
|
||||
|
||||
// STL style iterator
|
||||
class CIterator
|
||||
{
|
||||
public:
|
||||
void operator++(); // Pre-increment
|
||||
void operator++(int); // Post-increment
|
||||
|
||||
// This is needed to support C++11 range-for
|
||||
CIterator &operator*();
|
||||
|
||||
bool operator==(const CIterator &other) const;
|
||||
bool operator!=(const CIterator &other) const;
|
||||
|
||||
// Accessors
|
||||
const dictKey_t &GetKey() const;
|
||||
int GetTypeId() const;
|
||||
bool GetValue(asINT64 &value) const;
|
||||
bool GetValue(double &value) const;
|
||||
bool GetValue(void *value, int typeId) const;
|
||||
const void * GetAddressOfValue() const;
|
||||
|
||||
protected:
|
||||
friend class CScriptDictionary;
|
||||
|
||||
CIterator();
|
||||
CIterator(const CScriptDictionary &dict,
|
||||
dictMap_t::const_iterator it);
|
||||
|
||||
CIterator &operator=(const CIterator &) {return *this;} // Not used
|
||||
|
||||
dictMap_t::const_iterator m_it;
|
||||
const CScriptDictionary &m_dict;
|
||||
};
|
||||
|
||||
CIterator begin() const;
|
||||
CIterator end() const;
|
||||
CIterator find(const dictKey_t &key) const;
|
||||
|
||||
// Garbage collections behaviours
|
||||
int GetRefCount();
|
||||
void SetGCFlag();
|
||||
bool GetGCFlag();
|
||||
void EnumReferences(asIScriptEngine *engine);
|
||||
void ReleaseAllReferences(asIScriptEngine *engine);
|
||||
|
||||
protected:
|
||||
// Since the dictionary uses the asAllocMem and asFreeMem functions to allocate memory
|
||||
// the constructors are made protected so that the application cannot allocate it
|
||||
// manually in a different way
|
||||
CScriptDictionary(asIScriptEngine *engine);
|
||||
CScriptDictionary(asBYTE *buffer);
|
||||
|
||||
// We don't want anyone to call the destructor directly, it should be called through the Release method
|
||||
virtual ~CScriptDictionary();
|
||||
|
||||
// Cache the object types needed
|
||||
void Init(asIScriptEngine *engine);
|
||||
|
||||
// Our properties
|
||||
asIScriptEngine *engine;
|
||||
mutable int refCount;
|
||||
mutable bool gcFlag;
|
||||
dictMap_t dict;
|
||||
};
|
||||
|
||||
// This function will determine the configuration of the engine
|
||||
// and use one of the two functions below to register the dictionary object
|
||||
void RegisterScriptDictionary(asIScriptEngine *engine);
|
||||
|
||||
// Call this function to register the math functions
|
||||
// using native calling conventions
|
||||
void RegisterScriptDictionary_Native(asIScriptEngine *engine);
|
||||
|
||||
// Use this one instead if native calling conventions
|
||||
// are not supported on the target platform
|
||||
void RegisterScriptDictionary_Generic(asIScriptEngine *engine);
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,660 @@
|
|||
#include "scriptfile.h"
|
||||
#include <new>
|
||||
#include <assert.h>
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
#include <windows.h> // For GetModuleFileName
|
||||
#ifdef GetObject
|
||||
#undef GetObject
|
||||
#endif
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
CScriptFile *ScriptFile_Factory()
|
||||
{
|
||||
return new CScriptFile();
|
||||
}
|
||||
|
||||
void ScriptFile_Factory_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
*(CScriptFile**)gen->GetAddressOfReturnLocation() = ScriptFile_Factory();
|
||||
}
|
||||
|
||||
void ScriptFile_AddRef_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptFile *file = (CScriptFile*)gen->GetObject();
|
||||
file->AddRef();
|
||||
}
|
||||
|
||||
void ScriptFile_Release_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptFile *file = (CScriptFile*)gen->GetObject();
|
||||
file->Release();
|
||||
}
|
||||
|
||||
void ScriptFile_Open_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptFile *file = (CScriptFile*)gen->GetObject();
|
||||
std::string *f = (std::string*)gen->GetArgAddress(0);
|
||||
std::string *m = (std::string*)gen->GetArgAddress(1);
|
||||
int r = file->Open(*f, *m);
|
||||
gen->SetReturnDWord(r);
|
||||
}
|
||||
|
||||
void ScriptFile_Close_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptFile *file = (CScriptFile*)gen->GetObject();
|
||||
int r = file->Close();
|
||||
gen->SetReturnDWord(r);
|
||||
}
|
||||
|
||||
void ScriptFile_GetSize_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptFile *file = (CScriptFile*)gen->GetObject();
|
||||
int r = file->GetSize();
|
||||
gen->SetReturnDWord(r);
|
||||
}
|
||||
|
||||
void ScriptFile_ReadString_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptFile *file = (CScriptFile*)gen->GetObject();
|
||||
int len = gen->GetArgDWord(0);
|
||||
string str = file->ReadString(len);
|
||||
gen->SetReturnObject(&str);
|
||||
}
|
||||
|
||||
void ScriptFile_ReadLine_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptFile *file = (CScriptFile*)gen->GetObject();
|
||||
std::string str = file->ReadLine();
|
||||
gen->SetReturnObject(&str);
|
||||
}
|
||||
|
||||
void ScriptFile_ReadInt_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptFile *file = (CScriptFile*)gen->GetObject();
|
||||
asUINT bytes = *(asUINT*)gen->GetAddressOfArg(0);
|
||||
*(asINT64*)gen->GetAddressOfReturnLocation() = file->ReadInt(bytes);
|
||||
}
|
||||
|
||||
void ScriptFile_ReadUInt_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptFile *file = (CScriptFile*)gen->GetObject();
|
||||
asUINT bytes = *(asUINT*)gen->GetAddressOfArg(0);
|
||||
*(asQWORD*)gen->GetAddressOfReturnLocation() = file->ReadUInt(bytes);
|
||||
}
|
||||
|
||||
void ScriptFile_ReadFloat_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptFile *file = (CScriptFile*)gen->GetObject();
|
||||
*(float*)gen->GetAddressOfReturnLocation() = file->ReadFloat();
|
||||
}
|
||||
|
||||
void ScriptFile_ReadDouble_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptFile *file = (CScriptFile*)gen->GetObject();
|
||||
*(double*)gen->GetAddressOfReturnLocation() = file->ReadDouble();
|
||||
}
|
||||
|
||||
void ScriptFile_WriteString_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptFile *file = (CScriptFile*)gen->GetObject();
|
||||
std::string *str = (std::string*)gen->GetArgAddress(0);
|
||||
gen->SetReturnDWord(file->WriteString(*str));
|
||||
}
|
||||
|
||||
void ScriptFile_WriteInt_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptFile *file = (CScriptFile*)gen->GetObject();
|
||||
asINT64 val = *(asINT64*)gen->GetAddressOfArg(0);
|
||||
asUINT bytes = *(asUINT*)gen->GetAddressOfArg(1);
|
||||
*(int*)gen->GetAddressOfReturnLocation() = file->WriteInt(val, bytes);
|
||||
}
|
||||
|
||||
void ScriptFile_WriteUInt_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptFile *file = (CScriptFile*)gen->GetObject();
|
||||
asQWORD val = *(asQWORD*)gen->GetAddressOfArg(0);
|
||||
asUINT bytes = *(asUINT*)gen->GetAddressOfArg(1);
|
||||
*(int*)gen->GetAddressOfReturnLocation() = file->WriteUInt(val, bytes);
|
||||
}
|
||||
|
||||
void ScriptFile_WriteFloat_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptFile *file = (CScriptFile*)gen->GetObject();
|
||||
float val = *(float*)gen->GetAddressOfArg(0);
|
||||
*(int*)gen->GetAddressOfReturnLocation() = file->WriteFloat(val);
|
||||
}
|
||||
|
||||
void ScriptFile_WriteDouble_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptFile *file = (CScriptFile*)gen->GetObject();
|
||||
double val = *(double*)gen->GetAddressOfArg(0);
|
||||
*(int*)gen->GetAddressOfReturnLocation() = file->WriteDouble(val);
|
||||
}
|
||||
|
||||
void ScriptFile_IsEOF_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptFile *file = (CScriptFile*)gen->GetObject();
|
||||
bool r = file->IsEOF();
|
||||
gen->SetReturnByte(r);
|
||||
}
|
||||
|
||||
void ScriptFile_GetPos_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptFile *file = (CScriptFile*)gen->GetObject();
|
||||
gen->SetReturnDWord(file->GetPos());
|
||||
}
|
||||
|
||||
void ScriptFile_SetPos_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptFile *file = (CScriptFile*)gen->GetObject();
|
||||
int pos = (int)gen->GetArgDWord(0);
|
||||
gen->SetReturnDWord(file->SetPos(pos));
|
||||
}
|
||||
|
||||
void ScriptFile_MovePos_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptFile *file = (CScriptFile*)gen->GetObject();
|
||||
int delta = (int)gen->GetArgDWord(0);
|
||||
gen->SetReturnDWord(file->MovePos(delta));
|
||||
}
|
||||
|
||||
void RegisterScriptFile_Native(asIScriptEngine *engine)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = engine->RegisterObjectType("file", 0, asOBJ_REF); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("file", asBEHAVE_FACTORY, "file @f()", asFUNCTION(ScriptFile_Factory), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("file", asBEHAVE_ADDREF, "void f()", asMETHOD(CScriptFile,AddRef), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("file", asBEHAVE_RELEASE, "void f()", asMETHOD(CScriptFile,Release), asCALL_THISCALL); assert( r >= 0 );
|
||||
|
||||
r = engine->RegisterObjectMethod("file", "int open(const string &in, const string &in)", asMETHOD(CScriptFile,Open), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "int close()", asMETHOD(CScriptFile,Close), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "int getSize() const", asMETHOD(CScriptFile,GetSize), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "bool isEndOfFile() const", asMETHOD(CScriptFile,IsEOF), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "string readString(uint)", asMETHOD(CScriptFile,ReadString), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "string readLine()", asMETHOD(CScriptFile,ReadLine), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "int64 readInt(uint)", asMETHOD(CScriptFile,ReadInt), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "uint64 readUInt(uint)", asMETHOD(CScriptFile,ReadUInt), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "float readFloat()", asMETHOD(CScriptFile,ReadFloat), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "double readDouble()", asMETHOD(CScriptFile,ReadDouble), asCALL_THISCALL); assert( r >= 0 );
|
||||
#if AS_WRITE_OPS == 1
|
||||
r = engine->RegisterObjectMethod("file", "int writeString(const string &in)", asMETHOD(CScriptFile,WriteString), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "int writeInt(int64, uint)", asMETHOD(CScriptFile,WriteInt), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "int writeUInt(uint64, uint)", asMETHOD(CScriptFile,WriteUInt), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "int writeFloat(float)", asMETHOD(CScriptFile,WriteFloat), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "int writeDouble(double)", asMETHOD(CScriptFile,WriteDouble), asCALL_THISCALL); assert( r >= 0 );
|
||||
#endif
|
||||
r = engine->RegisterObjectMethod("file", "int getPos() const", asMETHOD(CScriptFile,GetPos), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "int setPos(int)", asMETHOD(CScriptFile,SetPos), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "int movePos(int)", asMETHOD(CScriptFile,MovePos), asCALL_THISCALL); assert( r >= 0 );
|
||||
|
||||
r = engine->RegisterObjectProperty("file", "bool mostSignificantByteFirst", asOFFSET(CScriptFile, mostSignificantByteFirst)); assert( r >= 0 );
|
||||
}
|
||||
|
||||
void RegisterScriptFile_Generic(asIScriptEngine *engine)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = engine->RegisterObjectType("file", 0, asOBJ_REF); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("file", asBEHAVE_FACTORY, "file @f()", asFUNCTION(ScriptFile_Factory_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("file", asBEHAVE_ADDREF, "void f()", asFUNCTION(ScriptFile_AddRef_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("file", asBEHAVE_RELEASE, "void f()", asFUNCTION(ScriptFile_Release_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
|
||||
r = engine->RegisterObjectMethod("file", "int open(const string &in, const string &in)", asFUNCTION(ScriptFile_Open_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "int close()", asFUNCTION(ScriptFile_Close_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "int getSize() const", asFUNCTION(ScriptFile_GetSize_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "bool isEndOfFile() const", asFUNCTION(ScriptFile_IsEOF_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "string readString(uint)", asFUNCTION(ScriptFile_ReadString_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "string readLine()", asFUNCTION(ScriptFile_ReadLine_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "int64 readInt(uint)", asFUNCTION(ScriptFile_ReadInt_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "uint64 readUInt(uint)", asFUNCTION(ScriptFile_ReadUInt_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "float readFloat()", asFUNCTION(ScriptFile_ReadFloat_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "double readDouble()", asFUNCTION(ScriptFile_ReadDouble_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
#if AS_WRITE_OPS == 1
|
||||
r = engine->RegisterObjectMethod("file", "int writeString(const string &in)", asFUNCTION(ScriptFile_WriteString_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "int writeInt(int64, uint)", asFUNCTION(ScriptFile_WriteInt_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "int writeUInt(uint64, uint)", asFUNCTION(ScriptFile_WriteUInt_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "int writeFloat(float)", asFUNCTION(ScriptFile_WriteFloat_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "int writeDouble(double)", asFUNCTION(ScriptFile_WriteDouble_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
#endif
|
||||
r = engine->RegisterObjectMethod("file", "int getPos() const", asFUNCTION(ScriptFile_GetPos_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "int setPos(int)", asFUNCTION(ScriptFile_SetPos_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("file", "int movePos(int)", asFUNCTION(ScriptFile_MovePos_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
|
||||
r = engine->RegisterObjectProperty("file", "bool mostSignificantByteFirst", asOFFSET(CScriptFile, mostSignificantByteFirst)); assert( r >= 0 );
|
||||
}
|
||||
|
||||
void RegisterScriptFile(asIScriptEngine *engine)
|
||||
{
|
||||
if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
|
||||
RegisterScriptFile_Generic(engine);
|
||||
else
|
||||
RegisterScriptFile_Native(engine);
|
||||
}
|
||||
|
||||
CScriptFile::CScriptFile()
|
||||
{
|
||||
refCount = 1;
|
||||
file = 0;
|
||||
mostSignificantByteFirst = false;
|
||||
}
|
||||
|
||||
CScriptFile::~CScriptFile()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
void CScriptFile::AddRef() const
|
||||
{
|
||||
asAtomicInc(refCount);
|
||||
}
|
||||
|
||||
void CScriptFile::Release() const
|
||||
{
|
||||
if( asAtomicDec(refCount) == 0 )
|
||||
delete this;
|
||||
}
|
||||
|
||||
int CScriptFile::Open(const std::string &filename, const std::string &mode)
|
||||
{
|
||||
// Close the previously opened file handle
|
||||
if( file )
|
||||
Close();
|
||||
|
||||
std::string myFilename = filename;
|
||||
|
||||
// Validate the mode
|
||||
string m;
|
||||
#if AS_WRITE_OPS == 1
|
||||
if( mode != "r" && mode != "w" && mode != "a" )
|
||||
#else
|
||||
if( mode != "r" )
|
||||
#endif
|
||||
return -1;
|
||||
else
|
||||
m = mode;
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
// no relative pathing on CE
|
||||
char buf[MAX_PATH];
|
||||
static TCHAR apppath[MAX_PATH] = TEXT("");
|
||||
if (!apppath[0])
|
||||
{
|
||||
GetModuleFileName(NULL, apppath, MAX_PATH);
|
||||
|
||||
int appLen = _tcslen(apppath);
|
||||
while (appLen > 1)
|
||||
{
|
||||
if (apppath[appLen-1] == TEXT('\\'))
|
||||
break;
|
||||
appLen--;
|
||||
}
|
||||
|
||||
// Terminate the string after the trailing backslash
|
||||
apppath[appLen] = TEXT('\0');
|
||||
}
|
||||
#ifdef _UNICODE
|
||||
wcstombs(buf, apppath, wcslen(apppath)+1);
|
||||
#else
|
||||
memcpy(buf, apppath, strlen(apppath));
|
||||
#endif
|
||||
myFilename = buf + myFilename;
|
||||
#endif
|
||||
|
||||
|
||||
// By default windows translates "\r\n" to "\n", but we want to read the file as-is.
|
||||
m += "b";
|
||||
|
||||
// Open the file
|
||||
#if _MSC_VER >= 1400 && !defined(__S3E__)
|
||||
// MSVC 8.0 / 2005 introduced new functions
|
||||
// Marmalade doesn't use these, even though it uses the MSVC compiler
|
||||
fopen_s(&file, myFilename.c_str(), m.c_str());
|
||||
#else
|
||||
file = fopen(myFilename.c_str(), m.c_str());
|
||||
#endif
|
||||
if( file == 0 )
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CScriptFile::Close()
|
||||
{
|
||||
if( file == 0 )
|
||||
return -1;
|
||||
|
||||
fclose(file);
|
||||
file = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CScriptFile::GetSize() const
|
||||
{
|
||||
if( file == 0 )
|
||||
return -1;
|
||||
|
||||
int pos = ftell(file);
|
||||
fseek(file, 0, SEEK_END);
|
||||
int size = ftell(file);
|
||||
fseek(file, pos, SEEK_SET);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int CScriptFile::GetPos() const
|
||||
{
|
||||
if( file == 0 )
|
||||
return -1;
|
||||
|
||||
return ftell(file);
|
||||
}
|
||||
|
||||
int CScriptFile::SetPos(int pos)
|
||||
{
|
||||
if( file == 0 )
|
||||
return -1;
|
||||
|
||||
int r = fseek(file, pos, SEEK_SET);
|
||||
|
||||
// Return -1 on error
|
||||
return r ? -1 : 0;
|
||||
}
|
||||
|
||||
int CScriptFile::MovePos(int delta)
|
||||
{
|
||||
if( file == 0 )
|
||||
return -1;
|
||||
|
||||
int r = fseek(file, delta, SEEK_CUR);
|
||||
|
||||
// Return -1 on error
|
||||
return r ? -1 : 0;
|
||||
}
|
||||
|
||||
string CScriptFile::ReadString(unsigned int length)
|
||||
{
|
||||
if( file == 0 )
|
||||
return "";
|
||||
|
||||
// Read the string
|
||||
string str;
|
||||
str.resize(length);
|
||||
int size = (int)fread(&str[0], 1, length, file);
|
||||
str.resize(size);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
string CScriptFile::ReadLine()
|
||||
{
|
||||
if( file == 0 )
|
||||
return "";
|
||||
|
||||
// Read until the first new-line character
|
||||
string str;
|
||||
char buf[256];
|
||||
|
||||
do
|
||||
{
|
||||
// Get the current position so we can determine how many characters were read
|
||||
int start = ftell(file);
|
||||
|
||||
// Set the last byte to something different that 0, so that we can check if the buffer was filled up
|
||||
buf[255] = 1;
|
||||
|
||||
// Read the line (or first 255 characters, which ever comes first)
|
||||
char *r = fgets(buf, 256, file);
|
||||
if( r == 0 ) break;
|
||||
|
||||
// Get the position after the read
|
||||
int end = ftell(file);
|
||||
|
||||
// Add the read characters to the output buffer
|
||||
str.append(buf, end-start);
|
||||
}
|
||||
while( !feof(file) && buf[255] == 0 && buf[254] != '\n' );
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
asINT64 CScriptFile::ReadInt(asUINT bytes)
|
||||
{
|
||||
if( file == 0 )
|
||||
return 0;
|
||||
|
||||
if( bytes > 8 ) bytes = 8;
|
||||
if( bytes == 0 ) return 0;
|
||||
|
||||
unsigned char buf[8];
|
||||
size_t r = fread(buf, bytes, 1, file);
|
||||
if( r == 0 ) return 0;
|
||||
|
||||
asINT64 val = 0;
|
||||
if( mostSignificantByteFirst )
|
||||
{
|
||||
unsigned int n = 0;
|
||||
for( ; n < bytes; n++ )
|
||||
val |= asQWORD(buf[n]) << ((bytes-n-1)*8);
|
||||
|
||||
// Check the most significant byte to determine if the rest
|
||||
// of the qword must be filled to give a negative value
|
||||
if( buf[0] & 0x80 )
|
||||
for( ; n < 8; n++ )
|
||||
val |= asQWORD(0xFF) << (n*8);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int n = 0;
|
||||
for( ; n < bytes; n++ )
|
||||
val |= asQWORD(buf[n]) << (n*8);
|
||||
|
||||
// Check the most significant byte to determine if the rest
|
||||
// of the qword must be filled to give a negative value
|
||||
if( buf[bytes-1] & 0x80 )
|
||||
for( ; n < 8; n++ )
|
||||
val |= asQWORD(0xFF) << (n*8);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
asQWORD CScriptFile::ReadUInt(asUINT bytes)
|
||||
{
|
||||
if( file == 0 )
|
||||
return 0;
|
||||
|
||||
if( bytes > 8 ) bytes = 8;
|
||||
if( bytes == 0 ) return 0;
|
||||
|
||||
unsigned char buf[8];
|
||||
size_t r = fread(buf, bytes, 1, file);
|
||||
if( r == 0 ) return 0;
|
||||
|
||||
asQWORD val = 0;
|
||||
if( mostSignificantByteFirst )
|
||||
{
|
||||
unsigned int n = 0;
|
||||
for( ; n < bytes; n++ )
|
||||
val |= asQWORD(buf[n]) << ((bytes-n-1)*8);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int n = 0;
|
||||
for( ; n < bytes; n++ )
|
||||
val |= asQWORD(buf[n]) << (n*8);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
float CScriptFile::ReadFloat()
|
||||
{
|
||||
if( file == 0 )
|
||||
return 0;
|
||||
|
||||
unsigned char buf[4];
|
||||
size_t r = fread(buf, 4, 1, file);
|
||||
if( r == 0 ) return 0;
|
||||
|
||||
asUINT val = 0;
|
||||
if( mostSignificantByteFirst )
|
||||
{
|
||||
unsigned int n = 0;
|
||||
for( ; n < 4; n++ )
|
||||
val |= asUINT(buf[n]) << ((3-n)*8);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int n = 0;
|
||||
for( ; n < 4; n++ )
|
||||
val |= asUINT(buf[n]) << (n*8);
|
||||
}
|
||||
|
||||
return *reinterpret_cast<float*>(&val);
|
||||
}
|
||||
|
||||
double CScriptFile::ReadDouble()
|
||||
{
|
||||
if( file == 0 )
|
||||
return 0;
|
||||
|
||||
unsigned char buf[8];
|
||||
size_t r = fread(buf, 8, 1, file);
|
||||
if( r == 0 ) return 0;
|
||||
|
||||
asQWORD val = 0;
|
||||
if( mostSignificantByteFirst )
|
||||
{
|
||||
unsigned int n = 0;
|
||||
for( ; n < 8; n++ )
|
||||
val |= asQWORD(buf[n]) << ((7-n)*8);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int n = 0;
|
||||
for( ; n < 8; n++ )
|
||||
val |= asQWORD(buf[n]) << (n*8);
|
||||
}
|
||||
|
||||
return *reinterpret_cast<double*>(&val);
|
||||
}
|
||||
|
||||
bool CScriptFile::IsEOF() const
|
||||
{
|
||||
if( file == 0 )
|
||||
return true;
|
||||
|
||||
return feof(file) ? true : false;
|
||||
}
|
||||
|
||||
#if AS_WRITE_OPS == 1
|
||||
int CScriptFile::WriteString(const std::string &str)
|
||||
{
|
||||
if( file == 0 )
|
||||
return -1;
|
||||
|
||||
// Write the entire string
|
||||
size_t r = fwrite(&str[0], 1, str.length(), file);
|
||||
|
||||
return int(r);
|
||||
}
|
||||
|
||||
int CScriptFile::WriteInt(asINT64 val, asUINT bytes)
|
||||
{
|
||||
if( file == 0 )
|
||||
return 0;
|
||||
|
||||
unsigned char buf[8];
|
||||
if( mostSignificantByteFirst )
|
||||
{
|
||||
for( unsigned int n = 0; n < bytes; n++ )
|
||||
buf[n] = (val >> ((bytes-n-1)*8)) & 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( unsigned int n = 0; n < bytes; n++ )
|
||||
buf[n] = (val >> (n*8)) & 0xFF;
|
||||
}
|
||||
|
||||
size_t r = fwrite(&buf, bytes, 1, file);
|
||||
return int(r);
|
||||
}
|
||||
|
||||
int CScriptFile::WriteUInt(asQWORD val, asUINT bytes)
|
||||
{
|
||||
if( file == 0 )
|
||||
return 0;
|
||||
|
||||
unsigned char buf[8];
|
||||
if( mostSignificantByteFirst )
|
||||
{
|
||||
for( unsigned int n = 0; n < bytes; n++ )
|
||||
buf[n] = (val >> ((bytes-n-1)*8)) & 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( unsigned int n = 0; n < bytes; n++ )
|
||||
buf[n] = (val >> (n*8)) & 0xFF;
|
||||
}
|
||||
|
||||
size_t r = fwrite(&buf, bytes, 1, file);
|
||||
return int(r);
|
||||
}
|
||||
|
||||
int CScriptFile::WriteFloat(float f)
|
||||
{
|
||||
if( file == 0 )
|
||||
return 0;
|
||||
|
||||
unsigned char buf[4];
|
||||
asUINT val = *reinterpret_cast<asUINT*>(&f);
|
||||
if( mostSignificantByteFirst )
|
||||
{
|
||||
for( unsigned int n = 0; n < 4; n++ )
|
||||
buf[n] = (val >> ((3-n)*4)) & 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( unsigned int n = 0; n < 4; n++ )
|
||||
buf[n] = (val >> (n*8)) & 0xFF;
|
||||
}
|
||||
|
||||
size_t r = fwrite(&buf, 4, 1, file);
|
||||
return int(r);
|
||||
}
|
||||
|
||||
int CScriptFile::WriteDouble(double d)
|
||||
{
|
||||
if( file == 0 )
|
||||
return 0;
|
||||
|
||||
unsigned char buf[8];
|
||||
asQWORD val = *reinterpret_cast<asQWORD*>(&d);
|
||||
if( mostSignificantByteFirst )
|
||||
{
|
||||
for( unsigned int n = 0; n < 8; n++ )
|
||||
buf[n] = (val >> ((7-n)*8)) & 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( unsigned int n = 0; n < 8; n++ )
|
||||
buf[n] = (val >> (n*8)) & 0xFF;
|
||||
}
|
||||
|
||||
size_t r = fwrite(&buf, 8, 1, file);
|
||||
return int(r);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
END_AS_NAMESPACE
|
|
@ -0,0 +1,101 @@
|
|||
//
|
||||
// CScriptFile
|
||||
//
|
||||
// This class encapsulates a FILE pointer in a reference counted class for
|
||||
// use within AngelScript.
|
||||
//
|
||||
|
||||
#ifndef SCRIPTFILE_H
|
||||
#define SCRIPTFILE_H
|
||||
|
||||
//---------------------------
|
||||
// Compilation settings
|
||||
//
|
||||
|
||||
// Set this flag to turn on/off write support
|
||||
// 0 = off
|
||||
// 1 = on
|
||||
|
||||
#ifndef AS_WRITE_OPS
|
||||
#define AS_WRITE_OPS 1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------
|
||||
// Declaration
|
||||
//
|
||||
|
||||
#ifndef ANGELSCRIPT_H
|
||||
// Avoid having to inform include path if header is already include before
|
||||
#include <angelscript.h>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
class CScriptFile
|
||||
{
|
||||
public:
|
||||
CScriptFile();
|
||||
|
||||
void AddRef() const;
|
||||
void Release() const;
|
||||
|
||||
// TODO: Implement the "r+", "w+" and "a+" modes
|
||||
// mode = "r" -> open the file for reading
|
||||
// "w" -> open the file for writing (overwrites existing file)
|
||||
// "a" -> open the file for appending
|
||||
int Open(const std::string &filename, const std::string &mode);
|
||||
int Close();
|
||||
int GetSize() const;
|
||||
bool IsEOF() const;
|
||||
|
||||
// Reading
|
||||
std::string ReadString(unsigned int length);
|
||||
std::string ReadLine();
|
||||
asINT64 ReadInt(asUINT bytes);
|
||||
asQWORD ReadUInt(asUINT bytes);
|
||||
float ReadFloat();
|
||||
double ReadDouble();
|
||||
|
||||
// Writing
|
||||
int WriteString(const std::string &str);
|
||||
int WriteInt(asINT64 v, asUINT bytes);
|
||||
int WriteUInt(asQWORD v, asUINT bytes);
|
||||
int WriteFloat(float v);
|
||||
int WriteDouble(double v);
|
||||
|
||||
// Cursor
|
||||
int GetPos() const;
|
||||
int SetPos(int pos);
|
||||
int MovePos(int delta);
|
||||
|
||||
// Big-endian = most significant byte first
|
||||
bool mostSignificantByteFirst;
|
||||
|
||||
protected:
|
||||
~CScriptFile();
|
||||
|
||||
mutable int refCount;
|
||||
FILE *file;
|
||||
};
|
||||
|
||||
// This function will determine the configuration of the engine
|
||||
// and use one of the two functions below to register the file type
|
||||
void RegisterScriptFile(asIScriptEngine *engine);
|
||||
|
||||
// Call this function to register the file type
|
||||
// using native calling conventions
|
||||
void RegisterScriptFile_Native(asIScriptEngine *engine);
|
||||
|
||||
// Use this one instead if native calling conventions
|
||||
// are not supported on the target platform
|
||||
void RegisterScriptFile_Generic(asIScriptEngine *engine);
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,629 @@
|
|||
#include "scriptfilesystem.h"
|
||||
#include "../autowrapper/aswrappedcall.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <direct.h> // _getcwd
|
||||
#include <Windows.h> // FindFirstFile, GetFileAttributes
|
||||
|
||||
#undef DeleteFile
|
||||
#undef CopyFile
|
||||
|
||||
#else
|
||||
#include <unistd.h> // getcwd
|
||||
#include <dirent.h> // opendir, readdir, closedir
|
||||
#include <sys/stat.h> // stat
|
||||
#endif
|
||||
#include <assert.h> // assert
|
||||
|
||||
using namespace std;
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
// TODO: The file system should have a way to allow the application to define in
|
||||
// which sub directories it is allowed to make changes and/or read
|
||||
|
||||
CScriptFileSystem *ScriptFileSystem_Factory()
|
||||
{
|
||||
return new CScriptFileSystem();
|
||||
}
|
||||
|
||||
void RegisterScriptFileSystem_Native(asIScriptEngine *engine)
|
||||
{
|
||||
int r;
|
||||
|
||||
assert( engine->GetTypeInfoByName("string") );
|
||||
assert( engine->GetTypeInfoByDecl("array<string>") );
|
||||
assert( engine->GetTypeInfoByName("datetime") );
|
||||
|
||||
r = engine->RegisterObjectType("filesystem", 0, asOBJ_REF); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("filesystem", asBEHAVE_FACTORY, "filesystem @f()", asFUNCTION(ScriptFileSystem_Factory), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("filesystem", asBEHAVE_ADDREF, "void f()", asMETHOD(CScriptFileSystem,AddRef), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("filesystem", asBEHAVE_RELEASE, "void f()", asMETHOD(CScriptFileSystem,Release), asCALL_THISCALL); assert( r >= 0 );
|
||||
|
||||
r = engine->RegisterObjectMethod("filesystem", "bool changeCurrentPath(const string &in)", asMETHOD(CScriptFileSystem, ChangeCurrentPath), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("filesystem", "string getCurrentPath() const", asMETHOD(CScriptFileSystem, GetCurrentPath), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("filesystem", "array<string> @getDirs() const", asMETHOD(CScriptFileSystem, GetDirs), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("filesystem", "array<string> @getFiles() const", asMETHOD(CScriptFileSystem, GetFiles), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("filesystem", "bool isDir(const string &in) const", asMETHOD(CScriptFileSystem, IsDir), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("filesystem", "bool isLink(const string &in) const", asMETHOD(CScriptFileSystem, IsLink), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("filesystem", "int64 getSize(const string &in) const", asMETHOD(CScriptFileSystem, GetSize), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("filesystem", "int makeDir(const string &in)", asMETHOD(CScriptFileSystem, MakeDir), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("filesystem", "int removeDir(const string &in)", asMETHOD(CScriptFileSystem, RemoveDir), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("filesystem", "int deleteFile(const string &in)", asMETHOD(CScriptFileSystem, DeleteFile), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("filesystem", "int copyFile(const string &in, const string &in)", asMETHOD(CScriptFileSystem, CopyFile), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("filesystem", "int move(const string &in, const string &in)", asMETHOD(CScriptFileSystem, Move), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("filesystem", "datetime getCreateDateTime(const string &in) const", asMETHOD(CScriptFileSystem, GetCreateDateTime), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("filesystem", "datetime getModifyDateTime(const string &in) const", asMETHOD(CScriptFileSystem, GetModifyDateTime), asCALL_THISCALL); assert(r >= 0);
|
||||
}
|
||||
|
||||
void RegisterScriptFileSystem_Generic(asIScriptEngine *engine)
|
||||
{
|
||||
int r;
|
||||
|
||||
assert( engine->GetTypeInfoByName("string") );
|
||||
assert( engine->GetTypeInfoByDecl("array<string>") );
|
||||
assert( engine->GetTypeInfoByName("datetime") );
|
||||
|
||||
r = engine->RegisterObjectType("filesystem", 0, asOBJ_REF); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("filesystem", asBEHAVE_FACTORY, "filesystem @f()", WRAP_FN(ScriptFileSystem_Factory), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("filesystem", asBEHAVE_ADDREF, "void f()", WRAP_MFN(CScriptFileSystem,AddRef), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("filesystem", asBEHAVE_RELEASE, "void f()", WRAP_MFN(CScriptFileSystem,Release), asCALL_GENERIC); assert( r >= 0 );
|
||||
|
||||
r = engine->RegisterObjectMethod("filesystem", "bool changeCurrentPath(const string &in)", WRAP_MFN(CScriptFileSystem, ChangeCurrentPath), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("filesystem", "string getCurrentPath() const", WRAP_MFN(CScriptFileSystem, GetCurrentPath), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("filesystem", "array<string> @getDirs() const", WRAP_MFN(CScriptFileSystem, GetDirs), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("filesystem", "array<string> @getFiles() const", WRAP_MFN(CScriptFileSystem, GetFiles), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("filesystem", "bool isDir(const string &in) const", WRAP_MFN(CScriptFileSystem, IsDir), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("filesystem", "bool isLink(const string &in) const", WRAP_MFN(CScriptFileSystem, IsLink), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("filesystem", "int64 getSize(const string &in) const", WRAP_MFN(CScriptFileSystem, GetSize), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("filesystem", "int makeDir(const string &in)", WRAP_MFN(CScriptFileSystem, MakeDir), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("filesystem", "int removeDir(const string &in)", WRAP_MFN(CScriptFileSystem, RemoveDir), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("filesystem", "int deleteFile(const string &in)", WRAP_MFN(CScriptFileSystem, DeleteFile), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("filesystem", "int copyFile(const string &in, const string &in)", WRAP_MFN(CScriptFileSystem, CopyFile), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("filesystem", "int move(const string &in, const string &in)", WRAP_MFN(CScriptFileSystem, Move), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("filesystem", "datetime getCreateDateTime(const string &in) const", WRAP_MFN(CScriptFileSystem, GetCreateDateTime), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("filesystem", "datetime getModifyDateTime(const string &in) const", WRAP_MFN(CScriptFileSystem, GetModifyDateTime), asCALL_GENERIC); assert(r >= 0);
|
||||
}
|
||||
|
||||
void RegisterScriptFileSystem(asIScriptEngine *engine)
|
||||
{
|
||||
if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
|
||||
RegisterScriptFileSystem_Generic(engine);
|
||||
else
|
||||
RegisterScriptFileSystem_Native(engine);
|
||||
}
|
||||
|
||||
CScriptFileSystem::CScriptFileSystem()
|
||||
{
|
||||
refCount = 1;
|
||||
|
||||
// Gets the application's current working directory as the starting point
|
||||
// TODO: Replace backslash with slash to keep a unified naming convention
|
||||
char buffer[1000];
|
||||
#if defined(_WIN32)
|
||||
currentPath = _getcwd(buffer, 1000);
|
||||
#else
|
||||
currentPath = getcwd(buffer, 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
CScriptFileSystem::~CScriptFileSystem()
|
||||
{
|
||||
}
|
||||
|
||||
void CScriptFileSystem::AddRef() const
|
||||
{
|
||||
asAtomicInc(refCount);
|
||||
}
|
||||
|
||||
void CScriptFileSystem::Release() const
|
||||
{
|
||||
if( asAtomicDec(refCount) == 0 )
|
||||
delete this;
|
||||
}
|
||||
|
||||
CScriptArray *CScriptFileSystem::GetFiles() const
|
||||
{
|
||||
// Obtain a pointer to the engine
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
asIScriptEngine *engine = ctx->GetEngine();
|
||||
|
||||
// TODO: This should only be done once
|
||||
// TODO: This assumes that CScriptArray was already registered
|
||||
asITypeInfo *arrayType = engine->GetTypeInfoByDecl("array<string>");
|
||||
|
||||
// Create the array object
|
||||
CScriptArray *array = CScriptArray::Create(arrayType);
|
||||
|
||||
#if defined(_WIN32)
|
||||
// Windows uses UTF16 so it is necessary to convert the string
|
||||
wchar_t bufUTF16[10000];
|
||||
string searchPattern = currentPath + "/*";
|
||||
MultiByteToWideChar(CP_UTF8, 0, searchPattern.c_str(), -1, bufUTF16, 10000);
|
||||
|
||||
WIN32_FIND_DATAW ffd;
|
||||
HANDLE hFind = FindFirstFileW(bufUTF16, &ffd);
|
||||
if( INVALID_HANDLE_VALUE == hFind )
|
||||
return array;
|
||||
|
||||
do
|
||||
{
|
||||
// Skip directories
|
||||
if( (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
|
||||
continue;
|
||||
|
||||
// Convert the file name back to UTF8
|
||||
char bufUTF8[10000];
|
||||
WideCharToMultiByte(CP_UTF8, 0, ffd.cFileName, -1, bufUTF8, 10000, 0, 0);
|
||||
|
||||
// Add the file to the array
|
||||
array->Resize(array->GetSize()+1);
|
||||
((string*)(array->At(array->GetSize()-1)))->assign(bufUTF8);
|
||||
}
|
||||
while( FindNextFileW(hFind, &ffd) != 0 );
|
||||
|
||||
FindClose(hFind);
|
||||
#else
|
||||
dirent *ent = 0;
|
||||
DIR *dir = opendir(currentPath.c_str());
|
||||
while( (ent = readdir(dir)) != NULL )
|
||||
{
|
||||
const string filename = ent->d_name;
|
||||
|
||||
// Skip . and ..
|
||||
if( filename[0] == '.' )
|
||||
continue;
|
||||
|
||||
// Skip sub directories
|
||||
const string fullname = currentPath + "/" + filename;
|
||||
struct stat st;
|
||||
if( stat(fullname.c_str(), &st) == -1 )
|
||||
continue;
|
||||
if( (st.st_mode & S_IFDIR) != 0 )
|
||||
continue;
|
||||
|
||||
// Add the file to the array
|
||||
array->Resize(array->GetSize()+1);
|
||||
((string*)(array->At(array->GetSize()-1)))->assign(filename);
|
||||
}
|
||||
closedir(dir);
|
||||
#endif
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
CScriptArray *CScriptFileSystem::GetDirs() const
|
||||
{
|
||||
// Obtain a pointer to the engine
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
asIScriptEngine *engine = ctx->GetEngine();
|
||||
|
||||
// TODO: This should only be done once
|
||||
// TODO: This assumes that CScriptArray was already registered
|
||||
asITypeInfo *arrayType = engine->GetTypeInfoByDecl("array<string>");
|
||||
|
||||
// Create the array object
|
||||
CScriptArray *array = CScriptArray::Create(arrayType);
|
||||
|
||||
#if defined(_WIN32)
|
||||
// Windows uses UTF16 so it is necessary to convert the string
|
||||
wchar_t bufUTF16[10000];
|
||||
string searchPattern = currentPath + "/*";
|
||||
MultiByteToWideChar(CP_UTF8, 0, searchPattern.c_str(), -1, bufUTF16, 10000);
|
||||
|
||||
WIN32_FIND_DATAW ffd;
|
||||
HANDLE hFind = FindFirstFileW(bufUTF16, &ffd);
|
||||
if( INVALID_HANDLE_VALUE == hFind )
|
||||
return array;
|
||||
|
||||
do
|
||||
{
|
||||
// Skip files
|
||||
if( !(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
|
||||
continue;
|
||||
|
||||
// Convert the file name back to UTF8
|
||||
char bufUTF8[10000];
|
||||
WideCharToMultiByte(CP_UTF8, 0, ffd.cFileName, -1, bufUTF8, 10000, 0, 0);
|
||||
|
||||
if( strcmp(bufUTF8, ".") == 0 || strcmp(bufUTF8, "..") == 0 )
|
||||
continue;
|
||||
|
||||
// Add the dir to the array
|
||||
array->Resize(array->GetSize()+1);
|
||||
((string*)(array->At(array->GetSize()-1)))->assign(bufUTF8);
|
||||
}
|
||||
while( FindNextFileW(hFind, &ffd) != 0 );
|
||||
|
||||
FindClose(hFind);
|
||||
#else
|
||||
dirent *ent = 0;
|
||||
DIR *dir = opendir(currentPath.c_str());
|
||||
while( (ent = readdir(dir)) != NULL )
|
||||
{
|
||||
const string filename = ent->d_name;
|
||||
|
||||
// Skip . and ..
|
||||
if( filename[0] == '.' )
|
||||
continue;
|
||||
|
||||
// Skip files
|
||||
const string fullname = currentPath + "/" + filename;
|
||||
struct stat st;
|
||||
if( stat(fullname.c_str(), &st) == -1 )
|
||||
continue;
|
||||
if( (st.st_mode & S_IFDIR) == 0 )
|
||||
continue;
|
||||
|
||||
// Add the dir to the array
|
||||
array->Resize(array->GetSize()+1);
|
||||
((string*)(array->At(array->GetSize()-1)))->assign(filename);
|
||||
}
|
||||
closedir(dir);
|
||||
#endif
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
// Doesn't change anything if the new path is not valid
|
||||
bool CScriptFileSystem::ChangeCurrentPath(const string &path)
|
||||
{
|
||||
string newPath;
|
||||
if( path.find(":") != string::npos || path.find("/") == 0 || path.find("\\") == 0 )
|
||||
newPath = path;
|
||||
else
|
||||
newPath = currentPath + "/" + path;
|
||||
|
||||
// TODO: Resolve internal /./ and /../
|
||||
// TODO: Replace backslash with slash to keep a unified naming convention
|
||||
|
||||
// Remove trailing slashes from the path
|
||||
while(newPath.length() && (newPath[newPath.length()-1] == '/' || newPath[newPath.length()-1] == '\\') )
|
||||
newPath.resize(newPath.length()-1);
|
||||
|
||||
if (!IsDir(newPath))
|
||||
return false;
|
||||
|
||||
currentPath = newPath;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CScriptFileSystem::IsDir(const string &path) const
|
||||
{
|
||||
string search;
|
||||
if( path.find(":") != string::npos || path.find("/") == 0 || path.find("\\") == 0 )
|
||||
search = path;
|
||||
else
|
||||
search = currentPath + "/" + path;
|
||||
|
||||
#if defined(_WIN32)
|
||||
// Windows uses UTF16 so it is necessary to convert the string
|
||||
wchar_t bufUTF16[10000];
|
||||
MultiByteToWideChar(CP_UTF8, 0, search.c_str(), -1, bufUTF16, 10000);
|
||||
|
||||
// Check if the path exists and is a directory
|
||||
DWORD attrib = GetFileAttributesW(bufUTF16);
|
||||
if( attrib == INVALID_FILE_ATTRIBUTES ||
|
||||
!(attrib & FILE_ATTRIBUTE_DIRECTORY) )
|
||||
return false;
|
||||
#else
|
||||
// Check if the path exists and is a directory
|
||||
struct stat st;
|
||||
if( stat(search.c_str(), &st) == -1 )
|
||||
return false;
|
||||
if( (st.st_mode & S_IFDIR) == 0 )
|
||||
return false;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CScriptFileSystem::IsLink(const string &path) const
|
||||
{
|
||||
string search;
|
||||
if (path.find(":") != string::npos || path.find("/") == 0 || path.find("\\") == 0)
|
||||
search = path;
|
||||
else
|
||||
search = currentPath + "/" + path;
|
||||
|
||||
#if defined(_WIN32)
|
||||
// Windows uses UTF16 so it is necessary to convert the string
|
||||
wchar_t bufUTF16[10000];
|
||||
MultiByteToWideChar(CP_UTF8, 0, search.c_str(), -1, bufUTF16, 10000);
|
||||
|
||||
// Check if the path exists and is a link
|
||||
DWORD attrib = GetFileAttributesW(bufUTF16);
|
||||
if (attrib == INVALID_FILE_ATTRIBUTES ||
|
||||
!(attrib & FILE_ATTRIBUTE_REPARSE_POINT))
|
||||
return false;
|
||||
#else
|
||||
// Check if the path exists and is a link
|
||||
struct stat st;
|
||||
if (stat(search.c_str(), &st) == -1)
|
||||
return false;
|
||||
if ((st.st_mode & S_IFLNK) == 0)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
asINT64 CScriptFileSystem::GetSize(const string &path) const
|
||||
{
|
||||
string search;
|
||||
if (path.find(":") != string::npos || path.find("/") == 0 || path.find("\\") == 0)
|
||||
search = path;
|
||||
else
|
||||
search = currentPath + "/" + path;
|
||||
|
||||
#if defined(_WIN32)
|
||||
// Windows uses UTF16 so it is necessary to convert the string
|
||||
wchar_t bufUTF16[10000];
|
||||
MultiByteToWideChar(CP_UTF8, 0, search.c_str(), -1, bufUTF16, 10000);
|
||||
|
||||
// Get the size of the file
|
||||
LARGE_INTEGER largeInt;
|
||||
HANDLE file = CreateFileW(bufUTF16, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
BOOL success = GetFileSizeEx(file, &largeInt);
|
||||
CloseHandle(file);
|
||||
if( !success )
|
||||
return -1;
|
||||
return asINT64(largeInt.QuadPart);
|
||||
#else
|
||||
// Get the size of the file
|
||||
struct stat st;
|
||||
if (stat(search.c_str(), &st) == -1)
|
||||
return -1;
|
||||
return asINT64(st.st_size);
|
||||
#endif
|
||||
}
|
||||
|
||||
// TODO: Should be able to return different codes for
|
||||
// - directory exists
|
||||
// - path not found
|
||||
// - access denied
|
||||
// TODO: Should be able to define the permissions for the directory
|
||||
int CScriptFileSystem::MakeDir(const string &path)
|
||||
{
|
||||
string search;
|
||||
if (path.find(":") != string::npos || path.find("/") == 0 || path.find("\\") == 0)
|
||||
search = path;
|
||||
else
|
||||
search = currentPath + "/" + path;
|
||||
|
||||
#if defined(_WIN32)
|
||||
// Windows uses UTF16 so it is necessary to convert the string
|
||||
wchar_t bufUTF16[10000];
|
||||
MultiByteToWideChar(CP_UTF8, 0, search.c_str(), -1, bufUTF16, 10000);
|
||||
|
||||
// Create the directory
|
||||
BOOL success = CreateDirectoryW(bufUTF16, 0);
|
||||
return success ? 0 : -1;
|
||||
#else
|
||||
// Create the directory
|
||||
int failure = mkdir(search.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
||||
return !failure ? 0 : -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
// TODO: Should be able to return different codes for
|
||||
// - directory doesn't exist
|
||||
// - directory is not empty
|
||||
// - access denied
|
||||
// TODO: Should have an option to remove the directory and all content recursively
|
||||
int CScriptFileSystem::RemoveDir(const string &path)
|
||||
{
|
||||
string search;
|
||||
if (path.find(":") != string::npos || path.find("/") == 0 || path.find("\\") == 0)
|
||||
search = path;
|
||||
else
|
||||
search = currentPath + "/" + path;
|
||||
|
||||
#if defined(_WIN32)
|
||||
// Windows uses UTF16 so it is necessary to convert the string
|
||||
wchar_t bufUTF16[10000];
|
||||
MultiByteToWideChar(CP_UTF8, 0, search.c_str(), -1, bufUTF16, 10000);
|
||||
|
||||
// Remove the directory
|
||||
BOOL success = RemoveDirectoryW(bufUTF16);
|
||||
return success ? 0 : -1;
|
||||
#else
|
||||
// Remove the directory
|
||||
int failure = rmdir(search.c_str());
|
||||
return !failure ? 0 : -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int CScriptFileSystem::DeleteFile(const string &path)
|
||||
{
|
||||
string search;
|
||||
if (path.find(":") != string::npos || path.find("/") == 0 || path.find("\\") == 0)
|
||||
search = path;
|
||||
else
|
||||
search = currentPath + "/" + path;
|
||||
|
||||
#if defined(_WIN32)
|
||||
// Windows uses UTF16 so it is necessary to convert the string
|
||||
wchar_t bufUTF16[10000];
|
||||
MultiByteToWideChar(CP_UTF8, 0, search.c_str(), -1, bufUTF16, 10000);
|
||||
|
||||
// Remove the file
|
||||
BOOL success = DeleteFileW(bufUTF16);
|
||||
return success ? 0 : -1;
|
||||
#else
|
||||
// Remove the file
|
||||
int failure = unlink(search.c_str());
|
||||
return !failure ? 0 : -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int CScriptFileSystem::CopyFile(const string &source, const string &target)
|
||||
{
|
||||
string search1;
|
||||
if (source.find(":") != string::npos || source.find("/") == 0 || source.find("\\") == 0)
|
||||
search1 = source;
|
||||
else
|
||||
search1 = currentPath + "/" + source;
|
||||
|
||||
string search2;
|
||||
if (target.find(":") != string::npos || target.find("/") == 0 || target.find("\\") == 0)
|
||||
search2 = target;
|
||||
else
|
||||
search2 = currentPath + "/" + target;
|
||||
|
||||
#if defined(_WIN32)
|
||||
// Windows uses UTF16 so it is necessary to convert the string
|
||||
wchar_t bufUTF16_1[10000];
|
||||
MultiByteToWideChar(CP_UTF8, 0, search1.c_str(), -1, bufUTF16_1, 10000);
|
||||
|
||||
wchar_t bufUTF16_2[10000];
|
||||
MultiByteToWideChar(CP_UTF8, 0, search2.c_str(), -1, bufUTF16_2, 10000);
|
||||
|
||||
// Copy the file
|
||||
BOOL success = CopyFileW(bufUTF16_1, bufUTF16_2, TRUE);
|
||||
return success ? 0 : -1;
|
||||
#else
|
||||
// Copy the file manually as there is no posix function for this
|
||||
bool failure = false;
|
||||
FILE *src = 0, *tgt = 0;
|
||||
src = fopen(search1.c_str(), "r");
|
||||
if (src == 0) failure = true;
|
||||
if( !failure ) tgt = fopen(search2.c_str(), "w");
|
||||
if (tgt == 0) failure = true;
|
||||
char buf[1024];
|
||||
size_t n;
|
||||
while (!failure && (n = fread(buf, sizeof(char), sizeof(buf), src)) > 0)
|
||||
{
|
||||
if (fwrite(buf, sizeof(char), n, tgt) != n)
|
||||
failure = true;
|
||||
}
|
||||
if (src) fclose(src);
|
||||
if (tgt) fclose(tgt);
|
||||
return !failure ? 0 : -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int CScriptFileSystem::Move(const string &source, const string &target)
|
||||
{
|
||||
string search1;
|
||||
if (source.find(":") != string::npos || source.find("/") == 0 || source.find("\\") == 0)
|
||||
search1 = source;
|
||||
else
|
||||
search1 = currentPath + "/" + source;
|
||||
|
||||
string search2;
|
||||
if (target.find(":") != string::npos || target.find("/") == 0 || target.find("\\") == 0)
|
||||
search2 = target;
|
||||
else
|
||||
search2 = currentPath + "/" + target;
|
||||
|
||||
#if defined(_WIN32)
|
||||
// Windows uses UTF16 so it is necessary to convert the string
|
||||
wchar_t bufUTF16_1[10000];
|
||||
MultiByteToWideChar(CP_UTF8, 0, search1.c_str(), -1, bufUTF16_1, 10000);
|
||||
|
||||
wchar_t bufUTF16_2[10000];
|
||||
MultiByteToWideChar(CP_UTF8, 0, search2.c_str(), -1, bufUTF16_2, 10000);
|
||||
|
||||
// Move the file or directory
|
||||
BOOL success = MoveFileW(bufUTF16_1, bufUTF16_2);
|
||||
return success ? 0 : -1;
|
||||
#else
|
||||
// Move the file or directory
|
||||
int failure = rename(search1.c_str(), search2.c_str());
|
||||
return !failure ? 0 : -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
string CScriptFileSystem::GetCurrentPath() const
|
||||
{
|
||||
return currentPath;
|
||||
}
|
||||
|
||||
CDateTime CScriptFileSystem::GetCreateDateTime(const string &path) const
|
||||
{
|
||||
string search;
|
||||
if (path.find(":") != string::npos || path.find("/") == 0 || path.find("\\") == 0)
|
||||
search = path;
|
||||
else
|
||||
search = currentPath + "/" + path;
|
||||
|
||||
#if defined(_WIN32)
|
||||
// Windows uses UTF16 so it is necessary to convert the string
|
||||
wchar_t bufUTF16[10000];
|
||||
MultiByteToWideChar(CP_UTF8, 0, search.c_str(), -1, bufUTF16, 10000);
|
||||
|
||||
// Get the create date/time of the file
|
||||
FILETIME createTm;
|
||||
HANDLE file = CreateFileW(bufUTF16, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
BOOL success = GetFileTime(file, &createTm, 0, 0);
|
||||
CloseHandle(file);
|
||||
if( !success )
|
||||
{
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
if( ctx )
|
||||
ctx->SetException("Failed to get file creation date/time");
|
||||
return CDateTime();
|
||||
}
|
||||
SYSTEMTIME tm;
|
||||
FileTimeToSystemTime(&createTm, &tm);
|
||||
return CDateTime(tm.wYear, tm.wMonth, tm.wDay, tm.wHour, tm.wMinute, tm.wSecond);
|
||||
#else
|
||||
// Get the create date/time of the file
|
||||
struct stat st;
|
||||
if (stat(search.c_str(), &st) == -1)
|
||||
{
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
if( ctx )
|
||||
ctx->SetException("Failed to get file creation date/time");
|
||||
return CDateTime();
|
||||
}
|
||||
tm *t = localtime(&st.st_ctime);
|
||||
return CDateTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
|
||||
#endif
|
||||
}
|
||||
|
||||
CDateTime CScriptFileSystem::GetModifyDateTime(const string &path) const
|
||||
{
|
||||
string search;
|
||||
if (path.find(":") != string::npos || path.find("/") == 0 || path.find("\\") == 0)
|
||||
search = path;
|
||||
else
|
||||
search = currentPath + "/" + path;
|
||||
|
||||
#if defined(_WIN32)
|
||||
// Windows uses UTF16 so it is necessary to convert the string
|
||||
wchar_t bufUTF16[10000];
|
||||
MultiByteToWideChar(CP_UTF8, 0, search.c_str(), -1, bufUTF16, 10000);
|
||||
|
||||
// Get the last modify date/time of the file
|
||||
FILETIME modifyTm;
|
||||
HANDLE file = CreateFileW(bufUTF16, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
BOOL success = GetFileTime(file, 0, 0, &modifyTm);
|
||||
CloseHandle(file);
|
||||
if( !success )
|
||||
{
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
if( ctx )
|
||||
ctx->SetException("Failed to get file modify date/time");
|
||||
return CDateTime();
|
||||
}
|
||||
SYSTEMTIME tm;
|
||||
FileTimeToSystemTime(&modifyTm, &tm);
|
||||
return CDateTime(tm.wYear, tm.wMonth, tm.wDay, tm.wHour, tm.wMinute, tm.wSecond);
|
||||
#else
|
||||
// Get the last modify date/time of the file
|
||||
struct stat st;
|
||||
if (stat(search.c_str(), &st) == -1)
|
||||
{
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
if( ctx )
|
||||
ctx->SetException("Failed to get file modify date/time");
|
||||
return CDateTime();
|
||||
}
|
||||
tm *t = localtime(&st.st_mtime);
|
||||
return CDateTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
|
||||
#endif
|
||||
}
|
||||
|
||||
END_AS_NAMESPACE
|
|
@ -0,0 +1,78 @@
|
|||
#ifndef AS_SCRIPTFILESYSTEM_H
|
||||
#define AS_SCRIPTFILESYSTEM_H
|
||||
|
||||
#ifndef ANGELSCRIPT_H
|
||||
// Avoid having to inform include path if header is already include before
|
||||
#include <angelscript.h>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../scriptarray/scriptarray.h"
|
||||
#include "../datetime/datetime.h"
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
class CScriptFileSystem
|
||||
{
|
||||
public:
|
||||
CScriptFileSystem();
|
||||
|
||||
void AddRef() const;
|
||||
void Release() const;
|
||||
|
||||
// Sets the current path that should be used in other calls when using relative paths
|
||||
// It can use relative paths too, so moving up a directory is used by passing in ".."
|
||||
bool ChangeCurrentPath(const std::string &path);
|
||||
std::string GetCurrentPath() const;
|
||||
|
||||
// Returns true if the path is a directory. Input can be either a full path or a relative path.
|
||||
// This method does not return the dirs '.' and '..'
|
||||
bool IsDir(const std::string &path) const;
|
||||
|
||||
// Returns true if the path is a link. Input can be either a full path or a relative path
|
||||
bool IsLink(const std::string &path) const;
|
||||
|
||||
// Returns the size of file. Input can be either a full path or a relative path
|
||||
asINT64 GetSize(const std::string &path) const;
|
||||
|
||||
// Returns a list of the files in the current path
|
||||
CScriptArray *GetFiles() const;
|
||||
|
||||
// Returns a list of the directories in the current path
|
||||
CScriptArray *GetDirs() const;
|
||||
|
||||
// Creates a new directory. Returns 0 on success
|
||||
int MakeDir(const std::string &path);
|
||||
|
||||
// Removes a directory. Will only remove the directory if it is empty. Returns 0 on success
|
||||
int RemoveDir(const std::string &path);
|
||||
|
||||
// Deletes a file. Returns 0 on success
|
||||
int DeleteFile(const std::string &path);
|
||||
|
||||
// Copies a file. Returns 0 on success
|
||||
int CopyFile(const std::string &source, const std::string &target);
|
||||
|
||||
// Moves or renames a file or directory. Returns 0 on success
|
||||
int Move(const std::string &source, const std::string &target);
|
||||
|
||||
// Gets the date and time of the file/dir creation
|
||||
CDateTime GetCreateDateTime(const std::string &path) const;
|
||||
|
||||
// Gets the date and time of the file/dir modification
|
||||
CDateTime GetModifyDateTime(const std::string &path) const;
|
||||
|
||||
protected:
|
||||
~CScriptFileSystem();
|
||||
|
||||
mutable int refCount;
|
||||
std::string currentPath;
|
||||
};
|
||||
|
||||
void RegisterScriptFileSystem(asIScriptEngine *engine);
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,807 @@
|
|||
#include <new>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h> // sprintf
|
||||
|
||||
#include "scriptgrid.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
// Set the default memory routines
|
||||
// Use the angelscript engine's memory routines by default
|
||||
static asALLOCFUNC_t userAlloc = asAllocMem;
|
||||
static asFREEFUNC_t userFree = asFreeMem;
|
||||
|
||||
// Allows the application to set which memory routines should be used by the array object
|
||||
void CScriptGrid::SetMemoryFunctions(asALLOCFUNC_t allocFunc, asFREEFUNC_t freeFunc)
|
||||
{
|
||||
userAlloc = allocFunc;
|
||||
userFree = freeFunc;
|
||||
}
|
||||
|
||||
static void RegisterScriptGrid_Native(asIScriptEngine *engine);
|
||||
|
||||
struct SGridBuffer
|
||||
{
|
||||
asDWORD width;
|
||||
asDWORD height;
|
||||
asBYTE data[1];
|
||||
};
|
||||
|
||||
CScriptGrid *CScriptGrid::Create(asITypeInfo *ti)
|
||||
{
|
||||
return CScriptGrid::Create(ti, 0, 0);
|
||||
}
|
||||
|
||||
CScriptGrid *CScriptGrid::Create(asITypeInfo *ti, asUINT w, asUINT h)
|
||||
{
|
||||
// Allocate the memory
|
||||
void *mem = userAlloc(sizeof(CScriptGrid));
|
||||
if( mem == 0 )
|
||||
{
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
if( ctx )
|
||||
ctx->SetException("Out of memory");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Initialize the object
|
||||
CScriptGrid *a = new(mem) CScriptGrid(w, h, ti);
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
CScriptGrid *CScriptGrid::Create(asITypeInfo *ti, void *initList)
|
||||
{
|
||||
// Allocate the memory
|
||||
void *mem = userAlloc(sizeof(CScriptGrid));
|
||||
if( mem == 0 )
|
||||
{
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
if( ctx )
|
||||
ctx->SetException("Out of memory");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Initialize the object
|
||||
CScriptGrid *a = new(mem) CScriptGrid(ti, initList);
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
CScriptGrid *CScriptGrid::Create(asITypeInfo *ti, asUINT w, asUINT h, void *defVal)
|
||||
{
|
||||
// Allocate the memory
|
||||
void *mem = userAlloc(sizeof(CScriptGrid));
|
||||
if( mem == 0 )
|
||||
{
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
if( ctx )
|
||||
ctx->SetException("Out of memory");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Initialize the object
|
||||
CScriptGrid *a = new(mem) CScriptGrid(w, h, defVal, ti);
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
// This optional callback is called when the template type is first used by the compiler.
|
||||
// It allows the application to validate if the template can be instantiated for the requested
|
||||
// subtype at compile time, instead of at runtime. The output argument dontGarbageCollect
|
||||
// allow the callback to tell the engine if the template instance type shouldn't be garbage collected,
|
||||
// i.e. no asOBJ_GC flag.
|
||||
static bool ScriptGridTemplateCallback(asITypeInfo *ti, bool &dontGarbageCollect)
|
||||
{
|
||||
// Make sure the subtype can be instantiated with a default factory/constructor,
|
||||
// otherwise we won't be able to instantiate the elements.
|
||||
int typeId = ti->GetSubTypeId();
|
||||
if( typeId == asTYPEID_VOID )
|
||||
return false;
|
||||
if( (typeId & asTYPEID_MASK_OBJECT) && !(typeId & asTYPEID_OBJHANDLE) )
|
||||
{
|
||||
asITypeInfo *subtype = ti->GetEngine()->GetTypeInfoById(typeId);
|
||||
asDWORD flags = subtype->GetFlags();
|
||||
if( (flags & asOBJ_VALUE) && !(flags & asOBJ_POD) )
|
||||
{
|
||||
// Verify that there is a default constructor
|
||||
bool found = false;
|
||||
for( asUINT n = 0; n < subtype->GetBehaviourCount(); n++ )
|
||||
{
|
||||
asEBehaviours beh;
|
||||
asIScriptFunction *func = subtype->GetBehaviourByIndex(n, &beh);
|
||||
if( beh != asBEHAVE_CONSTRUCT ) continue;
|
||||
|
||||
if( func->GetParamCount() == 0 )
|
||||
{
|
||||
// Found the default constructor
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !found )
|
||||
{
|
||||
// There is no default constructor
|
||||
ti->GetEngine()->WriteMessage("array", 0, 0, asMSGTYPE_ERROR, "The subtype has no default constructor");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if( (flags & asOBJ_REF) )
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
// If value assignment for ref type has been disabled then the array
|
||||
// can be created if the type has a default factory function
|
||||
if( !ti->GetEngine()->GetEngineProperty(asEP_DISALLOW_VALUE_ASSIGN_FOR_REF_TYPE) )
|
||||
{
|
||||
// Verify that there is a default factory
|
||||
for( asUINT n = 0; n < subtype->GetFactoryCount(); n++ )
|
||||
{
|
||||
asIScriptFunction *func = subtype->GetFactoryByIndex(n);
|
||||
if( func->GetParamCount() == 0 )
|
||||
{
|
||||
// Found the default factory
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !found )
|
||||
{
|
||||
// No default factory
|
||||
ti->GetEngine()->WriteMessage("array", 0, 0, asMSGTYPE_ERROR, "The subtype has no default factory");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If the object type is not garbage collected then the array also doesn't need to be
|
||||
if( !(flags & asOBJ_GC) )
|
||||
dontGarbageCollect = true;
|
||||
}
|
||||
else if( !(typeId & asTYPEID_OBJHANDLE) )
|
||||
{
|
||||
// Arrays with primitives cannot form circular references,
|
||||
// thus there is no need to garbage collect them
|
||||
dontGarbageCollect = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( typeId & asTYPEID_OBJHANDLE );
|
||||
|
||||
// It is not necessary to set the array as garbage collected for all handle types.
|
||||
// If it is possible to determine that the handle cannot refer to an object type
|
||||
// that can potentially form a circular reference with the array then it is not
|
||||
// necessary to make the array garbage collected.
|
||||
asITypeInfo *subtype = ti->GetEngine()->GetTypeInfoById(typeId);
|
||||
asDWORD flags = subtype->GetFlags();
|
||||
if( !(flags & asOBJ_GC) )
|
||||
{
|
||||
if( (flags & asOBJ_SCRIPT_OBJECT) )
|
||||
{
|
||||
// Even if a script class is by itself not garbage collected, it is possible
|
||||
// that classes that derive from it may be, so it is not possible to know
|
||||
// that no circular reference can occur.
|
||||
if( (flags & asOBJ_NOINHERIT) )
|
||||
{
|
||||
// A script class declared as final cannot be inherited from, thus
|
||||
// we can be certain that the object cannot be garbage collected.
|
||||
dontGarbageCollect = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// For application registered classes we assume the application knows
|
||||
// what it is doing and don't mark the array as garbage collected unless
|
||||
// the type is also garbage collected.
|
||||
dontGarbageCollect = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The type is ok
|
||||
return true;
|
||||
}
|
||||
|
||||
// Registers the template array type
|
||||
void RegisterScriptGrid(asIScriptEngine *engine)
|
||||
{
|
||||
// TODO: Implement the generic calling convention
|
||||
RegisterScriptGrid_Native(engine);
|
||||
}
|
||||
|
||||
static void RegisterScriptGrid_Native(asIScriptEngine *engine)
|
||||
{
|
||||
int r;
|
||||
|
||||
// Register the grid type as a template
|
||||
r = engine->RegisterObjectType("grid<class T>", 0, asOBJ_REF | asOBJ_GC | asOBJ_TEMPLATE); assert( r >= 0 );
|
||||
|
||||
// Register a callback for validating the subtype before it is used
|
||||
r = engine->RegisterObjectBehaviour("grid<T>", asBEHAVE_TEMPLATE_CALLBACK, "bool f(int&in, bool&out)", asFUNCTION(ScriptGridTemplateCallback), asCALL_CDECL); assert( r >= 0 );
|
||||
|
||||
// Templates receive the object type as the first parameter. To the script writer this is hidden
|
||||
r = engine->RegisterObjectBehaviour("grid<T>", asBEHAVE_FACTORY, "grid<T>@ f(int&in)", asFUNCTIONPR(CScriptGrid::Create, (asITypeInfo*), CScriptGrid*), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("grid<T>", asBEHAVE_FACTORY, "grid<T>@ f(int&in, uint, uint)", asFUNCTIONPR(CScriptGrid::Create, (asITypeInfo*, asUINT, asUINT), CScriptGrid*), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("grid<T>", asBEHAVE_FACTORY, "grid<T>@ f(int&in, uint, uint, const T &in)", asFUNCTIONPR(CScriptGrid::Create, (asITypeInfo*, asUINT, asUINT, void *), CScriptGrid*), asCALL_CDECL); assert( r >= 0 );
|
||||
|
||||
// Register the factory that will be used for initialization lists
|
||||
r = engine->RegisterObjectBehaviour("grid<T>", asBEHAVE_LIST_FACTORY, "grid<T>@ f(int&in type, int&in list) {repeat {repeat_same T}}", asFUNCTIONPR(CScriptGrid::Create, (asITypeInfo*, void*), CScriptGrid*), asCALL_CDECL); assert( r >= 0 );
|
||||
|
||||
// The memory management methods
|
||||
r = engine->RegisterObjectBehaviour("grid<T>", asBEHAVE_ADDREF, "void f()", asMETHOD(CScriptGrid,AddRef), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("grid<T>", asBEHAVE_RELEASE, "void f()", asMETHOD(CScriptGrid,Release), asCALL_THISCALL); assert( r >= 0 );
|
||||
|
||||
// The index operator returns the template subtype
|
||||
r = engine->RegisterObjectMethod("grid<T>", "T &opIndex(uint, uint)", asMETHODPR(CScriptGrid, At, (asUINT, asUINT), void*), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("grid<T>", "const T &opIndex(uint, uint) const", asMETHODPR(CScriptGrid, At, (asUINT, asUINT) const, const void*), asCALL_THISCALL); assert( r >= 0 );
|
||||
|
||||
// Other methods
|
||||
r = engine->RegisterObjectMethod("grid<T>", "void resize(uint width, uint height)", asMETHODPR(CScriptGrid, Resize, (asUINT, asUINT), void), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("grid<T>", "uint width() const", asMETHOD(CScriptGrid, GetWidth), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("grid<T>", "uint height() const", asMETHOD(CScriptGrid, GetHeight), asCALL_THISCALL); assert( r >= 0 );
|
||||
|
||||
// Register GC behaviours in case the array needs to be garbage collected
|
||||
r = engine->RegisterObjectBehaviour("grid<T>", asBEHAVE_GETREFCOUNT, "int f()", asMETHOD(CScriptGrid, GetRefCount), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("grid<T>", asBEHAVE_SETGCFLAG, "void f()", asMETHOD(CScriptGrid, SetFlag), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("grid<T>", asBEHAVE_GETGCFLAG, "bool f()", asMETHOD(CScriptGrid, GetFlag), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("grid<T>", asBEHAVE_ENUMREFS, "void f(int&in)", asMETHOD(CScriptGrid, EnumReferences), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("grid<T>", asBEHAVE_RELEASEREFS, "void f(int&in)", asMETHOD(CScriptGrid, ReleaseAllHandles), asCALL_THISCALL); assert( r >= 0 );
|
||||
}
|
||||
|
||||
CScriptGrid::CScriptGrid(asITypeInfo *ti, void *buf)
|
||||
{
|
||||
refCount = 1;
|
||||
gcFlag = false;
|
||||
objType = ti;
|
||||
objType->AddRef();
|
||||
buffer = 0;
|
||||
subTypeId = objType->GetSubTypeId();
|
||||
|
||||
asIScriptEngine *engine = ti->GetEngine();
|
||||
|
||||
// Determine element size
|
||||
if( subTypeId & asTYPEID_MASK_OBJECT )
|
||||
elementSize = sizeof(asPWORD);
|
||||
else
|
||||
elementSize = engine->GetSizeOfPrimitiveType(subTypeId);
|
||||
|
||||
// Determine the initial size from the buffer
|
||||
asUINT height = *(asUINT*)buf;
|
||||
asUINT width = height ? *(asUINT*)((char*)(buf)+4) : 0;
|
||||
|
||||
// Make sure the grid size isn't too large for us to handle
|
||||
if( !CheckMaxSize(width, height) )
|
||||
{
|
||||
// Don't continue with the initialization
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip the height value at the start of the buffer
|
||||
buf = (asUINT*)(buf)+1;
|
||||
|
||||
// Copy the values of the grid elements from the buffer
|
||||
if( (ti->GetSubTypeId() & asTYPEID_MASK_OBJECT) == 0 )
|
||||
{
|
||||
CreateBuffer(&buffer, width, height);
|
||||
|
||||
// Copy the values of the primitive type into the internal buffer
|
||||
for( asUINT y = 0; y < height; y++ )
|
||||
{
|
||||
// Skip the length value at the start of each row
|
||||
buf = (asUINT*)(buf)+1;
|
||||
|
||||
// Copy the line
|
||||
if( width > 0 )
|
||||
memcpy(At(0,y), buf, width*elementSize);
|
||||
|
||||
// Move to next line
|
||||
buf = (char*)(buf) + width*elementSize;
|
||||
|
||||
// Align to 4 byte boundary
|
||||
if( asPWORD(buf) & 0x3 )
|
||||
buf = (char*)(buf) + 4 - (asPWORD(buf) & 0x3);
|
||||
}
|
||||
}
|
||||
else if( ti->GetSubTypeId() & asTYPEID_OBJHANDLE )
|
||||
{
|
||||
CreateBuffer(&buffer, width, height);
|
||||
|
||||
// Copy the handles into the internal buffer
|
||||
for( asUINT y = 0; y < height; y++ )
|
||||
{
|
||||
// Skip the length value at the start of each row
|
||||
buf = (asUINT*)(buf)+1;
|
||||
|
||||
// Copy the line
|
||||
if( width > 0 )
|
||||
memcpy(At(0,y), buf, width*elementSize);
|
||||
|
||||
// With object handles it is safe to clear the memory in the received buffer
|
||||
// instead of increasing the ref count. It will save time both by avoiding the
|
||||
// call the increase ref, and also relieve the engine from having to release
|
||||
// its references too
|
||||
memset(buf, 0, width*elementSize);
|
||||
|
||||
// Move to next line
|
||||
buf = (char*)(buf) + width*elementSize;
|
||||
|
||||
// Align to 4 byte boundary
|
||||
if( asPWORD(buf) & 0x3 )
|
||||
buf = (char*)(buf) + 4 - (asPWORD(buf) & 0x3);
|
||||
}
|
||||
}
|
||||
else if( ti->GetSubType()->GetFlags() & asOBJ_REF )
|
||||
{
|
||||
// Only allocate the buffer, but not the objects
|
||||
subTypeId |= asTYPEID_OBJHANDLE;
|
||||
CreateBuffer(&buffer, width, height);
|
||||
subTypeId &= ~asTYPEID_OBJHANDLE;
|
||||
|
||||
// Copy the handles into the internal buffer
|
||||
for( asUINT y = 0; y < height; y++ )
|
||||
{
|
||||
// Skip the length value at the start of each row
|
||||
buf = (asUINT*)(buf)+1;
|
||||
|
||||
// Copy the line
|
||||
if( width > 0 )
|
||||
memcpy(At(0,y), buf, width*elementSize);
|
||||
|
||||
// With object handles it is safe to clear the memory in the received buffer
|
||||
// instead of increasing the ref count. It will save time both by avoiding the
|
||||
// call the increase ref, and also relieve the engine from having to release
|
||||
// its references too
|
||||
memset(buf, 0, width*elementSize);
|
||||
|
||||
// Move to next line
|
||||
buf = (char*)(buf) + width*elementSize;
|
||||
|
||||
// Align to 4 byte boundary
|
||||
if( asPWORD(buf) & 0x3 )
|
||||
buf = (char*)(buf) + 4 - (asPWORD(buf) & 0x3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Optimize by calling the copy constructor of the object instead of
|
||||
// constructing with the default constructor and then assigning the value
|
||||
// TODO: With C++11 ideally we should be calling the move constructor, instead
|
||||
// of the copy constructor as the engine will just discard the objects in the
|
||||
// buffer afterwards.
|
||||
CreateBuffer(&buffer, width, height);
|
||||
|
||||
// For value types we need to call the opAssign for each individual object
|
||||
asITypeInfo *subType = ti->GetSubType();
|
||||
asUINT subTypeSize = subType->GetSize();
|
||||
for( asUINT y = 0;y < height; y++ )
|
||||
{
|
||||
// Skip the length value at the start of each row
|
||||
buf = (asUINT*)(buf)+1;
|
||||
|
||||
// Call opAssign for each of the objects on the row
|
||||
for( asUINT x = 0; x < width; x++ )
|
||||
{
|
||||
void *obj = At(x,y);
|
||||
asBYTE *srcObj = (asBYTE*)(buf) + x*subTypeSize;
|
||||
engine->AssignScriptObject(obj, srcObj, subType);
|
||||
}
|
||||
|
||||
// Move to next line
|
||||
buf = (char*)(buf) + width*subTypeSize;
|
||||
|
||||
// Align to 4 byte boundary
|
||||
if( asPWORD(buf) & 0x3 )
|
||||
buf = (char*)(buf) + 4 - (asPWORD(buf) & 0x3);
|
||||
}
|
||||
}
|
||||
|
||||
// Notify the GC of the successful creation
|
||||
if( objType->GetFlags() & asOBJ_GC )
|
||||
objType->GetEngine()->NotifyGarbageCollectorOfNewObject(this, objType);
|
||||
}
|
||||
|
||||
CScriptGrid::CScriptGrid(asUINT width, asUINT height, asITypeInfo *ti)
|
||||
{
|
||||
refCount = 1;
|
||||
gcFlag = false;
|
||||
objType = ti;
|
||||
objType->AddRef();
|
||||
buffer = 0;
|
||||
subTypeId = objType->GetSubTypeId();
|
||||
|
||||
// Determine element size
|
||||
if( subTypeId & asTYPEID_MASK_OBJECT )
|
||||
elementSize = sizeof(asPWORD);
|
||||
else
|
||||
elementSize = objType->GetEngine()->GetSizeOfPrimitiveType(subTypeId);
|
||||
|
||||
// Make sure the array size isn't too large for us to handle
|
||||
if( !CheckMaxSize(width, height) )
|
||||
{
|
||||
// Don't continue with the initialization
|
||||
return;
|
||||
}
|
||||
|
||||
CreateBuffer(&buffer, width, height);
|
||||
|
||||
// Notify the GC of the successful creation
|
||||
if( objType->GetFlags() & asOBJ_GC )
|
||||
objType->GetEngine()->NotifyGarbageCollectorOfNewObject(this, objType);
|
||||
}
|
||||
|
||||
void CScriptGrid::Resize(asUINT width, asUINT height)
|
||||
{
|
||||
// Make sure the size isn't too large for us to handle
|
||||
if( !CheckMaxSize(width, height) )
|
||||
return;
|
||||
|
||||
// Create a new buffer
|
||||
SGridBuffer *tmpBuffer = 0;
|
||||
CreateBuffer(&tmpBuffer, width, height);
|
||||
if( tmpBuffer == 0 )
|
||||
return;
|
||||
|
||||
if( buffer )
|
||||
{
|
||||
// Copy the existing values to the new buffer
|
||||
asUINT w = width > buffer->width ? buffer->width : width;
|
||||
asUINT h = height > buffer->height ? buffer->height : height;
|
||||
for( asUINT y = 0; y < h; y++ )
|
||||
for( asUINT x = 0; x < w; x++ )
|
||||
SetValue(tmpBuffer, x, y, At(buffer, x, y));
|
||||
|
||||
// Replace the internal buffer
|
||||
DeleteBuffer(buffer);
|
||||
}
|
||||
|
||||
buffer = tmpBuffer;
|
||||
}
|
||||
|
||||
CScriptGrid::CScriptGrid(asUINT width, asUINT height, void *defVal, asITypeInfo *ti)
|
||||
{
|
||||
refCount = 1;
|
||||
gcFlag = false;
|
||||
objType = ti;
|
||||
objType->AddRef();
|
||||
buffer = 0;
|
||||
subTypeId = objType->GetSubTypeId();
|
||||
|
||||
// Determine element size
|
||||
if( subTypeId & asTYPEID_MASK_OBJECT )
|
||||
elementSize = sizeof(asPWORD);
|
||||
else
|
||||
elementSize = objType->GetEngine()->GetSizeOfPrimitiveType(subTypeId);
|
||||
|
||||
// Make sure the array size isn't too large for us to handle
|
||||
if( !CheckMaxSize(width, height) )
|
||||
{
|
||||
// Don't continue with the initialization
|
||||
return;
|
||||
}
|
||||
|
||||
CreateBuffer(&buffer, width, height);
|
||||
|
||||
// Notify the GC of the successful creation
|
||||
if( objType->GetFlags() & asOBJ_GC )
|
||||
objType->GetEngine()->NotifyGarbageCollectorOfNewObject(this, objType);
|
||||
|
||||
// Initialize the elements with the default value
|
||||
for( asUINT y = 0; y < GetHeight(); y++ )
|
||||
for( asUINT x = 0; x < GetWidth(); x++ )
|
||||
SetValue(x, y, defVal);
|
||||
}
|
||||
|
||||
void CScriptGrid::SetValue(asUINT x, asUINT y, void *value)
|
||||
{
|
||||
SetValue(buffer, x, y, value);
|
||||
}
|
||||
|
||||
void CScriptGrid::SetValue(SGridBuffer *buf, asUINT x, asUINT y, void *value)
|
||||
{
|
||||
// At() will take care of the out-of-bounds checking, though
|
||||
// if called from the application then nothing will be done
|
||||
void *ptr = At(buf, x, y);
|
||||
if( ptr == 0 ) return;
|
||||
|
||||
if( (subTypeId & ~asTYPEID_MASK_SEQNBR) && !(subTypeId & asTYPEID_OBJHANDLE) )
|
||||
objType->GetEngine()->AssignScriptObject(ptr, value, objType->GetSubType());
|
||||
else if( subTypeId & asTYPEID_OBJHANDLE )
|
||||
{
|
||||
void *tmp = *(void**)ptr;
|
||||
*(void**)ptr = *(void**)value;
|
||||
objType->GetEngine()->AddRefScriptObject(*(void**)value, objType->GetSubType());
|
||||
if( tmp )
|
||||
objType->GetEngine()->ReleaseScriptObject(tmp, objType->GetSubType());
|
||||
}
|
||||
else if( subTypeId == asTYPEID_BOOL ||
|
||||
subTypeId == asTYPEID_INT8 ||
|
||||
subTypeId == asTYPEID_UINT8 )
|
||||
*(char*)ptr = *(char*)value;
|
||||
else if( subTypeId == asTYPEID_INT16 ||
|
||||
subTypeId == asTYPEID_UINT16 )
|
||||
*(short*)ptr = *(short*)value;
|
||||
else if( subTypeId == asTYPEID_INT32 ||
|
||||
subTypeId == asTYPEID_UINT32 ||
|
||||
subTypeId == asTYPEID_FLOAT ||
|
||||
subTypeId > asTYPEID_DOUBLE ) // enums have a type id larger than doubles
|
||||
*(int*)ptr = *(int*)value;
|
||||
else if( subTypeId == asTYPEID_INT64 ||
|
||||
subTypeId == asTYPEID_UINT64 ||
|
||||
subTypeId == asTYPEID_DOUBLE )
|
||||
*(double*)ptr = *(double*)value;
|
||||
}
|
||||
|
||||
CScriptGrid::~CScriptGrid()
|
||||
{
|
||||
if( buffer )
|
||||
{
|
||||
DeleteBuffer(buffer);
|
||||
buffer = 0;
|
||||
}
|
||||
if( objType ) objType->Release();
|
||||
}
|
||||
|
||||
asUINT CScriptGrid::GetWidth() const
|
||||
{
|
||||
if( buffer )
|
||||
return buffer->width;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
asUINT CScriptGrid::GetHeight() const
|
||||
{
|
||||
if( buffer )
|
||||
return buffer->height;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// internal
|
||||
bool CScriptGrid::CheckMaxSize(asUINT width, asUINT height)
|
||||
{
|
||||
// This code makes sure the size of the buffer that is allocated
|
||||
// for the array doesn't overflow and becomes smaller than requested
|
||||
|
||||
asUINT maxSize = 0xFFFFFFFFul - sizeof(SGridBuffer) + 1;
|
||||
if( elementSize > 0 )
|
||||
maxSize /= elementSize;
|
||||
|
||||
asINT64 numElements = width * height;
|
||||
|
||||
if( (numElements >> 32) || numElements > maxSize )
|
||||
{
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
if( ctx )
|
||||
ctx->SetException("Too large grid size");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// OK
|
||||
return true;
|
||||
}
|
||||
|
||||
asITypeInfo *CScriptGrid::GetGridObjectType() const
|
||||
{
|
||||
return objType;
|
||||
}
|
||||
|
||||
int CScriptGrid::GetGridTypeId() const
|
||||
{
|
||||
return objType->GetTypeId();
|
||||
}
|
||||
|
||||
int CScriptGrid::GetElementTypeId() const
|
||||
{
|
||||
return subTypeId;
|
||||
}
|
||||
|
||||
void *CScriptGrid::At(asUINT x, asUINT y)
|
||||
{
|
||||
return At(buffer, x, y);
|
||||
}
|
||||
|
||||
// Return a pointer to the array element. Returns 0 if the index is out of bounds
|
||||
void *CScriptGrid::At(SGridBuffer *buf, asUINT x, asUINT y)
|
||||
{
|
||||
if( buf == 0 || x >= buf->width || y >= buf->height )
|
||||
{
|
||||
// If this is called from a script we raise a script exception
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
if( ctx )
|
||||
ctx->SetException("Index out of bounds");
|
||||
return 0;
|
||||
}
|
||||
|
||||
asUINT index = x+y*buf->width;
|
||||
if( (subTypeId & asTYPEID_MASK_OBJECT) && !(subTypeId & asTYPEID_OBJHANDLE) )
|
||||
return *(void**)(buf->data + elementSize*index);
|
||||
else
|
||||
return buf->data + elementSize*index;
|
||||
}
|
||||
const void *CScriptGrid::At(asUINT x, asUINT y) const
|
||||
{
|
||||
return const_cast<CScriptGrid*>(this)->At(const_cast<SGridBuffer*>(buffer), x, y);
|
||||
}
|
||||
|
||||
|
||||
// internal
|
||||
void CScriptGrid::CreateBuffer(SGridBuffer **buf, asUINT w, asUINT h)
|
||||
{
|
||||
asUINT numElements = w * h;
|
||||
|
||||
*buf = reinterpret_cast<SGridBuffer*>(userAlloc(sizeof(SGridBuffer)-1+elementSize*numElements));
|
||||
|
||||
if( *buf )
|
||||
{
|
||||
(*buf)->width = w;
|
||||
(*buf)->height = h;
|
||||
Construct(*buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Oops, out of memory
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
if( ctx )
|
||||
ctx->SetException("Out of memory");
|
||||
}
|
||||
}
|
||||
|
||||
// internal
|
||||
void CScriptGrid::DeleteBuffer(SGridBuffer *buf)
|
||||
{
|
||||
assert( buf );
|
||||
|
||||
Destruct(buf);
|
||||
|
||||
// Free the buffer
|
||||
userFree(buf);
|
||||
}
|
||||
|
||||
// internal
|
||||
void CScriptGrid::Construct(SGridBuffer *buf)
|
||||
{
|
||||
assert( buf );
|
||||
|
||||
if( subTypeId & asTYPEID_OBJHANDLE )
|
||||
{
|
||||
// Set all object handles to null
|
||||
void *d = (void*)(buf->data);
|
||||
memset(d, 0, (buf->width*buf->height)*sizeof(void*));
|
||||
}
|
||||
else if( subTypeId & asTYPEID_MASK_OBJECT )
|
||||
{
|
||||
void **max = (void**)(buf->data + (buf->width*buf->height) * sizeof(void*));
|
||||
void **d = (void**)(buf->data);
|
||||
|
||||
asIScriptEngine *engine = objType->GetEngine();
|
||||
asITypeInfo *subType = objType->GetSubType();
|
||||
|
||||
for( ; d < max; d++ )
|
||||
{
|
||||
*d = (void*)engine->CreateScriptObject(subType);
|
||||
if( *d == 0 )
|
||||
{
|
||||
// Set the remaining entries to null so the destructor
|
||||
// won't attempt to destroy invalid objects later
|
||||
memset(d, 0, sizeof(void*)*(max-d));
|
||||
|
||||
// There is no need to set an exception on the context,
|
||||
// as CreateScriptObject has already done that
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// internal
|
||||
void CScriptGrid::Destruct(SGridBuffer *buf)
|
||||
{
|
||||
assert( buf );
|
||||
|
||||
if( subTypeId & asTYPEID_MASK_OBJECT )
|
||||
{
|
||||
asIScriptEngine *engine = objType->GetEngine();
|
||||
|
||||
void **max = (void**)(buf->data + (buf->width*buf->height) * sizeof(void*));
|
||||
void **d = (void**)(buf->data);
|
||||
|
||||
for( ; d < max; d++ )
|
||||
{
|
||||
if( *d )
|
||||
engine->ReleaseScriptObject(*d, objType->GetSubType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GC behaviour
|
||||
void CScriptGrid::EnumReferences(asIScriptEngine *engine)
|
||||
{
|
||||
if( buffer == 0 ) return;
|
||||
|
||||
// If the grid is holding handles, then we need to notify the GC of them
|
||||
if (subTypeId & asTYPEID_MASK_OBJECT)
|
||||
{
|
||||
asUINT numElements = buffer->width * buffer->height;
|
||||
void **d = (void**)buffer->data;
|
||||
asITypeInfo *subType = engine->GetTypeInfoById(subTypeId);
|
||||
if ((subType->GetFlags() & asOBJ_REF))
|
||||
{
|
||||
// For reference types we need to notify the GC of each instance
|
||||
for (asUINT n = 0; n < numElements; n++)
|
||||
{
|
||||
if (d[n])
|
||||
engine->GCEnumCallback(d[n]);
|
||||
}
|
||||
}
|
||||
else if ((subType->GetFlags() & asOBJ_VALUE) && (subType->GetFlags() & asOBJ_GC))
|
||||
{
|
||||
// For value types we need to forward the enum callback
|
||||
// to the object so it can decide what to do
|
||||
for (asUINT n = 0; n < numElements; n++)
|
||||
{
|
||||
if (d[n])
|
||||
engine->ForwardGCEnumReferences(d[n], subType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GC behaviour
|
||||
void CScriptGrid::ReleaseAllHandles(asIScriptEngine*)
|
||||
{
|
||||
if( buffer == 0 ) return;
|
||||
|
||||
DeleteBuffer(buffer);
|
||||
buffer = 0;
|
||||
}
|
||||
|
||||
void CScriptGrid::AddRef() const
|
||||
{
|
||||
// Clear the GC flag then increase the counter
|
||||
gcFlag = false;
|
||||
asAtomicInc(refCount);
|
||||
}
|
||||
|
||||
void CScriptGrid::Release() const
|
||||
{
|
||||
// Clearing the GC flag then descrease the counter
|
||||
gcFlag = false;
|
||||
if( asAtomicDec(refCount) == 0 )
|
||||
{
|
||||
// When reaching 0 no more references to this instance
|
||||
// exists and the object should be destroyed
|
||||
this->~CScriptGrid();
|
||||
userFree(const_cast<CScriptGrid*>(this));
|
||||
}
|
||||
}
|
||||
|
||||
// GC behaviour
|
||||
int CScriptGrid::GetRefCount()
|
||||
{
|
||||
return refCount;
|
||||
}
|
||||
|
||||
// GC behaviour
|
||||
void CScriptGrid::SetFlag()
|
||||
{
|
||||
gcFlag = true;
|
||||
}
|
||||
|
||||
// GC behaviour
|
||||
bool CScriptGrid::GetFlag()
|
||||
{
|
||||
return gcFlag;
|
||||
}
|
||||
|
||||
END_AS_NAMESPACE
|
|
@ -0,0 +1,82 @@
|
|||
#ifndef SCRIPTGRID_H
|
||||
#define SCRIPTGRID_H
|
||||
|
||||
#ifndef ANGELSCRIPT_H
|
||||
// Avoid having to inform include path if header is already include before
|
||||
#include <angelscript.h>
|
||||
#endif
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
struct SGridBuffer;
|
||||
|
||||
class CScriptGrid
|
||||
{
|
||||
public:
|
||||
// Set the memory functions that should be used by all CScriptGrids
|
||||
static void SetMemoryFunctions(asALLOCFUNC_t allocFunc, asFREEFUNC_t freeFunc);
|
||||
|
||||
// Factory functions
|
||||
static CScriptGrid *Create(asITypeInfo *ot);
|
||||
static CScriptGrid *Create(asITypeInfo *ot, asUINT width, asUINT height);
|
||||
static CScriptGrid *Create(asITypeInfo *ot, asUINT width, asUINT height, void *defaultValue);
|
||||
static CScriptGrid *Create(asITypeInfo *ot, void *listBuffer);
|
||||
|
||||
// Memory management
|
||||
void AddRef() const;
|
||||
void Release() const;
|
||||
|
||||
// Type information
|
||||
asITypeInfo *GetGridObjectType() const;
|
||||
int GetGridTypeId() const;
|
||||
int GetElementTypeId() const;
|
||||
|
||||
// Size
|
||||
asUINT GetWidth() const;
|
||||
asUINT GetHeight() const;
|
||||
void Resize(asUINT width, asUINT height);
|
||||
|
||||
// Get a pointer to an element. Returns 0 if out of bounds
|
||||
void *At(asUINT x, asUINT y);
|
||||
const void *At(asUINT x, asUINT y) const;
|
||||
|
||||
// Set value of an element
|
||||
// Remember, if the grid holds handles the value parameter should be the
|
||||
// address of the handle. The refCount of the object will also be incremented
|
||||
void SetValue(asUINT x, asUINT y, void *value);
|
||||
|
||||
// GC methods
|
||||
int GetRefCount();
|
||||
void SetFlag();
|
||||
bool GetFlag();
|
||||
void EnumReferences(asIScriptEngine *engine);
|
||||
void ReleaseAllHandles(asIScriptEngine *engine);
|
||||
|
||||
protected:
|
||||
mutable int refCount;
|
||||
mutable bool gcFlag;
|
||||
asITypeInfo *objType;
|
||||
SGridBuffer *buffer;
|
||||
int elementSize;
|
||||
int subTypeId;
|
||||
|
||||
// Constructors
|
||||
CScriptGrid(asITypeInfo *ot, void *initBuf); // Called from script when initialized with list
|
||||
CScriptGrid(asUINT w, asUINT h, asITypeInfo *ot);
|
||||
CScriptGrid(asUINT w, asUINT h, void *defVal, asITypeInfo *ot);
|
||||
virtual ~CScriptGrid();
|
||||
|
||||
bool CheckMaxSize(asUINT x, asUINT y);
|
||||
void CreateBuffer(SGridBuffer **buf, asUINT w, asUINT h);
|
||||
void DeleteBuffer(SGridBuffer *buf);
|
||||
void Construct(SGridBuffer *buf);
|
||||
void Destruct(SGridBuffer *buf);
|
||||
void SetValue(SGridBuffer *buf, asUINT x, asUINT y, void *value);
|
||||
void *At(SGridBuffer *buf, asUINT x, asUINT y);
|
||||
};
|
||||
|
||||
void RegisterScriptGrid(asIScriptEngine *engine);
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,360 @@
|
|||
#include "scripthandle.h"
|
||||
#include <new>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
static void Construct(CScriptHandle *self) { new(self) CScriptHandle(); }
|
||||
static void Construct(CScriptHandle *self, const CScriptHandle &o) { new(self) CScriptHandle(o); }
|
||||
// This one is not static because it needs to be friend with the CScriptHandle class
|
||||
void Construct(CScriptHandle *self, void *ref, int typeId) { new(self) CScriptHandle(ref, typeId); }
|
||||
static void Destruct(CScriptHandle *self) { self->~CScriptHandle(); }
|
||||
|
||||
CScriptHandle::CScriptHandle()
|
||||
{
|
||||
m_ref = 0;
|
||||
m_type = 0;
|
||||
}
|
||||
|
||||
CScriptHandle::CScriptHandle(const CScriptHandle &other)
|
||||
{
|
||||
m_ref = other.m_ref;
|
||||
m_type = other.m_type;
|
||||
|
||||
AddRefHandle();
|
||||
}
|
||||
|
||||
CScriptHandle::CScriptHandle(void *ref, asITypeInfo *type)
|
||||
{
|
||||
m_ref = ref;
|
||||
m_type = type;
|
||||
|
||||
AddRefHandle();
|
||||
}
|
||||
|
||||
// This constructor shouldn't be called from the application
|
||||
// directly as it requires an active script context
|
||||
CScriptHandle::CScriptHandle(void *ref, int typeId)
|
||||
{
|
||||
m_ref = 0;
|
||||
m_type = 0;
|
||||
|
||||
Assign(ref, typeId);
|
||||
}
|
||||
|
||||
CScriptHandle::~CScriptHandle()
|
||||
{
|
||||
ReleaseHandle();
|
||||
}
|
||||
|
||||
void CScriptHandle::ReleaseHandle()
|
||||
{
|
||||
if( m_ref && m_type )
|
||||
{
|
||||
asIScriptEngine *engine = m_type->GetEngine();
|
||||
engine->ReleaseScriptObject(m_ref, m_type);
|
||||
|
||||
engine->Release();
|
||||
|
||||
m_ref = 0;
|
||||
m_type = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CScriptHandle::AddRefHandle()
|
||||
{
|
||||
if( m_ref && m_type )
|
||||
{
|
||||
asIScriptEngine *engine = m_type->GetEngine();
|
||||
engine->AddRefScriptObject(m_ref, m_type);
|
||||
|
||||
// Hold on to the engine so it isn't destroyed while
|
||||
// a reference to a script object is still held
|
||||
engine->AddRef();
|
||||
}
|
||||
}
|
||||
|
||||
CScriptHandle &CScriptHandle::operator =(const CScriptHandle &other)
|
||||
{
|
||||
Set(other.m_ref, other.m_type);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void CScriptHandle::Set(void *ref, asITypeInfo *type)
|
||||
{
|
||||
if( m_ref == ref ) return;
|
||||
|
||||
ReleaseHandle();
|
||||
|
||||
m_ref = ref;
|
||||
m_type = type;
|
||||
|
||||
AddRefHandle();
|
||||
}
|
||||
|
||||
void *CScriptHandle::GetRef()
|
||||
{
|
||||
return m_ref;
|
||||
}
|
||||
|
||||
asITypeInfo *CScriptHandle::GetType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
int CScriptHandle::GetTypeId() const
|
||||
{
|
||||
if( m_type == 0 ) return 0;
|
||||
|
||||
return m_type->GetTypeId() | asTYPEID_OBJHANDLE;
|
||||
}
|
||||
|
||||
// This method shouldn't be called from the application
|
||||
// directly as it requires an active script context
|
||||
CScriptHandle &CScriptHandle::Assign(void *ref, int typeId)
|
||||
{
|
||||
// When receiving a null handle we just clear our memory
|
||||
if( typeId == 0 )
|
||||
{
|
||||
Set(0, 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Dereference received handles to get the object
|
||||
if( typeId & asTYPEID_OBJHANDLE )
|
||||
{
|
||||
// Store the actual reference
|
||||
ref = *(void**)ref;
|
||||
typeId &= ~asTYPEID_OBJHANDLE;
|
||||
}
|
||||
|
||||
// Get the object type
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
asIScriptEngine *engine = ctx->GetEngine();
|
||||
asITypeInfo *type = engine->GetTypeInfoById(typeId);
|
||||
|
||||
// If the argument is another CScriptHandle, we should copy the content instead
|
||||
if( type && strcmp(type->GetName(), "ref") == 0 )
|
||||
{
|
||||
CScriptHandle *r = (CScriptHandle*)ref;
|
||||
ref = r->m_ref;
|
||||
type = r->m_type;
|
||||
}
|
||||
|
||||
Set(ref, type);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool CScriptHandle::operator==(const CScriptHandle &o) const
|
||||
{
|
||||
if( m_ref == o.m_ref &&
|
||||
m_type == o.m_type )
|
||||
return true;
|
||||
|
||||
// TODO: If type is not the same, we should attempt to do a dynamic cast,
|
||||
// which may change the pointer for application registered classes
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CScriptHandle::operator!=(const CScriptHandle &o) const
|
||||
{
|
||||
return !(*this == o);
|
||||
}
|
||||
|
||||
bool CScriptHandle::Equals(void *ref, int typeId) const
|
||||
{
|
||||
// Null handles are received as reference to a null handle
|
||||
if( typeId == 0 )
|
||||
ref = 0;
|
||||
|
||||
// Dereference handles to get the object
|
||||
if( typeId & asTYPEID_OBJHANDLE )
|
||||
{
|
||||
// Compare the actual reference
|
||||
ref = *(void**)ref;
|
||||
typeId &= ~asTYPEID_OBJHANDLE;
|
||||
}
|
||||
|
||||
// TODO: If typeId is not the same, we should attempt to do a dynamic cast,
|
||||
// which may change the pointer for application registered classes
|
||||
|
||||
if( ref == m_ref ) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// AngelScript: used as '@obj = cast<obj>(ref);'
|
||||
void CScriptHandle::Cast(void **outRef, int typeId)
|
||||
{
|
||||
// If we hold a null handle, then just return null
|
||||
if( m_type == 0 )
|
||||
{
|
||||
*outRef = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// It is expected that the outRef is always a handle
|
||||
assert( typeId & asTYPEID_OBJHANDLE );
|
||||
|
||||
// Compare the type id of the actual object
|
||||
typeId &= ~asTYPEID_OBJHANDLE;
|
||||
asIScriptEngine *engine = m_type->GetEngine();
|
||||
asITypeInfo *type = engine->GetTypeInfoById(typeId);
|
||||
|
||||
*outRef = 0;
|
||||
|
||||
// RefCastObject will increment the refCount of the returned object if successful
|
||||
engine->RefCastObject(m_ref, m_type, type, outRef);
|
||||
}
|
||||
|
||||
void CScriptHandle::EnumReferences(asIScriptEngine *inEngine)
|
||||
{
|
||||
// If we're holding a reference, we'll notify the garbage collector of it
|
||||
if (m_ref)
|
||||
inEngine->GCEnumCallback(m_ref);
|
||||
|
||||
// The object type itself is also garbage collected
|
||||
if( m_type)
|
||||
inEngine->GCEnumCallback(m_type);
|
||||
}
|
||||
|
||||
void CScriptHandle::ReleaseReferences(asIScriptEngine *inEngine)
|
||||
{
|
||||
// Simply clear the content to release the references
|
||||
Set(0, 0);
|
||||
}
|
||||
|
||||
void RegisterScriptHandle_Native(asIScriptEngine *engine)
|
||||
{
|
||||
int r;
|
||||
|
||||
#if AS_CAN_USE_CPP11
|
||||
// With C++11 it is possible to use asGetTypeTraits to automatically determine the flags that represent the C++ class
|
||||
r = engine->RegisterObjectType("ref", sizeof(CScriptHandle), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_GC | asGetTypeTraits<CScriptHandle>()); assert( r >= 0 );
|
||||
#else
|
||||
r = engine->RegisterObjectType("ref", sizeof(CScriptHandle), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_GC | asOBJ_APP_CLASS_CDAK); assert( r >= 0 );
|
||||
#endif
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_CONSTRUCT, "void f()", asFUNCTIONPR(Construct, (CScriptHandle *), void), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_CONSTRUCT, "void f(const ref &in)", asFUNCTIONPR(Construct, (CScriptHandle *, const CScriptHandle &), void), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_CONSTRUCT, "void f(const ?&in)", asFUNCTIONPR(Construct, (CScriptHandle *, void *, int), void), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_DESTRUCT, "void f()", asFUNCTIONPR(Destruct, (CScriptHandle *), void), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_ENUMREFS, "void f(int&in)", asMETHOD(CScriptHandle,EnumReferences), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_RELEASEREFS, "void f(int&in)", asMETHOD(CScriptHandle, ReleaseReferences), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("ref", "void opCast(?&out)", asMETHODPR(CScriptHandle, Cast, (void **, int), void), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("ref", "ref &opHndlAssign(const ref &in)", asMETHOD(CScriptHandle, operator=), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("ref", "ref &opHndlAssign(const ?&in)", asMETHOD(CScriptHandle, Assign), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("ref", "bool opEquals(const ref &in) const", asMETHODPR(CScriptHandle, operator==, (const CScriptHandle &) const, bool), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("ref", "bool opEquals(const ?&in) const", asMETHODPR(CScriptHandle, Equals, (void*, int) const, bool), asCALL_THISCALL); assert( r >= 0 );
|
||||
}
|
||||
|
||||
void CScriptHandle_Construct_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
new(self) CScriptHandle();
|
||||
}
|
||||
|
||||
void CScriptHandle_ConstructCopy_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptHandle *other = reinterpret_cast<CScriptHandle*>(gen->GetArgAddress(0));
|
||||
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
new(self) CScriptHandle(*other);
|
||||
}
|
||||
|
||||
void CScriptHandle_ConstructVar_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
void *ref = gen->GetArgAddress(0);
|
||||
int typeId = gen->GetArgTypeId(0);
|
||||
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
Construct(self, ref, typeId);
|
||||
}
|
||||
|
||||
void CScriptHandle_Destruct_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
self->~CScriptHandle();
|
||||
}
|
||||
|
||||
void CScriptHandle_Cast_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
void **ref = reinterpret_cast<void**>(gen->GetArgAddress(0));
|
||||
int typeId = gen->GetArgTypeId(0);
|
||||
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
self->Cast(ref, typeId);
|
||||
}
|
||||
|
||||
void CScriptHandle_Assign_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptHandle *other = reinterpret_cast<CScriptHandle*>(gen->GetArgAddress(0));
|
||||
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
*self = *other;
|
||||
gen->SetReturnAddress(self);
|
||||
}
|
||||
|
||||
void CScriptHandle_AssignVar_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
void *ref = gen->GetArgAddress(0);
|
||||
int typeId = gen->GetArgTypeId(0);
|
||||
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
self->Assign(ref, typeId);
|
||||
gen->SetReturnAddress(self);
|
||||
}
|
||||
|
||||
void CScriptHandle_Equals_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptHandle *other = reinterpret_cast<CScriptHandle*>(gen->GetArgAddress(0));
|
||||
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
gen->SetReturnByte(*self == *other);
|
||||
}
|
||||
|
||||
void CScriptHandle_EqualsVar_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
void *ref = gen->GetArgAddress(0);
|
||||
int typeId = gen->GetArgTypeId(0);
|
||||
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
gen->SetReturnByte(self->Equals(ref, typeId));
|
||||
}
|
||||
|
||||
void CScriptHandle_EnumReferences_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
self->EnumReferences(gen->GetEngine());
|
||||
}
|
||||
|
||||
void CScriptHandle_ReleaseReferences_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptHandle *self = reinterpret_cast<CScriptHandle*>(gen->GetObject());
|
||||
self->ReleaseReferences(gen->GetEngine());
|
||||
}
|
||||
|
||||
void RegisterScriptHandle_Generic(asIScriptEngine *engine)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = engine->RegisterObjectType("ref", sizeof(CScriptHandle), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_GC | asOBJ_APP_CLASS_CDAK); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(CScriptHandle_Construct_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_CONSTRUCT, "void f(const ref &in)", asFUNCTION(CScriptHandle_ConstructCopy_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_CONSTRUCT, "void f(const ?&in)", asFUNCTION(CScriptHandle_ConstructVar_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(CScriptHandle_Destruct_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_ENUMREFS, "void f(int&in)", asFUNCTION(CScriptHandle_EnumReferences_Generic), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_RELEASEREFS, "void f(int&in)", asFUNCTION(CScriptHandle_ReleaseReferences_Generic), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("ref", "void opCast(?&out)", asFUNCTION(CScriptHandle_Cast_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("ref", "ref &opHndlAssign(const ref &in)", asFUNCTION(CScriptHandle_Assign_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("ref", "ref &opHndlAssign(const ?&in)", asFUNCTION(CScriptHandle_AssignVar_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("ref", "bool opEquals(const ref &in) const", asFUNCTION(CScriptHandle_Equals_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("ref", "bool opEquals(const ?&in) const", asFUNCTION(CScriptHandle_EqualsVar_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
}
|
||||
|
||||
void RegisterScriptHandle(asIScriptEngine *engine)
|
||||
{
|
||||
if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
|
||||
RegisterScriptHandle_Generic(engine);
|
||||
else
|
||||
RegisterScriptHandle_Native(engine);
|
||||
}
|
||||
|
||||
|
||||
END_AS_NAMESPACE
|
|
@ -0,0 +1,69 @@
|
|||
#ifndef SCRIPTHANDLE_H
|
||||
#define SCRIPTHANDLE_H
|
||||
|
||||
#ifndef ANGELSCRIPT_H
|
||||
// Avoid having to inform include path if header is already include before
|
||||
#include <angelscript.h>
|
||||
#endif
|
||||
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
class CScriptHandle
|
||||
{
|
||||
public:
|
||||
// Constructors
|
||||
CScriptHandle();
|
||||
CScriptHandle(const CScriptHandle &other);
|
||||
CScriptHandle(void *ref, asITypeInfo *type);
|
||||
~CScriptHandle();
|
||||
|
||||
// Copy the stored value from another any object
|
||||
CScriptHandle &operator=(const CScriptHandle &other);
|
||||
|
||||
// Set the reference
|
||||
void Set(void *ref, asITypeInfo *type);
|
||||
|
||||
// Compare equalness
|
||||
bool operator==(const CScriptHandle &o) const;
|
||||
bool operator!=(const CScriptHandle &o) const;
|
||||
bool Equals(void *ref, int typeId) const;
|
||||
|
||||
// Dynamic cast to desired handle type
|
||||
void Cast(void **outRef, int typeId);
|
||||
|
||||
// Returns the type of the reference held
|
||||
asITypeInfo *GetType() const;
|
||||
int GetTypeId() const;
|
||||
|
||||
// Get the reference
|
||||
void *GetRef();
|
||||
|
||||
// GC callback
|
||||
void EnumReferences(asIScriptEngine *engine);
|
||||
void ReleaseReferences(asIScriptEngine *engine);
|
||||
|
||||
protected:
|
||||
// These functions need to have access to protected
|
||||
// members in order to call them from the script engine
|
||||
friend void Construct(CScriptHandle *self, void *ref, int typeId);
|
||||
friend void RegisterScriptHandle_Native(asIScriptEngine *engine);
|
||||
friend void CScriptHandle_AssignVar_Generic(asIScriptGeneric *gen);
|
||||
|
||||
void ReleaseHandle();
|
||||
void AddRefHandle();
|
||||
|
||||
// These shouldn't be called directly by the
|
||||
// application as they requires an active context
|
||||
CScriptHandle(void *ref, int typeId);
|
||||
CScriptHandle &Assign(void *ref, int typeId);
|
||||
|
||||
void *m_ref;
|
||||
asITypeInfo *m_type;
|
||||
};
|
||||
|
||||
void RegisterScriptHandle(asIScriptEngine *engine);
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,987 @@
|
|||
#include <string.h>
|
||||
#include "scripthelper.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <fstream>
|
||||
#include <set>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
int CompareRelation(asIScriptEngine *engine, void *lobj, void *robj, int typeId, int &result)
|
||||
{
|
||||
// TODO: If a lot of script objects are going to be compared, e.g. when sorting an array,
|
||||
// then the method id and context should be cached between calls.
|
||||
|
||||
int retval = -1;
|
||||
asIScriptFunction *func = 0;
|
||||
|
||||
asITypeInfo *ti = engine->GetTypeInfoById(typeId);
|
||||
if( ti )
|
||||
{
|
||||
// Check if the object type has a compatible opCmp method
|
||||
for( asUINT n = 0; n < ti->GetMethodCount(); n++ )
|
||||
{
|
||||
asIScriptFunction *f = ti->GetMethodByIndex(n);
|
||||
asDWORD flags;
|
||||
if( strcmp(f->GetName(), "opCmp") == 0 &&
|
||||
f->GetReturnTypeId(&flags) == asTYPEID_INT32 &&
|
||||
flags == asTM_NONE &&
|
||||
f->GetParamCount() == 1 )
|
||||
{
|
||||
int paramTypeId;
|
||||
f->GetParam(0, ¶mTypeId, &flags);
|
||||
|
||||
// The parameter must be an input reference of the same type
|
||||
// If the reference is a inout reference, then it must also be read-only
|
||||
if( !(flags & asTM_INREF) || typeId != paramTypeId || ((flags & asTM_OUTREF) && !(flags & asTM_CONST)) )
|
||||
break;
|
||||
|
||||
// Found the method
|
||||
func = f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( func )
|
||||
{
|
||||
// Call the method
|
||||
asIScriptContext *ctx = engine->CreateContext();
|
||||
ctx->Prepare(func);
|
||||
ctx->SetObject(lobj);
|
||||
ctx->SetArgAddress(0, robj);
|
||||
int r = ctx->Execute();
|
||||
if( r == asEXECUTION_FINISHED )
|
||||
{
|
||||
result = (int)ctx->GetReturnDWord();
|
||||
|
||||
// The comparison was successful
|
||||
retval = 0;
|
||||
}
|
||||
ctx->Release();
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int CompareEquality(asIScriptEngine *engine, void *lobj, void *robj, int typeId, bool &result)
|
||||
{
|
||||
// TODO: If a lot of script objects are going to be compared, e.g. when searching for an
|
||||
// entry in a set, then the method and context should be cached between calls.
|
||||
|
||||
int retval = -1;
|
||||
asIScriptFunction *func = 0;
|
||||
|
||||
asITypeInfo *ti = engine->GetTypeInfoById(typeId);
|
||||
if( ti )
|
||||
{
|
||||
// Check if the object type has a compatible opEquals method
|
||||
for( asUINT n = 0; n < ti->GetMethodCount(); n++ )
|
||||
{
|
||||
asIScriptFunction *f = ti->GetMethodByIndex(n);
|
||||
asDWORD flags;
|
||||
if( strcmp(f->GetName(), "opEquals") == 0 &&
|
||||
f->GetReturnTypeId(&flags) == asTYPEID_BOOL &&
|
||||
flags == asTM_NONE &&
|
||||
f->GetParamCount() == 1 )
|
||||
{
|
||||
int paramTypeId;
|
||||
f->GetParam(0, ¶mTypeId, &flags);
|
||||
|
||||
// The parameter must be an input reference of the same type
|
||||
// If the reference is a inout reference, then it must also be read-only
|
||||
if( !(flags & asTM_INREF) || typeId != paramTypeId || ((flags & asTM_OUTREF) && !(flags & asTM_CONST)) )
|
||||
break;
|
||||
|
||||
// Found the method
|
||||
func = f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( func )
|
||||
{
|
||||
// Call the method
|
||||
asIScriptContext *ctx = engine->CreateContext();
|
||||
ctx->Prepare(func);
|
||||
ctx->SetObject(lobj);
|
||||
ctx->SetArgAddress(0, robj);
|
||||
int r = ctx->Execute();
|
||||
if( r == asEXECUTION_FINISHED )
|
||||
{
|
||||
result = ctx->GetReturnByte() ? true : false;
|
||||
|
||||
// The comparison was successful
|
||||
retval = 0;
|
||||
}
|
||||
ctx->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the opEquals method doesn't exist, then we try with opCmp instead
|
||||
int relation;
|
||||
retval = CompareRelation(engine, lobj, robj, typeId, relation);
|
||||
if( retval >= 0 )
|
||||
result = relation == 0 ? true : false;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int ExecuteString(asIScriptEngine *engine, const char *code, asIScriptModule *mod, asIScriptContext *ctx)
|
||||
{
|
||||
return ExecuteString(engine, code, 0, asTYPEID_VOID, mod, ctx);
|
||||
}
|
||||
|
||||
int ExecuteString(asIScriptEngine *engine, const char *code, void *ref, int refTypeId, asIScriptModule *mod, asIScriptContext *ctx)
|
||||
{
|
||||
// Wrap the code in a function so that it can be compiled and executed
|
||||
string funcCode = " ExecuteString() {\n";
|
||||
funcCode += code;
|
||||
funcCode += "\n;}";
|
||||
|
||||
// Determine the return type based on the type of the ref arg
|
||||
funcCode = engine->GetTypeDeclaration(refTypeId, true) + funcCode;
|
||||
|
||||
// GetModule will free unused types, so to be on the safe side we'll hold on to a reference to the type
|
||||
asITypeInfo *type = 0;
|
||||
if( refTypeId & asTYPEID_MASK_OBJECT )
|
||||
{
|
||||
type = engine->GetTypeInfoById(refTypeId);
|
||||
if( type )
|
||||
type->AddRef();
|
||||
}
|
||||
|
||||
// If no module was provided, get a dummy from the engine
|
||||
asIScriptModule *execMod = mod ? mod : engine->GetModule("ExecuteString", asGM_ALWAYS_CREATE);
|
||||
|
||||
// Now it's ok to release the type
|
||||
if( type )
|
||||
type->Release();
|
||||
|
||||
// Compile the function that can be executed
|
||||
asIScriptFunction *func = 0;
|
||||
int r = execMod->CompileFunction("ExecuteString", funcCode.c_str(), -1, 0, &func);
|
||||
if( r < 0 )
|
||||
return r;
|
||||
|
||||
// If no context was provided, request a new one from the engine
|
||||
asIScriptContext *execCtx = ctx ? ctx : engine->RequestContext();
|
||||
r = execCtx->Prepare(func);
|
||||
if (r >= 0)
|
||||
{
|
||||
// Execute the function
|
||||
r = execCtx->Execute();
|
||||
|
||||
// Unless the provided type was void retrieve it's value
|
||||
if (ref != 0 && refTypeId != asTYPEID_VOID)
|
||||
{
|
||||
if (refTypeId & asTYPEID_OBJHANDLE)
|
||||
{
|
||||
// Expect the pointer to be null to start with
|
||||
assert(*reinterpret_cast<void**>(ref) == 0);
|
||||
*reinterpret_cast<void**>(ref) = *reinterpret_cast<void**>(execCtx->GetAddressOfReturnValue());
|
||||
engine->AddRefScriptObject(*reinterpret_cast<void**>(ref), engine->GetTypeInfoById(refTypeId));
|
||||
}
|
||||
else if (refTypeId & asTYPEID_MASK_OBJECT)
|
||||
{
|
||||
// Use the registered assignment operator to do a value assign.
|
||||
// This assumes that the ref is pointing to a valid object instance.
|
||||
engine->AssignScriptObject(ref, execCtx->GetAddressOfReturnValue(), engine->GetTypeInfoById(refTypeId));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Copy the primitive value
|
||||
memcpy(ref, execCtx->GetAddressOfReturnValue(), engine->GetSizeOfPrimitiveType(refTypeId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up
|
||||
func->Release();
|
||||
if( !ctx ) engine->ReturnContext(execCtx);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int WriteConfigToFile(asIScriptEngine *engine, const char *filename)
|
||||
{
|
||||
ofstream strm;
|
||||
strm.open(filename);
|
||||
|
||||
return WriteConfigToStream(engine, strm);
|
||||
}
|
||||
|
||||
int WriteConfigToStream(asIScriptEngine *engine, ostream &strm)
|
||||
{
|
||||
// A helper function for escaping quotes in default arguments
|
||||
struct Escape
|
||||
{
|
||||
static string Quotes(const char *decl)
|
||||
{
|
||||
string str = decl;
|
||||
size_t pos = 0;
|
||||
for(;;)
|
||||
{
|
||||
// Find " characters
|
||||
pos = str.find("\"",pos);
|
||||
if( pos == string::npos )
|
||||
break;
|
||||
|
||||
// Add a \ to escape them
|
||||
str.insert(pos, "\\");
|
||||
pos += 2;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
};
|
||||
|
||||
int c, n;
|
||||
|
||||
asDWORD currAccessMask = 0;
|
||||
string currNamespace = "";
|
||||
engine->SetDefaultNamespace("");
|
||||
|
||||
// Export the engine version, just for info
|
||||
strm << "// AngelScript " << asGetLibraryVersion() << "\n";
|
||||
strm << "// Lib options " << asGetLibraryOptions() << "\n";
|
||||
|
||||
// Export the relevant engine properties
|
||||
strm << "// Engine properties\n";
|
||||
for( n = 0; n < asEP_LAST_PROPERTY; n++ )
|
||||
strm << "ep " << n << " " << engine->GetEngineProperty(asEEngineProp(n)) << "\n";
|
||||
|
||||
// Make sure the default array type is expanded to the template form
|
||||
bool expandDefArrayToTempl = engine->GetEngineProperty(asEP_EXPAND_DEF_ARRAY_TO_TMPL) ? true : false;
|
||||
engine->SetEngineProperty(asEP_EXPAND_DEF_ARRAY_TO_TMPL, true);
|
||||
|
||||
// Write enum types and their values
|
||||
strm << "\n// Enums\n";
|
||||
c = engine->GetEnumCount();
|
||||
for( n = 0; n < c; n++ )
|
||||
{
|
||||
asITypeInfo *ti = engine->GetEnumByIndex(n);
|
||||
asDWORD accessMask = ti->GetAccessMask();
|
||||
if( accessMask != currAccessMask )
|
||||
{
|
||||
strm << "access " << hex << (unsigned int)(accessMask) << dec << "\n";
|
||||
currAccessMask = accessMask;
|
||||
}
|
||||
const char *nameSpace = ti->GetNamespace();
|
||||
if( nameSpace != currNamespace )
|
||||
{
|
||||
strm << "namespace \"" << nameSpace << "\"\n";
|
||||
currNamespace = nameSpace;
|
||||
engine->SetDefaultNamespace(currNamespace.c_str());
|
||||
}
|
||||
const char *enumName = ti->GetName();
|
||||
strm << "enum " << enumName << "\n";
|
||||
for( asUINT m = 0; m < ti->GetEnumValueCount(); m++ )
|
||||
{
|
||||
const char *valName;
|
||||
int val;
|
||||
valName = ti->GetEnumValueByIndex(m, &val);
|
||||
strm << "enumval " << enumName << " " << valName << " " << val << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Enumerate all types
|
||||
strm << "\n// Types\n";
|
||||
|
||||
// Keep a list of the template types, as the methods for these need to be exported first
|
||||
set<asITypeInfo*> templateTypes;
|
||||
|
||||
c = engine->GetObjectTypeCount();
|
||||
for( n = 0; n < c; n++ )
|
||||
{
|
||||
asITypeInfo *type = engine->GetObjectTypeByIndex(n);
|
||||
asDWORD accessMask = type->GetAccessMask();
|
||||
if( accessMask != currAccessMask )
|
||||
{
|
||||
strm << "access " << hex << (unsigned int)(accessMask) << dec << "\n";
|
||||
currAccessMask = accessMask;
|
||||
}
|
||||
const char *nameSpace = type->GetNamespace();
|
||||
if( nameSpace != currNamespace )
|
||||
{
|
||||
strm << "namespace \"" << nameSpace << "\"\n";
|
||||
currNamespace = nameSpace;
|
||||
engine->SetDefaultNamespace(currNamespace.c_str());
|
||||
}
|
||||
if( type->GetFlags() & asOBJ_SCRIPT_OBJECT )
|
||||
{
|
||||
// This should only be interfaces
|
||||
assert( type->GetSize() == 0 );
|
||||
|
||||
strm << "intf " << type->GetName() << "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only the type flags are necessary. The application flags are application
|
||||
// specific and doesn't matter to the offline compiler. The object size is also
|
||||
// unnecessary for the offline compiler
|
||||
strm << "objtype \"" << engine->GetTypeDeclaration(type->GetTypeId()) << "\" " << (unsigned int)(type->GetFlags() & asOBJ_MASK_VALID_FLAGS) << "\n";
|
||||
|
||||
// Store the template types (but not template instances)
|
||||
if( (type->GetFlags() & asOBJ_TEMPLATE) && type->GetSubType() && (type->GetSubType()->GetFlags() & asOBJ_TEMPLATE_SUBTYPE) )
|
||||
templateTypes.insert(type);
|
||||
}
|
||||
}
|
||||
|
||||
c = engine->GetTypedefCount();
|
||||
for( n = 0; n < c; n++ )
|
||||
{
|
||||
asITypeInfo *ti = engine->GetTypedefByIndex(n);
|
||||
const char *nameSpace = ti->GetNamespace();
|
||||
if( nameSpace != currNamespace )
|
||||
{
|
||||
strm << "namespace \"" << nameSpace << "\"\n";
|
||||
currNamespace = nameSpace;
|
||||
engine->SetDefaultNamespace(currNamespace.c_str());
|
||||
}
|
||||
asDWORD accessMask = ti->GetAccessMask();
|
||||
if( accessMask != currAccessMask )
|
||||
{
|
||||
strm << "access " << hex << (unsigned int)(accessMask) << dec << "\n";
|
||||
currAccessMask = accessMask;
|
||||
}
|
||||
strm << "typedef " << ti->GetName() << " \"" << engine->GetTypeDeclaration(ti->GetTypedefTypeId()) << "\"\n";
|
||||
}
|
||||
|
||||
c = engine->GetFuncdefCount();
|
||||
for( n = 0; n < c; n++ )
|
||||
{
|
||||
asITypeInfo *funcDef = engine->GetFuncdefByIndex(n);
|
||||
asDWORD accessMask = funcDef->GetAccessMask();
|
||||
const char *nameSpace = funcDef->GetNamespace();
|
||||
// Child funcdefs do not have any namespace, as they belong to the parent object
|
||||
if( nameSpace && nameSpace != currNamespace )
|
||||
{
|
||||
strm << "namespace \"" << nameSpace << "\"\n";
|
||||
currNamespace = nameSpace;
|
||||
engine->SetDefaultNamespace(currNamespace.c_str());
|
||||
}
|
||||
if( accessMask != currAccessMask )
|
||||
{
|
||||
strm << "access " << hex << (unsigned int)(accessMask) << dec << "\n";
|
||||
currAccessMask = accessMask;
|
||||
}
|
||||
strm << "funcdef \"" << funcDef->GetFuncdefSignature()->GetDeclaration() << "\"\n";
|
||||
}
|
||||
|
||||
// A helper for writing object type members
|
||||
struct TypeWriter
|
||||
{
|
||||
static void Write(asIScriptEngine *engine, ostream &strm, asITypeInfo *type, string &currNamespace, asDWORD &currAccessMask)
|
||||
{
|
||||
const char *nameSpace = type->GetNamespace();
|
||||
if( nameSpace != currNamespace )
|
||||
{
|
||||
strm << "namespace \"" << nameSpace << "\"\n";
|
||||
currNamespace = nameSpace;
|
||||
engine->SetDefaultNamespace(currNamespace.c_str());
|
||||
}
|
||||
string typeDecl = engine->GetTypeDeclaration(type->GetTypeId());
|
||||
if( type->GetFlags() & asOBJ_SCRIPT_OBJECT )
|
||||
{
|
||||
for( asUINT m = 0; m < type->GetMethodCount(); m++ )
|
||||
{
|
||||
asIScriptFunction *func = type->GetMethodByIndex(m);
|
||||
asDWORD accessMask = func->GetAccessMask();
|
||||
if( accessMask != currAccessMask )
|
||||
{
|
||||
strm << "access " << hex << (unsigned int)(accessMask) << dec << "\n";
|
||||
currAccessMask = accessMask;
|
||||
}
|
||||
strm << "intfmthd " << typeDecl.c_str() << " \"" << Escape::Quotes(func->GetDeclaration(false)).c_str() << (func->IsProperty() ? " property" : "") << "\"\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
asUINT m;
|
||||
for( m = 0; m < type->GetFactoryCount(); m++ )
|
||||
{
|
||||
asIScriptFunction *func = type->GetFactoryByIndex(m);
|
||||
asDWORD accessMask = func->GetAccessMask();
|
||||
if( accessMask != currAccessMask )
|
||||
{
|
||||
strm << "access " << hex << (unsigned int)(accessMask) << dec << "\n";
|
||||
currAccessMask = accessMask;
|
||||
}
|
||||
strm << "objbeh \"" << typeDecl.c_str() << "\" " << asBEHAVE_FACTORY << " \"" << Escape::Quotes(func->GetDeclaration(false)).c_str() << "\"\n";
|
||||
}
|
||||
for( m = 0; m < type->GetBehaviourCount(); m++ )
|
||||
{
|
||||
asEBehaviours beh;
|
||||
asIScriptFunction *func = type->GetBehaviourByIndex(m, &beh);
|
||||
|
||||
if( beh == asBEHAVE_CONSTRUCT )
|
||||
// Prefix 'void'
|
||||
strm << "objbeh \"" << typeDecl.c_str() << "\" " << beh << " \"void " << Escape::Quotes(func->GetDeclaration(false)).c_str() << "\"\n";
|
||||
else if( beh == asBEHAVE_DESTRUCT )
|
||||
// Prefix 'void' and remove ~
|
||||
strm << "objbeh \"" << typeDecl.c_str() << "\" " << beh << " \"void " << Escape::Quotes(func->GetDeclaration(false)).c_str()+1 << "\"\n";
|
||||
else
|
||||
strm << "objbeh \"" << typeDecl.c_str() << "\" " << beh << " \"" << Escape::Quotes(func->GetDeclaration(false)).c_str() << "\"\n";
|
||||
}
|
||||
for( m = 0; m < type->GetMethodCount(); m++ )
|
||||
{
|
||||
asIScriptFunction *func = type->GetMethodByIndex(m);
|
||||
asDWORD accessMask = func->GetAccessMask();
|
||||
if( accessMask != currAccessMask )
|
||||
{
|
||||
strm << "access " << hex << (unsigned int)(accessMask) << dec << "\n";
|
||||
currAccessMask = accessMask;
|
||||
}
|
||||
strm << "objmthd \"" << typeDecl.c_str() << "\" \"" << Escape::Quotes(func->GetDeclaration(false)).c_str() << (func->IsProperty() ? " property" : "") << "\"\n";
|
||||
}
|
||||
for( m = 0; m < type->GetPropertyCount(); m++ )
|
||||
{
|
||||
asDWORD accessMask;
|
||||
type->GetProperty(m, 0, 0, 0, 0, 0, 0, &accessMask);
|
||||
if( accessMask != currAccessMask )
|
||||
{
|
||||
strm << "access " << hex << (unsigned int)(accessMask) << dec << "\n";
|
||||
currAccessMask = accessMask;
|
||||
}
|
||||
strm << "objprop \"" << typeDecl.c_str() << "\" \"" << type->GetPropertyDeclaration(m) << "\"";
|
||||
|
||||
// Save information about composite properties
|
||||
int compositeOffset;
|
||||
bool isCompositeIndirect;
|
||||
type->GetProperty(m, 0, 0, 0, 0, 0, 0, 0, &compositeOffset, &isCompositeIndirect);
|
||||
strm << " " << compositeOffset << " " << (isCompositeIndirect ? "1" : "0") << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Write the members of the template types, so they can be fully registered before any other type uses them
|
||||
// TODO: Order the template types based on dependency to avoid failure if one type uses instances of another
|
||||
strm << "\n// Template type members\n";
|
||||
for( set<asITypeInfo*>::iterator it = templateTypes.begin(); it != templateTypes.end(); ++it )
|
||||
{
|
||||
asITypeInfo *type = *it;
|
||||
TypeWriter::Write(engine, strm, type, currNamespace, currAccessMask);
|
||||
}
|
||||
|
||||
// Write the object types members
|
||||
strm << "\n// Type members\n";
|
||||
|
||||
c = engine->GetObjectTypeCount();
|
||||
for( n = 0; n < c; n++ )
|
||||
{
|
||||
asITypeInfo *type = engine->GetObjectTypeByIndex(n);
|
||||
if( templateTypes.find(type) == templateTypes.end() )
|
||||
TypeWriter::Write(engine, strm, type, currNamespace, currAccessMask);
|
||||
}
|
||||
|
||||
// Write functions
|
||||
strm << "\n// Functions\n";
|
||||
|
||||
c = engine->GetGlobalFunctionCount();
|
||||
for( n = 0; n < c; n++ )
|
||||
{
|
||||
asIScriptFunction *func = engine->GetGlobalFunctionByIndex(n);
|
||||
const char *nameSpace = func->GetNamespace();
|
||||
if( nameSpace != currNamespace )
|
||||
{
|
||||
strm << "namespace \"" << nameSpace << "\"\n";
|
||||
currNamespace = nameSpace;
|
||||
engine->SetDefaultNamespace(currNamespace.c_str());
|
||||
}
|
||||
asDWORD accessMask = func->GetAccessMask();
|
||||
if( accessMask != currAccessMask )
|
||||
{
|
||||
strm << "access " << hex << (unsigned int)(accessMask) << dec << "\n";
|
||||
currAccessMask = accessMask;
|
||||
}
|
||||
strm << "func \"" << Escape::Quotes(func->GetDeclaration()).c_str() << (func->IsProperty() ? " property" : "") << "\"\n";
|
||||
}
|
||||
|
||||
// Write global properties
|
||||
strm << "\n// Properties\n";
|
||||
|
||||
c = engine->GetGlobalPropertyCount();
|
||||
for( n = 0; n < c; n++ )
|
||||
{
|
||||
const char *name;
|
||||
int typeId;
|
||||
bool isConst;
|
||||
asDWORD accessMask;
|
||||
const char *nameSpace;
|
||||
engine->GetGlobalPropertyByIndex(n, &name, &nameSpace, &typeId, &isConst, 0, 0, &accessMask);
|
||||
if( accessMask != currAccessMask )
|
||||
{
|
||||
strm << "access " << hex << (unsigned int)(accessMask) << dec << "\n";
|
||||
currAccessMask = accessMask;
|
||||
}
|
||||
if( nameSpace != currNamespace )
|
||||
{
|
||||
strm << "namespace \"" << nameSpace << "\"\n";
|
||||
currNamespace = nameSpace;
|
||||
engine->SetDefaultNamespace(currNamespace.c_str());
|
||||
}
|
||||
strm << "prop \"" << (isConst ? "const " : "") << engine->GetTypeDeclaration(typeId) << " " << name << "\"\n";
|
||||
}
|
||||
|
||||
// Write string factory
|
||||
strm << "\n// String factory\n";
|
||||
|
||||
// Reset the namespace for the string factory and default array type
|
||||
if ("" != currNamespace)
|
||||
{
|
||||
strm << "namespace \"\"\n";
|
||||
currNamespace = "";
|
||||
engine->SetDefaultNamespace("");
|
||||
}
|
||||
|
||||
asDWORD flags = 0;
|
||||
int typeId = engine->GetStringFactoryReturnTypeId(&flags);
|
||||
if( typeId > 0 )
|
||||
strm << "strfactory \"" << ((flags & asTM_CONST) ? "const " : "") << engine->GetTypeDeclaration(typeId) << ((flags & asTM_INOUTREF) ? "&" : "") << "\"\n";
|
||||
|
||||
// Write default array type
|
||||
strm << "\n// Default array type\n";
|
||||
typeId = engine->GetDefaultArrayTypeId();
|
||||
if( typeId > 0 )
|
||||
strm << "defarray \"" << engine->GetTypeDeclaration(typeId) << "\"\n";
|
||||
|
||||
// Restore original settings
|
||||
engine->SetEngineProperty(asEP_EXPAND_DEF_ARRAY_TO_TMPL, expandDefArrayToTempl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ConfigEngineFromStream(asIScriptEngine *engine, istream &strm, const char *configFile, asIStringFactory *stringFactory)
|
||||
{
|
||||
int r;
|
||||
|
||||
// Some helper functions for parsing the configuration
|
||||
struct in
|
||||
{
|
||||
static asETokenClass GetToken(asIScriptEngine *engine, string &token, const string &text, asUINT &pos)
|
||||
{
|
||||
asUINT len = 0;
|
||||
asETokenClass t = engine->ParseToken(&text[pos], text.length() - pos, &len);
|
||||
while( (t == asTC_WHITESPACE || t == asTC_COMMENT) && pos < text.length() )
|
||||
{
|
||||
pos += len;
|
||||
t = engine->ParseToken(&text[pos], text.length() - pos, &len);
|
||||
}
|
||||
|
||||
token.assign(&text[pos], len);
|
||||
|
||||
pos += len;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
static void ReplaceSlashQuote(string &str)
|
||||
{
|
||||
size_t pos = 0;
|
||||
for(;;)
|
||||
{
|
||||
// Search for \" in the string
|
||||
pos = str.find("\\\"", pos);
|
||||
if( pos == string::npos )
|
||||
break;
|
||||
|
||||
// Remove the \ character
|
||||
str.erase(pos, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static asUINT GetLineNumber(const string &text, asUINT pos)
|
||||
{
|
||||
asUINT count = 1;
|
||||
for( asUINT n = 0; n < pos; n++ )
|
||||
if( text[n] == '\n' )
|
||||
count++;
|
||||
|
||||
return count;
|
||||
}
|
||||
};
|
||||
|
||||
// Since we are only going to compile the script and never actually execute it,
|
||||
// we turn off the initialization of global variables, so that the compiler can
|
||||
// just register dummy types and functions for the application interface.
|
||||
r = engine->SetEngineProperty(asEP_INIT_GLOBAL_VARS_AFTER_BUILD, false); assert( r >= 0 );
|
||||
|
||||
// Read the entire file
|
||||
char buffer[1000];
|
||||
string config;
|
||||
do {
|
||||
strm.getline(buffer, 1000);
|
||||
config += buffer;
|
||||
config += "\n";
|
||||
} while( !strm.eof() && strm.good() );
|
||||
|
||||
// Process the configuration file and register each entity
|
||||
asUINT pos = 0;
|
||||
while( pos < config.length() )
|
||||
{
|
||||
string token;
|
||||
// TODO: The position where the initial token is found should be stored for error messages
|
||||
in::GetToken(engine, token, config, pos);
|
||||
if( token == "ep" )
|
||||
{
|
||||
string tmp;
|
||||
in::GetToken(engine, tmp, config, pos);
|
||||
|
||||
asEEngineProp ep = asEEngineProp(atol(tmp.c_str()));
|
||||
|
||||
// Only set properties that affect the compiler
|
||||
if( ep != asEP_COPY_SCRIPT_SECTIONS &&
|
||||
ep != asEP_MAX_STACK_SIZE &&
|
||||
ep != asEP_INIT_GLOBAL_VARS_AFTER_BUILD &&
|
||||
ep != asEP_EXPAND_DEF_ARRAY_TO_TMPL &&
|
||||
ep != asEP_AUTO_GARBAGE_COLLECT )
|
||||
{
|
||||
// Get the value for the property
|
||||
in::GetToken(engine, tmp, config, pos);
|
||||
stringstream s(tmp);
|
||||
asPWORD value;
|
||||
|
||||
s >> value;
|
||||
|
||||
engine->SetEngineProperty(ep, value);
|
||||
}
|
||||
}
|
||||
else if( token == "namespace" )
|
||||
{
|
||||
string ns;
|
||||
in::GetToken(engine, ns, config, pos);
|
||||
ns = ns.substr(1, ns.length() - 2);
|
||||
|
||||
r = engine->SetDefaultNamespace(ns.c_str());
|
||||
if( r < 0 )
|
||||
{
|
||||
engine->WriteMessage(configFile, in::GetLineNumber(config, pos), 0, asMSGTYPE_ERROR, "Failed to set namespace");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if( token == "access" )
|
||||
{
|
||||
string maskStr;
|
||||
in::GetToken(engine, maskStr, config, pos);
|
||||
asDWORD mask = strtoul(maskStr.c_str(), 0, 16);
|
||||
engine->SetDefaultAccessMask(mask);
|
||||
}
|
||||
else if( token == "objtype" )
|
||||
{
|
||||
string name, flags;
|
||||
in::GetToken(engine, name, config, pos);
|
||||
name = name.substr(1, name.length() - 2);
|
||||
in::GetToken(engine, flags, config, pos);
|
||||
|
||||
// The size of the value type doesn't matter, because the
|
||||
// engine must adjust it anyway for different platforms
|
||||
r = engine->RegisterObjectType(name.c_str(), (atol(flags.c_str()) & asOBJ_VALUE) ? 1 : 0, atol(flags.c_str()));
|
||||
if( r < 0 )
|
||||
{
|
||||
engine->WriteMessage(configFile, in::GetLineNumber(config, pos), 0, asMSGTYPE_ERROR, "Failed to register object type");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if( token == "objbeh" )
|
||||
{
|
||||
string name, behaviour, decl;
|
||||
in::GetToken(engine, name, config, pos);
|
||||
name = name.substr(1, name.length() - 2);
|
||||
in::GetToken(engine, behaviour, config, pos);
|
||||
in::GetToken(engine, decl, config, pos);
|
||||
decl = decl.substr(1, decl.length() - 2);
|
||||
in::ReplaceSlashQuote(decl);
|
||||
|
||||
// Remove the $ that the engine prefixes the behaviours with
|
||||
size_t n = decl.find("$");
|
||||
if( n != string::npos )
|
||||
decl[n] = ' ';
|
||||
|
||||
asEBehaviours behave = static_cast<asEBehaviours>(atol(behaviour.c_str()));
|
||||
if( behave == asBEHAVE_TEMPLATE_CALLBACK )
|
||||
{
|
||||
// TODO: How can we let the compiler register this? Maybe through a plug-in system? Or maybe by implementing the callback as a script itself
|
||||
engine->WriteMessage(configFile, in::GetLineNumber(config, pos), 0, asMSGTYPE_WARNING, "Cannot register template callback without the actual implementation");
|
||||
}
|
||||
else
|
||||
{
|
||||
r = engine->RegisterObjectBehaviour(name.c_str(), behave, decl.c_str(), asFUNCTION(0), asCALL_GENERIC);
|
||||
if( r < 0 )
|
||||
{
|
||||
engine->WriteMessage(configFile, in::GetLineNumber(config, pos), 0, asMSGTYPE_ERROR, "Failed to register behaviour");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( token == "objmthd" )
|
||||
{
|
||||
string name, decl;
|
||||
in::GetToken(engine, name, config, pos);
|
||||
name = name.substr(1, name.length() - 2);
|
||||
in::GetToken(engine, decl, config, pos);
|
||||
decl = decl.substr(1, decl.length() - 2);
|
||||
in::ReplaceSlashQuote(decl);
|
||||
|
||||
r = engine->RegisterObjectMethod(name.c_str(), decl.c_str(), asFUNCTION(0), asCALL_GENERIC);
|
||||
if( r < 0 )
|
||||
{
|
||||
engine->WriteMessage(configFile, in::GetLineNumber(config, pos), 0, asMSGTYPE_ERROR, "Failed to register object method");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if( token == "objprop" )
|
||||
{
|
||||
string name, decl, compositeOffset, isCompositeIndirect;
|
||||
in::GetToken(engine, name, config, pos);
|
||||
name = name.substr(1, name.length() - 2);
|
||||
in::GetToken(engine, decl, config, pos);
|
||||
decl = decl.substr(1, decl.length() - 2);
|
||||
in::GetToken(engine, compositeOffset, config, pos);
|
||||
in::GetToken(engine, isCompositeIndirect, config, pos);
|
||||
|
||||
asITypeInfo *type = engine->GetTypeInfoById(engine->GetTypeIdByDecl(name.c_str()));
|
||||
if( type == 0 )
|
||||
{
|
||||
engine->WriteMessage(configFile, in::GetLineNumber(config, pos), 0, asMSGTYPE_ERROR, "Type doesn't exist for property registration");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// All properties must have different offsets in order to make them
|
||||
// distinct, so we simply register them with an incremental offset
|
||||
r = engine->RegisterObjectProperty(name.c_str(), decl.c_str(), type->GetPropertyCount(), compositeOffset != "0" ? type->GetPropertyCount() : 0, isCompositeIndirect != "0");
|
||||
if( r < 0 )
|
||||
{
|
||||
engine->WriteMessage(configFile, in::GetLineNumber(config, pos), 0, asMSGTYPE_ERROR, "Failed to register object property");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if( token == "intf" )
|
||||
{
|
||||
string name, size, flags;
|
||||
in::GetToken(engine, name, config, pos);
|
||||
|
||||
r = engine->RegisterInterface(name.c_str());
|
||||
if( r < 0 )
|
||||
{
|
||||
engine->WriteMessage(configFile, in::GetLineNumber(config, pos), 0, asMSGTYPE_ERROR, "Failed to register interface");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if( token == "intfmthd" )
|
||||
{
|
||||
string name, decl;
|
||||
in::GetToken(engine, name, config, pos);
|
||||
in::GetToken(engine, decl, config, pos);
|
||||
decl = decl.substr(1, decl.length() - 2);
|
||||
in::ReplaceSlashQuote(decl);
|
||||
|
||||
r = engine->RegisterInterfaceMethod(name.c_str(), decl.c_str());
|
||||
if( r < 0 )
|
||||
{
|
||||
engine->WriteMessage(configFile, in::GetLineNumber(config, pos), 0, asMSGTYPE_ERROR, "Failed to register interface method");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if( token == "func" )
|
||||
{
|
||||
string decl;
|
||||
in::GetToken(engine, decl, config, pos);
|
||||
decl = decl.substr(1, decl.length() - 2);
|
||||
in::ReplaceSlashQuote(decl);
|
||||
|
||||
r = engine->RegisterGlobalFunction(decl.c_str(), asFUNCTION(0), asCALL_GENERIC);
|
||||
if( r < 0 )
|
||||
{
|
||||
engine->WriteMessage(configFile, in::GetLineNumber(config, pos), 0, asMSGTYPE_ERROR, "Failed to register global function");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if( token == "prop" )
|
||||
{
|
||||
string decl;
|
||||
in::GetToken(engine, decl, config, pos);
|
||||
decl = decl.substr(1, decl.length() - 2);
|
||||
|
||||
// All properties must have different offsets in order to make them
|
||||
// distinct, so we simply register them with an incremental offset.
|
||||
// The pointer must also be non-null so we add 1 to have a value.
|
||||
r = engine->RegisterGlobalProperty(decl.c_str(), reinterpret_cast<void*>(asPWORD(engine->GetGlobalPropertyCount()+1)));
|
||||
if( r < 0 )
|
||||
{
|
||||
engine->WriteMessage(configFile, in::GetLineNumber(config, pos), 0, asMSGTYPE_ERROR, "Failed to register global property");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if( token == "strfactory" )
|
||||
{
|
||||
string type;
|
||||
in::GetToken(engine, type, config, pos);
|
||||
type = type.substr(1, type.length() - 2);
|
||||
|
||||
if (stringFactory == 0)
|
||||
{
|
||||
engine->WriteMessage(configFile, in::GetLineNumber(config, pos), 0, asMSGTYPE_WARNING, "Cannot register string factory without the actual implementation");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = engine->RegisterStringFactory(type.c_str(), stringFactory);
|
||||
if (r < 0)
|
||||
{
|
||||
engine->WriteMessage(configFile, in::GetLineNumber(config, pos), 0, asMSGTYPE_ERROR, "Failed to register string factory");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( token == "defarray" )
|
||||
{
|
||||
string type;
|
||||
in::GetToken(engine, type, config, pos);
|
||||
type = type.substr(1, type.length() - 2);
|
||||
|
||||
r = engine->RegisterDefaultArrayType(type.c_str());
|
||||
if( r < 0 )
|
||||
{
|
||||
engine->WriteMessage(configFile, in::GetLineNumber(config, pos), 0, asMSGTYPE_ERROR, "Failed to register the default array type");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if( token == "enum" )
|
||||
{
|
||||
string type;
|
||||
in::GetToken(engine, type, config, pos);
|
||||
|
||||
r = engine->RegisterEnum(type.c_str());
|
||||
if( r < 0 )
|
||||
{
|
||||
engine->WriteMessage(configFile, in::GetLineNumber(config, pos), 0, asMSGTYPE_ERROR, "Failed to register enum type");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if( token == "enumval" )
|
||||
{
|
||||
string type, name, value;
|
||||
in::GetToken(engine, type, config, pos);
|
||||
in::GetToken(engine, name, config, pos);
|
||||
in::GetToken(engine, value, config, pos);
|
||||
|
||||
r = engine->RegisterEnumValue(type.c_str(), name.c_str(), atol(value.c_str()));
|
||||
if( r < 0 )
|
||||
{
|
||||
engine->WriteMessage(configFile, in::GetLineNumber(config, pos), 0, asMSGTYPE_ERROR, "Failed to register enum value");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if( token == "typedef" )
|
||||
{
|
||||
string type, decl;
|
||||
in::GetToken(engine, type, config, pos);
|
||||
in::GetToken(engine, decl, config, pos);
|
||||
decl = decl.substr(1, decl.length() - 2);
|
||||
|
||||
r = engine->RegisterTypedef(type.c_str(), decl.c_str());
|
||||
if( r < 0 )
|
||||
{
|
||||
engine->WriteMessage(configFile, in::GetLineNumber(config, pos), 0, asMSGTYPE_ERROR, "Failed to register typedef");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if( token == "funcdef" )
|
||||
{
|
||||
string decl;
|
||||
in::GetToken(engine, decl, config, pos);
|
||||
decl = decl.substr(1, decl.length() - 2);
|
||||
|
||||
r = engine->RegisterFuncdef(decl.c_str());
|
||||
if( r < 0 )
|
||||
{
|
||||
engine->WriteMessage(configFile, in::GetLineNumber(config, pos), 0, asMSGTYPE_ERROR, "Failed to register funcdef");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
string GetExceptionInfo(asIScriptContext *ctx, bool showStack)
|
||||
{
|
||||
if( ctx->GetState() != asEXECUTION_EXCEPTION ) return "";
|
||||
|
||||
stringstream text;
|
||||
|
||||
const asIScriptFunction *function = ctx->GetExceptionFunction();
|
||||
text << "func: " << function->GetDeclaration() << "\n";
|
||||
text << "modl: " << (function->GetModuleName() ? function->GetModuleName() : "") << "\n";
|
||||
text << "sect: " << (function->GetScriptSectionName() ? function->GetScriptSectionName() : "") << "\n";
|
||||
text << "line: " << ctx->GetExceptionLineNumber() << "\n";
|
||||
text << "desc: " << ctx->GetExceptionString() << "\n";
|
||||
|
||||
if( showStack )
|
||||
{
|
||||
text << "--- call stack ---\n";
|
||||
for( asUINT n = 1; n < ctx->GetCallstackSize(); n++ )
|
||||
{
|
||||
function = ctx->GetFunction(n);
|
||||
if( function )
|
||||
{
|
||||
if( function->GetFuncType() == asFUNC_SCRIPT )
|
||||
{
|
||||
text << (function->GetScriptSectionName() ? function->GetScriptSectionName() : "") << " (" << ctx->GetLineNumber(n) << "): " << function->GetDeclaration() << "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
// The context is being reused by the application for a nested call
|
||||
text << "{...application...}: " << function->GetDeclaration() << "\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The context is being reused by the script engine for a nested call
|
||||
text << "{...script engine...}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return text.str();
|
||||
}
|
||||
|
||||
void ScriptThrow(const string &msg)
|
||||
{
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
if (ctx)
|
||||
ctx->SetException(msg.c_str());
|
||||
}
|
||||
|
||||
string ScriptGetExceptionInfo()
|
||||
{
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
if (!ctx)
|
||||
return "";
|
||||
|
||||
const char *msg = ctx->GetExceptionString();
|
||||
if (msg == 0)
|
||||
return "";
|
||||
|
||||
return string(msg);
|
||||
}
|
||||
|
||||
void RegisterExceptionRoutines(asIScriptEngine *engine)
|
||||
{
|
||||
int r;
|
||||
|
||||
// The string type must be available
|
||||
assert(engine->GetTypeInfoByDecl("string"));
|
||||
|
||||
r = engine->RegisterGlobalFunction("void throw(const string &in)", asFUNCTION(ScriptThrow), asCALL_CDECL); assert(r >= 0);
|
||||
r = engine->RegisterGlobalFunction("string getExceptionInfo()", asFUNCTION(ScriptGetExceptionInfo), asCALL_CDECL); assert(r >= 0);
|
||||
}
|
||||
|
||||
END_AS_NAMESPACE
|
|
@ -0,0 +1,53 @@
|
|||
#ifndef SCRIPTHELPER_H
|
||||
#define SCRIPTHELPER_H
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#ifndef ANGELSCRIPT_H
|
||||
// Avoid having to inform include path if header is already include before
|
||||
#include <angelscript.h>
|
||||
#endif
|
||||
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
// Compare relation between two objects of the same type
|
||||
int CompareRelation(asIScriptEngine *engine, void *lobj, void *robj, int typeId, int &result);
|
||||
|
||||
// Compare equality between two objects of the same type
|
||||
int CompareEquality(asIScriptEngine *engine, void *lobj, void *robj, int typeId, bool &result);
|
||||
|
||||
// Compile and execute simple statements
|
||||
// The module is optional. If given the statements can access the entities compiled in the module.
|
||||
// The caller can optionally provide its own context, for example if a context should be reused.
|
||||
int ExecuteString(asIScriptEngine *engine, const char *code, asIScriptModule *mod = 0, asIScriptContext *ctx = 0);
|
||||
|
||||
// Compile and execute simple statements with option of return value
|
||||
// The module is optional. If given the statements can access the entitites compiled in the module.
|
||||
// The caller can optionally provide its own context, for example if a context should be reused.
|
||||
int ExecuteString(asIScriptEngine *engine, const char *code, void *ret, int retTypeId, asIScriptModule *mod = 0, asIScriptContext *ctx = 0);
|
||||
|
||||
// Write the registered application interface to a file for an offline compiler.
|
||||
// The format is compatible with the offline compiler in /sdk/samples/asbuild/.
|
||||
int WriteConfigToFile(asIScriptEngine *engine, const char *filename);
|
||||
|
||||
// Write the registered application interface to a text stream.
|
||||
int WriteConfigToStream(asIScriptEngine *engine, std::ostream &strm);
|
||||
|
||||
// Loads an interface from a text stream and configures the engine with it. This will not
|
||||
// set the correct function pointers, so it is not possible to use this engine to execute
|
||||
// scripts, but it can be used to compile scripts and save the byte code.
|
||||
int ConfigEngineFromStream(asIScriptEngine *engine, std::istream &strm, const char *nameOfStream = "config", asIStringFactory *stringFactory = 0);
|
||||
|
||||
// Format the details of the script exception into a human readable text
|
||||
std::string GetExceptionInfo(asIScriptContext *ctx, bool showStack = false);
|
||||
|
||||
// Register the exception routines
|
||||
// 'void throw(const string &msg)'
|
||||
// 'string getExceptionInfo()'
|
||||
void RegisterExceptionRoutines(asIScriptEngine *engine);
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,347 @@
|
|||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
#include <string.h>
|
||||
#include "scriptmath.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#include <cmath>
|
||||
|
||||
// The C++Builder RTL doesn't pull the *f functions into the global namespace per default.
|
||||
using namespace std;
|
||||
|
||||
#if __BORLANDC__ < 0x580
|
||||
// C++Builder 6 and earlier don't come with any *f variants of the math functions at all.
|
||||
inline float cosf (float arg) { return std::cos (arg); }
|
||||
inline float sinf (float arg) { return std::sin (arg); }
|
||||
inline float tanf (float arg) { return std::tan (arg); }
|
||||
inline float atan2f (float y, float x) { return std::atan2 (y, x); }
|
||||
inline float logf (float arg) { return std::log (arg); }
|
||||
inline float powf (float x, float y) { return std::pow (x, y); }
|
||||
inline float sqrtf (float arg) { return std::sqrt (arg); }
|
||||
#endif
|
||||
|
||||
// C++Builder doesn't define most of the non-standard float-specific math functions with
|
||||
// "*f" suffix; instead it provides overloads for the standard math functions which take
|
||||
// "float" arguments.
|
||||
inline float acosf (float arg) { return std::acos (arg); }
|
||||
inline float asinf (float arg) { return std::asin (arg); }
|
||||
inline float atanf (float arg) { return std::atan (arg); }
|
||||
inline float coshf (float arg) { return std::cosh (arg); }
|
||||
inline float sinhf (float arg) { return std::sinh (arg); }
|
||||
inline float tanhf (float arg) { return std::tanh (arg); }
|
||||
inline float log10f (float arg) { return std::log10 (arg); }
|
||||
inline float ceilf (float arg) { return std::ceil (arg); }
|
||||
inline float fabsf (float arg) { return std::fabs (arg); }
|
||||
inline float floorf (float arg) { return std::floor (arg); }
|
||||
|
||||
// C++Builder doesn't define a non-standard "modff" function but rather an overload of "modf"
|
||||
// for float arguments. However, BCC's float overload of fmod() is broken (QC #74816; fixed
|
||||
// in C++Builder 2010).
|
||||
inline float modff (float x, float *y)
|
||||
{
|
||||
double d;
|
||||
float f = (float) modf((double) x, &d);
|
||||
*y = (float) d;
|
||||
return f;
|
||||
}
|
||||
#endif
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
// Determine whether the float version should be registered, or the double version
|
||||
#ifndef AS_USE_FLOAT
|
||||
#if !defined(_WIN32_WCE) // WinCE doesn't have the float versions of the math functions
|
||||
#define AS_USE_FLOAT 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// The modf function doesn't seem very intuitive, so I'm writing this
|
||||
// function that simply returns the fractional part of the float value
|
||||
#if AS_USE_FLOAT
|
||||
float fractionf(float v)
|
||||
{
|
||||
float intPart;
|
||||
return modff(v, &intPart);
|
||||
}
|
||||
#else
|
||||
double fraction(double v)
|
||||
{
|
||||
double intPart;
|
||||
return modf(v, &intPart);
|
||||
}
|
||||
#endif
|
||||
|
||||
// As AngelScript doesn't allow bitwise manipulation of float types we'll provide a couple of
|
||||
// functions for converting float values to IEEE 754 formatted values etc. This also allow us to
|
||||
// provide a platform agnostic representation to the script so the scripts don't have to worry
|
||||
// about whether the CPU uses IEEE 754 floats or some other representation
|
||||
float fpFromIEEE(asUINT raw)
|
||||
{
|
||||
// TODO: Identify CPU family to provide proper conversion
|
||||
// if the CPU doesn't natively use IEEE style floats
|
||||
return *reinterpret_cast<float*>(&raw);
|
||||
}
|
||||
asUINT fpToIEEE(float fp)
|
||||
{
|
||||
return *reinterpret_cast<asUINT*>(&fp);
|
||||
}
|
||||
double fpFromIEEE(asQWORD raw)
|
||||
{
|
||||
return *reinterpret_cast<double*>(&raw);
|
||||
}
|
||||
asQWORD fpToIEEE(double fp)
|
||||
{
|
||||
return *reinterpret_cast<asQWORD*>(&fp);
|
||||
}
|
||||
|
||||
// closeTo() is used to determine if the binary representation of two numbers are
|
||||
// relatively close to each other. Numerical errors due to rounding errors build
|
||||
// up over many operations, so it is almost impossible to get exact numbers and
|
||||
// this is where closeTo() comes in.
|
||||
//
|
||||
// It shouldn't be used to determine if two numbers are mathematically close to
|
||||
// each other.
|
||||
//
|
||||
// ref: http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
|
||||
// ref: http://www.gamedev.net/topic/653449-scriptmath-and-closeto/
|
||||
bool closeTo(float a, float b, float epsilon)
|
||||
{
|
||||
// Equal numbers and infinity will return immediately
|
||||
if( a == b ) return true;
|
||||
|
||||
// When very close to 0, we can use the absolute comparison
|
||||
float diff = fabsf(a - b);
|
||||
if( (a == 0 || b == 0) && (diff < epsilon) )
|
||||
return true;
|
||||
|
||||
// Otherwise we need to use relative comparison to account for precision
|
||||
return diff / (fabs(a) + fabs(b)) < epsilon;
|
||||
}
|
||||
|
||||
bool closeTo(double a, double b, double epsilon)
|
||||
{
|
||||
if( a == b ) return true;
|
||||
|
||||
double diff = fabs(a - b);
|
||||
if( (a == 0 || b == 0) && (diff < epsilon) )
|
||||
return true;
|
||||
|
||||
return diff / (fabs(a) + fabs(b)) < epsilon;
|
||||
}
|
||||
|
||||
void RegisterScriptMath_Native(asIScriptEngine *engine)
|
||||
{
|
||||
int r;
|
||||
|
||||
// Conversion between floating point and IEEE bits representations
|
||||
r = engine->RegisterGlobalFunction("float fpFromIEEE(uint)", asFUNCTIONPR(fpFromIEEE, (asUINT), float), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("uint fpToIEEE(float)", asFUNCTIONPR(fpToIEEE, (float), asUINT), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double fpFromIEEE(uint64)", asFUNCTIONPR(fpFromIEEE, (asQWORD), double), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("uint64 fpToIEEE(double)", asFUNCTIONPR(fpToIEEE, (double), asQWORD), asCALL_CDECL); assert( r >= 0 );
|
||||
|
||||
// Close to comparison with epsilon
|
||||
r = engine->RegisterGlobalFunction("bool closeTo(float, float, float = 0.00001f)", asFUNCTIONPR(closeTo, (float, float, float), bool), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("bool closeTo(double, double, double = 0.0000000001)", asFUNCTIONPR(closeTo, (double, double, double), bool), asCALL_CDECL); assert( r >= 0 );
|
||||
|
||||
#if AS_USE_FLOAT
|
||||
// Trigonometric functions
|
||||
r = engine->RegisterGlobalFunction("float cos(float)", asFUNCTIONPR(cosf, (float), float), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("float sin(float)", asFUNCTIONPR(sinf, (float), float), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("float tan(float)", asFUNCTIONPR(tanf, (float), float), asCALL_CDECL); assert( r >= 0 );
|
||||
|
||||
r = engine->RegisterGlobalFunction("float acos(float)", asFUNCTIONPR(acosf, (float), float), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("float asin(float)", asFUNCTIONPR(asinf, (float), float), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("float atan(float)", asFUNCTIONPR(atanf, (float), float), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("float atan2(float,float)", asFUNCTIONPR(atan2f, (float, float), float), asCALL_CDECL); assert( r >= 0 );
|
||||
|
||||
// Hyberbolic functions
|
||||
r = engine->RegisterGlobalFunction("float cosh(float)", asFUNCTIONPR(coshf, (float), float), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("float sinh(float)", asFUNCTIONPR(sinhf, (float), float), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("float tanh(float)", asFUNCTIONPR(tanhf, (float), float), asCALL_CDECL); assert( r >= 0 );
|
||||
|
||||
// Exponential and logarithmic functions
|
||||
r = engine->RegisterGlobalFunction("float log(float)", asFUNCTIONPR(logf, (float), float), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("float log10(float)", asFUNCTIONPR(log10f, (float), float), asCALL_CDECL); assert( r >= 0 );
|
||||
|
||||
// Power functions
|
||||
r = engine->RegisterGlobalFunction("float pow(float, float)", asFUNCTIONPR(powf, (float, float), float), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("float sqrt(float)", asFUNCTIONPR(sqrtf, (float), float), asCALL_CDECL); assert( r >= 0 );
|
||||
|
||||
// Nearest integer, absolute value, and remainder functions
|
||||
r = engine->RegisterGlobalFunction("float ceil(float)", asFUNCTIONPR(ceilf, (float), float), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("float abs(float)", asFUNCTIONPR(fabsf, (float), float), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("float floor(float)", asFUNCTIONPR(floorf, (float), float), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("float fraction(float)", asFUNCTIONPR(fractionf, (float), float), asCALL_CDECL); assert( r >= 0 );
|
||||
|
||||
// Don't register modf because AngelScript already supports the % operator
|
||||
#else
|
||||
// double versions of the same
|
||||
r = engine->RegisterGlobalFunction("double cos(double)", asFUNCTIONPR(cos, (double), double), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double sin(double)", asFUNCTIONPR(sin, (double), double), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double tan(double)", asFUNCTIONPR(tan, (double), double), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double acos(double)", asFUNCTIONPR(acos, (double), double), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double asin(double)", asFUNCTIONPR(asin, (double), double), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double atan(double)", asFUNCTIONPR(atan, (double), double), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double atan2(double,double)", asFUNCTIONPR(atan2, (double, double), double), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double cosh(double)", asFUNCTIONPR(cosh, (double), double), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double sinh(double)", asFUNCTIONPR(sinh, (double), double), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double tanh(double)", asFUNCTIONPR(tanh, (double), double), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double log(double)", asFUNCTIONPR(log, (double), double), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double log10(double)", asFUNCTIONPR(log10, (double), double), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double pow(double, double)", asFUNCTIONPR(pow, (double, double), double), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double sqrt(double)", asFUNCTIONPR(sqrt, (double), double), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double ceil(double)", asFUNCTIONPR(ceil, (double), double), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double abs(double)", asFUNCTIONPR(fabs, (double), double), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double floor(double)", asFUNCTIONPR(floor, (double), double), asCALL_CDECL); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double fraction(double)", asFUNCTIONPR(fraction, (double), double), asCALL_CDECL); assert( r >= 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
#if AS_USE_FLOAT
|
||||
// This macro creates simple generic wrappers for functions of type 'float func(float)'
|
||||
#define GENERICff(x) \
|
||||
void x##_generic(asIScriptGeneric *gen) \
|
||||
{ \
|
||||
float f = *(float*)gen->GetAddressOfArg(0); \
|
||||
*(float*)gen->GetAddressOfReturnLocation() = x(f); \
|
||||
}
|
||||
|
||||
GENERICff(cosf)
|
||||
GENERICff(sinf)
|
||||
GENERICff(tanf)
|
||||
GENERICff(acosf)
|
||||
GENERICff(asinf)
|
||||
GENERICff(atanf)
|
||||
GENERICff(coshf)
|
||||
GENERICff(sinhf)
|
||||
GENERICff(tanhf)
|
||||
GENERICff(logf)
|
||||
GENERICff(log10f)
|
||||
GENERICff(sqrtf)
|
||||
GENERICff(ceilf)
|
||||
GENERICff(fabsf)
|
||||
GENERICff(floorf)
|
||||
GENERICff(fractionf)
|
||||
|
||||
void powf_generic(asIScriptGeneric *gen)
|
||||
{
|
||||
float f1 = *(float*)gen->GetAddressOfArg(0);
|
||||
float f2 = *(float*)gen->GetAddressOfArg(1);
|
||||
*(float*)gen->GetAddressOfReturnLocation() = powf(f1, f2);
|
||||
}
|
||||
void atan2f_generic(asIScriptGeneric *gen)
|
||||
{
|
||||
float f1 = *(float*)gen->GetAddressOfArg(0);
|
||||
float f2 = *(float*)gen->GetAddressOfArg(1);
|
||||
*(float*)gen->GetAddressOfReturnLocation() = atan2f(f1, f2);
|
||||
}
|
||||
|
||||
#else
|
||||
// This macro creates simple generic wrappers for functions of type 'double func(double)'
|
||||
#define GENERICdd(x) \
|
||||
void x##_generic(asIScriptGeneric *gen) \
|
||||
{ \
|
||||
double f = *(double*)gen->GetAddressOfArg(0); \
|
||||
*(double*)gen->GetAddressOfReturnLocation() = x(f); \
|
||||
}
|
||||
|
||||
GENERICdd(cos)
|
||||
GENERICdd(sin)
|
||||
GENERICdd(tan)
|
||||
GENERICdd(acos)
|
||||
GENERICdd(asin)
|
||||
GENERICdd(atan)
|
||||
GENERICdd(cosh)
|
||||
GENERICdd(sinh)
|
||||
GENERICdd(tanh)
|
||||
GENERICdd(log)
|
||||
GENERICdd(log10)
|
||||
GENERICdd(sqrt)
|
||||
GENERICdd(ceil)
|
||||
GENERICdd(fabs)
|
||||
GENERICdd(floor)
|
||||
GENERICdd(fraction)
|
||||
|
||||
void pow_generic(asIScriptGeneric *gen)
|
||||
{
|
||||
double f1 = *(double*)gen->GetAddressOfArg(0);
|
||||
double f2 = *(double*)gen->GetAddressOfArg(1);
|
||||
*(double*)gen->GetAddressOfReturnLocation() = pow(f1, f2);
|
||||
}
|
||||
void atan2_generic(asIScriptGeneric *gen)
|
||||
{
|
||||
double f1 = *(double*)gen->GetAddressOfArg(0);
|
||||
double f2 = *(double*)gen->GetAddressOfArg(1);
|
||||
*(double*)gen->GetAddressOfReturnLocation() = atan2(f1, f2);
|
||||
}
|
||||
#endif
|
||||
void RegisterScriptMath_Generic(asIScriptEngine *engine)
|
||||
{
|
||||
int r;
|
||||
|
||||
#if AS_USE_FLOAT
|
||||
// Trigonometric functions
|
||||
r = engine->RegisterGlobalFunction("float cos(float)", asFUNCTION(cosf_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("float sin(float)", asFUNCTION(sinf_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("float tan(float)", asFUNCTION(tanf_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
|
||||
r = engine->RegisterGlobalFunction("float acos(float)", asFUNCTION(acosf_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("float asin(float)", asFUNCTION(asinf_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("float atan(float)", asFUNCTION(atanf_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("float atan2(float,float)", asFUNCTION(atan2f_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
|
||||
// Hyberbolic functions
|
||||
r = engine->RegisterGlobalFunction("float cosh(float)", asFUNCTION(coshf_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("float sinh(float)", asFUNCTION(sinhf_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("float tanh(float)", asFUNCTION(tanhf_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
|
||||
// Exponential and logarithmic functions
|
||||
r = engine->RegisterGlobalFunction("float log(float)", asFUNCTION(logf_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("float log10(float)", asFUNCTION(log10f_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
|
||||
// Power functions
|
||||
r = engine->RegisterGlobalFunction("float pow(float, float)", asFUNCTION(powf_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("float sqrt(float)", asFUNCTION(sqrtf_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
|
||||
// Nearest integer, absolute value, and remainder functions
|
||||
r = engine->RegisterGlobalFunction("float ceil(float)", asFUNCTION(ceilf_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("float abs(float)", asFUNCTION(fabsf_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("float floor(float)", asFUNCTION(floorf_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("float fraction(float)", asFUNCTION(fractionf_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
|
||||
// Don't register modf because AngelScript already supports the % operator
|
||||
#else
|
||||
// double versions of the same
|
||||
r = engine->RegisterGlobalFunction("double cos(double)", asFUNCTION(cos_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double sin(double)", asFUNCTION(sin_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double tan(double)", asFUNCTION(tan_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double acos(double)", asFUNCTION(acos_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double asin(double)", asFUNCTION(asin_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double atan(double)", asFUNCTION(atan_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double atan2(double,double)", asFUNCTION(atan2_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double cosh(double)", asFUNCTION(cosh_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double sinh(double)", asFUNCTION(sinh_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double tanh(double)", asFUNCTION(tanh_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double log(double)", asFUNCTION(log_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double log10(double)", asFUNCTION(log10_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double pow(double, double)", asFUNCTION(pow_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double sqrt(double)", asFUNCTION(sqrt_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double ceil(double)", asFUNCTION(ceil_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double abs(double)", asFUNCTION(fabs_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double floor(double)", asFUNCTION(floor_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterGlobalFunction("double fraction(double)", asFUNCTION(fraction_generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
void RegisterScriptMath(asIScriptEngine *engine)
|
||||
{
|
||||
if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
|
||||
RegisterScriptMath_Generic(engine);
|
||||
else
|
||||
RegisterScriptMath_Native(engine);
|
||||
}
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef SCRIPTMATH_H
|
||||
#define SCRIPTMATH_H
|
||||
|
||||
#ifndef ANGELSCRIPT_H
|
||||
// Avoid having to inform include path if header is already include before
|
||||
#include <angelscript.h>
|
||||
#endif
|
||||
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
// This function will determine the configuration of the engine
|
||||
// and use one of the two functions below to register the math functions
|
||||
void RegisterScriptMath(asIScriptEngine *engine);
|
||||
|
||||
// Call this function to register the math functions
|
||||
// using native calling conventions
|
||||
void RegisterScriptMath_Native(asIScriptEngine *engine);
|
||||
|
||||
// Use this one instead if native calling conventions
|
||||
// are not supported on the target platform
|
||||
void RegisterScriptMath_Generic(asIScriptEngine *engine);
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,222 @@
|
|||
#include <assert.h>
|
||||
#include <string.h> // strstr
|
||||
#include <new> // new()
|
||||
#include <math.h>
|
||||
#include "scriptmathcomplex.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
// C++Builder doesn't define a non-standard "sqrtf" function but rather an overload of "sqrt"
|
||||
// for float arguments.
|
||||
inline float sqrtf (float x) { return sqrt (x); }
|
||||
#endif
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
Complex::Complex()
|
||||
{
|
||||
r = 0;
|
||||
i = 0;
|
||||
}
|
||||
|
||||
Complex::Complex(const Complex &other)
|
||||
{
|
||||
r = other.r;
|
||||
i = other.i;
|
||||
}
|
||||
|
||||
Complex::Complex(float _r, float _i)
|
||||
{
|
||||
r = _r;
|
||||
i = _i;
|
||||
}
|
||||
|
||||
bool Complex::operator==(const Complex &o) const
|
||||
{
|
||||
return (r == o.r) && (i == o.i);
|
||||
}
|
||||
|
||||
bool Complex::operator!=(const Complex &o) const
|
||||
{
|
||||
return !(*this == o);
|
||||
}
|
||||
|
||||
Complex &Complex::operator=(const Complex &other)
|
||||
{
|
||||
r = other.r;
|
||||
i = other.i;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Complex &Complex::operator+=(const Complex &other)
|
||||
{
|
||||
r += other.r;
|
||||
i += other.i;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Complex &Complex::operator-=(const Complex &other)
|
||||
{
|
||||
r -= other.r;
|
||||
i -= other.i;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Complex &Complex::operator*=(const Complex &other)
|
||||
{
|
||||
*this = *this * other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Complex &Complex::operator/=(const Complex &other)
|
||||
{
|
||||
*this = *this / other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
float Complex::squaredLength() const
|
||||
{
|
||||
return r*r + i*i;
|
||||
}
|
||||
|
||||
float Complex::length() const
|
||||
{
|
||||
return sqrtf(squaredLength());
|
||||
}
|
||||
|
||||
Complex Complex::operator+(const Complex &other) const
|
||||
{
|
||||
return Complex(r + other.r, i + other.i);
|
||||
}
|
||||
|
||||
Complex Complex::operator-(const Complex &other) const
|
||||
{
|
||||
return Complex(r - other.r, i + other.i);
|
||||
}
|
||||
|
||||
Complex Complex::operator*(const Complex &other) const
|
||||
{
|
||||
return Complex(r*other.r - i*other.i, r*other.i + i*other.r);
|
||||
}
|
||||
|
||||
Complex Complex::operator/(const Complex &other) const
|
||||
{
|
||||
float squaredLen = other.squaredLength();
|
||||
if( squaredLen == 0 ) return Complex(0,0);
|
||||
|
||||
return Complex((r*other.r + i*other.i)/squaredLen, (i*other.r - r*other.i)/squaredLen);
|
||||
}
|
||||
|
||||
//-----------------------
|
||||
// Swizzle operators
|
||||
//-----------------------
|
||||
|
||||
Complex Complex::get_ri() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
Complex Complex::get_ir() const
|
||||
{
|
||||
return Complex(r,i);
|
||||
}
|
||||
void Complex::set_ri(const Complex &o)
|
||||
{
|
||||
*this = o;
|
||||
}
|
||||
void Complex::set_ir(const Complex &o)
|
||||
{
|
||||
r = o.i;
|
||||
i = o.r;
|
||||
}
|
||||
|
||||
//-----------------------
|
||||
// AngelScript functions
|
||||
//-----------------------
|
||||
|
||||
static void ComplexDefaultConstructor(Complex *self)
|
||||
{
|
||||
new(self) Complex();
|
||||
}
|
||||
|
||||
static void ComplexCopyConstructor(const Complex &other, Complex *self)
|
||||
{
|
||||
new(self) Complex(other);
|
||||
}
|
||||
|
||||
static void ComplexConvConstructor(float r, Complex *self)
|
||||
{
|
||||
new(self) Complex(r);
|
||||
}
|
||||
|
||||
static void ComplexInitConstructor(float r, float i, Complex *self)
|
||||
{
|
||||
new(self) Complex(r,i);
|
||||
}
|
||||
|
||||
static void ComplexListConstructor(float *list, Complex *self)
|
||||
{
|
||||
new(self) Complex(list[0], list[1]);
|
||||
}
|
||||
|
||||
//--------------------------------
|
||||
// Registration
|
||||
//-------------------------------------
|
||||
|
||||
static void RegisterScriptMathComplex_Native(asIScriptEngine *engine)
|
||||
{
|
||||
int r;
|
||||
|
||||
// Register the type
|
||||
#if AS_CAN_USE_CPP11
|
||||
// With C++11 it is possible to use asGetTypeTraits to determine the correct flags to represent the C++ class, except for the asOBJ_APP_CLASS_ALLFLOATS
|
||||
r = engine->RegisterObjectType("complex", sizeof(Complex), asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<Complex>() | asOBJ_APP_CLASS_ALLFLOATS); assert( r >= 0 );
|
||||
#else
|
||||
r = engine->RegisterObjectType("complex", sizeof(Complex), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_CAK | asOBJ_APP_CLASS_ALLFLOATS); assert( r >= 0 );
|
||||
#endif
|
||||
|
||||
// Register the object properties
|
||||
r = engine->RegisterObjectProperty("complex", "float r", asOFFSET(Complex, r)); assert( r >= 0 );
|
||||
r = engine->RegisterObjectProperty("complex", "float i", asOFFSET(Complex, i)); assert( r >= 0 );
|
||||
|
||||
// Register the constructors
|
||||
r = engine->RegisterObjectBehaviour("complex", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ComplexDefaultConstructor), asCALL_CDECL_OBJLAST); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("complex", asBEHAVE_CONSTRUCT, "void f(const complex &in)", asFUNCTION(ComplexCopyConstructor), asCALL_CDECL_OBJLAST); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("complex", asBEHAVE_CONSTRUCT, "void f(float)", asFUNCTION(ComplexConvConstructor), asCALL_CDECL_OBJLAST); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("complex", asBEHAVE_CONSTRUCT, "void f(float, float)", asFUNCTION(ComplexInitConstructor), asCALL_CDECL_OBJLAST); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("complex", asBEHAVE_LIST_CONSTRUCT, "void f(const int &in) {float, float}", asFUNCTION(ComplexListConstructor), asCALL_CDECL_OBJLAST); assert( r >= 0 );
|
||||
|
||||
// Register the operator overloads
|
||||
r = engine->RegisterObjectMethod("complex", "complex &opAddAssign(const complex &in)", asMETHODPR(Complex, operator+=, (const Complex &), Complex&), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("complex", "complex &opSubAssign(const complex &in)", asMETHODPR(Complex, operator-=, (const Complex &), Complex&), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("complex", "complex &opMulAssign(const complex &in)", asMETHODPR(Complex, operator*=, (const Complex &), Complex&), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("complex", "complex &opDivAssign(const complex &in)", asMETHODPR(Complex, operator/=, (const Complex &), Complex&), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("complex", "bool opEquals(const complex &in) const", asMETHODPR(Complex, operator==, (const Complex &) const, bool), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("complex", "complex opAdd(const complex &in) const", asMETHODPR(Complex, operator+, (const Complex &) const, Complex), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("complex", "complex opSub(const complex &in) const", asMETHODPR(Complex, operator-, (const Complex &) const, Complex), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("complex", "complex opMul(const complex &in) const", asMETHODPR(Complex, operator*, (const Complex &) const, Complex), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("complex", "complex opDiv(const complex &in) const", asMETHODPR(Complex, operator/, (const Complex &) const, Complex), asCALL_THISCALL); assert( r >= 0 );
|
||||
|
||||
// Register the object methods
|
||||
r = engine->RegisterObjectMethod("complex", "float abs() const", asMETHOD(Complex,length), asCALL_THISCALL); assert( r >= 0 );
|
||||
|
||||
// Register the swizzle operators
|
||||
r = engine->RegisterObjectMethod("complex", "complex get_ri() const property", asMETHOD(Complex, get_ri), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("complex", "complex get_ir() const property", asMETHOD(Complex, get_ir), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("complex", "void set_ri(const complex &in) property", asMETHOD(Complex, set_ri), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("complex", "void set_ir(const complex &in) property", asMETHOD(Complex, set_ir), asCALL_THISCALL); assert( r >= 0 );
|
||||
}
|
||||
|
||||
void RegisterScriptMathComplex(asIScriptEngine *engine)
|
||||
{
|
||||
if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
|
||||
{
|
||||
assert( false );
|
||||
// TODO: implement support for generic calling convention
|
||||
// RegisterScriptMathComplex_Generic(engine);
|
||||
}
|
||||
else
|
||||
RegisterScriptMathComplex_Native(engine);
|
||||
}
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
#ifndef SCRIPTMATHCOMPLEX_H
|
||||
#define SCRIPTMATHCOMPLEX_H
|
||||
|
||||
#ifndef ANGELSCRIPT_H
|
||||
// Avoid having to inform include path if header is already include before
|
||||
#include <angelscript.h>
|
||||
#endif
|
||||
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
// This class implements complex numbers and the common
|
||||
// operations that can be done with it.
|
||||
//
|
||||
// Ref: http://mathworld.wolfram.com/ComplexNumber.html
|
||||
|
||||
struct Complex
|
||||
{
|
||||
Complex();
|
||||
Complex(const Complex &other);
|
||||
Complex(float r, float i = 0);
|
||||
|
||||
// Assignment operator
|
||||
Complex &operator=(const Complex &other);
|
||||
|
||||
// Compound assigment operators
|
||||
Complex &operator+=(const Complex &other);
|
||||
Complex &operator-=(const Complex &other);
|
||||
Complex &operator*=(const Complex &other);
|
||||
Complex &operator/=(const Complex &other);
|
||||
|
||||
float length() const;
|
||||
float squaredLength() const;
|
||||
|
||||
// Swizzle operators
|
||||
Complex get_ri() const;
|
||||
void set_ri(const Complex &in);
|
||||
Complex get_ir() const;
|
||||
void set_ir(const Complex &in);
|
||||
|
||||
// Comparison
|
||||
bool operator==(const Complex &other) const;
|
||||
bool operator!=(const Complex &other) const;
|
||||
|
||||
// Math operators
|
||||
Complex operator+(const Complex &other) const;
|
||||
Complex operator-(const Complex &other) const;
|
||||
Complex operator*(const Complex &other) const;
|
||||
Complex operator/(const Complex &other) const;
|
||||
|
||||
float r;
|
||||
float i;
|
||||
};
|
||||
|
||||
// This function will determine the configuration of the engine
|
||||
// and use one of the two functions below to register the string type
|
||||
void RegisterScriptMathComplex(asIScriptEngine *engine);
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,48 @@
|
|||
//
|
||||
// Script std::string
|
||||
//
|
||||
// This function registers the std::string type with AngelScript to be used as the default string type.
|
||||
//
|
||||
// The string type is registered as a value type, thus may have performance issues if a lot of
|
||||
// string operations are performed in the script. However, for relatively few operations, this should
|
||||
// not cause any problem for most applications.
|
||||
//
|
||||
|
||||
#ifndef SCRIPTSTDSTRING_H
|
||||
#define SCRIPTSTDSTRING_H
|
||||
|
||||
#ifndef ANGELSCRIPT_H
|
||||
// Avoid having to inform include path if header is already include before
|
||||
#include <angelscript.h>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
//---------------------------
|
||||
// Compilation settings
|
||||
//
|
||||
|
||||
// Sometimes it may be desired to use the same method names as used by C++ STL.
|
||||
// This may for example reduce time when converting code from script to C++ or
|
||||
// back.
|
||||
//
|
||||
// 0 = off
|
||||
// 1 = on
|
||||
#ifndef AS_USE_STLNAMES
|
||||
#define AS_USE_STLNAMES 0
|
||||
#endif
|
||||
|
||||
// Some prefer to use property accessors to get/set the length of the string
|
||||
// This option registers the accessors instead of the method length()
|
||||
#ifndef AS_USE_ACCESSORS
|
||||
#define AS_USE_ACCESSORS 0
|
||||
#endif
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
void RegisterStdString(asIScriptEngine *engine);
|
||||
void RegisterStdStringUtils(asIScriptEngine *engine);
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,129 @@
|
|||
#include <assert.h>
|
||||
#include "scriptstdstring.h"
|
||||
#include "../scriptarray/scriptarray.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
// This function takes an input string and splits it into parts by looking
|
||||
// for a specified delimiter. Example:
|
||||
//
|
||||
// string str = "A|B||D";
|
||||
// array<string>@ array = str.split("|");
|
||||
//
|
||||
// The resulting array has the following elements:
|
||||
//
|
||||
// {"A", "B", "", "D"}
|
||||
//
|
||||
// AngelScript signature:
|
||||
// array<string>@ string::split(const string &in delim) const
|
||||
static CScriptArray *StringSplit(const string &delim, const string &str)
|
||||
{
|
||||
// Obtain a pointer to the engine
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
asIScriptEngine *engine = ctx->GetEngine();
|
||||
|
||||
// TODO: This should only be done once
|
||||
// TODO: This assumes that CScriptArray was already registered
|
||||
asITypeInfo *arrayType = engine->GetTypeInfoByDecl("array<string>");
|
||||
|
||||
// Create the array object
|
||||
CScriptArray *array = CScriptArray::Create(arrayType);
|
||||
|
||||
// Find the existence of the delimiter in the input string
|
||||
int pos = 0, prev = 0, count = 0;
|
||||
while( (pos = (int)str.find(delim, prev)) != (int)string::npos )
|
||||
{
|
||||
// Add the part to the array
|
||||
array->Resize(array->GetSize()+1);
|
||||
((string*)array->At(count))->assign(&str[prev], pos-prev);
|
||||
|
||||
// Find the next part
|
||||
count++;
|
||||
prev = pos + (int)delim.length();
|
||||
}
|
||||
|
||||
// Add the remaining part
|
||||
array->Resize(array->GetSize()+1);
|
||||
((string*)array->At(count))->assign(&str[prev]);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
static void StringSplit_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
// Get the arguments
|
||||
string *str = (string*)gen->GetObject();
|
||||
string *delim = *(string**)gen->GetAddressOfArg(0);
|
||||
|
||||
// Return the array by handle
|
||||
*(CScriptArray**)gen->GetAddressOfReturnLocation() = StringSplit(*delim, *str);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// This function takes as input an array of string handles as well as a
|
||||
// delimiter and concatenates the array elements into one delimited string.
|
||||
// Example:
|
||||
//
|
||||
// array<string> array = {"A", "B", "", "D"};
|
||||
// string str = join(array, "|");
|
||||
//
|
||||
// The resulting string is:
|
||||
//
|
||||
// "A|B||D"
|
||||
//
|
||||
// AngelScript signature:
|
||||
// string join(const array<string> &in array, const string &in delim)
|
||||
static string StringJoin(const CScriptArray &array, const string &delim)
|
||||
{
|
||||
// Create the new string
|
||||
string str = "";
|
||||
if( array.GetSize() )
|
||||
{
|
||||
int n;
|
||||
for( n = 0; n < (int)array.GetSize() - 1; n++ )
|
||||
{
|
||||
str += *(string*)array.At(n);
|
||||
str += delim;
|
||||
}
|
||||
|
||||
// Add the last part
|
||||
str += *(string*)array.At(n);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
static void StringJoin_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
// Get the arguments
|
||||
CScriptArray *array = *(CScriptArray**)gen->GetAddressOfArg(0);
|
||||
string *delim = *(string**)gen->GetAddressOfArg(1);
|
||||
|
||||
// Return the string
|
||||
new(gen->GetAddressOfReturnLocation()) string(StringJoin(*array, *delim));
|
||||
}
|
||||
|
||||
// This is where the utility functions are registered.
|
||||
// The string type must have been registered first.
|
||||
void RegisterStdStringUtils(asIScriptEngine *engine)
|
||||
{
|
||||
int r;
|
||||
|
||||
if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
|
||||
{
|
||||
r = engine->RegisterObjectMethod("string", "array<string>@ split(const string &in) const", asFUNCTION(StringSplit_Generic), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterGlobalFunction("string join(const array<string> &in, const string &in)", asFUNCTION(StringJoin_Generic), asCALL_GENERIC); assert(r >= 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
r = engine->RegisterObjectMethod("string", "array<string>@ split(const string &in) const", asFUNCTION(StringSplit), asCALL_CDECL_OBJLAST); assert(r >= 0);
|
||||
r = engine->RegisterGlobalFunction("string join(const array<string> &in, const string &in)", asFUNCTION(StringJoin), asCALL_CDECL); assert(r >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
END_AS_NAMESPACE
|
|
@ -0,0 +1,548 @@
|
|||
//
|
||||
// CSerializer
|
||||
//
|
||||
// This code was based on the CScriptReloader written by FDsagizi
|
||||
// http://www.gamedev.net/topic/604890-dynamic-reloading-script/
|
||||
//
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h> // strstr
|
||||
#include <stdio.h> // sprintf
|
||||
#include "serializer.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CSerializer::CSerializer()
|
||||
{
|
||||
m_engine = 0;
|
||||
}
|
||||
|
||||
CSerializer::~CSerializer()
|
||||
{
|
||||
// Extra objects need to be released, since they are not stored in
|
||||
// the module and we cannot rely on the application releasing them
|
||||
for( size_t i = 0; i < m_extraObjects.size(); i++ )
|
||||
{
|
||||
SExtraObject &o = m_extraObjects[i];
|
||||
for( size_t i2 = 0; i2 < m_root.m_children.size(); i2++ )
|
||||
{
|
||||
if( m_root.m_children[i2]->m_originalPtr == o.originalObject && m_root.m_children[i2]->m_restorePtr )
|
||||
reinterpret_cast<asIScriptObject*>(m_root.m_children[i2]->m_restorePtr)->Release();
|
||||
}
|
||||
}
|
||||
|
||||
// Clean the serialized values before we remove the user types
|
||||
m_root.Uninit();
|
||||
|
||||
// Delete the user types
|
||||
std::map<std::string, CUserType*>::iterator it;
|
||||
for( it = m_userTypes.begin(); it != m_userTypes.end(); it++ )
|
||||
delete it->second;
|
||||
|
||||
if( m_engine )
|
||||
m_engine->Release();
|
||||
}
|
||||
|
||||
void CSerializer::AddUserType(CUserType *ref, const std::string &name)
|
||||
{
|
||||
m_userTypes[name] = ref;
|
||||
}
|
||||
|
||||
int CSerializer::Store(asIScriptModule *mod)
|
||||
{
|
||||
m_mod = mod;
|
||||
|
||||
// The engine must not be destroyed before we're completed, so we'll hold on to a reference
|
||||
mod->GetEngine()->AddRef();
|
||||
if( m_engine ) m_engine->Release();
|
||||
m_engine = mod->GetEngine();
|
||||
|
||||
m_root.m_serializer = this;
|
||||
|
||||
// First store global variables
|
||||
asUINT i;
|
||||
for( i = 0; i < mod->GetGlobalVarCount(); i++ )
|
||||
{
|
||||
const char *name, *nameSpace;
|
||||
int typeId;
|
||||
mod->GetGlobalVar(i, &name, &nameSpace, &typeId);
|
||||
m_root.m_children.push_back(new CSerializedValue(&m_root, name, nameSpace, mod->GetAddressOfGlobalVar(i), typeId));
|
||||
}
|
||||
|
||||
// Second store extra objects
|
||||
for( i = 0; i < m_extraObjects.size(); i++ )
|
||||
m_root.m_children.push_back(new CSerializedValue(&m_root, "", "", m_extraObjects[i].originalObject, m_extraObjects[i].originalTypeId));
|
||||
|
||||
// For the handles that were stored, we need to substitute the stored pointer
|
||||
// that is still pointing to the original object to an internal reference so
|
||||
// it can be restored later on.
|
||||
m_root.ReplaceHandles();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Retrieve all global variables after reload script.
|
||||
int CSerializer::Restore(asIScriptModule *mod)
|
||||
{
|
||||
m_mod = mod;
|
||||
|
||||
// The engine must not be destroyed before we're completed, so we'll hold on to a reference
|
||||
mod->GetEngine()->AddRef();
|
||||
if( m_engine ) m_engine->Release();
|
||||
m_engine = mod->GetEngine();
|
||||
|
||||
// First restore extra objects, i.e. the ones that are not directly seen from the module's global variables
|
||||
asUINT i;
|
||||
for( i = 0; i < m_extraObjects.size(); i++ )
|
||||
{
|
||||
SExtraObject &o = m_extraObjects[i];
|
||||
asITypeInfo *type = m_mod->GetTypeInfoByName( o.originalClassName.c_str() );
|
||||
if( type )
|
||||
{
|
||||
for( size_t i2 = 0; i2 < m_root.m_children.size(); i2++ )
|
||||
{
|
||||
if( m_root.m_children[i2]->m_originalPtr == o.originalObject )
|
||||
{
|
||||
// Create a new script object, but don't call its constructor as we will initialize the members.
|
||||
// Calling the constructor may have unwanted side effects if for example the constructor changes
|
||||
// any outside entities, such as setting global variables to point to new objects, etc.
|
||||
void *newPtr = m_engine->CreateUninitializedScriptObject( type );
|
||||
m_root.m_children[i2]->Restore( newPtr, type->GetTypeId() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Second restore the global variables
|
||||
asUINT varCount = mod->GetGlobalVarCount();
|
||||
for( i = 0; i < varCount; i++ )
|
||||
{
|
||||
const char *name, *nameSpace;
|
||||
int typeId;
|
||||
mod->GetGlobalVar(i, &name, &nameSpace, &typeId);
|
||||
|
||||
CSerializedValue *v = m_root.FindByName(name, nameSpace);
|
||||
if( v )
|
||||
v->Restore(mod->GetAddressOfGlobalVar(i), typeId);
|
||||
}
|
||||
|
||||
// The handles that were restored needs to be
|
||||
// updated to point to their final objects.
|
||||
m_root.RestoreHandles();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *CSerializer::GetPointerToRestoredObject(void *ptr)
|
||||
{
|
||||
return m_root.GetPointerToRestoredObject( ptr );
|
||||
}
|
||||
|
||||
void CSerializer::AddExtraObjectToStore( asIScriptObject *object )
|
||||
{
|
||||
if( !object )
|
||||
return;
|
||||
|
||||
// Check if the object hasn't been included already
|
||||
for( size_t i=0; i < m_extraObjects.size(); i++ )
|
||||
if( m_extraObjects[i].originalObject == object )
|
||||
return;
|
||||
|
||||
SExtraObject o;
|
||||
o.originalObject = object;
|
||||
o.originalClassName = object->GetObjectType()->GetName();
|
||||
o.originalTypeId = object->GetTypeId();
|
||||
|
||||
m_extraObjects.push_back( o );
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CSerializedValue::CSerializedValue()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
CSerializedValue::CSerializedValue(CSerializedValue *parent, const std::string &name, const std::string &nameSpace, void *ref, int typeId)
|
||||
{
|
||||
Init();
|
||||
|
||||
m_name = name;
|
||||
m_nameSpace = nameSpace;
|
||||
m_serializer = parent->m_serializer;
|
||||
Store(ref, typeId);
|
||||
}
|
||||
|
||||
void CSerializedValue::Init()
|
||||
{
|
||||
m_handlePtr = 0;
|
||||
m_restorePtr = 0;
|
||||
m_typeId = 0;
|
||||
m_isInit = false;
|
||||
m_serializer = 0;
|
||||
m_userData = 0;
|
||||
m_originalPtr = 0;
|
||||
}
|
||||
|
||||
void CSerializedValue::Uninit()
|
||||
{
|
||||
m_isInit = false;
|
||||
|
||||
ClearChildren();
|
||||
|
||||
if( m_userData )
|
||||
{
|
||||
CUserType *type = m_serializer->m_userTypes[m_typeName];
|
||||
if( type )
|
||||
type->CleanupUserData(this);
|
||||
m_userData = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CSerializedValue::ClearChildren()
|
||||
{
|
||||
// If this value is for an object handle that created an object during the restore
|
||||
// then it is necessary to release the handle here, so we won't get a memory leak
|
||||
if( (m_typeId & asTYPEID_OBJHANDLE) && m_children.size() == 1 && m_children[0]->m_restorePtr )
|
||||
{
|
||||
m_serializer->m_engine->ReleaseScriptObject(m_children[0]->m_restorePtr, m_serializer->m_engine->GetTypeInfoById(m_children[0]->m_typeId));
|
||||
}
|
||||
|
||||
for( size_t n = 0; n < m_children.size(); n++ )
|
||||
delete m_children[n];
|
||||
m_children.clear();
|
||||
}
|
||||
|
||||
CSerializedValue::~CSerializedValue()
|
||||
{
|
||||
Uninit();
|
||||
}
|
||||
|
||||
CSerializedValue *CSerializedValue::FindByName(const std::string &name, const std::string &nameSpace)
|
||||
{
|
||||
for( size_t i = 0; i < m_children.size(); i++ )
|
||||
if( m_children[i]->m_name == name &&
|
||||
m_children[i]->m_nameSpace == nameSpace )
|
||||
return m_children[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CSerializedValue::GetAllPointersOfChildren(std::vector<void*> *ptrs)
|
||||
{
|
||||
ptrs->push_back(m_originalPtr);
|
||||
|
||||
for( size_t i = 0; i < m_children.size(); ++i )
|
||||
m_children[i]->GetAllPointersOfChildren(ptrs);
|
||||
}
|
||||
|
||||
CSerializedValue *CSerializedValue::FindByPtr(void *ptr)
|
||||
{
|
||||
if( m_originalPtr == ptr )
|
||||
return this;
|
||||
|
||||
for( size_t i = 0; i < m_children.size(); i++ )
|
||||
{
|
||||
CSerializedValue *find = m_children[i]->FindByPtr(ptr);
|
||||
if( find )
|
||||
return find;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *CSerializedValue::GetPointerToRestoredObject(void *ptr)
|
||||
{
|
||||
if( m_originalPtr == ptr )
|
||||
return m_restorePtr;
|
||||
|
||||
for( size_t i = 0; i < m_children.size(); ++i )
|
||||
{
|
||||
void *ret = m_children[i]->GetPointerToRestoredObject(ptr);
|
||||
if( ret )
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// find variable by ptr but looking only at those in the references, which will create a new object
|
||||
CSerializedValue *CSerializedValue::FindByPtrInHandles(void *ptr)
|
||||
{
|
||||
// if this handle created object
|
||||
if( (m_typeId & asTYPEID_OBJHANDLE) && m_children.size() == 1 )
|
||||
{
|
||||
if( m_children[0]->m_originalPtr == ptr )
|
||||
return this;
|
||||
}
|
||||
|
||||
if( !(m_typeId & asTYPEID_OBJHANDLE) )
|
||||
{
|
||||
for( size_t i = 0; i < m_children.size(); i++ )
|
||||
{
|
||||
CSerializedValue *find = m_children[i]->FindByPtrInHandles(ptr);
|
||||
if( find )
|
||||
return find;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CSerializedValue::Store(void *ref, int typeId)
|
||||
{
|
||||
m_isInit = true;
|
||||
SetType(typeId);
|
||||
m_originalPtr = ref;
|
||||
|
||||
if( m_typeId & asTYPEID_OBJHANDLE )
|
||||
{
|
||||
m_handlePtr = *(void**)ref;
|
||||
}
|
||||
else if( m_typeId & asTYPEID_SCRIPTOBJECT )
|
||||
{
|
||||
asIScriptObject *obj = (asIScriptObject *)ref;
|
||||
asITypeInfo *type = obj->GetObjectType();
|
||||
SetType(type->GetTypeId());
|
||||
|
||||
// Store children
|
||||
for( asUINT i = 0; i < type->GetPropertyCount(); i++ )
|
||||
{
|
||||
int childId;
|
||||
const char *childName;
|
||||
type->GetProperty(i, &childName, &childId);
|
||||
|
||||
m_children.push_back(new CSerializedValue(this, childName, "", obj->GetAddressOfProperty(i), childId));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int size = m_serializer->m_engine->GetSizeOfPrimitiveType(m_typeId);
|
||||
|
||||
if( size == 0 )
|
||||
{
|
||||
// if it is user type( string, array, etc ... )
|
||||
if( m_serializer->m_userTypes[m_typeName] )
|
||||
m_serializer->m_userTypes[m_typeName]->Store(this, m_originalPtr);
|
||||
else
|
||||
{
|
||||
// POD-types can be stored without need for user type
|
||||
asITypeInfo *type = GetType();
|
||||
if( type && (type->GetFlags() & asOBJ_POD) )
|
||||
size = GetType()->GetSize();
|
||||
|
||||
// It is not necessary to report an error here if it is not a POD-type as that will be done when restoring
|
||||
}
|
||||
}
|
||||
|
||||
if( size )
|
||||
{
|
||||
m_mem.resize(size);
|
||||
memcpy(&m_mem[0], ref, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSerializedValue::Restore(void *ref, int typeId)
|
||||
{
|
||||
if( !this || !m_isInit || !ref )
|
||||
return;
|
||||
|
||||
// Verify that the stored type matched the new type of the value being restored
|
||||
if( typeId <= asTYPEID_DOUBLE && typeId != m_typeId ) return; // TODO: We may try to do a type conversion for primitives
|
||||
if( (typeId & ~asTYPEID_MASK_SEQNBR) ^ (m_typeId & ~asTYPEID_MASK_SEQNBR) ) return;
|
||||
asITypeInfo *type = m_serializer->m_engine->GetTypeInfoById(typeId);
|
||||
if( type && m_typeName != type->GetName() ) return;
|
||||
|
||||
// Set the new pointer and type
|
||||
m_restorePtr = ref;
|
||||
SetType(typeId);
|
||||
|
||||
// Restore the value
|
||||
if( m_typeId & asTYPEID_OBJHANDLE )
|
||||
{
|
||||
// if need create objects
|
||||
if( m_children.size() == 1 )
|
||||
{
|
||||
asITypeInfo *ctype = m_children[0]->GetType();
|
||||
|
||||
if( ctype->GetFactoryCount() == 0 )
|
||||
{
|
||||
// There are no factories, so assume the same pointer is going to be used
|
||||
m_children[0]->m_restorePtr = m_handlePtr;
|
||||
|
||||
// Increase the refCount for the object as it will be released upon clean-up
|
||||
m_serializer->m_engine->AddRefScriptObject(m_handlePtr, ctype);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a new script object, but don't call its constructor as we will initialize the members.
|
||||
// Calling the constructor may have unwanted side effects if for example the constructor changes
|
||||
// any outside entities, such as setting global variables to point to new objects, etc.
|
||||
void *newObject = m_serializer->m_engine->CreateUninitializedScriptObject(ctype);
|
||||
m_children[0]->Restore(newObject, ctype->GetTypeId());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( m_typeId & asTYPEID_SCRIPTOBJECT )
|
||||
{
|
||||
asIScriptObject *obj = (asIScriptObject *)ref;
|
||||
|
||||
// Retrieve children
|
||||
for( asUINT i = 0; i < type->GetPropertyCount() ; i++ )
|
||||
{
|
||||
const char *nameProperty;
|
||||
int ptypeId;
|
||||
type->GetProperty(i, &nameProperty, &ptypeId);
|
||||
|
||||
CSerializedValue *var = FindByName(nameProperty, "");
|
||||
if( var )
|
||||
var->Restore(obj->GetAddressOfProperty(i), ptypeId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_mem.size() )
|
||||
{
|
||||
// POD values can be restored with direct copy
|
||||
memcpy(ref, &m_mem[0], m_mem.size());
|
||||
}
|
||||
else if( m_serializer->m_userTypes[m_typeName] )
|
||||
{
|
||||
// user type restore
|
||||
m_serializer->m_userTypes[m_typeName]->Restore(this, m_restorePtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string str = "Cannot restore type '";
|
||||
str += type->GetName();
|
||||
str += "'";
|
||||
m_serializer->m_engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSerializedValue::CancelDuplicates(CSerializedValue *from)
|
||||
{
|
||||
std::vector<void*> ptrs;
|
||||
from->GetAllPointersOfChildren(&ptrs);
|
||||
|
||||
for( size_t i = 0; i < ptrs.size(); ++i )
|
||||
{
|
||||
CSerializedValue *find = m_serializer->m_root.FindByPtrInHandles(ptrs[i]);
|
||||
|
||||
while( find )
|
||||
{
|
||||
// cancel create object
|
||||
find->ClearChildren();
|
||||
|
||||
// Find next link to this ptr
|
||||
find = m_serializer->m_root.FindByPtrInHandles(ptrs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSerializedValue::ReplaceHandles()
|
||||
{
|
||||
if( m_handlePtr )
|
||||
{
|
||||
// Find the object that the handle is referring to
|
||||
CSerializedValue *handle_to = m_serializer->m_root.FindByPtr(m_handlePtr);
|
||||
|
||||
// If the object hasn't been stored yet...
|
||||
if( handle_to == 0 )
|
||||
{
|
||||
// Store the object now
|
||||
asITypeInfo *type = GetType();
|
||||
CSerializedValue *need_create = new CSerializedValue(this, m_name, m_nameSpace, m_handlePtr, type->GetTypeId());
|
||||
|
||||
// Make sure all other handles that point to the same object
|
||||
// are updated, so we don't end up creating duplicates
|
||||
CancelDuplicates(need_create);
|
||||
|
||||
m_children.push_back(need_create);
|
||||
}
|
||||
}
|
||||
|
||||
// Replace the handles in the children too
|
||||
for( size_t i = 0; i < m_children.size(); ++i )
|
||||
m_children[i]->ReplaceHandles();
|
||||
}
|
||||
|
||||
void CSerializedValue::RestoreHandles()
|
||||
{
|
||||
if( m_typeId & asTYPEID_OBJHANDLE )
|
||||
{
|
||||
if( m_handlePtr )
|
||||
{
|
||||
// Find the object the handle is supposed to point to
|
||||
CSerializedValue *handleTo = m_serializer->m_root.FindByPtr(m_handlePtr);
|
||||
|
||||
if( m_restorePtr && handleTo && handleTo->m_restorePtr )
|
||||
{
|
||||
asITypeInfo *type = m_serializer->m_engine->GetTypeInfoById(m_typeId);
|
||||
|
||||
// If the handle is already pointing to something it must be released first
|
||||
if( *(void**)m_restorePtr )
|
||||
m_serializer->m_engine->ReleaseScriptObject(*(void**)m_restorePtr, type);
|
||||
|
||||
// Update the internal pointer
|
||||
*(void**)m_restorePtr = handleTo->m_restorePtr;
|
||||
|
||||
// Increase the reference
|
||||
m_serializer->m_engine->AddRefScriptObject(handleTo->m_restorePtr, type);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the handle is pointing to something, we must release it to restore the null pointer
|
||||
if( m_restorePtr && *(void**)m_restorePtr )
|
||||
{
|
||||
m_serializer->m_engine->ReleaseScriptObject(*(void**)m_restorePtr, m_serializer->m_engine->GetTypeInfoById(m_typeId));
|
||||
*(void**)m_restorePtr = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do the same for the children
|
||||
for( size_t i = 0; i < m_children.size(); ++i )
|
||||
m_children[i]->RestoreHandles();
|
||||
}
|
||||
|
||||
void CSerializedValue::SetType(int typeId)
|
||||
{
|
||||
m_typeId = typeId;
|
||||
|
||||
asITypeInfo *type = m_serializer->m_engine->GetTypeInfoById(typeId);
|
||||
|
||||
if( type )
|
||||
m_typeName = type->GetName();
|
||||
}
|
||||
|
||||
asITypeInfo *CSerializedValue::GetType()
|
||||
{
|
||||
if( !m_typeName.empty() )
|
||||
{
|
||||
int newTypeId = m_serializer->m_mod->GetTypeIdByDecl(m_typeName.c_str());
|
||||
return m_serializer->m_engine->GetTypeInfoById(newTypeId);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CSerializedValue::SetUserData(void *data)
|
||||
{
|
||||
m_userData = data;
|
||||
}
|
||||
|
||||
void *CSerializedValue::GetUserData()
|
||||
{
|
||||
return m_userData;
|
||||
}
|
||||
|
||||
END_AS_NAMESPACE
|
|
@ -0,0 +1,193 @@
|
|||
//
|
||||
// CSerializer
|
||||
//
|
||||
// This code was based on the CScriptReloader written by FDsagizi
|
||||
// http://www.gamedev.net/topic/604890-dynamic-reloading-script/
|
||||
//
|
||||
|
||||
#ifndef SERIALIZER_H
|
||||
#define SERIALIZER_H
|
||||
|
||||
#ifndef ANGELSCRIPT_H
|
||||
// Avoid having to inform include path if header is already include before
|
||||
#include <angelscript.h>
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
class CSerializer;
|
||||
class CSerializedValue;
|
||||
|
||||
// Need for register user types objects
|
||||
// string, any, array... for all object
|
||||
// user ref type.
|
||||
struct CUserType
|
||||
{
|
||||
virtual ~CUserType() {};
|
||||
virtual void Store(CSerializedValue *val, void *ptr) = 0;
|
||||
virtual void Restore(CSerializedValue *val, void *ptr) = 0;
|
||||
virtual void CleanupUserData(CSerializedValue * /*val*/) {}
|
||||
};
|
||||
|
||||
|
||||
class CSerializedValue
|
||||
{
|
||||
public:
|
||||
CSerializedValue();
|
||||
CSerializedValue(CSerializedValue *parent, const std::string &name, const std::string &nameSpace, void *ref, int typeId);
|
||||
~CSerializedValue();
|
||||
|
||||
// Save the object and its children
|
||||
void Store(void *ref, int refTypeId);
|
||||
|
||||
// Restore the object and its children
|
||||
void Restore(void *ref, int refTypeId);
|
||||
|
||||
// Set type of this var
|
||||
void SetType(int typeId);
|
||||
|
||||
// Returns the object type for non-primitives
|
||||
asITypeInfo *GetType();
|
||||
|
||||
// Get child by name variable
|
||||
CSerializedValue *FindByName(const std::string &name, const std::string &nameSpace);
|
||||
|
||||
// Find variable by ptr
|
||||
CSerializedValue *FindByPtr(void *ptr);
|
||||
|
||||
// User data
|
||||
void *GetUserData();
|
||||
void SetUserData(void *data);
|
||||
|
||||
// Children, e.g. properties of a script class, or elements
|
||||
// of an array, or object pointed to by a handle unless it
|
||||
// is already a variable)
|
||||
std::vector<CSerializedValue*> m_children;
|
||||
|
||||
protected:
|
||||
friend class CSerializer;
|
||||
|
||||
void Init();
|
||||
void Uninit();
|
||||
|
||||
// you first need to save all the objects before you can save references to objects
|
||||
void ReplaceHandles();
|
||||
|
||||
// After the objects has been restored, the handles needs to
|
||||
// be updated to point to the right objects
|
||||
void RestoreHandles();
|
||||
|
||||
// Recursively get all ptrs of the children
|
||||
void GetAllPointersOfChildren(std::vector<void*> *ptrs);
|
||||
|
||||
// may be that the two references refer to the same variable.
|
||||
// But this variable is not available in the global list.
|
||||
// According to this reference will be restores it.
|
||||
// And so two links are not created 2 variables,
|
||||
// it is necessary to cancel the creation of one of them.
|
||||
void CancelDuplicates(CSerializedValue *from);
|
||||
|
||||
// Find variable by ptr but looking only at those in the references, which will create a new object
|
||||
CSerializedValue *FindByPtrInHandles(void *ptr);
|
||||
|
||||
// ptr - is a handle to class
|
||||
void *GetPointerToRestoredObject(void *ptr);
|
||||
|
||||
// Cleanup children
|
||||
void ClearChildren();
|
||||
|
||||
// The serializer object
|
||||
CSerializer *m_serializer;
|
||||
|
||||
// The user data can be used by CUserType to store extra information
|
||||
void *m_userData;
|
||||
|
||||
// The type id of the stored value
|
||||
int m_typeId;
|
||||
|
||||
// For non-primitives the typeId may change if the module is reloaded so
|
||||
// it is necessary to store the type name to determine the new type id
|
||||
std::string m_typeName;
|
||||
|
||||
// Name of variable or property
|
||||
std::string m_name;
|
||||
std::string m_nameSpace;
|
||||
|
||||
// Is initialized
|
||||
bool m_isInit;
|
||||
|
||||
// 'this' pointer to variable.
|
||||
// While storing, this points to the actual variable that was stored.
|
||||
// While restoring, it is just a unique identifier.
|
||||
void *m_originalPtr;
|
||||
|
||||
// where handle references
|
||||
// While storing, this points to the actual object.
|
||||
// While restoring, it is just a unique identifier.
|
||||
void *m_handlePtr;
|
||||
|
||||
// new address object, ie address the restoration
|
||||
// While storing this isn't used.
|
||||
// While restoring it will point to the actual variable/object that is restored.
|
||||
void *m_restorePtr;
|
||||
|
||||
// Serialized data for primitives
|
||||
std::vector<char> m_mem;
|
||||
};
|
||||
|
||||
|
||||
// This class keeps a list of variables, then restores them after the script is rebuilt.
|
||||
// But you have to be careful with the change of signature in classes, or
|
||||
// changing the types of objects. You can remove or add variables, functions,
|
||||
// methods, but you can not (yet) change the type of variables.
|
||||
//
|
||||
// You also need to understand that after a rebuild you should get
|
||||
// new functions and typeids from the module.
|
||||
class CSerializer
|
||||
{
|
||||
public:
|
||||
CSerializer();
|
||||
~CSerializer();
|
||||
|
||||
// Add implementation for serializing user types
|
||||
void AddUserType(CUserType *ref, const std::string &name);
|
||||
|
||||
// Store all global variables in the module
|
||||
int Store(asIScriptModule *mod);
|
||||
|
||||
// Restore all global variables after reloading script
|
||||
int Restore(asIScriptModule *mod);
|
||||
|
||||
// Store extra objects that are not seen from the module's global variables
|
||||
void AddExtraObjectToStore(asIScriptObject *object);
|
||||
|
||||
// Return new pointer to restored object
|
||||
void *GetPointerToRestoredObject(void *originalObject);
|
||||
|
||||
protected:
|
||||
friend class CSerializedValue;
|
||||
|
||||
CSerializedValue m_root;
|
||||
asIScriptEngine *m_engine;
|
||||
asIScriptModule *m_mod;
|
||||
|
||||
std::map<std::string, CUserType*> m_userTypes;
|
||||
|
||||
struct SExtraObject
|
||||
{
|
||||
asIScriptObject *originalObject;
|
||||
std::string originalClassName;
|
||||
int originalTypeId;
|
||||
};
|
||||
|
||||
std::vector<SExtraObject> m_extraObjects;
|
||||
};
|
||||
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,377 @@
|
|||
|
||||
// The CScriptWeakRef class was originally implemented by vroad in March 2013
|
||||
|
||||
#include "weakref.h"
|
||||
#include <new>
|
||||
#include <assert.h>
|
||||
#include <string.h> // strstr()
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
static void ScriptWeakRefConstruct(asITypeInfo *type, void *mem)
|
||||
{
|
||||
new(mem) CScriptWeakRef(type);
|
||||
}
|
||||
|
||||
static void ScriptWeakRefConstruct2(asITypeInfo *type, void *ref, void *mem)
|
||||
{
|
||||
new(mem) CScriptWeakRef(ref, type);
|
||||
|
||||
// It's possible the constructor raised a script exception, in which case we
|
||||
// need to call the destructor in order to cleanup the memory before returning
|
||||
asIScriptContext *ctx = asGetActiveContext();
|
||||
if( ctx && ctx->GetState() == asEXECUTION_EXCEPTION )
|
||||
reinterpret_cast<CScriptWeakRef*>(mem)->~CScriptWeakRef();
|
||||
}
|
||||
|
||||
static void ScriptWeakRefDestruct(CScriptWeakRef *obj)
|
||||
{
|
||||
obj->~CScriptWeakRef();
|
||||
}
|
||||
|
||||
static bool ScriptWeakRefTemplateCallback(asITypeInfo *ti, bool &/*dontGarbageCollect*/)
|
||||
{
|
||||
asITypeInfo *subType = ti->GetSubType();
|
||||
|
||||
// Weak references only work for reference types
|
||||
if( subType == 0 ) return false;
|
||||
if( !(subType->GetFlags() & asOBJ_REF) ) return false;
|
||||
|
||||
// The subtype shouldn't be a handle
|
||||
if( ti->GetSubTypeId() & asTYPEID_OBJHANDLE )
|
||||
return false;
|
||||
|
||||
// Make sure the type really supports weak references
|
||||
asUINT cnt = subType->GetBehaviourCount();
|
||||
for( asUINT n = 0; n < cnt; n++ )
|
||||
{
|
||||
asEBehaviours beh;
|
||||
subType->GetBehaviourByIndex(n, &beh);
|
||||
if( beh == asBEHAVE_GET_WEAKREF_FLAG )
|
||||
return true;
|
||||
}
|
||||
|
||||
ti->GetEngine()->WriteMessage("weakref", 0, 0, asMSGTYPE_ERROR, "The subtype doesn't support weak references");
|
||||
return false;
|
||||
}
|
||||
|
||||
CScriptWeakRef::CScriptWeakRef(asITypeInfo *type)
|
||||
{
|
||||
m_ref = 0;
|
||||
m_type = type;
|
||||
m_type->AddRef();
|
||||
m_weakRefFlag = 0;
|
||||
}
|
||||
|
||||
CScriptWeakRef::CScriptWeakRef(const CScriptWeakRef &other)
|
||||
{
|
||||
m_ref = other.m_ref;
|
||||
m_type = other.m_type;
|
||||
m_type->AddRef();
|
||||
m_weakRefFlag = other.m_weakRefFlag;
|
||||
if( m_weakRefFlag )
|
||||
m_weakRefFlag->AddRef();
|
||||
}
|
||||
|
||||
CScriptWeakRef::CScriptWeakRef(void *ref, asITypeInfo *type)
|
||||
{
|
||||
m_ref = ref;
|
||||
m_type = type;
|
||||
m_type->AddRef();
|
||||
|
||||
// The given type should be the weakref template instance
|
||||
assert( strcmp(type->GetName(), "weakref") == 0 ||
|
||||
strcmp(type->GetName(), "const_weakref") == 0 );
|
||||
|
||||
// Get the shared flag that will tell us when the object has been destroyed
|
||||
// This is threadsafe as we hold a strong reference to the object
|
||||
m_weakRefFlag = m_type->GetEngine()->GetWeakRefFlagOfScriptObject(m_ref, m_type->GetSubType());
|
||||
if( m_weakRefFlag )
|
||||
m_weakRefFlag->AddRef();
|
||||
}
|
||||
|
||||
CScriptWeakRef::~CScriptWeakRef()
|
||||
{
|
||||
if( m_type )
|
||||
m_type->Release();
|
||||
if( m_weakRefFlag )
|
||||
m_weakRefFlag->Release();
|
||||
}
|
||||
|
||||
CScriptWeakRef &CScriptWeakRef::operator =(const CScriptWeakRef &other)
|
||||
{
|
||||
// Don't do anything if it is the same reference
|
||||
// It is not enough to verify only the reference to the object, as the
|
||||
// address may be reused by another instance after the first has been freed.
|
||||
// By checking also the weakRefFlag we can be certain that it is the same
|
||||
// instance.
|
||||
if( m_ref == other.m_ref &&
|
||||
m_weakRefFlag == other.m_weakRefFlag )
|
||||
return *this;
|
||||
|
||||
// Must not allow changing the type
|
||||
if( m_type != other.m_type )
|
||||
{
|
||||
// We can allow a weakref to be assigned to a const_weakref
|
||||
if( !(strcmp(m_type->GetName(), "const_weakref") == 0 &&
|
||||
strcmp(other.m_type->GetName(), "weakref") == 0 &&
|
||||
m_type->GetSubType() == other.m_type->GetSubType()) )
|
||||
{
|
||||
assert( false );
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
m_ref = other.m_ref;
|
||||
|
||||
if( m_weakRefFlag )
|
||||
m_weakRefFlag->Release();
|
||||
m_weakRefFlag = other.m_weakRefFlag;
|
||||
if( m_weakRefFlag )
|
||||
m_weakRefFlag->AddRef();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
CScriptWeakRef &CScriptWeakRef::Set(void *newRef)
|
||||
{
|
||||
// Release the previous weak ref
|
||||
if( m_weakRefFlag )
|
||||
m_weakRefFlag->Release();
|
||||
|
||||
// Retrieve the new weak ref
|
||||
m_ref = newRef;
|
||||
if( newRef )
|
||||
{
|
||||
m_weakRefFlag = m_type->GetEngine()->GetWeakRefFlagOfScriptObject(newRef, m_type->GetSubType());
|
||||
m_weakRefFlag->AddRef();
|
||||
}
|
||||
else
|
||||
m_weakRefFlag = 0;
|
||||
|
||||
// Release the newRef since we're only supposed to hold a weakref
|
||||
m_type->GetEngine()->ReleaseScriptObject(newRef, m_type->GetSubType());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
asITypeInfo *CScriptWeakRef::GetRefType() const
|
||||
{
|
||||
return m_type->GetSubType();
|
||||
}
|
||||
|
||||
bool CScriptWeakRef::operator==(const CScriptWeakRef &o) const
|
||||
{
|
||||
// It is not enough to compare just the address of the object, as it may
|
||||
// be reused by another instance after the first has been freed. By verifying
|
||||
// also the weakRefFlag we can guarantee that it is indeed the same instance.
|
||||
if( m_ref == o.m_ref &&
|
||||
m_weakRefFlag == o.m_weakRefFlag &&
|
||||
m_type == o.m_type )
|
||||
return true;
|
||||
|
||||
// TODO: If type is not the same, we should attempt to do a dynamic cast,
|
||||
// which may change the pointer for application registered classes
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CScriptWeakRef::operator!=(const CScriptWeakRef &o) const
|
||||
{
|
||||
return !(*this == o);
|
||||
}
|
||||
|
||||
// AngelScript: used as '@obj = ref.get();'
|
||||
void *CScriptWeakRef::Get() const
|
||||
{
|
||||
// If we hold a null handle, then just return null
|
||||
if( m_ref == 0 || m_weakRefFlag == 0 )
|
||||
return 0;
|
||||
|
||||
// Lock on the shared bool, so we can be certain it won't be changed to true
|
||||
// between the inspection of the flag and the increase of the ref count in the
|
||||
// owning object.
|
||||
m_weakRefFlag->Lock();
|
||||
if( !m_weakRefFlag->Get() )
|
||||
{
|
||||
m_type->GetEngine()->AddRefScriptObject(m_ref, m_type->GetSubType());
|
||||
m_weakRefFlag->Unlock();
|
||||
return m_ref;
|
||||
}
|
||||
m_weakRefFlag->Unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CScriptWeakRef::Equals(void *ref) const
|
||||
{
|
||||
if( m_ref != ref )
|
||||
return false;
|
||||
|
||||
// It is not enough to compare just the address, as another instance may
|
||||
// get the same address after the first instance has been freed. Verify the
|
||||
// weakref flag too to make sure it is the same instance
|
||||
asILockableSharedBool *flag = m_type->GetEngine()->GetWeakRefFlagOfScriptObject(ref, m_type->GetSubType());
|
||||
if (m_weakRefFlag != flag)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RegisterScriptWeakRef_Native(asIScriptEngine *engine)
|
||||
{
|
||||
int r;
|
||||
|
||||
// Register a type for non-const handles
|
||||
r = engine->RegisterObjectType("weakref<class T>", sizeof(CScriptWeakRef), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_TEMPLATE | asOBJ_APP_CLASS_DAK); assert( r >= 0 );
|
||||
|
||||
r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in)", asFUNCTION(ScriptWeakRefConstruct), asCALL_CDECL_OBJLAST); assert( r>= 0 );
|
||||
r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in, T@+)", asFUNCTION(ScriptWeakRefConstruct2), asCALL_CDECL_OBJLAST); assert( r>= 0 );
|
||||
r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(ScriptWeakRefDestruct), asCALL_CDECL_OBJLAST); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_TEMPLATE_CALLBACK, "bool f(int&in, bool&out)", asFUNCTION(ScriptWeakRefTemplateCallback), asCALL_CDECL); assert( r >= 0 );
|
||||
|
||||
r = engine->RegisterObjectMethod("weakref<T>", "T@ opImplCast()", asMETHOD(CScriptWeakRef, Get), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("weakref<T>", "T@ get() const", asMETHODPR(CScriptWeakRef, Get, () const, void*), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("weakref<T>", "weakref<T> &opHndlAssign(const weakref<T> &in)", asMETHOD(CScriptWeakRef, operator=), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("weakref<T>", "weakref<T> &opAssign(const weakref<T> &in)", asMETHOD(CScriptWeakRef, operator=), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("weakref<T>", "bool opEquals(const weakref<T> &in) const", asMETHODPR(CScriptWeakRef, operator==, (const CScriptWeakRef &) const, bool), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("weakref<T>", "weakref<T> &opHndlAssign(T@)", asMETHOD(CScriptWeakRef, Set), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("weakref<T>", "bool opEquals(const T@+) const", asMETHOD(CScriptWeakRef, Equals), asCALL_THISCALL); assert(r >= 0);
|
||||
|
||||
// Register another type for const handles
|
||||
r = engine->RegisterObjectType("const_weakref<class T>", sizeof(CScriptWeakRef), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_TEMPLATE | asOBJ_APP_CLASS_DAK); assert( r >= 0 );
|
||||
|
||||
r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in)", asFUNCTION(ScriptWeakRefConstruct), asCALL_CDECL_OBJLAST); assert( r>= 0 );
|
||||
r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in, const T@+)", asFUNCTION(ScriptWeakRefConstruct2), asCALL_CDECL_OBJLAST); assert( r>= 0 );
|
||||
r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(ScriptWeakRefDestruct), asCALL_CDECL_OBJLAST); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_TEMPLATE_CALLBACK, "bool f(int&in, bool&out)", asFUNCTION(ScriptWeakRefTemplateCallback), asCALL_CDECL); assert( r >= 0 );
|
||||
|
||||
r = engine->RegisterObjectMethod("const_weakref<T>", "const T@ opImplCast() const", asMETHOD(CScriptWeakRef, Get), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("const_weakref<T>", "const T@ get() const", asMETHODPR(CScriptWeakRef, Get, () const, void*), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("const_weakref<T>", "const_weakref<T> &opHndlAssign(const const_weakref<T> &in)", asMETHOD(CScriptWeakRef, operator=), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("const_weakref<T>", "const_weakref<T> &opAssign(const const_weakref<T> &in)", asMETHOD(CScriptWeakRef, operator=), asCALL_THISCALL); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("const_weakref<T>", "bool opEquals(const const_weakref<T> &in) const", asMETHODPR(CScriptWeakRef, operator==, (const CScriptWeakRef &) const, bool), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("const_weakref<T>", "const_weakref<T> &opHndlAssign(const T@)", asMETHOD(CScriptWeakRef, Set), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("const_weakref<T>", "bool opEquals(const T@+) const", asMETHOD(CScriptWeakRef, Equals), asCALL_THISCALL); assert(r >= 0);
|
||||
|
||||
// Allow non-const weak references to be converted to const weak references
|
||||
r = engine->RegisterObjectMethod("const_weakref<T>", "const_weakref<T> &opHndlAssign(const weakref<T> &in)", asMETHOD(CScriptWeakRef, operator=), asCALL_THISCALL); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("const_weakref<T>", "bool opEquals(const weakref<T> &in) const", asMETHODPR(CScriptWeakRef, operator==, (const CScriptWeakRef &) const, bool), asCALL_THISCALL); assert( r >= 0 );
|
||||
}
|
||||
|
||||
static void ScriptWeakRefConstruct_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
asITypeInfo *ti = *reinterpret_cast<asITypeInfo**>(gen->GetAddressOfArg(0));
|
||||
|
||||
ScriptWeakRefConstruct(ti, gen->GetObject());
|
||||
}
|
||||
|
||||
static void ScriptWeakRefConstruct2_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
asITypeInfo *ti = *reinterpret_cast<asITypeInfo**>(gen->GetAddressOfArg(0));
|
||||
void *ref = gen->GetArgAddress(1);
|
||||
|
||||
ScriptWeakRefConstruct2(ti, ref, gen->GetObject());
|
||||
}
|
||||
|
||||
static void ScriptWeakRefDestruct_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptWeakRef *self = reinterpret_cast<CScriptWeakRef*>(gen->GetObject());
|
||||
self->~CScriptWeakRef();
|
||||
}
|
||||
|
||||
void CScriptWeakRef_Get_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptWeakRef *self = reinterpret_cast<CScriptWeakRef*>(gen->GetObject());
|
||||
gen->SetReturnAddress(self->Get());
|
||||
}
|
||||
|
||||
void CScriptWeakRef_Assign_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptWeakRef *other = reinterpret_cast<CScriptWeakRef*>(gen->GetArgAddress(0));
|
||||
CScriptWeakRef *self = reinterpret_cast<CScriptWeakRef*>(gen->GetObject());
|
||||
*self = *other;
|
||||
gen->SetReturnAddress(self);
|
||||
}
|
||||
|
||||
void CScriptWeakRef_Assign2_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
void *other = gen->GetArgAddress(0);
|
||||
CScriptWeakRef *self = reinterpret_cast<CScriptWeakRef*>(gen->GetObject());
|
||||
self->Set(other);
|
||||
gen->SetReturnAddress(self);
|
||||
}
|
||||
|
||||
void CScriptWeakRef_Equals_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
CScriptWeakRef *other = reinterpret_cast<CScriptWeakRef*>(gen->GetArgAddress(0));
|
||||
CScriptWeakRef *self = reinterpret_cast<CScriptWeakRef*>(gen->GetObject());
|
||||
gen->SetReturnByte(*self == *other);
|
||||
}
|
||||
|
||||
void CScriptWeakRef_Equals2_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
void *other = gen->GetArgAddress(0);
|
||||
CScriptWeakRef *self = reinterpret_cast<CScriptWeakRef*>(gen->GetObject());
|
||||
|
||||
gen->SetReturnByte(self->Equals(other));
|
||||
}
|
||||
|
||||
static void ScriptWeakRefTemplateCallback_Generic(asIScriptGeneric *gen)
|
||||
{
|
||||
asITypeInfo *ti = *reinterpret_cast<asITypeInfo**>(gen->GetAddressOfArg(0));
|
||||
bool *dontGarbageCollect = *reinterpret_cast<bool**>(gen->GetAddressOfArg(1));
|
||||
*reinterpret_cast<bool*>(gen->GetAddressOfReturnLocation()) = ScriptWeakRefTemplateCallback(ti, *dontGarbageCollect);
|
||||
}
|
||||
|
||||
void RegisterScriptWeakRef_Generic(asIScriptEngine *engine)
|
||||
{
|
||||
int r;
|
||||
|
||||
// Register a type for non-const handles
|
||||
r = engine->RegisterObjectType("weakref<class T>", sizeof(CScriptWeakRef), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_TEMPLATE | asOBJ_APP_CLASS_DAK); assert( r >= 0 );
|
||||
|
||||
r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in)", asFUNCTION(ScriptWeakRefConstruct_Generic), asCALL_GENERIC); assert( r>= 0 );
|
||||
r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in, T@+)", asFUNCTION(ScriptWeakRefConstruct2_Generic), asCALL_GENERIC); assert( r>= 0 );
|
||||
r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_TEMPLATE_CALLBACK, "bool f(int&in, bool&out)", asFUNCTION(ScriptWeakRefTemplateCallback_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("weakref<T>", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(ScriptWeakRefDestruct_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
|
||||
r = engine->RegisterObjectMethod("weakref<T>", "T@ opImplCast()", asFUNCTION(CScriptWeakRef_Get_Generic), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("weakref<T>", "T@ get() const", asFUNCTION(CScriptWeakRef_Get_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("weakref<T>", "weakref<T> &opHndlAssign(const weakref<T> &in)", asFUNCTION(CScriptWeakRef_Assign_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("weakref<T>", "weakref<T> &opAssign(const weakref<T> &in)", asFUNCTION(CScriptWeakRef_Assign_Generic), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("weakref<T>", "bool opEquals(const weakref<T> &in) const", asFUNCTION(CScriptWeakRef_Equals_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("weakref<T>", "weakref<T> &opHndlAssign(T@)", asFUNCTION(CScriptWeakRef_Assign2_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("weakref<T>", "bool opEquals(const T@+) const", asFUNCTION(CScriptWeakRef_Equals2_Generic), asCALL_GENERIC); assert(r >= 0);
|
||||
|
||||
// Register another type for const handles
|
||||
r = engine->RegisterObjectType("const_weakref<class T>", sizeof(CScriptWeakRef), asOBJ_VALUE | asOBJ_ASHANDLE | asOBJ_TEMPLATE | asOBJ_APP_CLASS_DAK); assert( r >= 0 );
|
||||
|
||||
r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in)", asFUNCTION(ScriptWeakRefConstruct_Generic), asCALL_GENERIC); assert( r>= 0 );
|
||||
r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_CONSTRUCT, "void f(int&in, const T@+)", asFUNCTION(ScriptWeakRefConstruct2_Generic), asCALL_GENERIC); assert( r>= 0 );
|
||||
r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_TEMPLATE_CALLBACK, "bool f(int&in, bool&out)", asFUNCTION(ScriptWeakRefTemplateCallback_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectBehaviour("const_weakref<T>", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(ScriptWeakRefDestruct_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
|
||||
r = engine->RegisterObjectMethod("const_weakref<T>", "const T@ opImplCast() const", asFUNCTION(CScriptWeakRef_Get_Generic), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("const_weakref<T>", "const T@ get() const", asFUNCTION(CScriptWeakRef_Get_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("const_weakref<T>", "const_weakref<T> &opHndlAssign(const const_weakref<T> &in)", asFUNCTION(CScriptWeakRef_Assign_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("const_weakref<T>", "const_weakref<T> &opAssign(const const_weakref<T> &in)", asFUNCTION(CScriptWeakRef_Assign_Generic), asCALL_GENERIC); assert(r >= 0);
|
||||
r = engine->RegisterObjectMethod("const_weakref<T>", "bool opEquals(const const_weakref<T> &in) const", asFUNCTION(CScriptWeakRef_Equals_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("const_weakref<T>", "const_weakref<T> &opHndlAssign(const T@)", asFUNCTION(CScriptWeakRef_Assign2_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("const_weakref<T>", "bool opEquals(const T@+) const", asFUNCTION(CScriptWeakRef_Equals2_Generic), asCALL_GENERIC); assert(r >= 0);
|
||||
|
||||
// Allow non-const weak references to be converted to const weak references
|
||||
r = engine->RegisterObjectMethod("const_weakref<T>", "const_weakref<T> &opHndlAssign(const weakref<T> &in)", asFUNCTION(CScriptWeakRef_Assign_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
r = engine->RegisterObjectMethod("const_weakref<T>", "bool opEquals(const weakref<T> &in) const", asFUNCTION(CScriptWeakRef_Equals_Generic), asCALL_GENERIC); assert( r >= 0 );
|
||||
}
|
||||
|
||||
void RegisterScriptWeakRef(asIScriptEngine *engine)
|
||||
{
|
||||
if( strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
|
||||
RegisterScriptWeakRef_Generic(engine);
|
||||
else
|
||||
RegisterScriptWeakRef_Native(engine);
|
||||
}
|
||||
|
||||
|
||||
END_AS_NAMESPACE
|
|
@ -0,0 +1,58 @@
|
|||
#ifndef SCRIPTWEAKREF_H
|
||||
#define SCRIPTWEAKREF_H
|
||||
|
||||
// The CScriptWeakRef class was originally implemented by vroad in March 2013
|
||||
|
||||
#ifndef ANGELSCRIPT_H
|
||||
// Avoid having to inform include path if header is already include before
|
||||
#include <angelscript.h>
|
||||
#endif
|
||||
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
class CScriptWeakRef
|
||||
{
|
||||
public:
|
||||
// Constructors
|
||||
CScriptWeakRef(asITypeInfo *type);
|
||||
CScriptWeakRef(const CScriptWeakRef &other);
|
||||
CScriptWeakRef(void *ref, asITypeInfo *type);
|
||||
|
||||
~CScriptWeakRef();
|
||||
|
||||
// Copy the stored value from another weakref object
|
||||
CScriptWeakRef &operator=(const CScriptWeakRef &other);
|
||||
|
||||
// Compare equalness
|
||||
bool operator==(const CScriptWeakRef &o) const;
|
||||
bool operator!=(const CScriptWeakRef &o) const;
|
||||
|
||||
// Sets a new reference
|
||||
CScriptWeakRef &Set(void *newRef);
|
||||
|
||||
// Returns the object if it is still alive
|
||||
// This will increment the refCount of the returned object
|
||||
void *Get() const;
|
||||
|
||||
// Returns true if the contained reference is the same
|
||||
bool Equals(void *ref) const;
|
||||
|
||||
// Returns the type of the reference held
|
||||
asITypeInfo *GetRefType() const;
|
||||
|
||||
protected:
|
||||
// These functions need to have access to protected
|
||||
// members in order to call them from the script engine
|
||||
friend void RegisterScriptWeakRef_Native(asIScriptEngine *engine);
|
||||
|
||||
void *m_ref;
|
||||
asITypeInfo *m_type;
|
||||
asILockableSharedBool *m_weakRefFlag;
|
||||
};
|
||||
|
||||
void RegisterScriptWeakRef(asIScriptEngine *engine);
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
|||
This file is only here to guarantee that unpackers don't skip creating the /lib directory.
|
|
@ -0,0 +1,43 @@
|
|||
# This makefile assumes the ndk-build tool is executed from the sdk/angelscript/projects/android directory
|
||||
# Change the next line to full path if there are any errors to link or find files
|
||||
SDK_BASE_PATH := $(call my-dir)/../../../..
|
||||
|
||||
ANGELSCRIPT_INCLUDE := $(SDK_BASE_PATH)/angelscript/include/
|
||||
|
||||
# -----------------------------------------------------
|
||||
# Build the AngelScript library
|
||||
# -----------------------------------------------------
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := libangelscript
|
||||
|
||||
# Android API: Checks if can use pthreads. Version 2.3 fully supports threads and atomic instructions
|
||||
# ifeq ($(TARGET_PLATFORM),android-3)
|
||||
# LOCAL_CFLAGS := -DAS_NO_THREADS
|
||||
# else
|
||||
# ifeq ($(TARGET_PLATFORM),android-4)
|
||||
# LOCAL_CFLAGS := -DAS_NO_THREADS
|
||||
# else
|
||||
# ifeq ($(TARGET_PLATFORM),android-5)
|
||||
# LOCAL_CFLAGS := -DAS_NO_THREADS
|
||||
# else
|
||||
# ifeq ($(TARGET_PLATFORM),android-6)
|
||||
# LOCAL_CFLAGS := -DAS_NO_THREADS
|
||||
# else
|
||||
# ifeq ($(TARGET_PLATFORM),android-7)
|
||||
# LOCAL_CFLAGS := -DAS_NO_THREADS
|
||||
# else
|
||||
# ifeq ($(TARGET_PLATFORM),android-8)
|
||||
# LOCAL_CFLAGS := -DAS_NO_THREADS
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
|
||||
LOCAL_CPP_FEATURES += rtti exceptions
|
||||
LOCAL_SRC_FILES := $(wildcard $(SDK_BASE_PATH)/angelscript/source/*.S)
|
||||
LOCAL_SRC_FILES += $(wildcard $(SDK_BASE_PATH)/angelscript/source/*.cpp)
|
||||
LOCAL_PATH := .
|
||||
LOCAL_ARM_MODE := arm
|
||||
include $(BUILD_STATIC_LIBRARY)
|
|
@ -0,0 +1,3 @@
|
|||
APP_ABI := mips armeabi armeabi-v7a x86
|
||||
APP_PLATFORM := android-19
|
||||
APP_STL := gnustl_static
|
|
@ -0,0 +1,2 @@
|
|||
include("${CMAKE_CURRENT_LIST_DIR}/AngelscriptTargets.cmake")
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
# This is a basic version file for the Config-mode of find_package().
|
||||
# It is used by write_basic_package_version_file() as input file for configure_file()
|
||||
# to create a version-file which can be installed along a config.cmake file.
|
||||
#
|
||||
# The created file sets PACKAGE_VERSION_EXACT if the current version string and
|
||||
# the requested version string are exactly the same and it sets
|
||||
# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version.
|
||||
# The variable CVF_VERSION must be set before calling configure_file().
|
||||
|
||||
set(PACKAGE_VERSION "2.34.0")
|
||||
|
||||
if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
|
||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||
else()
|
||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||
if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
|
||||
set(PACKAGE_VERSION_EXACT TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# if the installed project requested no architecture check, don't perform the check
|
||||
if("FALSE")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
|
||||
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "8" STREQUAL "")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
|
||||
if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "8")
|
||||
math(EXPR installedBits "8 * 8")
|
||||
set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
|
||||
set(PACKAGE_VERSION_UNSUITABLE TRUE)
|
||||
endif()
|
|
@ -0,0 +1,63 @@
|
|||
# Generated by CMake
|
||||
|
||||
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.5)
|
||||
message(FATAL_ERROR "CMake >= 2.6.0 required")
|
||||
endif()
|
||||
cmake_policy(PUSH)
|
||||
cmake_policy(VERSION 2.6)
|
||||
#----------------------------------------------------------------
|
||||
# Generated CMake target import file.
|
||||
#----------------------------------------------------------------
|
||||
|
||||
# Commands may need to know the format version.
|
||||
set(CMAKE_IMPORT_FILE_VERSION 1)
|
||||
|
||||
# Protect against multiple inclusion, which would fail when already imported targets are added once more.
|
||||
set(_targetsDefined)
|
||||
set(_targetsNotDefined)
|
||||
set(_expectedTargets)
|
||||
foreach(_expectedTarget Angelscript::angelscript)
|
||||
list(APPEND _expectedTargets ${_expectedTarget})
|
||||
if(NOT TARGET ${_expectedTarget})
|
||||
list(APPEND _targetsNotDefined ${_expectedTarget})
|
||||
endif()
|
||||
if(TARGET ${_expectedTarget})
|
||||
list(APPEND _targetsDefined ${_expectedTarget})
|
||||
endif()
|
||||
endforeach()
|
||||
if("${_targetsDefined}" STREQUAL "${_expectedTargets}")
|
||||
unset(_targetsDefined)
|
||||
unset(_targetsNotDefined)
|
||||
unset(_expectedTargets)
|
||||
set(CMAKE_IMPORT_FILE_VERSION)
|
||||
cmake_policy(POP)
|
||||
return()
|
||||
endif()
|
||||
if(NOT "${_targetsDefined}" STREQUAL "")
|
||||
message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_targetsDefined}\nTargets not yet defined: ${_targetsNotDefined}\n")
|
||||
endif()
|
||||
unset(_targetsDefined)
|
||||
unset(_targetsNotDefined)
|
||||
unset(_expectedTargets)
|
||||
|
||||
|
||||
# Create imported target Angelscript::angelscript
|
||||
add_library(Angelscript::angelscript STATIC IMPORTED)
|
||||
|
||||
set_target_properties(Angelscript::angelscript PROPERTIES
|
||||
INTERFACE_LINK_LIBRARIES "Threads::Threads"
|
||||
)
|
||||
|
||||
# Import target "Angelscript::angelscript" for configuration "Debug"
|
||||
set_property(TARGET Angelscript::angelscript APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
|
||||
set_target_properties(Angelscript::angelscript PROPERTIES
|
||||
IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX"
|
||||
IMPORTED_LOCATION_DEBUG "/home/nathan/Projects/Angelscript/angelscript/projects/cmake/libangelscript.a"
|
||||
)
|
||||
|
||||
# This file does not depend on other imported targets which have
|
||||
# been exported from the same project but in a separate export set.
|
||||
|
||||
# Commands beyond this point should not need to know the version.
|
||||
set(CMAKE_IMPORT_FILE_VERSION)
|
||||
cmake_policy(POP)
|
|
@ -0,0 +1,239 @@
|
|||
cmake_minimum_required(VERSION 3.16)
|
||||
include(CheckIPOSupported)
|
||||
|
||||
project(angelscript)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
option(BUILD_SHARED_LIBS "Build shared library" OFF)
|
||||
option(LINK_STD_STATICALLY "Build shared library" OFF)
|
||||
option(AS_NO_EXCEPTIONS "Disable exception handling in script context" OFF)
|
||||
|
||||
if(MSVC)
|
||||
option(MSVC_COMPILE_FLAGS "Compiler flags to use with MSVC" "/MP")
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
option(BUILD_FRAMEWORK "Build Framework bundle for OSX" OFF)
|
||||
endif()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
add_link_options(-fuse-ld=lld)
|
||||
endif ()
|
||||
|
||||
|
||||
file(READ ../../include/angelscript.h ANGELSCRIPT_H)
|
||||
string(REGEX MATCH "#define ANGELSCRIPT_VERSION_STRING \"([0-9]*).([0-9]*).([0-9]*)" ANGELSCRIPT_VERSION_REGEX ${ANGELSCRIPT_H})
|
||||
set(ANGELSCRIPT_VERSION_MAJOR ${CMAKE_MATCH_1})
|
||||
set(ANGELSCRIPT_VERSION_MINOR ${CMAKE_MATCH_2})
|
||||
set(ANGELSCRIPT_VERSION_PATCH ${CMAKE_MATCH_3})
|
||||
set(PROJECT_VERSION ${ANGELSCRIPT_VERSION_MAJOR}.${ANGELSCRIPT_VERSION_MINOR}.${ANGELSCRIPT_VERSION_PATCH})
|
||||
|
||||
message(STATUS "Configuring angelscript ${PROJECT_VERSION}")
|
||||
|
||||
set(ANGELSCRIPT_HEADERS
|
||||
../../include/angelscript.h
|
||||
../../source/as_array.h
|
||||
../../source/as_builder.h
|
||||
../../source/as_bytecode.h
|
||||
../../source/as_callfunc.h
|
||||
../../source/as_compiler.h
|
||||
../../source/as_config.h
|
||||
../../source/as_configgroup.h
|
||||
../../source/as_context.h
|
||||
../../source/as_criticalsection.h
|
||||
../../source/as_datatype.h
|
||||
../../source/as_debug.h
|
||||
../../source/as_generic.h
|
||||
../../source/as_map.h
|
||||
../../source/as_memory.h
|
||||
../../source/as_module.h
|
||||
../../source/as_objecttype.h
|
||||
../../source/as_outputbuffer.h
|
||||
../../source/as_parser.h
|
||||
../../source/as_property.h
|
||||
../../source/as_restore.h
|
||||
../../source/as_scriptcode.h
|
||||
../../source/as_scriptengine.h
|
||||
../../source/as_scriptfunction.h
|
||||
../../source/as_scriptnode.h
|
||||
../../source/as_scriptobject.h
|
||||
../../source/as_string.h
|
||||
../../source/as_string_util.h
|
||||
../../source/as_texts.h
|
||||
../../source/as_thread.h
|
||||
../../source/as_tokendef.h
|
||||
../../source/as_tokenizer.h
|
||||
../../source/as_typeinfo.h
|
||||
../../source/as_variablescope.h
|
||||
)
|
||||
|
||||
set(ANGELSCRIPT_SOURCE
|
||||
../../source/as_atomic.cpp
|
||||
../../source/as_builder.cpp
|
||||
../../source/as_bytecode.cpp
|
||||
../../source/as_callfunc.cpp
|
||||
../../source/as_callfunc_mips.cpp
|
||||
../../source/as_callfunc_x86.cpp
|
||||
../../source/as_callfunc_x64_gcc.cpp
|
||||
../../source/as_callfunc_x64_msvc.cpp
|
||||
../../source/as_callfunc_x64_mingw.cpp
|
||||
../../source/as_compiler.cpp
|
||||
../../source/as_configgroup.cpp
|
||||
../../source/as_context.cpp
|
||||
../../source/as_datatype.cpp
|
||||
../../source/as_gc.cpp
|
||||
../../source/as_generic.cpp
|
||||
../../source/as_globalproperty.cpp
|
||||
../../source/as_memory.cpp
|
||||
../../source/as_module.cpp
|
||||
../../source/as_objecttype.cpp
|
||||
../../source/as_outputbuffer.cpp
|
||||
../../source/as_parser.cpp
|
||||
../../source/as_restore.cpp
|
||||
../../source/as_scriptcode.cpp
|
||||
../../source/as_scriptengine.cpp
|
||||
../../source/as_scriptfunction.cpp
|
||||
../../source/as_scriptnode.cpp
|
||||
../../source/as_scriptobject.cpp
|
||||
../../source/as_string.cpp
|
||||
../../source/as_string_util.cpp
|
||||
../../source/as_thread.cpp
|
||||
../../source/as_tokenizer.cpp
|
||||
../../source/as_typeinfo.cpp
|
||||
../../source/as_variablescope.cpp
|
||||
)
|
||||
|
||||
if(MSVC AND CMAKE_CL_64)
|
||||
enable_language(ASM_MASM)
|
||||
if(CMAKE_ASM_MASM_COMPILER_WORKS)
|
||||
set(ANGELSCRIPT_SOURCE ${ANGELSCRIPT_SOURCE} ../../source/as_callfunc_x64_msvc_asm.asm)
|
||||
else()
|
||||
message(FATAL ERROR "MSVC x86_64 target requires a working assembler")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^arm")
|
||||
enable_language(ASM)
|
||||
if(CMAKE_ASM_COMPILER_WORKS)
|
||||
set(ANGELSCRIPT_SOURCE ${ANGELSCRIPT_SOURCE} ../../source/as_callfunc_arm.cpp ../../source/as_callfunc_arm_gcc.S)
|
||||
set_property(SOURCE ../../source/as_callfunc_arm_gcc.S APPEND PROPERTY COMPILE_FLAGS " -Wa,-mimplicit-it=always")
|
||||
else()
|
||||
message(FATAL ERROR "ARM target requires a working assembler")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^aarch64")
|
||||
enable_language(ASM)
|
||||
if(CMAKE_ASM_COMPILER_WORKS)
|
||||
set(ANGELSCRIPT_SOURCE ${ANGELSCRIPT_SOURCE} ../../source/as_callfunc_arm64.cpp ../../source/as_callfunc_arm64_gcc.S)
|
||||
#set_property(SOURCE ../../source/as_callfunc_arm64_gcc.S APPEND PROPERTY COMPILE_FLAGS " -Wa")
|
||||
else()
|
||||
message(FATAL ERROR "ARM target requires a working assembler")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
set(CMAKE_DEBUG_POSTFIX "d")
|
||||
endif()
|
||||
|
||||
if(NOT BUILD_FRAMEWORK)
|
||||
set(ANGELSCRIPT_LIBRARY_NAME angelscript)
|
||||
else()
|
||||
set(ANGELSCRIPT_LIBRARY_NAME Angelscript) # OS X frameworks should have capitalized name
|
||||
set(BUILD_SHARED_LIBS TRUE)
|
||||
endif()
|
||||
set(ANGELSCRIPT_LIBRARY_NAME ${ANGELSCRIPT_LIBRARY_NAME} CACHE STRING "" FORCE)
|
||||
|
||||
add_library(${ANGELSCRIPT_LIBRARY_NAME} ${ANGELSCRIPT_SOURCE} ${ANGELSCRIPT_HEADERS})
|
||||
|
||||
target_include_directories(${ANGELSCRIPT_LIBRARY_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../include)
|
||||
|
||||
if(MSVC)
|
||||
target_compile_definitions(${ANGELSCRIPT_LIBRARY_NAME} PRIVATE -D_CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(${ANGELSCRIPT_LIBRARY_NAME} PRIVATE -DANGELSCRIPT_EXPORT -D_LIB)
|
||||
|
||||
if(AS_NO_EXCEPTIONS)
|
||||
target_compile_definitions(${ANGELSCRIPT_LIBRARY_NAME} PRIVATE AS_NO_EXCEPTIONS)
|
||||
endif()
|
||||
|
||||
# Don't override the default library output path to avoid conflicts when building for multiple target platforms
|
||||
#set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/../../lib)
|
||||
|
||||
if (LINK_STD_STATICALLY)
|
||||
message(STATUS "Linking std libraries statically")
|
||||
set (CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
|
||||
target_link_libraries(${ANGELSCRIPT_LIBRARY_NAME} -lpthread -static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ )
|
||||
else()
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(${ANGELSCRIPT_LIBRARY_NAME} -lpthread)
|
||||
endif()
|
||||
|
||||
set_target_properties(${ANGELSCRIPT_LIBRARY_NAME} PROPERTIES VERSION ${PROJECT_VERSION})
|
||||
|
||||
if(BUILD_FRAMEWORK)
|
||||
set_target_properties(${ANGELSCRIPT_LIBRARY_NAME} PROPERTIES
|
||||
FRAMEWORK TRUE
|
||||
FRAMEWORK_VERSION ${PROJECT_VERSION}
|
||||
MACOSX_FRAMEWORK_IDENTIFIER com.angelcode.Angelscript
|
||||
MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${PROJECT_VERSION}
|
||||
MACOSX_FRAMEWORK_BUNDLE_VERSION ${PROJECT_VERSION}
|
||||
XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
|
||||
PUBLIC_HEADER ../../include/angelscript.h
|
||||
)
|
||||
endif()
|
||||
|
||||
if(MSVC AND MSVC_COMPILE_FLAGS)
|
||||
target_compile_options(${ANGELSCRIPT_LIBRARY_NAME} PRIVATE "${MSVC_COMPILE_FLAGS}")
|
||||
endif()
|
||||
|
||||
# Don't override the default runtime output path to avoid conflicts when building for multiple target platforms
|
||||
#set(RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../../bin)
|
||||
|
||||
#See https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#creating-packages for a detailed explanation about this part
|
||||
install(TARGETS ${ANGELSCRIPT_LIBRARY_NAME} EXPORT AngelscriptTargets
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
INCLUDES DESTINATION include
|
||||
)
|
||||
|
||||
install(FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../include/angelscript.h
|
||||
DESTINATION include
|
||||
COMPONENT Devel
|
||||
)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
write_basic_package_version_file(
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/Angelscript/AngelscriptConfigVersion.cmake"
|
||||
VERSION ${PROJECT_VERSION}
|
||||
COMPATIBILITY AnyNewerVersion
|
||||
)
|
||||
|
||||
export(EXPORT AngelscriptTargets
|
||||
FILE "${CMAKE_CURRENT_BINARY_DIR}/Angelscript/AngelscriptTargets.cmake"
|
||||
NAMESPACE Angelscript::
|
||||
)
|
||||
configure_file(cmake/AngelscriptConfig.cmake
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/Angelscript/AngelscriptConfig.cmake"
|
||||
COPYONLY
|
||||
)
|
||||
|
||||
set(ConfigPackageLocation lib/cmake/Angelscript)
|
||||
install(EXPORT AngelscriptTargets
|
||||
FILE AngelscriptTargets.cmake
|
||||
NAMESPACE Angelscript::
|
||||
DESTINATION ${ConfigPackageLocation}
|
||||
)
|
||||
install(
|
||||
FILES
|
||||
cmake/AngelscriptConfig.cmake
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/Angelscript/AngelscriptConfigVersion.cmake"
|
||||
DESTINATION ${ConfigPackageLocation}
|
||||
COMPONENT Devel
|
||||
)
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
include("${CMAKE_CURRENT_LIST_DIR}/AngelscriptTargets.cmake")
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"graph_lock": {
|
||||
"nodes": {
|
||||
"0": {
|
||||
"ref": "AngelScript/2.35",
|
||||
"options": "link_std_statically=True\nshared=True",
|
||||
"path": "conanfile.py",
|
||||
"context": "host"
|
||||
}
|
||||
},
|
||||
"revisions_enabled": false
|
||||
},
|
||||
"version": "0.4",
|
||||
"profile_host": "[settings]\narch=x86_64\narch_build=x86_64\nbuild_type=Release\ncompiler=clang\ncompiler.libcxx=libstdc++11\ncompiler.version=11\nos=Linux\nos_build=Linux\n[options]\nlink_std_statically=True\nshared=True\n[build_requires]\n[env]\n"
|
||||
}
|
|
@ -0,0 +1,675 @@
|
|||
include(CMakeParseArguments)
|
||||
|
||||
macro(conan_find_apple_frameworks FRAMEWORKS_FOUND FRAMEWORKS SUFFIX BUILD_TYPE)
|
||||
if(APPLE)
|
||||
if(CMAKE_BUILD_TYPE)
|
||||
set(_BTYPE ${CMAKE_BUILD_TYPE})
|
||||
elseif(NOT BUILD_TYPE STREQUAL "")
|
||||
set(_BTYPE ${BUILD_TYPE})
|
||||
endif()
|
||||
if(_BTYPE)
|
||||
if(${_BTYPE} MATCHES "Debug|_DEBUG")
|
||||
set(CONAN_FRAMEWORKS${SUFFIX} ${CONAN_FRAMEWORKS${SUFFIX}_DEBUG} ${CONAN_FRAMEWORKS${SUFFIX}})
|
||||
set(CONAN_FRAMEWORK_DIRS${SUFFIX} ${CONAN_FRAMEWORK_DIRS${SUFFIX}_DEBUG} ${CONAN_FRAMEWORK_DIRS${SUFFIX}})
|
||||
elseif(${_BTYPE} MATCHES "Release|_RELEASE")
|
||||
set(CONAN_FRAMEWORKS${SUFFIX} ${CONAN_FRAMEWORKS${SUFFIX}_RELEASE} ${CONAN_FRAMEWORKS${SUFFIX}})
|
||||
set(CONAN_FRAMEWORK_DIRS${SUFFIX} ${CONAN_FRAMEWORK_DIRS${SUFFIX}_RELEASE} ${CONAN_FRAMEWORK_DIRS${SUFFIX}})
|
||||
elseif(${_BTYPE} MATCHES "RelWithDebInfo|_RELWITHDEBINFO")
|
||||
set(CONAN_FRAMEWORKS${SUFFIX} ${CONAN_FRAMEWORKS${SUFFIX}_RELWITHDEBINFO} ${CONAN_FRAMEWORKS${SUFFIX}})
|
||||
set(CONAN_FRAMEWORK_DIRS${SUFFIX} ${CONAN_FRAMEWORK_DIRS${SUFFIX}_RELWITHDEBINFO} ${CONAN_FRAMEWORK_DIRS${SUFFIX}})
|
||||
elseif(${_BTYPE} MATCHES "MinSizeRel|_MINSIZEREL")
|
||||
set(CONAN_FRAMEWORKS${SUFFIX} ${CONAN_FRAMEWORKS${SUFFIX}_MINSIZEREL} ${CONAN_FRAMEWORKS${SUFFIX}})
|
||||
set(CONAN_FRAMEWORK_DIRS${SUFFIX} ${CONAN_FRAMEWORK_DIRS${SUFFIX}_MINSIZEREL} ${CONAN_FRAMEWORK_DIRS${SUFFIX}})
|
||||
endif()
|
||||
endif()
|
||||
foreach(_FRAMEWORK ${FRAMEWORKS})
|
||||
# https://cmake.org/pipermail/cmake-developers/2017-August/030199.html
|
||||
find_library(CONAN_FRAMEWORK_${_FRAMEWORK}_FOUND NAME ${_FRAMEWORK} PATHS ${CONAN_FRAMEWORK_DIRS${SUFFIX}} CMAKE_FIND_ROOT_PATH_BOTH)
|
||||
if(CONAN_FRAMEWORK_${_FRAMEWORK}_FOUND)
|
||||
list(APPEND ${FRAMEWORKS_FOUND} ${CONAN_FRAMEWORK_${_FRAMEWORK}_FOUND})
|
||||
else()
|
||||
message(FATAL_ERROR "Framework library ${_FRAMEWORK} not found in paths: ${CONAN_FRAMEWORK_DIRS${SUFFIX}}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
### Definition of global aggregated variables ###
|
||||
|
||||
set(CONAN_PACKAGE_NAME AngelScript)
|
||||
set(CONAN_PACKAGE_VERSION 2.35)
|
||||
|
||||
set(CONAN_SETTINGS_ARCH "x86_64")
|
||||
set(CONAN_SETTINGS_BUILD_TYPE "Release")
|
||||
set(CONAN_SETTINGS_COMPILER "clang")
|
||||
set(CONAN_SETTINGS_COMPILER_LIBCXX "libstdc++11")
|
||||
set(CONAN_SETTINGS_COMPILER_VERSION "11")
|
||||
set(CONAN_SETTINGS_OS "Linux")
|
||||
|
||||
set(CONAN_DEPENDENCIES )
|
||||
# Storing original command line args (CMake helper) flags
|
||||
set(CONAN_CMD_CXX_FLAGS ${CONAN_CXX_FLAGS})
|
||||
|
||||
set(CONAN_CMD_SHARED_LINKER_FLAGS ${CONAN_SHARED_LINKER_FLAGS})
|
||||
set(CONAN_CMD_C_FLAGS ${CONAN_C_FLAGS})
|
||||
# Defining accumulated conan variables for all deps
|
||||
|
||||
set(CONAN_INCLUDE_DIRS ${CONAN_INCLUDE_DIRS})
|
||||
set(CONAN_LIB_DIRS ${CONAN_LIB_DIRS})
|
||||
set(CONAN_BIN_DIRS ${CONAN_BIN_DIRS})
|
||||
set(CONAN_RES_DIRS ${CONAN_RES_DIRS})
|
||||
set(CONAN_FRAMEWORK_DIRS ${CONAN_FRAMEWORK_DIRS})
|
||||
set(CONAN_LIBS ${CONAN_LIBS})
|
||||
set(CONAN_PKG_LIBS ${CONAN_PKG_LIBS})
|
||||
set(CONAN_SYSTEM_LIBS ${CONAN_SYSTEM_LIBS})
|
||||
set(CONAN_FRAMEWORKS ${CONAN_FRAMEWORKS})
|
||||
set(CONAN_FRAMEWORKS_FOUND "") # Will be filled later
|
||||
set(CONAN_DEFINES ${CONAN_DEFINES})
|
||||
set(CONAN_BUILD_MODULES_PATHS ${CONAN_BUILD_MODULES_PATHS})
|
||||
set(CONAN_CMAKE_MODULE_PATH ${CONAN_CMAKE_MODULE_PATH})
|
||||
|
||||
set(CONAN_CXX_FLAGS " ${CONAN_CXX_FLAGS}")
|
||||
set(CONAN_SHARED_LINKER_FLAGS " ${CONAN_SHARED_LINKER_FLAGS}")
|
||||
set(CONAN_EXE_LINKER_FLAGS " ${CONAN_EXE_LINKER_FLAGS}")
|
||||
set(CONAN_C_FLAGS " ${CONAN_C_FLAGS}")
|
||||
|
||||
# Apple Frameworks
|
||||
conan_find_apple_frameworks(CONAN_FRAMEWORKS_FOUND "${CONAN_FRAMEWORKS}" "" "")
|
||||
# Append to aggregated values variable: Use CONAN_LIBS instead of CONAN_PKG_LIBS to include user appended vars
|
||||
set(CONAN_LIBS ${CONAN_LIBS} ${CONAN_SYSTEM_LIBS} ${CONAN_FRAMEWORKS_FOUND})
|
||||
|
||||
|
||||
### Definition of macros and functions ###
|
||||
|
||||
macro(conan_define_targets)
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.1.2")
|
||||
message(FATAL_ERROR "TARGETS not supported by your CMake version!")
|
||||
endif() # CMAKE > 3.x
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CONAN_CMD_CXX_FLAGS}")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CONAN_CMD_C_FLAGS}")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${CONAN_CMD_SHARED_LINKER_FLAGS}")
|
||||
|
||||
set(CONAN_TARGETS )
|
||||
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(conan_basic_setup)
|
||||
set(options TARGETS NO_OUTPUT_DIRS SKIP_RPATH KEEP_RPATHS SKIP_STD SKIP_FPIC)
|
||||
cmake_parse_arguments(ARGUMENTS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
|
||||
|
||||
if(CONAN_EXPORTED)
|
||||
conan_message(STATUS "Conan: called by CMake conan helper")
|
||||
endif()
|
||||
|
||||
if(CONAN_IN_LOCAL_CACHE)
|
||||
conan_message(STATUS "Conan: called inside local cache")
|
||||
endif()
|
||||
|
||||
if(NOT ARGUMENTS_NO_OUTPUT_DIRS)
|
||||
conan_message(STATUS "Conan: Adjusting output directories")
|
||||
conan_output_dirs_setup()
|
||||
endif()
|
||||
|
||||
if(NOT ARGUMENTS_TARGETS)
|
||||
conan_message(STATUS "Conan: Using cmake global configuration")
|
||||
conan_global_flags()
|
||||
else()
|
||||
conan_message(STATUS "Conan: Using cmake targets configuration")
|
||||
conan_define_targets()
|
||||
endif()
|
||||
|
||||
if(ARGUMENTS_SKIP_RPATH)
|
||||
# Change by "DEPRECATION" or "SEND_ERROR" when we are ready
|
||||
conan_message(WARNING "Conan: SKIP_RPATH is deprecated, it has been renamed to KEEP_RPATHS")
|
||||
endif()
|
||||
|
||||
if(NOT ARGUMENTS_SKIP_RPATH AND NOT ARGUMENTS_KEEP_RPATHS)
|
||||
# Parameter has renamed, but we keep the compatibility with old SKIP_RPATH
|
||||
conan_set_rpath()
|
||||
endif()
|
||||
|
||||
if(NOT ARGUMENTS_SKIP_STD)
|
||||
conan_set_std()
|
||||
endif()
|
||||
|
||||
if(NOT ARGUMENTS_SKIP_FPIC)
|
||||
conan_set_fpic()
|
||||
endif()
|
||||
|
||||
conan_check_compiler()
|
||||
conan_set_libcxx()
|
||||
conan_set_vs_runtime()
|
||||
conan_set_find_paths()
|
||||
conan_include_build_modules()
|
||||
conan_set_find_library_paths()
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(conan_set_find_paths)
|
||||
# CMAKE_MODULE_PATH does not have Debug/Release config, but there are variables
|
||||
# CONAN_CMAKE_MODULE_PATH_DEBUG to be used by the consumer
|
||||
# CMake can find findXXX.cmake files in the root of packages
|
||||
set(CMAKE_MODULE_PATH ${CONAN_CMAKE_MODULE_PATH} ${CMAKE_MODULE_PATH})
|
||||
|
||||
# Make find_package() to work
|
||||
set(CMAKE_PREFIX_PATH ${CONAN_CMAKE_MODULE_PATH} ${CMAKE_PREFIX_PATH})
|
||||
|
||||
# Set the find root path (cross build)
|
||||
set(CMAKE_FIND_ROOT_PATH ${CONAN_CMAKE_FIND_ROOT_PATH} ${CMAKE_FIND_ROOT_PATH})
|
||||
if(CONAN_CMAKE_FIND_ROOT_PATH_MODE_PROGRAM)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ${CONAN_CMAKE_FIND_ROOT_PATH_MODE_PROGRAM})
|
||||
endif()
|
||||
if(CONAN_CMAKE_FIND_ROOT_PATH_MODE_LIBRARY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ${CONAN_CMAKE_FIND_ROOT_PATH_MODE_LIBRARY})
|
||||
endif()
|
||||
if(CONAN_CMAKE_FIND_ROOT_PATH_MODE_INCLUDE)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ${CONAN_CMAKE_FIND_ROOT_PATH_MODE_INCLUDE})
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(conan_set_find_library_paths)
|
||||
# CMAKE_INCLUDE_PATH, CMAKE_LIBRARY_PATH does not have Debug/Release config, but there are variables
|
||||
# CONAN_INCLUDE_DIRS_DEBUG/RELEASE CONAN_LIB_DIRS_DEBUG/RELEASE to be used by the consumer
|
||||
# For find_library
|
||||
set(CMAKE_INCLUDE_PATH ${CONAN_INCLUDE_DIRS} ${CMAKE_INCLUDE_PATH})
|
||||
set(CMAKE_LIBRARY_PATH ${CONAN_LIB_DIRS} ${CMAKE_LIBRARY_PATH})
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(conan_set_vs_runtime)
|
||||
if(CONAN_LINK_RUNTIME)
|
||||
conan_get_policy(CMP0091 policy_0091)
|
||||
if(policy_0091 STREQUAL "NEW")
|
||||
if(CONAN_LINK_RUNTIME MATCHES "MTd")
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDebug")
|
||||
elseif(CONAN_LINK_RUNTIME MATCHES "MDd")
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDebugDLL")
|
||||
elseif(CONAN_LINK_RUNTIME MATCHES "MT")
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded")
|
||||
elseif(CONAN_LINK_RUNTIME MATCHES "MD")
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL")
|
||||
endif()
|
||||
else()
|
||||
foreach(flag CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_RELWITHDEBINFO CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_C_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_MINSIZEREL)
|
||||
if(DEFINED ${flag})
|
||||
string(REPLACE "/MD" ${CONAN_LINK_RUNTIME} ${flag} "${${flag}}")
|
||||
endif()
|
||||
endforeach()
|
||||
foreach(flag CMAKE_C_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG)
|
||||
if(DEFINED ${flag})
|
||||
string(REPLACE "/MDd" ${CONAN_LINK_RUNTIME} ${flag} "${${flag}}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(conan_flags_setup)
|
||||
# Macro maintained for backwards compatibility
|
||||
conan_set_find_library_paths()
|
||||
conan_global_flags()
|
||||
conan_set_rpath()
|
||||
conan_set_vs_runtime()
|
||||
conan_set_libcxx()
|
||||
endmacro()
|
||||
|
||||
|
||||
function(conan_message MESSAGE_OUTPUT)
|
||||
if(NOT CONAN_CMAKE_SILENT_OUTPUT)
|
||||
message(${ARGV${0}})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
function(conan_get_policy policy_id policy)
|
||||
if(POLICY "${policy_id}")
|
||||
cmake_policy(GET "${policy_id}" _policy)
|
||||
set(${policy} "${_policy}" PARENT_SCOPE)
|
||||
else()
|
||||
set(${policy} "" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
function(conan_find_libraries_abs_path libraries package_libdir libraries_abs_path)
|
||||
foreach(_LIBRARY_NAME ${libraries})
|
||||
find_library(CONAN_FOUND_LIBRARY NAME ${_LIBRARY_NAME} PATHS ${package_libdir}
|
||||
NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
|
||||
if(CONAN_FOUND_LIBRARY)
|
||||
conan_message(STATUS "Library ${_LIBRARY_NAME} found ${CONAN_FOUND_LIBRARY}")
|
||||
set(CONAN_FULLPATH_LIBS ${CONAN_FULLPATH_LIBS} ${CONAN_FOUND_LIBRARY})
|
||||
else()
|
||||
conan_message(STATUS "Library ${_LIBRARY_NAME} not found in package, might be system one")
|
||||
set(CONAN_FULLPATH_LIBS ${CONAN_FULLPATH_LIBS} ${_LIBRARY_NAME})
|
||||
endif()
|
||||
unset(CONAN_FOUND_LIBRARY CACHE)
|
||||
endforeach()
|
||||
set(${libraries_abs_path} ${CONAN_FULLPATH_LIBS} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
function(conan_package_library_targets libraries package_libdir libraries_abs_path deps build_type package_name)
|
||||
unset(_CONAN_ACTUAL_TARGETS CACHE)
|
||||
unset(_CONAN_FOUND_SYSTEM_LIBS CACHE)
|
||||
foreach(_LIBRARY_NAME ${libraries})
|
||||
find_library(CONAN_FOUND_LIBRARY NAME ${_LIBRARY_NAME} PATHS ${package_libdir}
|
||||
NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
|
||||
if(CONAN_FOUND_LIBRARY)
|
||||
conan_message(STATUS "Library ${_LIBRARY_NAME} found ${CONAN_FOUND_LIBRARY}")
|
||||
set(_LIB_NAME CONAN_LIB::${package_name}_${_LIBRARY_NAME}${build_type})
|
||||
add_library(${_LIB_NAME} UNKNOWN IMPORTED)
|
||||
set_target_properties(${_LIB_NAME} PROPERTIES IMPORTED_LOCATION ${CONAN_FOUND_LIBRARY})
|
||||
set(CONAN_FULLPATH_LIBS ${CONAN_FULLPATH_LIBS} ${_LIB_NAME})
|
||||
set(_CONAN_ACTUAL_TARGETS ${_CONAN_ACTUAL_TARGETS} ${_LIB_NAME})
|
||||
else()
|
||||
conan_message(STATUS "Library ${_LIBRARY_NAME} not found in package, might be system one")
|
||||
set(CONAN_FULLPATH_LIBS ${CONAN_FULLPATH_LIBS} ${_LIBRARY_NAME})
|
||||
set(_CONAN_FOUND_SYSTEM_LIBS "${_CONAN_FOUND_SYSTEM_LIBS};${_LIBRARY_NAME}")
|
||||
endif()
|
||||
unset(CONAN_FOUND_LIBRARY CACHE)
|
||||
endforeach()
|
||||
|
||||
# Add all dependencies to all targets
|
||||
string(REPLACE " " ";" deps_list "${deps}")
|
||||
foreach(_CONAN_ACTUAL_TARGET ${_CONAN_ACTUAL_TARGETS})
|
||||
set_property(TARGET ${_CONAN_ACTUAL_TARGET} PROPERTY INTERFACE_LINK_LIBRARIES "${_CONAN_FOUND_SYSTEM_LIBS};${deps_list}")
|
||||
endforeach()
|
||||
|
||||
set(${libraries_abs_path} ${CONAN_FULLPATH_LIBS} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
macro(conan_set_libcxx)
|
||||
if(DEFINED CONAN_LIBCXX)
|
||||
conan_message(STATUS "Conan: C++ stdlib: ${CONAN_LIBCXX}")
|
||||
if(CONAN_COMPILER STREQUAL "clang" OR CONAN_COMPILER STREQUAL "apple-clang")
|
||||
if(CONAN_LIBCXX STREQUAL "libstdc++" OR CONAN_LIBCXX STREQUAL "libstdc++11" )
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libstdc++")
|
||||
elseif(CONAN_LIBCXX STREQUAL "libc++")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
||||
endif()
|
||||
endif()
|
||||
if(CONAN_COMPILER STREQUAL "sun-cc")
|
||||
if(CONAN_LIBCXX STREQUAL "libCstd")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -library=Cstd")
|
||||
elseif(CONAN_LIBCXX STREQUAL "libstdcxx")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -library=stdcxx4")
|
||||
elseif(CONAN_LIBCXX STREQUAL "libstlport")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -library=stlport4")
|
||||
elseif(CONAN_LIBCXX STREQUAL "libstdc++")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -library=stdcpp")
|
||||
endif()
|
||||
endif()
|
||||
if(CONAN_LIBCXX STREQUAL "libstdc++11")
|
||||
add_definitions(-D_GLIBCXX_USE_CXX11_ABI=1)
|
||||
elseif(CONAN_LIBCXX STREQUAL "libstdc++")
|
||||
add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(conan_set_std)
|
||||
conan_message(STATUS "Conan: Adjusting language standard")
|
||||
# Do not warn "Manually-specified variables were not used by the project"
|
||||
set(ignorevar "${CONAN_STD_CXX_FLAG}${CONAN_CMAKE_CXX_STANDARD}${CONAN_CMAKE_CXX_EXTENSIONS}")
|
||||
if (CMAKE_VERSION VERSION_LESS "3.1" OR
|
||||
(CMAKE_VERSION VERSION_LESS "3.12" AND ("${CONAN_CMAKE_CXX_STANDARD}" STREQUAL "20" OR "${CONAN_CMAKE_CXX_STANDARD}" STREQUAL "gnu20")))
|
||||
if(CONAN_STD_CXX_FLAG)
|
||||
conan_message(STATUS "Conan setting CXX_FLAGS flags: ${CONAN_STD_CXX_FLAG}")
|
||||
set(CMAKE_CXX_FLAGS "${CONAN_STD_CXX_FLAG} ${CMAKE_CXX_FLAGS}")
|
||||
endif()
|
||||
else()
|
||||
if(CONAN_CMAKE_CXX_STANDARD)
|
||||
conan_message(STATUS "Conan setting CPP STANDARD: ${CONAN_CMAKE_CXX_STANDARD} WITH EXTENSIONS ${CONAN_CMAKE_CXX_EXTENSIONS}")
|
||||
set(CMAKE_CXX_STANDARD ${CONAN_CMAKE_CXX_STANDARD})
|
||||
set(CMAKE_CXX_EXTENSIONS ${CONAN_CMAKE_CXX_EXTENSIONS})
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(conan_set_rpath)
|
||||
conan_message(STATUS "Conan: Adjusting default RPATHs Conan policies")
|
||||
if(APPLE)
|
||||
# https://cmake.org/Wiki/CMake_RPATH_handling
|
||||
# CONAN GUIDE: All generated libraries should have the id and dependencies to other
|
||||
# dylibs without path, just the name, EX:
|
||||
# libMyLib1.dylib:
|
||||
# libMyLib1.dylib (compatibility version 0.0.0, current version 0.0.0)
|
||||
# libMyLib0.dylib (compatibility version 0.0.0, current version 0.0.0)
|
||||
# /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
|
||||
# /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
|
||||
# AVOID RPATH FOR *.dylib, ALL LIBS BETWEEN THEM AND THE EXE
|
||||
# SHOULD BE ON THE LINKER RESOLVER PATH (./ IS ONE OF THEM)
|
||||
set(CMAKE_SKIP_RPATH 1 CACHE BOOL "rpaths" FORCE)
|
||||
# Policy CMP0068
|
||||
# We want the old behavior, in CMake >= 3.9 CMAKE_SKIP_RPATH won't affect the install_name in OSX
|
||||
set(CMAKE_INSTALL_NAME_DIR "")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(conan_set_fpic)
|
||||
if(DEFINED CONAN_CMAKE_POSITION_INDEPENDENT_CODE)
|
||||
conan_message(STATUS "Conan: Adjusting fPIC flag (${CONAN_CMAKE_POSITION_INDEPENDENT_CODE})")
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ${CONAN_CMAKE_POSITION_INDEPENDENT_CODE})
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(conan_output_dirs_setup)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
|
||||
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY})
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY})
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY})
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY})
|
||||
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(conan_split_version VERSION_STRING MAJOR MINOR)
|
||||
#make a list from the version string
|
||||
string(REPLACE "." ";" VERSION_LIST "${VERSION_STRING}")
|
||||
|
||||
#write output values
|
||||
list(LENGTH VERSION_LIST _version_len)
|
||||
list(GET VERSION_LIST 0 ${MAJOR})
|
||||
if(${_version_len} GREATER 1)
|
||||
list(GET VERSION_LIST 1 ${MINOR})
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(conan_error_compiler_version)
|
||||
message(FATAL_ERROR "Detected a mismatch for the compiler version between your conan profile settings and CMake: \n"
|
||||
"Compiler version specified in your conan profile: ${CONAN_COMPILER_VERSION}\n"
|
||||
"Compiler version detected in CMake: ${VERSION_MAJOR}.${VERSION_MINOR}\n"
|
||||
"Please check your conan profile settings (conan profile show [default|your_profile_name])\n"
|
||||
"P.S. You may set CONAN_DISABLE_CHECK_COMPILER CMake variable in order to disable this check."
|
||||
)
|
||||
endmacro()
|
||||
|
||||
set(_CONAN_CURRENT_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
function(conan_get_compiler CONAN_INFO_COMPILER CONAN_INFO_COMPILER_VERSION)
|
||||
conan_message(STATUS "Current conanbuildinfo.cmake directory: " ${_CONAN_CURRENT_DIR})
|
||||
if(NOT EXISTS ${_CONAN_CURRENT_DIR}/conaninfo.txt)
|
||||
conan_message(STATUS "WARN: conaninfo.txt not found")
|
||||
return()
|
||||
endif()
|
||||
|
||||
file (READ "${_CONAN_CURRENT_DIR}/conaninfo.txt" CONANINFO)
|
||||
|
||||
# MATCHALL will match all, including the last one, which is the full_settings one
|
||||
string(REGEX MATCH "full_settings.*" _FULL_SETTINGS_MATCHED ${CONANINFO})
|
||||
string(REGEX MATCH "compiler=([-A-Za-z0-9_ ]+)" _MATCHED ${_FULL_SETTINGS_MATCHED})
|
||||
if(DEFINED CMAKE_MATCH_1)
|
||||
string(STRIP "${CMAKE_MATCH_1}" _CONAN_INFO_COMPILER)
|
||||
set(${CONAN_INFO_COMPILER} ${_CONAN_INFO_COMPILER} PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
string(REGEX MATCH "compiler.version=([-A-Za-z0-9_.]+)" _MATCHED ${_FULL_SETTINGS_MATCHED})
|
||||
if(DEFINED CMAKE_MATCH_1)
|
||||
string(STRIP "${CMAKE_MATCH_1}" _CONAN_INFO_COMPILER_VERSION)
|
||||
set(${CONAN_INFO_COMPILER_VERSION} ${_CONAN_INFO_COMPILER_VERSION} PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
function(check_compiler_version)
|
||||
conan_split_version(${CMAKE_CXX_COMPILER_VERSION} VERSION_MAJOR VERSION_MINOR)
|
||||
if(DEFINED CONAN_SETTINGS_COMPILER_TOOLSET)
|
||||
conan_message(STATUS "Conan: Skipping compiler check: Declared 'compiler.toolset'")
|
||||
return()
|
||||
endif()
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
||||
# MSVC_VERSION is defined since 2.8.2 at least
|
||||
# https://cmake.org/cmake/help/v2.8.2/cmake.html#variable:MSVC_VERSION
|
||||
# https://cmake.org/cmake/help/v3.14/variable/MSVC_VERSION.html
|
||||
if(
|
||||
# 1920-1929 = VS 16.0 (v142 toolset)
|
||||
(CONAN_COMPILER_VERSION STREQUAL "16" AND NOT((MSVC_VERSION GREATER 1919) AND (MSVC_VERSION LESS 1930))) OR
|
||||
# 1910-1919 = VS 15.0 (v141 toolset)
|
||||
(CONAN_COMPILER_VERSION STREQUAL "15" AND NOT((MSVC_VERSION GREATER 1909) AND (MSVC_VERSION LESS 1920))) OR
|
||||
# 1900 = VS 14.0 (v140 toolset)
|
||||
(CONAN_COMPILER_VERSION STREQUAL "14" AND NOT(MSVC_VERSION EQUAL 1900)) OR
|
||||
# 1800 = VS 12.0 (v120 toolset)
|
||||
(CONAN_COMPILER_VERSION STREQUAL "12" AND NOT VERSION_MAJOR STREQUAL "18") OR
|
||||
# 1700 = VS 11.0 (v110 toolset)
|
||||
(CONAN_COMPILER_VERSION STREQUAL "11" AND NOT VERSION_MAJOR STREQUAL "17") OR
|
||||
# 1600 = VS 10.0 (v100 toolset)
|
||||
(CONAN_COMPILER_VERSION STREQUAL "10" AND NOT VERSION_MAJOR STREQUAL "16") OR
|
||||
# 1500 = VS 9.0 (v90 toolset)
|
||||
(CONAN_COMPILER_VERSION STREQUAL "9" AND NOT VERSION_MAJOR STREQUAL "15") OR
|
||||
# 1400 = VS 8.0 (v80 toolset)
|
||||
(CONAN_COMPILER_VERSION STREQUAL "8" AND NOT VERSION_MAJOR STREQUAL "14") OR
|
||||
# 1310 = VS 7.1, 1300 = VS 7.0
|
||||
(CONAN_COMPILER_VERSION STREQUAL "7" AND NOT VERSION_MAJOR STREQUAL "13") OR
|
||||
# 1200 = VS 6.0
|
||||
(CONAN_COMPILER_VERSION STREQUAL "6" AND NOT VERSION_MAJOR STREQUAL "12") )
|
||||
conan_error_compiler_version()
|
||||
endif()
|
||||
elseif(CONAN_COMPILER STREQUAL "gcc")
|
||||
conan_split_version(${CONAN_COMPILER_VERSION} CONAN_COMPILER_MAJOR CONAN_COMPILER_MINOR)
|
||||
set(_CHECK_VERSION ${VERSION_MAJOR}.${VERSION_MINOR})
|
||||
set(_CONAN_VERSION ${CONAN_COMPILER_MAJOR}.${CONAN_COMPILER_MINOR})
|
||||
if(NOT ${CONAN_COMPILER_VERSION} VERSION_LESS 5.0)
|
||||
conan_message(STATUS "Conan: Compiler GCC>=5, checking major version ${CONAN_COMPILER_VERSION}")
|
||||
conan_split_version(${CONAN_COMPILER_VERSION} CONAN_COMPILER_MAJOR CONAN_COMPILER_MINOR)
|
||||
if("${CONAN_COMPILER_MINOR}" STREQUAL "")
|
||||
set(_CHECK_VERSION ${VERSION_MAJOR})
|
||||
set(_CONAN_VERSION ${CONAN_COMPILER_MAJOR})
|
||||
endif()
|
||||
endif()
|
||||
conan_message(STATUS "Conan: Checking correct version: ${_CHECK_VERSION}")
|
||||
if(NOT ${_CHECK_VERSION} VERSION_EQUAL ${_CONAN_VERSION})
|
||||
conan_error_compiler_version()
|
||||
endif()
|
||||
elseif(CONAN_COMPILER STREQUAL "clang")
|
||||
conan_split_version(${CONAN_COMPILER_VERSION} CONAN_COMPILER_MAJOR CONAN_COMPILER_MINOR)
|
||||
set(_CHECK_VERSION ${VERSION_MAJOR}.${VERSION_MINOR})
|
||||
set(_CONAN_VERSION ${CONAN_COMPILER_MAJOR}.${CONAN_COMPILER_MINOR})
|
||||
if(NOT ${CONAN_COMPILER_VERSION} VERSION_LESS 8.0)
|
||||
conan_message(STATUS "Conan: Compiler Clang>=8, checking major version ${CONAN_COMPILER_VERSION}")
|
||||
if("${CONAN_COMPILER_MINOR}" STREQUAL "")
|
||||
set(_CHECK_VERSION ${VERSION_MAJOR})
|
||||
set(_CONAN_VERSION ${CONAN_COMPILER_MAJOR})
|
||||
endif()
|
||||
endif()
|
||||
conan_message(STATUS "Conan: Checking correct version: ${_CHECK_VERSION}")
|
||||
if(NOT ${_CHECK_VERSION} VERSION_EQUAL ${_CONAN_VERSION})
|
||||
conan_error_compiler_version()
|
||||
endif()
|
||||
elseif(CONAN_COMPILER STREQUAL "apple-clang" OR CONAN_COMPILER STREQUAL "sun-cc" OR CONAN_COMPILER STREQUAL "mcst-lcc")
|
||||
conan_split_version(${CONAN_COMPILER_VERSION} CONAN_COMPILER_MAJOR CONAN_COMPILER_MINOR)
|
||||
if(NOT ${VERSION_MAJOR}.${VERSION_MINOR} VERSION_EQUAL ${CONAN_COMPILER_MAJOR}.${CONAN_COMPILER_MINOR})
|
||||
conan_error_compiler_version()
|
||||
endif()
|
||||
elseif(CONAN_COMPILER STREQUAL "intel")
|
||||
conan_split_version(${CONAN_COMPILER_VERSION} CONAN_COMPILER_MAJOR CONAN_COMPILER_MINOR)
|
||||
if(NOT ${CONAN_COMPILER_VERSION} VERSION_LESS 19.1)
|
||||
if(NOT ${VERSION_MAJOR}.${VERSION_MINOR} VERSION_EQUAL ${CONAN_COMPILER_MAJOR}.${CONAN_COMPILER_MINOR})
|
||||
conan_error_compiler_version()
|
||||
endif()
|
||||
else()
|
||||
if(NOT ${VERSION_MAJOR} VERSION_EQUAL ${CONAN_COMPILER_MAJOR})
|
||||
conan_error_compiler_version()
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
conan_message(STATUS "WARN: Unknown compiler '${CONAN_COMPILER}', skipping the version check...")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
function(conan_check_compiler)
|
||||
if(CONAN_DISABLE_CHECK_COMPILER)
|
||||
conan_message(STATUS "WARN: Disabled conan compiler checks")
|
||||
return()
|
||||
endif()
|
||||
if(NOT DEFINED CMAKE_CXX_COMPILER_ID)
|
||||
if(DEFINED CMAKE_C_COMPILER_ID)
|
||||
conan_message(STATUS "This project seems to be plain C, using '${CMAKE_C_COMPILER_ID}' compiler")
|
||||
set(CMAKE_CXX_COMPILER_ID ${CMAKE_C_COMPILER_ID})
|
||||
set(CMAKE_CXX_COMPILER_VERSION ${CMAKE_C_COMPILER_VERSION})
|
||||
else()
|
||||
message(FATAL_ERROR "This project seems to be plain C, but no compiler defined")
|
||||
endif()
|
||||
endif()
|
||||
if(NOT CMAKE_CXX_COMPILER_ID AND NOT CMAKE_C_COMPILER_ID)
|
||||
# This use case happens when compiler is not identified by CMake, but the compilers are there and work
|
||||
conan_message(STATUS "*** WARN: CMake was not able to identify a C or C++ compiler ***")
|
||||
conan_message(STATUS "*** WARN: Disabling compiler checks. Please make sure your settings match your environment ***")
|
||||
return()
|
||||
endif()
|
||||
if(NOT DEFINED CONAN_COMPILER)
|
||||
conan_get_compiler(CONAN_COMPILER CONAN_COMPILER_VERSION)
|
||||
if(NOT DEFINED CONAN_COMPILER)
|
||||
conan_message(STATUS "WARN: CONAN_COMPILER variable not set, please make sure yourself that "
|
||||
"your compiler and version matches your declared settings")
|
||||
return()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_HOST_SYSTEM_NAME STREQUAL ${CMAKE_SYSTEM_NAME})
|
||||
set(CROSS_BUILDING 1)
|
||||
endif()
|
||||
|
||||
# If using VS, verify toolset
|
||||
if (CONAN_COMPILER STREQUAL "Visual Studio")
|
||||
if (CONAN_SETTINGS_COMPILER_TOOLSET MATCHES "LLVM" OR
|
||||
CONAN_SETTINGS_COMPILER_TOOLSET MATCHES "llvm" OR
|
||||
CONAN_SETTINGS_COMPILER_TOOLSET MATCHES "clang" OR
|
||||
CONAN_SETTINGS_COMPILER_TOOLSET MATCHES "Clang")
|
||||
set(EXPECTED_CMAKE_CXX_COMPILER_ID "Clang")
|
||||
elseif (CONAN_SETTINGS_COMPILER_TOOLSET MATCHES "Intel")
|
||||
set(EXPECTED_CMAKE_CXX_COMPILER_ID "Intel")
|
||||
else()
|
||||
set(EXPECTED_CMAKE_CXX_COMPILER_ID "MSVC")
|
||||
endif()
|
||||
|
||||
if (NOT CMAKE_CXX_COMPILER_ID MATCHES ${EXPECTED_CMAKE_CXX_COMPILER_ID})
|
||||
message(FATAL_ERROR "Incorrect '${CONAN_COMPILER}'. Toolset specifies compiler as '${EXPECTED_CMAKE_CXX_COMPILER_ID}' "
|
||||
"but CMake detected '${CMAKE_CXX_COMPILER_ID}'")
|
||||
endif()
|
||||
|
||||
# Avoid checks when cross compiling, apple-clang crashes because its APPLE but not apple-clang
|
||||
# Actually CMake is detecting "clang" when you are using apple-clang, only if CMP0025 is set to NEW will detect apple-clang
|
||||
elseif((CONAN_COMPILER STREQUAL "gcc" AND NOT CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR
|
||||
(CONAN_COMPILER STREQUAL "apple-clang" AND NOT CROSS_BUILDING AND (NOT APPLE OR NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")) OR
|
||||
(CONAN_COMPILER STREQUAL "clang" AND NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") OR
|
||||
(CONAN_COMPILER STREQUAL "sun-cc" AND NOT CMAKE_CXX_COMPILER_ID MATCHES "SunPro") )
|
||||
message(FATAL_ERROR "Incorrect '${CONAN_COMPILER}', is not the one detected by CMake: '${CMAKE_CXX_COMPILER_ID}'")
|
||||
endif()
|
||||
|
||||
|
||||
if(NOT DEFINED CONAN_COMPILER_VERSION)
|
||||
conan_message(STATUS "WARN: CONAN_COMPILER_VERSION variable not set, please make sure yourself "
|
||||
"that your compiler version matches your declared settings")
|
||||
return()
|
||||
endif()
|
||||
check_compiler_version()
|
||||
endfunction()
|
||||
|
||||
|
||||
macro(conan_set_flags build_type)
|
||||
set(CMAKE_CXX_FLAGS${build_type} "${CMAKE_CXX_FLAGS${build_type}} ${CONAN_CXX_FLAGS${build_type}}")
|
||||
set(CMAKE_C_FLAGS${build_type} "${CMAKE_C_FLAGS${build_type}} ${CONAN_C_FLAGS${build_type}}")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS${build_type} "${CMAKE_SHARED_LINKER_FLAGS${build_type}} ${CONAN_SHARED_LINKER_FLAGS${build_type}}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS${build_type} "${CMAKE_EXE_LINKER_FLAGS${build_type}} ${CONAN_EXE_LINKER_FLAGS${build_type}}")
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(conan_global_flags)
|
||||
if(CONAN_SYSTEM_INCLUDES)
|
||||
include_directories(SYSTEM ${CONAN_INCLUDE_DIRS}
|
||||
"$<$<CONFIG:Release>:${CONAN_INCLUDE_DIRS_RELEASE}>"
|
||||
"$<$<CONFIG:RelWithDebInfo>:${CONAN_INCLUDE_DIRS_RELWITHDEBINFO}>"
|
||||
"$<$<CONFIG:MinSizeRel>:${CONAN_INCLUDE_DIRS_MINSIZEREL}>"
|
||||
"$<$<CONFIG:Debug>:${CONAN_INCLUDE_DIRS_DEBUG}>")
|
||||
else()
|
||||
include_directories(${CONAN_INCLUDE_DIRS}
|
||||
"$<$<CONFIG:Release>:${CONAN_INCLUDE_DIRS_RELEASE}>"
|
||||
"$<$<CONFIG:RelWithDebInfo>:${CONAN_INCLUDE_DIRS_RELWITHDEBINFO}>"
|
||||
"$<$<CONFIG:MinSizeRel>:${CONAN_INCLUDE_DIRS_MINSIZEREL}>"
|
||||
"$<$<CONFIG:Debug>:${CONAN_INCLUDE_DIRS_DEBUG}>")
|
||||
endif()
|
||||
|
||||
link_directories(${CONAN_LIB_DIRS})
|
||||
|
||||
conan_find_libraries_abs_path("${CONAN_LIBS_DEBUG}" "${CONAN_LIB_DIRS_DEBUG}"
|
||||
CONAN_LIBS_DEBUG)
|
||||
conan_find_libraries_abs_path("${CONAN_LIBS_RELEASE}" "${CONAN_LIB_DIRS_RELEASE}"
|
||||
CONAN_LIBS_RELEASE)
|
||||
conan_find_libraries_abs_path("${CONAN_LIBS_RELWITHDEBINFO}" "${CONAN_LIB_DIRS_RELWITHDEBINFO}"
|
||||
CONAN_LIBS_RELWITHDEBINFO)
|
||||
conan_find_libraries_abs_path("${CONAN_LIBS_MINSIZEREL}" "${CONAN_LIB_DIRS_MINSIZEREL}"
|
||||
CONAN_LIBS_MINSIZEREL)
|
||||
|
||||
add_compile_options(${CONAN_DEFINES}
|
||||
"$<$<CONFIG:Debug>:${CONAN_DEFINES_DEBUG}>"
|
||||
"$<$<CONFIG:Release>:${CONAN_DEFINES_RELEASE}>"
|
||||
"$<$<CONFIG:RelWithDebInfo>:${CONAN_DEFINES_RELWITHDEBINFO}>"
|
||||
"$<$<CONFIG:MinSizeRel>:${CONAN_DEFINES_MINSIZEREL}>")
|
||||
|
||||
conan_set_flags("")
|
||||
conan_set_flags("_RELEASE")
|
||||
conan_set_flags("_DEBUG")
|
||||
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(conan_target_link_libraries target)
|
||||
if(CONAN_TARGETS)
|
||||
target_link_libraries(${target} ${CONAN_TARGETS})
|
||||
else()
|
||||
target_link_libraries(${target} ${CONAN_LIBS})
|
||||
foreach(_LIB ${CONAN_LIBS_RELEASE})
|
||||
target_link_libraries(${target} optimized ${_LIB})
|
||||
endforeach()
|
||||
foreach(_LIB ${CONAN_LIBS_DEBUG})
|
||||
target_link_libraries(${target} debug ${_LIB})
|
||||
endforeach()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(conan_include_build_modules)
|
||||
if(CMAKE_BUILD_TYPE)
|
||||
if(${CMAKE_BUILD_TYPE} MATCHES "Debug")
|
||||
set(CONAN_BUILD_MODULES_PATHS ${CONAN_BUILD_MODULES_PATHS_DEBUG} ${CONAN_BUILD_MODULES_PATHS})
|
||||
elseif(${CMAKE_BUILD_TYPE} MATCHES "Release")
|
||||
set(CONAN_BUILD_MODULES_PATHS ${CONAN_BUILD_MODULES_PATHS_RELEASE} ${CONAN_BUILD_MODULES_PATHS})
|
||||
elseif(${CMAKE_BUILD_TYPE} MATCHES "RelWithDebInfo")
|
||||
set(CONAN_BUILD_MODULES_PATHS ${CONAN_BUILD_MODULES_PATHS_RELWITHDEBINFO} ${CONAN_BUILD_MODULES_PATHS})
|
||||
elseif(${CMAKE_BUILD_TYPE} MATCHES "MinSizeRel")
|
||||
set(CONAN_BUILD_MODULES_PATHS ${CONAN_BUILD_MODULES_PATHS_MINSIZEREL} ${CONAN_BUILD_MODULES_PATHS})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
foreach(_BUILD_MODULE_PATH ${CONAN_BUILD_MODULES_PATHS})
|
||||
include(${_BUILD_MODULE_PATH})
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
|
||||
### Definition of user declared vars (user_info) ###
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
[includedirs]
|
||||
|
||||
|
||||
[libdirs]
|
||||
|
||||
|
||||
[bindirs]
|
||||
|
||||
|
||||
[resdirs]
|
||||
|
||||
|
||||
[builddirs]
|
||||
|
||||
|
||||
[libs]
|
||||
|
||||
|
||||
[system_libs]
|
||||
|
||||
|
||||
[defines]
|
||||
|
||||
|
||||
[cppflags]
|
||||
|
||||
|
||||
[cxxflags]
|
||||
|
||||
|
||||
[cflags]
|
||||
|
||||
|
||||
[sharedlinkflags]
|
||||
|
||||
|
||||
[exelinkflags]
|
||||
|
||||
|
||||
[sysroot]
|
||||
|
||||
|
||||
[frameworks]
|
||||
|
||||
|
||||
[frameworkdirs]
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
|
||||
from conans import ConanFile, CMake, tools
|
||||
import os
|
||||
|
||||
class AngelScriptConan(ConanFile):
|
||||
name = "AngelScript"
|
||||
version = "2.35"
|
||||
license = "<Put the package license here>"
|
||||
url = "<Package recipe repository url here, for issues about the package>"
|
||||
description = "<Description of Hello here>"
|
||||
settings = "os", "compiler", "build_type", "arch"
|
||||
options = {"shared": [True, False], "link_std_statically": [True, False]}
|
||||
default_options = {"shared": False, "link_std_statically": True}
|
||||
generators = "cmake"
|
||||
exports_sources = "../../*"
|
||||
|
||||
|
||||
def build(self):
|
||||
cmake = CMake(self)
|
||||
if (self.options.shared):
|
||||
self.output.info("Building shared lib.")
|
||||
cmake.definitions["BUILD_SHARED_LIBS"] = 1
|
||||
else:
|
||||
self.output.info("Building static lib.")
|
||||
if (self.options.link_std_statically):
|
||||
cmake.definitions["LINK_STD_STATICALLY"] = 1
|
||||
|
||||
cmake.configure(build_dir="./build", source_dir="../projects/cmake")
|
||||
cmake.build()
|
||||
|
||||
def package(self):
|
||||
os.chdir(os.path.dirname(__file__))
|
||||
print(os.getcwd())
|
||||
self.copy("include/angelscript.h", dst="include", keep_path=False)
|
||||
self.copy("*.dll", dst="bin", keep_path=False)
|
||||
self.copy("*.so", dst="lib", keep_path=False)
|
||||
self.copy("*.so.*", dst="lib", keep_path=False)
|
||||
self.copy("*.dylib", dst="lib", keep_path=False)
|
||||
self.copy("*.a", dst="lib", keep_path=False)
|
||||
|
||||
def package_info(self):
|
||||
self.cpp_info.libs = ["angelscript"]
|
|
@ -0,0 +1,35 @@
|
|||
[settings]
|
||||
arch=x86_64
|
||||
build_type=Release
|
||||
compiler=clang
|
||||
compiler.libcxx=libstdc++11
|
||||
compiler.version=11
|
||||
os=Linux
|
||||
|
||||
[requires]
|
||||
|
||||
|
||||
[options]
|
||||
link_std_statically=True
|
||||
shared=True
|
||||
|
||||
[full_settings]
|
||||
arch=x86_64
|
||||
build_type=Release
|
||||
compiler=clang
|
||||
compiler.libcxx=libstdc++11
|
||||
compiler.version=11
|
||||
os=Linux
|
||||
|
||||
[full_requires]
|
||||
|
||||
|
||||
[full_options]
|
||||
link_std_statically=True
|
||||
shared=True
|
||||
|
||||
[recipe_hash]
|
||||
|
||||
|
||||
[env]
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"options": [
|
||||
[
|
||||
"link_std_statically",
|
||||
"True"
|
||||
],
|
||||
[
|
||||
"shared",
|
||||
"True"
|
||||
]
|
||||
],
|
||||
"root": {
|
||||
"name": "AngelScript",
|
||||
"version": "2.35",
|
||||
"user": null,
|
||||
"channel": null
|
||||
}
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<CodeBlocks_project_file>
|
||||
<FileVersion major="1" minor="6" />
|
||||
<Project>
|
||||
<Option title="Static library" />
|
||||
<Option pch_mode="0" />
|
||||
<Option compiler="gcc" />
|
||||
<Build>
|
||||
<Target title="Debug">
|
||||
<Option output="../../lib/libangelscriptd.a" prefix_auto="0" extension_auto="0" />
|
||||
<Option working_dir="" />
|
||||
<Option object_output="objs/debug" />
|
||||
<Option type="2" />
|
||||
<Option compiler="gcc" />
|
||||
<Option createDefFile="1" />
|
||||
<Option projectResourceIncludeDirsRelation="2" />
|
||||
<Compiler>
|
||||
<Add option="-g" />
|
||||
<Add option="-m32" />
|
||||
<Add option="-DANGELSCRIPT_EXPORT" />
|
||||
<Add option="-D_DEBUG" />
|
||||
</Compiler>
|
||||
</Target>
|
||||
<Target title="Debug 64">
|
||||
<Option output="../../lib/libangelscript64d.a" prefix_auto="0" extension_auto="0" />
|
||||
<Option working_dir="" />
|
||||
<Option object_output="objs/debug_64" />
|
||||
<Option type="2" />
|
||||
<Option compiler="gcc" />
|
||||
<Option createDefFile="1" />
|
||||
<Option projectResourceIncludeDirsRelation="2" />
|
||||
<Compiler>
|
||||
<Add option="-g" />
|
||||
<Add option="-m64" />
|
||||
<Add option="-DANGELSCRIPT_EXPORT" />
|
||||
<Add option="-D_DEBUG" />
|
||||
</Compiler>
|
||||
</Target>
|
||||
<Target title="Release">
|
||||
<Option output="../../lib/libangelscript.a" prefix_auto="0" extension_auto="0" />
|
||||
<Option working_dir="" />
|
||||
<Option object_output="objs/release" />
|
||||
<Option type="2" />
|
||||
<Option compiler="gcc" />
|
||||
<Option createDefFile="1" />
|
||||
<Option projectResourceIncludeDirsRelation="2" />
|
||||
<Compiler>
|
||||
<Add option="-O3" />
|
||||
<Add option="-m32" />
|
||||
<Add option="-DANGELSCRIPT_EXPORT" />
|
||||
<Add option="-DNDEBUG" />
|
||||
</Compiler>
|
||||
</Target>
|
||||
<Target title="Release 64">
|
||||
<Option output="../../lib/libangelscript64.a" prefix_auto="0" extension_auto="0" />
|
||||
<Option working_dir="" />
|
||||
<Option object_output="objs/release_64" />
|
||||
<Option type="2" />
|
||||
<Option compiler="gcc" />
|
||||
<Option createDefFile="1" />
|
||||
<Option projectResourceIncludeDirsRelation="2" />
|
||||
<Compiler>
|
||||
<Add option="-O3" />
|
||||
<Add option="-m64" />
|
||||
<Add option="-DANGELSCRIPT_EXPORT" />
|
||||
<Add option="-DNDEBUG" />
|
||||
</Compiler>
|
||||
</Target>
|
||||
</Build>
|
||||
<VirtualTargets>
|
||||
<Add alias="All" targets="Debug;Debug 64;Release;Release 64;" />
|
||||
</VirtualTargets>
|
||||
<Compiler>
|
||||
<Add option="-std=c++11" />
|
||||
<Add option="-Wall" />
|
||||
<Add option="-fexceptions" />
|
||||
<Add option="-fno-strict-aliasing" />
|
||||
</Compiler>
|
||||
<Unit filename="../../include/angelscript.h" />
|
||||
<Unit filename="../../source/as_array.h" />
|
||||
<Unit filename="../../source/as_atomic.cpp" />
|
||||
<Unit filename="../../source/as_atomic.h" />
|
||||
<Unit filename="../../source/as_builder.cpp" />
|
||||
<Unit filename="../../source/as_builder.h" />
|
||||
<Unit filename="../../source/as_bytecode.cpp" />
|
||||
<Unit filename="../../source/as_bytecode.h" />
|
||||
<Unit filename="../../source/as_callfunc.cpp" />
|
||||
<Unit filename="../../source/as_callfunc.h" />
|
||||
<Unit filename="../../source/as_callfunc_arm.cpp" />
|
||||
<Unit filename="../../source/as_callfunc_mips.cpp" />
|
||||
<Unit filename="../../source/as_callfunc_ppc.cpp" />
|
||||
<Unit filename="../../source/as_callfunc_ppc_64.cpp" />
|
||||
<Unit filename="../../source/as_callfunc_sh4.cpp" />
|
||||
<Unit filename="../../source/as_callfunc_x64_gcc.cpp" />
|
||||
<Unit filename="../../source/as_callfunc_x64_mingw.cpp" />
|
||||
<Unit filename="../../source/as_callfunc_x64_msvc.cpp" />
|
||||
<Unit filename="../../source/as_callfunc_x86.cpp" />
|
||||
<Unit filename="../../source/as_callfunc_xenon.cpp" />
|
||||
<Unit filename="../../source/as_compiler.cpp" />
|
||||
<Unit filename="../../source/as_compiler.h" />
|
||||
<Unit filename="../../source/as_config.h" />
|
||||
<Unit filename="../../source/as_configgroup.cpp" />
|
||||
<Unit filename="../../source/as_configgroup.h" />
|
||||
<Unit filename="../../source/as_context.cpp" />
|
||||
<Unit filename="../../source/as_context.h" />
|
||||
<Unit filename="../../source/as_criticalsection.h" />
|
||||
<Unit filename="../../source/as_datatype.cpp" />
|
||||
<Unit filename="../../source/as_datatype.h" />
|
||||
<Unit filename="../../source/as_debug.h" />
|
||||
<Unit filename="../../source/as_gc.cpp" />
|
||||
<Unit filename="../../source/as_gc.h" />
|
||||
<Unit filename="../../source/as_generic.cpp" />
|
||||
<Unit filename="../../source/as_generic.h" />
|
||||
<Unit filename="../../source/as_globalproperty.cpp" />
|
||||
<Unit filename="../../source/as_map.h" />
|
||||
<Unit filename="../../source/as_memory.cpp" />
|
||||
<Unit filename="../../source/as_memory.h" />
|
||||
<Unit filename="../../source/as_module.cpp" />
|
||||
<Unit filename="../../source/as_module.h" />
|
||||
<Unit filename="../../source/as_objecttype.cpp" />
|
||||
<Unit filename="../../source/as_objecttype.h" />
|
||||
<Unit filename="../../source/as_outputbuffer.cpp" />
|
||||
<Unit filename="../../source/as_outputbuffer.h" />
|
||||
<Unit filename="../../source/as_parser.cpp" />
|
||||
<Unit filename="../../source/as_parser.h" />
|
||||
<Unit filename="../../source/as_property.h" />
|
||||
<Unit filename="../../source/as_restore.cpp" />
|
||||
<Unit filename="../../source/as_restore.h" />
|
||||
<Unit filename="../../source/as_scriptcode.cpp" />
|
||||
<Unit filename="../../source/as_scriptcode.h" />
|
||||
<Unit filename="../../source/as_scriptengine.cpp" />
|
||||
<Unit filename="../../source/as_scriptengine.h" />
|
||||
<Unit filename="../../source/as_scriptfunction.cpp" />
|
||||
<Unit filename="../../source/as_scriptfunction.h" />
|
||||
<Unit filename="../../source/as_scriptnode.cpp" />
|
||||
<Unit filename="../../source/as_scriptnode.h" />
|
||||
<Unit filename="../../source/as_scriptobject.cpp" />
|
||||
<Unit filename="../../source/as_scriptobject.h" />
|
||||
<Unit filename="../../source/as_string.cpp" />
|
||||
<Unit filename="../../source/as_string.h" />
|
||||
<Unit filename="../../source/as_string_util.cpp" />
|
||||
<Unit filename="../../source/as_string_util.h" />
|
||||
<Unit filename="../../source/as_texts.h" />
|
||||
<Unit filename="../../source/as_thread.cpp" />
|
||||
<Unit filename="../../source/as_thread.h" />
|
||||
<Unit filename="../../source/as_tokendef.h" />
|
||||
<Unit filename="../../source/as_tokenizer.cpp" />
|
||||
<Unit filename="../../source/as_tokenizer.h" />
|
||||
<Unit filename="../../source/as_typeinfo.cpp" />
|
||||
<Unit filename="../../source/as_typeinfo.h" />
|
||||
<Unit filename="../../source/as_variablescope.cpp" />
|
||||
<Unit filename="../../source/as_variablescope.h" />
|
||||
<Extensions>
|
||||
<code_completion />
|
||||
<envvars />
|
||||
<debugger />
|
||||
</Extensions>
|
||||
</Project>
|
||||
</CodeBlocks_project_file>
|
|
@ -0,0 +1,131 @@
|
|||
# Angelscript makefile for linux (based on MingW makefile)
|
||||
# Type 'make' then 'make install' to complete the installation of the library
|
||||
|
||||
# For 'make install' to work, set LOCAL according to your system configuration
|
||||
LOCAL = /usr/local
|
||||
|
||||
# If you want to build a shared library, then run make with SHARED=1 and VERSION=version
|
||||
LIB = libangelscript.a
|
||||
DEVLIB = libangelscript.dylib
|
||||
BUNDLE = libangelscript.so
|
||||
INC = angelscript.h
|
||||
|
||||
SRCDIR = ../../source
|
||||
INCDIR = ../../include
|
||||
OBJDIR = obj
|
||||
LIBDIR = ../../lib
|
||||
CXX = c++
|
||||
AFLAGS= -arch i386 -arch x86_64
|
||||
CXXFLAGS = -g -Wall -fPIC $(AFLAGS)
|
||||
CXXBFLAGS = $(CXXFLAGS) -fno-common
|
||||
|
||||
DELETER = rm -f
|
||||
COPIER = cp -a
|
||||
|
||||
SRCNAMES = \
|
||||
as_atomic.cpp \
|
||||
as_builder.cpp \
|
||||
as_bytecode.cpp \
|
||||
as_callfunc.cpp \
|
||||
as_callfunc_arm.cpp \
|
||||
as_callfunc_mips.cpp \
|
||||
as_callfunc_ppc.cpp \
|
||||
as_callfunc_ppc_64.cpp \
|
||||
as_callfunc_sh4.cpp \
|
||||
as_callfunc_x86.cpp \
|
||||
as_callfunc_x64_gcc.cpp \
|
||||
as_compiler.cpp \
|
||||
as_context.cpp \
|
||||
as_configgroup.cpp \
|
||||
as_datatype.cpp \
|
||||
as_generic.cpp \
|
||||
as_gc.cpp \
|
||||
as_globalproperty.cpp \
|
||||
as_memory.cpp \
|
||||
as_module.cpp \
|
||||
as_objecttype.cpp \
|
||||
as_outputbuffer.cpp \
|
||||
as_parser.cpp \
|
||||
as_restore.cpp \
|
||||
as_scriptcode.cpp \
|
||||
as_scriptengine.cpp \
|
||||
as_scriptfunction.cpp \
|
||||
as_scriptnode.cpp \
|
||||
as_scriptobject.cpp \
|
||||
as_string.cpp \
|
||||
as_string_util.cpp \
|
||||
as_thread.cpp \
|
||||
as_tokenizer.cpp \
|
||||
as_typeinfo.cpp \
|
||||
as_variablescope.cpp \
|
||||
|
||||
OBJ = $(addprefix $(OBJDIR)/, $(notdir $(SRCNAMES:.cpp=.o)))
|
||||
BOBJ = $(addprefix $(OBJDIR)/, $(notdir $(SRCNAMES:.cpp=.lo)))
|
||||
TARG = $(LIBDIR)/$(LIB) $(LIBDIR)/$(DEVLIB) $(LIBDIR)/$(BUNDLE)
|
||||
|
||||
|
||||
all: $(TARG)
|
||||
$(LIBDIR)/$(LIB): $(OBJDIR) $(LIBDIR) $(OBJ)
|
||||
rm -f $(LIBDIR)/$(LIB)
|
||||
ar r $(LIBDIR)/$(LIB) $(OBJ)
|
||||
ranlib $(LIBDIR)/$(LIB)
|
||||
file $(LIBDIR)/$(LIB)
|
||||
|
||||
$(LIBDIR)/$(DEVLIB): $(OBJDIR) $(LIBDIR) $(OBJ)
|
||||
rm -f $(LIBDIR)/$(DEVLIB)
|
||||
$(CXX) $(AFLAGS) -dynamiclib -o $(DEVLIB) $(OBJ)
|
||||
mv $(DEVLIB) $(LIBDIR)/$(DEVLIB)
|
||||
file $(LIBDIR)/$(DEVLIB)
|
||||
|
||||
$(LIBDIR)/$(BUNDLE): $(OBJDIR) $(LIBDIR) $(BOBJ)
|
||||
rm -f $(LIBDIR)/$(BUNDLE)
|
||||
$(CXX) $(AFLAGS) -bundle -flat_namespace -undefined suppress -o $(LIBDIR)/$(BUNDLE) $(BOBJ)
|
||||
file $(LIBDIR)/$(BUNDLE)
|
||||
|
||||
@echo -------------------------------------------------------------------
|
||||
@echo Done. As root, type 'make install' to install the library.
|
||||
|
||||
$(OBJDIR):
|
||||
mkdir $(OBJDIR)
|
||||
|
||||
$(LIBDIR):
|
||||
mkdir $(LIBDIR)
|
||||
|
||||
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
|
||||
$(CXX) $(CXXFLAGS) -o $@ -c $<
|
||||
|
||||
$(OBJDIR)/%.o: $(SRCDIR)/%.S
|
||||
$(CXX) $(CXXFLAGS) -o $@ -c $<
|
||||
|
||||
$(OBJDIR)/%.o: $(SRCDIR)/%.s
|
||||
$(CXX) $(CXXFLAGS) -o $@ -c $<
|
||||
|
||||
$(OBJDIR)/%.lo: $(SRCDIR)/%.cpp
|
||||
$(CXX) $(CXXBFLAGS) -o $@ -c $<
|
||||
|
||||
$(OBJDIR)/%.lo: $(SRCDIR)/%.S
|
||||
$(CXX) $(CXXBFLAGS) -o $@ -c $<
|
||||
|
||||
$(OBJDIR)/%.lo: $(SRCDIR)/%.s
|
||||
$(CXX) $(CXXBFLAGS) -o $@ -c $<
|
||||
|
||||
clean:
|
||||
$(DELETER) $(OBJ) $(BOBJ) $(TARG)
|
||||
|
||||
install: $(TARG)
|
||||
@echo Installing to: $(LOCAL)/lib and $(LOCAL)/include...
|
||||
@echo -------------------------------------------------------------------
|
||||
ifdef SHARED
|
||||
$(COPIER) $(LIBDIR)/$(DEVLIB) $(LOCAL)/lib
|
||||
endif
|
||||
$(COPIER) $(TARG) $(LOCAL)/lib
|
||||
$(COPIER) $(INCDIR)/$(INC) $(LOCAL)/include
|
||||
@echo -------------------------------------------------------------------
|
||||
@echo Angelscript library installed. Enjoy!
|
||||
|
||||
uninstall:
|
||||
$(DELETER) $(LOCAL)/include/$(INC) $(LOCAL)/lib/$(LIB) $(LOCAL)/lib/$(DEVLIB)
|
||||
@echo -------------------------------------------------------------------
|
||||
@echo Angelscript library uninstalled.
|
||||
|
||||
.PHONY: all clean install uninstall
|
|
@ -0,0 +1,73 @@
|
|||
** (UN)FREQUENTLY ASKED QUESTIONS **
|
||||
|
||||
1. Why do you have to specify PREFIX= even when building
|
||||
when overriding the default ?
|
||||
|
||||
2. When overriding the default prefix, how do you compile
|
||||
and link my program ?
|
||||
|
||||
--
|
||||
1. Why do you have to specify PREFIX= even when building,
|
||||
when overriding the default ?
|
||||
|
||||
Because it allows easier linking. The way the Linux
|
||||
link loader works, if the library name has a slash in it,
|
||||
then it resolves it that way. If it doesn't it goes through
|
||||
a series of steps which tries to find it. However, without
|
||||
updating a certain file it won't find it under '/usr/local'
|
||||
(and similar with '/tmp'). Therefore, as long as you have
|
||||
the same PREFIX= (or don't specify it at all), all you need
|
||||
to do to link to the shared version is link to it (and any
|
||||
other dependencies; -lpthread comes to mind here). For
|
||||
example the link options might be :
|
||||
-langelscript_s -lpthread
|
||||
|
||||
--
|
||||
2. When overriding the default prefix, how do you compile
|
||||
and link my program ?
|
||||
|
||||
An example scenario is the following :
|
||||
You installed into /opt which means the following
|
||||
files should exist :
|
||||
|
||||
/opt/include/angelscript.h
|
||||
/opt/lib/libangelscript.so (which is a symbolic link to
|
||||
the current version installed)
|
||||
/opt/lib/libangelscript.a (the static library).
|
||||
|
||||
If you #include angelscript.h you might normally
|
||||
have :
|
||||
|
||||
#include <angelscript.h>
|
||||
|
||||
However, when that file is not in the standard directories
|
||||
the compiler searches, you have to either use :
|
||||
|
||||
#include "/opt/include/angelscript.h"
|
||||
(method one)
|
||||
or alternatively keep the include (using the angle brackets)
|
||||
but pass the include path (or paths actually but in this case
|
||||
path) to the compiler so it knows to search an additional
|
||||
location. If you're using g++ then the following option
|
||||
will work (it also works for gcc but I am assuming you
|
||||
are using C++) :
|
||||
|
||||
-I/opt/include
|
||||
|
||||
You must however still link. You therefore must pass another
|
||||
option to the compiler (which will pass it to the linker)
|
||||
and the option os -L which is used like so (to follow the
|
||||
scenario) :
|
||||
|
||||
-L/opt/lib
|
||||
|
||||
The rest is the same.
|
||||
|
||||
CONTACT INFO:
|
||||
If you have any questions or concerns, by all
|
||||
means have Andreas contact me (at this time I
|
||||
don't have an email I feel okay sharing - if it
|
||||
seems this is of use to others I will likely
|
||||
create an email on my server for this very
|
||||
purpose). For now Andreas can forward the
|
||||
message to me.
|
|
@ -0,0 +1,247 @@
|
|||
# AngelScript makefile for Linux.
|
||||
# Type 'make' then 'make install' to complete
|
||||
# the installation of the library. You no
|
||||
# longer have to specify SHARED=1 VERSION=x.y.z
|
||||
# (the Makefile automatically determines it
|
||||
# and builds it and the static library).
|
||||
# See README for how to use the shared library
|
||||
# instead of the static. The README also
|
||||
# contains other information and in particular
|
||||
# specifies on how to override the install
|
||||
# location should you desire this (you don't
|
||||
# have to - nor should you - edit this
|
||||
# file).
|
||||
#
|
||||
# One note: I don't have a way to test
|
||||
# the phone builds. I am an old-timer
|
||||
# and I _still_ miss customer-owned
|
||||
# coin-operated telephones. In fact
|
||||
# I still _miss_ the rotary telephone!
|
||||
|
||||
|
||||
## library names and versions
|
||||
LIBNAME=libangelscript
|
||||
AS_VER:=$(shell awk -F\" '/\#define ANGELSCRIPT_VERSION_STRING/{print $$2}' ../../include/angelscript.h | cut -d" " -f1)
|
||||
SHLIB=$(LIBNAME).so.$(AS_VER)
|
||||
ARLIB=$(LIBNAME).a
|
||||
|
||||
|
||||
## install directories
|
||||
ifeq ($(PREFIX),)
|
||||
PREFIX=/usr/local
|
||||
endif
|
||||
INCLUDEDIR_DEST=$(PREFIX)/include
|
||||
LIBDIR_DEST=$(PREFIX)/lib
|
||||
DOCDIR_BASEDIR=$(PREFIX)/share/doc/angelscript-$(AS_VER)
|
||||
DOXYGEN_DEST=$(DOCDIR_BASEDIR)/html
|
||||
SAMPLES_DEST=$(DOCDIR_BASEDIR)/samples
|
||||
|
||||
|
||||
## install commands
|
||||
INSTALL = install
|
||||
INSTALL_DIR = $(INSTALL) -d
|
||||
INSTALL_SHLIB = $(INSTALL) -m 755
|
||||
INSTALL_ARLIB = $(INSTALL) -m 644
|
||||
INSTALL_HEADER = $(INSTALL) -m 644
|
||||
CP_SYMLINK = cp --no-dereference --preserve=links
|
||||
CP_R = cp -R
|
||||
|
||||
|
||||
HEADER = angelscript.h
|
||||
SRCDIR = ../../source
|
||||
INCDIR = ../../include
|
||||
|
||||
|
||||
## platform specific settings
|
||||
ifeq ($(TARGETPLATFORM), iphone)
|
||||
IPHONEBIN = /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin
|
||||
OBJDIR = obj-iphone
|
||||
LIBDIR = ../../lib-iphone
|
||||
CXX ?= $(IPHONEBIN)/clang++
|
||||
CXXFLAGS += -Wall -fPIC -fno-strict-aliasing -arch armv7 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk -miphoneos-version-min=3.0
|
||||
else ifeq ($(TARGETPLATFORM), iphonesimulator)
|
||||
IPHONEBIN = /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin
|
||||
OBJDIR = obj-iphone
|
||||
LIBDIR = ../../lib-iphone
|
||||
CXX ?= $(IPHONEBIN)/clang++
|
||||
CXXFLAGS += -Wall -fPIC -fno-strict-aliasing -arch i386 -isysroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk -miphoneos-version-min=3.0
|
||||
else ifeq ($(TARGETPLATFORM), android)
|
||||
ANDROIDNDKROOT = /cygdrive/c/android/android-ndk-1.6_r1
|
||||
ANDROIDBIN = $(ANDROIDNDKROOT)/build/prebuilt/windows/arm-eabi-4.2.1/bin
|
||||
SYSROOT = $(ANDROIDNDKROOT)/build/platforms/android-4/arch-arm
|
||||
OBJDIR = obj-android
|
||||
LIBDIR = ../../lib-android
|
||||
CXX ?= $(ANDROIDBIN)/arm-eabi-gcc
|
||||
CXXFLAGS += -I$(SYSROOT)/usr/include \
|
||||
-Wall \
|
||||
-DANDROID \
|
||||
-fno-exceptions \
|
||||
-march=armv6 -mthumb-interwork \
|
||||
-mfloat-abi=softfp -fno-rtti
|
||||
else
|
||||
OBJDIR = obj
|
||||
LIBDIR = ../../lib
|
||||
CXX ?= g++
|
||||
# On i686 architecture you may need to add -march=i686 if you get
|
||||
# an undefined symbol for __sync_sub_and_fetch_4 in as_atomic.cpp.
|
||||
CXXFLAGS += -Wall -fPIC -fno-strict-aliasing
|
||||
endif
|
||||
|
||||
## Detect if targetting ARM CPU and if so tell assembler to accept implicit IT constructs in thumb mode
|
||||
GCC_ARCH := $(shell $(CXX) -dumpmachine)
|
||||
$(info GCC ARCH: $(GCC_ARCH))
|
||||
ifneq (,$(findstring arm-,$(GCC_ARCH)))
|
||||
CXXFLAGS += -Wa,-mimplicit-it=thumb
|
||||
else ifneq (,$(findstring armv7-, $(GCC_ARCH)))
|
||||
CXXFLAGS += -Wa,-mimplicit-it=thumb
|
||||
endif
|
||||
|
||||
## toolchain
|
||||
AR ?= ar
|
||||
RANLIB ?= ranlib
|
||||
|
||||
|
||||
SRCNAMES = \
|
||||
as_atomic.cpp \
|
||||
as_builder.cpp \
|
||||
as_bytecode.cpp \
|
||||
as_callfunc.cpp \
|
||||
as_callfunc_arm.cpp \
|
||||
as_callfunc_mips.cpp \
|
||||
as_callfunc_ppc.cpp \
|
||||
as_callfunc_ppc_64.cpp \
|
||||
as_callfunc_sh4.cpp \
|
||||
as_callfunc_x86.cpp \
|
||||
as_callfunc_x64_gcc.cpp \
|
||||
as_callfunc_x64_mingw.cpp \
|
||||
as_compiler.cpp \
|
||||
as_context.cpp \
|
||||
as_configgroup.cpp \
|
||||
as_datatype.cpp \
|
||||
as_generic.cpp \
|
||||
as_gc.cpp \
|
||||
as_globalproperty.cpp \
|
||||
as_memory.cpp \
|
||||
as_module.cpp \
|
||||
as_objecttype.cpp \
|
||||
as_outputbuffer.cpp \
|
||||
as_parser.cpp \
|
||||
as_restore.cpp \
|
||||
as_scriptcode.cpp \
|
||||
as_scriptengine.cpp \
|
||||
as_scriptfunction.cpp \
|
||||
as_scriptnode.cpp \
|
||||
as_scriptobject.cpp \
|
||||
as_string.cpp \
|
||||
as_string_util.cpp \
|
||||
as_thread.cpp \
|
||||
as_tokenizer.cpp \
|
||||
as_typeinfo.cpp \
|
||||
as_variablescope.cpp \
|
||||
|
||||
OBJ = $(addprefix $(OBJDIR)/, $(notdir $(SRCNAMES:.cpp=.o)))
|
||||
|
||||
ifeq ($(TARGETPLATFORM), iphone)
|
||||
OBJ += $(OBJDIR)/as_callfunc_arm_xcode.o
|
||||
else
|
||||
OBJ += $(OBJDIR)/as_callfunc_arm_gcc.o
|
||||
endif
|
||||
|
||||
|
||||
default: all
|
||||
|
||||
all: shared static
|
||||
|
||||
shared: $(LIBDIR)/$(SHLIB) $(LIBDIR)/$(LIBNAME).so
|
||||
|
||||
static: $(LIBDIR) $(OBJDIR) $(LIBDIR)/$(ARLIB)
|
||||
|
||||
$(OBJDIR):
|
||||
mkdir -p "$(OBJDIR)"
|
||||
|
||||
$(LIBDIR):
|
||||
mkdir -p "$(LIBDIR)"
|
||||
|
||||
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
|
||||
$(CXX) $(CXXFLAGS) -o $@ -c $<
|
||||
|
||||
$(OBJDIR)/%.o: $(SRCDIR)/%.S
|
||||
$(CXX) $(CXXFLAGS) -o $@ -c $<
|
||||
|
||||
$(OBJDIR)/%.o: $(SRCDIR)/%.s
|
||||
$(CXX) $(CXXFLAGS) -o $@ -c $<
|
||||
|
||||
$(LIBDIR)/$(SHLIB): $(OBJ)
|
||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared -Wl,-soname,$(SHLIB) -o "$(LIBDIR)"/$(SHLIB) $(OBJ)
|
||||
|
||||
$(LIBDIR)/$(LIBNAME).so: $(LIBDIR)/$(SHLIB)
|
||||
@( cd "$(LIBDIR)" && ln -s $(SHLIB) $(LIBNAME).so )
|
||||
|
||||
$(LIBDIR)/$(ARLIB): $(OBJ)
|
||||
$(AR) r "$(LIBDIR)"/$(ARLIB) $(OBJ)
|
||||
$(RANLIB) "$(LIBDIR)"/$(ARLIB)
|
||||
|
||||
|
||||
## install rules
|
||||
install_header: $(INCDIR)/$(HEADER)
|
||||
$(INSTALL_DIR) "$(DESTDIR)/$(INCLUDEDIR_DEST)"
|
||||
$(INSTALL_HEADER) "$(INCDIR)"/$(HEADER) "$(DESTDIR)/$(INCLUDEDIR_DEST)/"$(HEADER)
|
||||
|
||||
install_shared:
|
||||
$(INSTALL_DIR) "$(DESTDIR)/$(LIBDIR_DEST)"
|
||||
$(INSTALL_SHLIB) "$(LIBDIR)"/$(SHLIB) "$(DESTDIR)/$(LIBDIR_DEST)/"$(SHLIB)
|
||||
$(CP_SYMLINK) "$(LIBDIR)"/$(LIBNAME).so "$(DESTDIR)/$(LIBDIR_DEST)/"$(LIBNAME).so
|
||||
|
||||
install_static: $(LIBDIR)/$(ARLIB) $(LIBDIR)/$(SHLIB)
|
||||
$(INSTALL_DIR) "$(DESTDIR)/$(LIBDIR_DEST)"
|
||||
$(INSTALL_ARLIB) "$(LIBDIR)"/$(ARLIB) "$(DESTDIR)/$(LIBDIR_DEST)/"$(ARLIB)
|
||||
|
||||
install_docs: ./../../../docs
|
||||
$(INSTALL_DIR) "$(DESTDIR)/$(DOCDIR_BASEDIR)"
|
||||
$(CP_R) ./../../../docs "$(DESTDIR)/$(DOXYGEN_DEST)"
|
||||
|
||||
install_samples: ./../../../samples
|
||||
$(INSTALL_DIR) "$(DESTDIR)/$(DOCDIR_BASEDIR)"
|
||||
$(CP_R) ./../../../samples "$(DESTDIR)/$(SAMPLES_DEST)"
|
||||
|
||||
install_all: install_docs install_samples install
|
||||
|
||||
install: install_header install_shared install_static
|
||||
|
||||
uninstall:
|
||||
rm -f "$(DESTDIR)/$(INCLUDEDIR_DEST)/$(HEADER)" "$(DESTDIR)/$(LIBDIR_DEST)"/$(LIBNAME)*
|
||||
|
||||
help:
|
||||
@echo -------------------------------------------------------------------
|
||||
@echo 'BUILDING:'
|
||||
@echo ' make all: build shared and static libs'
|
||||
@echo ' make shared: build shared lib only'
|
||||
@echo ' make static: build static lib only'
|
||||
@echo
|
||||
@echo 'INSTALLING:'
|
||||
@echo ' make install: install headers, shared and static libs'
|
||||
@echo ' make install_header: install only the headers'
|
||||
@echo ' make install_shared: install only the shared libs'
|
||||
@echo ' make install_static: install only the static libs'
|
||||
@echo ' make install_docs: install only the documentation'
|
||||
@echo ' make install_samples: install only the samples'
|
||||
@echo ' make install_all: install everything, including docs and samples'
|
||||
@echo
|
||||
@echo 'PARAMETERS (pass to make, as in PARAM=value):'
|
||||
@echo ' PREFIX: installation prefix (default /usr/local)'
|
||||
@echo ' INCLUDEDIR_DEST: where to install headers (default PREFIX/include)'
|
||||
@echo ' LIBDIR_DEST: where to install libraries (default PREFIX/lib)'
|
||||
@echo ' DOCDIR_BASEDIR: where the basedir of the documentation lies'
|
||||
@echo ' (default PREFIX/share/doc/angelscript-AS_VER)'
|
||||
@echo ' DOXYGEN_DEST: where to install doxygen documentation'
|
||||
@echo ' (default DOCDIR_BASEDIR/html)'
|
||||
@echo ' SAMPLES_DEST: where to install samples'
|
||||
@echo ' (default DOCDIR_BASEDIR/samples)'
|
||||
@echo ' DESTDIR: destination, prepended to PREFIX, usually used by'
|
||||
@echo ' package managers (default empty)'
|
||||
@echo -------------------------------------------------------------------
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ) "$(LIBDIR)"/$(ARLIB) "$(LIBDIR)"/$(SHLIB) "$(LIBDIR)"/$(LIBNAME).so
|
||||
|
||||
.PHONY: all clean install install_all install_docs install_header install_samples install_shared install_static shared static uninstall
|
|
@ -0,0 +1,63 @@
|
|||
If you want to override /usr/local as the default prefix
|
||||
(which means /usr/local/include would have the header file and
|
||||
/usr/local/lib would have the library files), then run
|
||||
make, make install and make uninstall (to build, to
|
||||
install and uninstall respectively - you need it for
|
||||
all three as I explain below) :
|
||||
|
||||
make PREFIX=/tmp
|
||||
make PREFIX=/tmp install
|
||||
make PREFIX=/tmp uninstall
|
||||
|
||||
The last two will of course have to be done
|
||||
as root if you need permissions to write to
|
||||
the directory (for /tmp you wouldn't unless
|
||||
the files already existed by someone else and
|
||||
you didn't have permission).
|
||||
|
||||
In any case, the above would install header file
|
||||
under '/tmp/include' and the library file(s) under
|
||||
'/tmp/lib'.
|
||||
|
||||
If you want to know the technical details as to why
|
||||
you have to (when overriding the install location)
|
||||
specify PREFIX= even when building, see the FAQ
|
||||
file (summary: it makes it easier for you when linking
|
||||
in the shared library).
|
||||
|
||||
A word of caution to those overriding prefix :
|
||||
--
|
||||
You are more than welcome to disregard this but I feel
|
||||
it is something I should bring up. If you do override
|
||||
the prefix I strongly recommend you do not specify
|
||||
'/usr'. Why one might ask. The typical way is
|
||||
that user-compiled programs/libraries/etc. go under
|
||||
'/usr/local' (other times '/opt'). This has multiple
|
||||
benefits: you keep '/usr' clean and if you have a
|
||||
package manager then it makes it easy to say:
|
||||
"The only files under /usr/include and /usr/lib are
|
||||
those that belong to a package."
|
||||
In other words it is easier to maintain integrity
|
||||
and verify everything. Most important of it all
|
||||
(aside the security implications) is this:
|
||||
You have less chance of name clashes. If there ever
|
||||
is a package that installs to /usr and it includes
|
||||
the files (maybe a package for AngelScript) then you
|
||||
will have issues.
|
||||
--
|
||||
|
||||
Lastly: I don't have a way to test the phone builds
|
||||
so I cannot verify the build process (it really
|
||||
depends on the environment and architecture, like
|
||||
most things); I'm an old-timer that hates the
|
||||
"smart" trend (besides: it is a horrible misuse
|
||||
of the world 'smart').
|
||||
|
||||
CONTACT:
|
||||
If you have any questions or concerns, by all
|
||||
means have Andreas contact me (at this time I
|
||||
don't have an email I feel okay sharing - if it
|
||||
seems this is of use to others I will likely
|
||||
create an email on my server for this very
|
||||
purpose). For now Andreas can forward the
|
||||
message to me.
|
|
@ -0,0 +1,2 @@
|
|||
This file is here just in case your unarchiver does not extract empty directories.
|
||||
Feel free to remove it.
|
|
@ -0,0 +1,111 @@
|
|||
#!/usr/bin/env mkb
|
||||
|
||||
options
|
||||
{
|
||||
enable-exceptions=1
|
||||
lib
|
||||
module_path="../../source"
|
||||
}
|
||||
|
||||
subproject angelscript_lib
|
||||
|
||||
defines
|
||||
{
|
||||
}
|
||||
|
||||
if {{ defined I3D_ARCH_ARM }}
|
||||
{
|
||||
files
|
||||
{
|
||||
(../../source)
|
||||
as_callfunc_arm_gcc.S
|
||||
}
|
||||
option buildenv=scons
|
||||
}
|
||||
else
|
||||
{
|
||||
files
|
||||
{
|
||||
(../../source)
|
||||
#as_callfunc_x64_msvc_asm.asm
|
||||
as_callfunc_arm_msvc.asm
|
||||
}
|
||||
}
|
||||
|
||||
files
|
||||
{
|
||||
(../../source)
|
||||
as_array.h
|
||||
as_atomic.cpp
|
||||
as_atomic.h
|
||||
as_builder.cpp
|
||||
as_builder.h
|
||||
as_bytecode.cpp
|
||||
as_bytecode.h
|
||||
as_callfunc.cpp
|
||||
as_callfunc.h
|
||||
as_callfunc_arm.cpp
|
||||
as_callfunc_mips.cpp
|
||||
as_callfunc_ppc.cpp
|
||||
as_callfunc_ppc_64.cpp
|
||||
as_callfunc_sh4.cpp
|
||||
as_callfunc_x64_gcc.cpp
|
||||
as_callfunc_x64_mingw.cpp
|
||||
as_callfunc_x64_msvc.cpp
|
||||
as_callfunc_x86.cpp
|
||||
as_callfunc_xenon.cpp
|
||||
as_compiler.cpp
|
||||
as_compiler.h
|
||||
as_config.h
|
||||
as_configgroup.cpp
|
||||
as_configgroup.h
|
||||
as_context.cpp
|
||||
as_context.h
|
||||
as_criticalsection.h
|
||||
as_datatype.cpp
|
||||
as_datatype.h
|
||||
as_debug.h
|
||||
as_gc.cpp
|
||||
as_gc.h
|
||||
as_generic.cpp
|
||||
as_generic.h
|
||||
as_globalproperty.cpp
|
||||
as_map.h
|
||||
as_memory.cpp
|
||||
as_memory.h
|
||||
as_module.cpp
|
||||
as_module.h
|
||||
as_objecttype.cpp
|
||||
as_objecttype.h
|
||||
as_outputbuffer.cpp
|
||||
as_outputbuffer.h
|
||||
as_parser.cpp
|
||||
as_parser.h
|
||||
as_property.h
|
||||
as_restore.cpp
|
||||
as_restore.h
|
||||
as_scriptcode.cpp
|
||||
as_scriptcode.h
|
||||
as_scriptengine.cpp
|
||||
as_scriptengine.h
|
||||
as_scriptfunction.cpp
|
||||
as_scriptfunction.h
|
||||
as_scriptnode.cpp
|
||||
as_scriptnode.h
|
||||
as_scriptobject.cpp
|
||||
as_scriptobject.h
|
||||
as_string.cpp
|
||||
as_string.h
|
||||
as_string_util.cpp
|
||||
as_string_util.h
|
||||
as_texts.h
|
||||
as_thread.cpp
|
||||
as_thread.h
|
||||
as_tokendef.h
|
||||
as_tokenizer.cpp
|
||||
as_tokenizer.h
|
||||
as_typeinfo.cpp
|
||||
as_typeinfo.h
|
||||
as_variablescope.cpp
|
||||
as_variablescope.h
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#!/usr/bin/env mkb
|
||||
|
||||
display_name "AngelScript_Lib"
|
||||
|
||||
includepath
|
||||
{
|
||||
../../include
|
||||
../../sdk/add_on
|
||||
}
|
||||
|
||||
defines
|
||||
{
|
||||
}
|
||||
|
||||
library
|
||||
{
|
||||
".,angelscript_lib"
|
||||
}
|
||||
|
||||
files
|
||||
{
|
||||
(../../include)
|
||||
angelscript.h
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
import argparse
|
||||
import os
|
||||
import re
|
||||
|
||||
HEADER = os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
||||
"..", "..", "include", "angelscript.h")
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--num", action="store_true", help="Print numeric version")
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.num:
|
||||
regex = re.compile(r'^#define ANGELSCRIPT_VERSION\s+(\d+)')
|
||||
else:
|
||||
regex = re.compile(r'^#define ANGELSCRIPT_VERSION_STRING\s+"(\d+\.\d+\.\d+.*)"')
|
||||
|
||||
with open(HEADER, "r") as fobj:
|
||||
for l in fobj:
|
||||
match = re.match(regex, l)
|
||||
if match is not None:
|
||||
print(match.group(1))
|
||||
return
|
||||
|
||||
assert False, "Can't find version"
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1,68 @@
|
|||
project('angelscript', 'cpp',
|
||||
version : run_command(find_program('python3'), 'detect_ver.py').stdout().strip(),
|
||||
meson_version : '>=0.28.0',
|
||||
license : 'zlib')
|
||||
|
||||
threads = dependency('threads')
|
||||
|
||||
angel_srcs = [
|
||||
'../../source/as_atomic.cpp',
|
||||
'../../source/as_builder.cpp',
|
||||
'../../source/as_bytecode.cpp',
|
||||
'../../source/as_callfunc.cpp',
|
||||
'../../source/as_callfunc_mips.cpp',
|
||||
'../../source/as_callfunc_ppc.cpp',
|
||||
'../../source/as_callfunc_ppc_64.cpp',
|
||||
'../../source/as_callfunc_sh4.cpp',
|
||||
'../../source/as_callfunc_x86.cpp',
|
||||
'../../source/as_callfunc_x64_gcc.cpp',
|
||||
'../../source/as_callfunc_x64_mingw.cpp',
|
||||
'../../source/as_compiler.cpp',
|
||||
'../../source/as_context.cpp',
|
||||
'../../source/as_configgroup.cpp',
|
||||
'../../source/as_datatype.cpp',
|
||||
'../../source/as_generic.cpp',
|
||||
'../../source/as_gc.cpp',
|
||||
'../../source/as_globalproperty.cpp',
|
||||
'../../source/as_memory.cpp',
|
||||
'../../source/as_module.cpp',
|
||||
'../../source/as_objecttype.cpp',
|
||||
'../../source/as_outputbuffer.cpp',
|
||||
'../../source/as_parser.cpp',
|
||||
'../../source/as_restore.cpp',
|
||||
'../../source/as_scriptcode.cpp',
|
||||
'../../source/as_scriptengine.cpp',
|
||||
'../../source/as_scriptfunction.cpp',
|
||||
'../../source/as_scriptnode.cpp',
|
||||
'../../source/as_scriptobject.cpp',
|
||||
'../../source/as_string.cpp',
|
||||
'../../source/as_string_util.cpp',
|
||||
'../../source/as_thread.cpp',
|
||||
'../../source/as_tokenizer.cpp',
|
||||
'../../source/as_typeinfo.cpp',
|
||||
'../../source/as_variablescope.cpp',
|
||||
]
|
||||
if host_machine.cpu_family() == 'arm'
|
||||
add_languages('c')
|
||||
angel_srcs += [
|
||||
'../../source/as_callfunc_arm.cpp',
|
||||
'../../source/as_callfunc_arm_gcc.S',
|
||||
]
|
||||
endif
|
||||
|
||||
angelscript_version_num = run_command(find_program('python3'), 'detect_ver.py', '--num').stdout().strip()
|
||||
angelscript_lib = library(
|
||||
'angelscript',
|
||||
sources : angel_srcs,
|
||||
dependencies : threads,
|
||||
version : angelscript_version_num,
|
||||
install : true,
|
||||
)
|
||||
angelscript_inc = include_directories('../../include')
|
||||
angelscript_dep = declare_dependency(
|
||||
link_with : angelscript_lib,
|
||||
include_directories : angelscript_inc,
|
||||
version : meson.project_version(),
|
||||
)
|
||||
|
||||
install_headers('../../include/angelscript.h')
|
|
@ -0,0 +1,83 @@
|
|||
# Angelscript MingW makefile
|
||||
# Type 'make' then 'make install' to complete the installation of the library
|
||||
|
||||
CXX ?= g++
|
||||
AR ?= ar
|
||||
# Debug flags: -ggdb -DAS_DEBUG
|
||||
# Release flags: -O2
|
||||
# to exclude the script compiler: -DAS_NO_COMPILER
|
||||
# to use only generic calling convention: -DAS_MAX_PORTABILITY
|
||||
CXXFLAGS ?= -O2
|
||||
SRCDIR = ../../source
|
||||
OBJDIR = obj
|
||||
SRCNAMES = \
|
||||
as_atomic.cpp \
|
||||
as_builder.cpp \
|
||||
as_bytecode.cpp \
|
||||
as_callfunc.cpp \
|
||||
as_callfunc_mips.cpp \
|
||||
as_callfunc_ppc_64.cpp \
|
||||
as_callfunc_ppc.cpp \
|
||||
as_callfunc_sh4.cpp \
|
||||
as_callfunc_x86.cpp \
|
||||
as_callfunc_x64_mingw.cpp \
|
||||
as_compiler.cpp \
|
||||
as_configgroup.cpp \
|
||||
as_context.cpp \
|
||||
as_datatype.cpp \
|
||||
as_generic.cpp \
|
||||
as_gc.cpp \
|
||||
as_globalproperty.cpp \
|
||||
as_memory.cpp \
|
||||
as_module.cpp \
|
||||
as_objecttype.cpp \
|
||||
as_outputbuffer.cpp \
|
||||
as_parser.cpp \
|
||||
as_restore.cpp \
|
||||
as_scriptcode.cpp \
|
||||
as_scriptengine.cpp \
|
||||
as_scriptfunction.cpp \
|
||||
as_scriptnode.cpp \
|
||||
as_scriptobject.cpp \
|
||||
as_string.cpp \
|
||||
as_string_util.cpp \
|
||||
as_thread.cpp \
|
||||
as_tokenizer.cpp \
|
||||
as_typeinfo.cpp \
|
||||
as_variablescope.cpp \
|
||||
|
||||
OBJ = $(addprefix $(OBJDIR)/, $(notdir $(SRCNAMES:.cpp=.o)))
|
||||
BIN = ../../lib/libangelscript.a
|
||||
OBJ_D = $(subst /,\,$(OBJ))
|
||||
BIN_D = $(subst /,\,$(BIN))
|
||||
DELETER = del /f
|
||||
COPIER = copy /y
|
||||
INCLUDEFILES_D = ..\..\include\angelscript.h
|
||||
UNINSTALLFILES_D = $(MINGDIR)\lib\libangelscript.a $(MINGDIR)\include\angelscript.h
|
||||
|
||||
all: $(BIN)
|
||||
|
||||
$(BIN): $(OBJ)
|
||||
$(AR) rcs $(BIN) $(OBJ)
|
||||
@echo -------------------------------------------------------------------
|
||||
@echo Done. Now type 'make install' to install the library on your MinGW.
|
||||
|
||||
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
|
||||
$(CXX) $(CXXFLAGS) -o $@ -c $<
|
||||
|
||||
|
||||
clean:
|
||||
$(DELETER) $(OBJ_D) $(BIN_D)
|
||||
|
||||
install: $(BIN)
|
||||
$(COPIER) $(BIN_D) $(MINGDIR)\lib
|
||||
$(COPIER) $(INCLUDEFILES_D) $(MINGDIR)\include
|
||||
@echo -------------------------------------------------------------------
|
||||
@echo Angelscript library installed. Enjoy!
|
||||
|
||||
uninstall:
|
||||
$(DELETER) $(UNINSTALLFILES_D)
|
||||
@echo -------------------------------------------------------------------
|
||||
@echo Angelscript library uninstalled.
|
||||
|
||||
.PHONY: all clean install uninstall
|
|
@ -0,0 +1,2 @@
|
|||
This file is here just in case your unarchiver does not extract empty directories.
|
||||
Feel free to remove it.
|
|
@ -0,0 +1,9 @@
|
|||
If you haven't done that already set up an environment variable named MINGDIR
|
||||
pointing the the directory where your MinGW is, e.g. "C:\MINGW"
|
||||
|
||||
To compile the library, just type in the command line:
|
||||
|
||||
make
|
||||
make install
|
||||
|
||||
Sent in by Jakub "krajzega" Wasilewski
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Express 2012 for Windows Desktop
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "angelscript", "angelscript.vcxproj", "{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Debug|x64.Build.0 = Debug|x64
|
||||
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Release|Win32.Build.0 = Release|Win32
|
||||
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Release|x64.ActiveCfg = Release|x64
|
||||
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,438 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="clang_debug|ARM">
|
||||
<Configuration>clang_debug</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="clang_debug|Win32">
|
||||
<Configuration>clang_debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="clang_debug|x64">
|
||||
<Configuration>clang_debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}</ProjectGuid>
|
||||
<RootNamespace>angelscript</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140_clang_3_7</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140_clang_3_7</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140_Clang_3_7</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\lib\</OutDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'">..\..\lib\</OutDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\lib\</OutDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">..\..\lib\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'">$(Configuration)\</IntDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../lib\</OutDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">../../lib\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)64d</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">$(ProjectName)64d</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectName)d</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'">$(ProjectName)d</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">$(ProjectName)d_arm</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">$(ProjectName)d_arm</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectName)64</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
<TargetName>$(ProjectName)_arm</TargetName>
|
||||
<OutDir>..\..\lib\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<OutDir>..\..\lib\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">
|
||||
<OutDir>..\..\lib\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(ProjectName)d.lib</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>AS_MAX_PORTABILITY;ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Enabled</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>EnableAllWarnings</WarningLevel>
|
||||
<DebugInformationFormat>FullDebug</DebugInformationFormat>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(ProjectName)d.lib</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(ProjectName)64d.lib</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Enabled</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>EnableAllWarnings</WarningLevel>
|
||||
<DebugInformationFormat>FullDebug</DebugInformationFormat>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(ProjectName)64d.lib</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Full</Optimization>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
<ClCompile>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Full</Optimization>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<EnableEnhancedInstructionSet>
|
||||
</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>Full</Optimization>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<EnableEnhancedInstructionSet>
|
||||
</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<FloatingPointExceptions>
|
||||
</FloatingPointExceptions>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>..\..\lib\angelscript64.lib</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\source\as_atomic.cpp" />
|
||||
<ClCompile Include="..\..\source\as_builder.cpp" />
|
||||
<ClCompile Include="..\..\source\as_bytecode.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_arm.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_mips.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_ppc.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_ppc_64.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_sh4.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_x64_gcc.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_x64_mingw.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_x64_msvc.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_x86.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_xenon.cpp" />
|
||||
<ClCompile Include="..\..\source\as_compiler.cpp" />
|
||||
<ClCompile Include="..\..\source\as_configgroup.cpp" />
|
||||
<ClCompile Include="..\..\source\as_context.cpp" />
|
||||
<ClCompile Include="..\..\source\as_datatype.cpp" />
|
||||
<ClCompile Include="..\..\source\as_gc.cpp" />
|
||||
<ClCompile Include="..\..\source\as_generic.cpp" />
|
||||
<ClCompile Include="..\..\source\as_globalproperty.cpp" />
|
||||
<ClCompile Include="..\..\source\as_memory.cpp" />
|
||||
<ClCompile Include="..\..\source\as_module.cpp" />
|
||||
<ClCompile Include="..\..\source\as_objecttype.cpp" />
|
||||
<ClCompile Include="..\..\source\as_outputbuffer.cpp" />
|
||||
<ClCompile Include="..\..\source\as_parser.cpp" />
|
||||
<ClCompile Include="..\..\source\as_restore.cpp" />
|
||||
<ClCompile Include="..\..\source\as_scriptcode.cpp" />
|
||||
<ClCompile Include="..\..\source\as_scriptengine.cpp" />
|
||||
<ClCompile Include="..\..\source\as_scriptfunction.cpp" />
|
||||
<ClCompile Include="..\..\source\as_scriptnode.cpp" />
|
||||
<ClCompile Include="..\..\source\as_scriptobject.cpp" />
|
||||
<ClCompile Include="..\..\source\as_string.cpp" />
|
||||
<ClCompile Include="..\..\source\as_string_util.cpp" />
|
||||
<ClCompile Include="..\..\source\as_thread.cpp" />
|
||||
<ClCompile Include="..\..\source\as_tokenizer.cpp" />
|
||||
<ClCompile Include="..\..\source\as_typeinfo.cpp" />
|
||||
<ClCompile Include="..\..\source\as_variablescope.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\include\angelscript.h" />
|
||||
<ClInclude Include="..\..\source\as_array.h" />
|
||||
<ClInclude Include="..\..\source\as_atomic.h" />
|
||||
<ClInclude Include="..\..\source\as_builder.h" />
|
||||
<ClInclude Include="..\..\source\as_bytecode.h" />
|
||||
<ClInclude Include="..\..\source\as_callfunc.h" />
|
||||
<ClInclude Include="..\..\source\as_compiler.h" />
|
||||
<ClInclude Include="..\..\source\as_config.h" />
|
||||
<ClInclude Include="..\..\source\as_configgroup.h" />
|
||||
<ClInclude Include="..\..\source\as_context.h" />
|
||||
<ClInclude Include="..\..\source\as_criticalsection.h" />
|
||||
<ClInclude Include="..\..\source\as_datatype.h" />
|
||||
<ClInclude Include="..\..\source\as_debug.h" />
|
||||
<ClInclude Include="..\..\source\as_gc.h" />
|
||||
<ClInclude Include="..\..\source\as_generic.h" />
|
||||
<ClInclude Include="..\..\source\as_map.h" />
|
||||
<ClInclude Include="..\..\source\as_memory.h" />
|
||||
<ClInclude Include="..\..\source\as_module.h" />
|
||||
<ClInclude Include="..\..\source\as_objecttype.h" />
|
||||
<ClInclude Include="..\..\source\as_outputbuffer.h" />
|
||||
<ClInclude Include="..\..\source\as_parser.h" />
|
||||
<ClInclude Include="..\..\source\as_property.h" />
|
||||
<ClInclude Include="..\..\source\as_restore.h" />
|
||||
<ClInclude Include="..\..\source\as_scriptcode.h" />
|
||||
<ClInclude Include="..\..\source\as_scriptengine.h" />
|
||||
<ClInclude Include="..\..\source\as_scriptfunction.h" />
|
||||
<ClInclude Include="..\..\source\as_scriptnode.h" />
|
||||
<ClInclude Include="..\..\source\as_scriptobject.h" />
|
||||
<ClInclude Include="..\..\source\as_string.h" />
|
||||
<ClInclude Include="..\..\source\as_string_util.h" />
|
||||
<ClInclude Include="..\..\source\as_symboltable.h" />
|
||||
<ClInclude Include="..\..\source\as_texts.h" />
|
||||
<ClInclude Include="..\..\source\as_thread.h" />
|
||||
<ClInclude Include="..\..\source\as_tokendef.h" />
|
||||
<ClInclude Include="..\..\source\as_tokenizer.h" />
|
||||
<ClInclude Include="..\..\source\as_typeinfo.h" />
|
||||
<ClInclude Include="..\..\source\as_variablescope.h" />
|
||||
<ClInclude Include="..\..\source\as_namespace.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="..\..\source\as_callfunc_x64_msvc_asm.asm">
|
||||
<FileType>Document</FileType>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ml64.exe /c /nologo /Fo"$(Configuration)\as_callfunc_x64_msvc_asm.obj" /W3 /Zi /Ta "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\as_callfunc_x64_msvc_asm.obj;%(Outputs)</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ml64.exe /c /nologo /Fo"$(Configuration)\as_callfunc_x64_msvc_asm.obj" /W3 /Zi /Ta "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">ml64.exe /c /nologo /Fo"$(Configuration)\as_callfunc_x64_msvc_asm.obj" /W3 /Zi /Ta "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\as_callfunc_x64_msvc_asm.obj;%(Outputs)</Outputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">$(Configuration)\as_callfunc_x64_msvc_asm.obj;%(Outputs)</Outputs>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\source\as_callfunc_arm_gcc.S" />
|
||||
<CustomBuild Include="..\..\source\as_callfunc_arm_msvc.asm">
|
||||
<FileType>Document</FileType>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">armasm.exe -g -32 -o "$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj" "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">armasm.exe -g -32 -o "$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj" "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj;%(Outputs)</Outputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj;%(Outputs)</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">armasm.exe -32 -o "$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj" "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj;%(Outputs)</Outputs>
|
||||
</CustomBuild>
|
||||
<None Include="..\..\source\as_callfunc_arm_vita.S" />
|
||||
<None Include="..\..\source\as_callfunc_arm_xcode.S" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,268 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\source\as_atomic.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_builder.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_bytecode.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_mips.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_sh4.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_x86.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_compiler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_configgroup.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_context.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_datatype.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_gc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_generic.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_globalproperty.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_memory.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_module.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_objecttype.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_outputbuffer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_parser.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_restore.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_scriptcode.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_scriptengine.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_scriptfunction.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_scriptnode.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_scriptobject.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_string.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_string_util.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_thread.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_tokenizer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_typeinfo.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_variablescope.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_x64_msvc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_arm.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_ppc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_ppc_64.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_x64_gcc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_x64_mingw.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_xenon.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\include\angelscript.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_array.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_builder.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_bytecode.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_callfunc.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_compiler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_config.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_configgroup.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_context.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_datatype.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_debug.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_generic.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_map.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_module.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_objecttype.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_outputbuffer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_parser.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_property.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_restore.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_scriptcode.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_scriptengine.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_scriptfunction.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_scriptnode.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_scriptobject.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_string.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_string_util.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_texts.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_thread.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_tokendef.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_tokenizer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_typeinfo.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_variablescope.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_gc.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_criticalsection.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_symboltable.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_atomic.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_memory.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_namespace.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="..\..\source\as_callfunc_x64_msvc_asm.asm">
|
||||
<Filter>Source Files</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="..\..\source\as_callfunc_arm_msvc.asm">
|
||||
<Filter>Source Files</Filter>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\source\as_callfunc_arm_gcc.S">
|
||||
<Filter>Source Files</Filter>
|
||||
</None>
|
||||
<None Include="..\..\source\as_callfunc_arm_xcode.S">
|
||||
<Filter>Source Files</Filter>
|
||||
</None>
|
||||
<None Include="..\..\source\as_callfunc_arm_vita.S">
|
||||
<Filter>Source Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Express 2012 for Windows Desktop
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "angelscript", "angelscript.vcxproj", "{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Debug|x64.Build.0 = Debug|x64
|
||||
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Release|Win32.Build.0 = Release|Win32
|
||||
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Release|x64.ActiveCfg = Release|x64
|
||||
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,439 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="clang_debug|ARM">
|
||||
<Configuration>clang_debug</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="clang_debug|Win32">
|
||||
<Configuration>clang_debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="clang_debug|x64">
|
||||
<Configuration>clang_debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}</ProjectGuid>
|
||||
<RootNamespace>angelscript</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140_clang_3_7</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140_clang_3_7</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140_Clang_3_7</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\lib\</OutDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'">..\..\lib\</OutDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\lib\</OutDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">..\..\lib\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'">$(Configuration)\</IntDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../lib\</OutDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">../../lib\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)64d</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">$(ProjectName)64d</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectName)d</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'">$(ProjectName)d</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">$(ProjectName)d_arm</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">$(ProjectName)d_arm</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectName)64</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
<TargetName>$(ProjectName)_arm</TargetName>
|
||||
<OutDir>..\..\lib\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<OutDir>..\..\lib\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">
|
||||
<OutDir>..\..\lib\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(ProjectName)d.lib</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>AS_MAX_PORTABILITY;ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Enabled</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>EnableAllWarnings</WarningLevel>
|
||||
<DebugInformationFormat>FullDebug</DebugInformationFormat>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(ProjectName)d.lib</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(ProjectName)64d.lib</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Enabled</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>EnableAllWarnings</WarningLevel>
|
||||
<DebugInformationFormat>FullDebug</DebugInformationFormat>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(ProjectName)64d.lib</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Full</Optimization>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
<ClCompile>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Full</Optimization>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<EnableEnhancedInstructionSet>
|
||||
</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>Full</Optimization>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<EnableEnhancedInstructionSet>
|
||||
</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<FloatingPointExceptions>
|
||||
</FloatingPointExceptions>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>..\..\lib\angelscript64.lib</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\source\as_atomic.cpp" />
|
||||
<ClCompile Include="..\..\source\as_builder.cpp" />
|
||||
<ClCompile Include="..\..\source\as_bytecode.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_arm.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_mips.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_ppc.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_ppc_64.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_sh4.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_x64_gcc.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_x64_mingw.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_x64_msvc.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_x86.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_xenon.cpp" />
|
||||
<ClCompile Include="..\..\source\as_compiler.cpp" />
|
||||
<ClCompile Include="..\..\source\as_configgroup.cpp" />
|
||||
<ClCompile Include="..\..\source\as_context.cpp" />
|
||||
<ClCompile Include="..\..\source\as_datatype.cpp" />
|
||||
<ClCompile Include="..\..\source\as_gc.cpp" />
|
||||
<ClCompile Include="..\..\source\as_generic.cpp" />
|
||||
<ClCompile Include="..\..\source\as_globalproperty.cpp" />
|
||||
<ClCompile Include="..\..\source\as_memory.cpp" />
|
||||
<ClCompile Include="..\..\source\as_module.cpp" />
|
||||
<ClCompile Include="..\..\source\as_objecttype.cpp" />
|
||||
<ClCompile Include="..\..\source\as_outputbuffer.cpp" />
|
||||
<ClCompile Include="..\..\source\as_parser.cpp" />
|
||||
<ClCompile Include="..\..\source\as_restore.cpp" />
|
||||
<ClCompile Include="..\..\source\as_scriptcode.cpp" />
|
||||
<ClCompile Include="..\..\source\as_scriptengine.cpp" />
|
||||
<ClCompile Include="..\..\source\as_scriptfunction.cpp" />
|
||||
<ClCompile Include="..\..\source\as_scriptnode.cpp" />
|
||||
<ClCompile Include="..\..\source\as_scriptobject.cpp" />
|
||||
<ClCompile Include="..\..\source\as_string.cpp" />
|
||||
<ClCompile Include="..\..\source\as_string_util.cpp" />
|
||||
<ClCompile Include="..\..\source\as_thread.cpp" />
|
||||
<ClCompile Include="..\..\source\as_tokenizer.cpp" />
|
||||
<ClCompile Include="..\..\source\as_typeinfo.cpp" />
|
||||
<ClCompile Include="..\..\source\as_variablescope.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\include\angelscript.h" />
|
||||
<ClInclude Include="..\..\source\as_array.h" />
|
||||
<ClInclude Include="..\..\source\as_atomic.h" />
|
||||
<ClInclude Include="..\..\source\as_builder.h" />
|
||||
<ClInclude Include="..\..\source\as_bytecode.h" />
|
||||
<ClInclude Include="..\..\source\as_callfunc.h" />
|
||||
<ClInclude Include="..\..\source\as_compiler.h" />
|
||||
<ClInclude Include="..\..\source\as_config.h" />
|
||||
<ClInclude Include="..\..\source\as_configgroup.h" />
|
||||
<ClInclude Include="..\..\source\as_context.h" />
|
||||
<ClInclude Include="..\..\source\as_criticalsection.h" />
|
||||
<ClInclude Include="..\..\source\as_datatype.h" />
|
||||
<ClInclude Include="..\..\source\as_debug.h" />
|
||||
<ClInclude Include="..\..\source\as_gc.h" />
|
||||
<ClInclude Include="..\..\source\as_generic.h" />
|
||||
<ClInclude Include="..\..\source\as_map.h" />
|
||||
<ClInclude Include="..\..\source\as_memory.h" />
|
||||
<ClInclude Include="..\..\source\as_module.h" />
|
||||
<ClInclude Include="..\..\source\as_objecttype.h" />
|
||||
<ClInclude Include="..\..\source\as_outputbuffer.h" />
|
||||
<ClInclude Include="..\..\source\as_parser.h" />
|
||||
<ClInclude Include="..\..\source\as_property.h" />
|
||||
<ClInclude Include="..\..\source\as_restore.h" />
|
||||
<ClInclude Include="..\..\source\as_scriptcode.h" />
|
||||
<ClInclude Include="..\..\source\as_scriptengine.h" />
|
||||
<ClInclude Include="..\..\source\as_scriptfunction.h" />
|
||||
<ClInclude Include="..\..\source\as_scriptnode.h" />
|
||||
<ClInclude Include="..\..\source\as_scriptobject.h" />
|
||||
<ClInclude Include="..\..\source\as_string.h" />
|
||||
<ClInclude Include="..\..\source\as_string_util.h" />
|
||||
<ClInclude Include="..\..\source\as_symboltable.h" />
|
||||
<ClInclude Include="..\..\source\as_texts.h" />
|
||||
<ClInclude Include="..\..\source\as_thread.h" />
|
||||
<ClInclude Include="..\..\source\as_tokendef.h" />
|
||||
<ClInclude Include="..\..\source\as_tokenizer.h" />
|
||||
<ClInclude Include="..\..\source\as_typeinfo.h" />
|
||||
<ClInclude Include="..\..\source\as_variablescope.h" />
|
||||
<ClInclude Include="..\..\source\as_namespace.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="..\..\source\as_callfunc_x64_msvc_asm.asm">
|
||||
<FileType>Document</FileType>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ml64.exe /c /nologo /Fo"$(Configuration)\as_callfunc_x64_msvc_asm.obj" /W3 /Zi /Ta "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\as_callfunc_x64_msvc_asm.obj;%(Outputs)</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ml64.exe /c /nologo /Fo"$(Configuration)\as_callfunc_x64_msvc_asm.obj" /W3 /Zi /Ta "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">ml64.exe /c /nologo /Fo"$(Configuration)\as_callfunc_x64_msvc_asm.obj" /W3 /Zi /Ta "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\as_callfunc_x64_msvc_asm.obj;%(Outputs)</Outputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">$(Configuration)\as_callfunc_x64_msvc_asm.obj;%(Outputs)</Outputs>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\source\as_callfunc_arm_gcc.S" />
|
||||
<CustomBuild Include="..\..\source\as_callfunc_arm_msvc.asm">
|
||||
<FileType>Document</FileType>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">armasm.exe -g -32 -o "$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj" "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">armasm.exe -g -32 -o "$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj" "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj;%(Outputs)</Outputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj;%(Outputs)</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">armasm.exe -32 -o "$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj" "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj;%(Outputs)</Outputs>
|
||||
</CustomBuild>
|
||||
<None Include="..\..\source\as_callfunc_arm_vita.S" />
|
||||
<None Include="..\..\source\as_callfunc_arm_xcode.S" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,268 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\source\as_atomic.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_builder.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_bytecode.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_mips.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_sh4.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_x86.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_compiler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_configgroup.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_context.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_datatype.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_gc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_generic.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_globalproperty.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_memory.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_module.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_objecttype.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_outputbuffer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_parser.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_restore.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_scriptcode.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_scriptengine.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_scriptfunction.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_scriptnode.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_scriptobject.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_string.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_string_util.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_thread.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_tokenizer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_typeinfo.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_variablescope.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_x64_msvc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_arm.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_ppc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_ppc_64.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_x64_gcc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_x64_mingw.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_xenon.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\include\angelscript.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_array.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_builder.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_bytecode.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_callfunc.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_compiler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_config.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_configgroup.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_context.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_datatype.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_debug.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_generic.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_map.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_module.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_objecttype.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_outputbuffer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_parser.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_property.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_restore.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_scriptcode.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_scriptengine.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_scriptfunction.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_scriptnode.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_scriptobject.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_string.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_string_util.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_texts.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_thread.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_tokendef.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_tokenizer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_typeinfo.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_variablescope.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_gc.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_criticalsection.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_symboltable.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_atomic.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_memory.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_namespace.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="..\..\source\as_callfunc_x64_msvc_asm.asm">
|
||||
<Filter>Source Files</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="..\..\source\as_callfunc_arm_msvc.asm">
|
||||
<Filter>Source Files</Filter>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\source\as_callfunc_arm_gcc.S">
|
||||
<Filter>Source Files</Filter>
|
||||
</None>
|
||||
<None Include="..\..\source\as_callfunc_arm_xcode.S">
|
||||
<Filter>Source Files</Filter>
|
||||
</None>
|
||||
<None Include="..\..\source\as_callfunc_arm_vita.S">
|
||||
<Filter>Source Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Express 2012 for Windows Desktop
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "angelscript", "angelscript.vcxproj", "{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Debug|x64.Build.0 = Debug|x64
|
||||
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Release|Win32.Build.0 = Release|Win32
|
||||
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Release|x64.ActiveCfg = Release|x64
|
||||
{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,554 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="clang_debug|ARM">
|
||||
<Configuration>clang_debug</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="clang_debug|ARM64">
|
||||
<Configuration>clang_debug</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="clang_debug|Win32">
|
||||
<Configuration>clang_debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="clang_debug|x64">
|
||||
<Configuration>clang_debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{39E6AF97-6BA3-4A72-8C61-BCEBF214EBFD}</ProjectGuid>
|
||||
<RootNamespace>angelscript</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140_clang_3_7</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140_clang_3_7</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140_clang_3_7</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140_Clang_3_7</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\lib\</OutDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'">..\..\lib\</OutDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\lib\</OutDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">..\..\lib\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'">$(Configuration)\</IntDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../lib\</OutDir>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">../../lib\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)64d</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">$(ProjectName)64d</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectName)d</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'">$(ProjectName)d</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">$(ProjectName)d_arm</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(ProjectName)d_arm64</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">$(ProjectName)d_arm</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM64'">$(ProjectName)d_arm64</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectName)64</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
<TargetName>$(ProjectName)_arm</TargetName>
|
||||
<OutDir>..\..\lib\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<TargetName>$(ProjectName)_arm64</TargetName>
|
||||
<OutDir>..\..\lib\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<OutDir>..\..\lib\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">
|
||||
<OutDir>..\..\lib\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM64'">
|
||||
<OutDir>..\..\lib\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<OutDir>..\..\lib\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(ProjectName)d.lib</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>AS_MAX_PORTABILITY;ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Enabled</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>EnableAllWarnings</WarningLevel>
|
||||
<DebugInformationFormat>FullDebug</DebugInformationFormat>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(ProjectName)d.lib</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(ProjectName)64d.lib</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;AS_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Enabled</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>EnableAllWarnings</WarningLevel>
|
||||
<DebugInformationFormat>FullDebug</DebugInformationFormat>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(ProjectName)64d.lib</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Full</Optimization>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
<ClCompile>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Full</Optimization>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<EnableEnhancedInstructionSet>
|
||||
</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<ClCompile>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Full</Optimization>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<EnableEnhancedInstructionSet>
|
||||
</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>ANGELSCRIPT_EXPORT;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>Full</Optimization>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<EnableEnhancedInstructionSet>
|
||||
</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<FloatingPointExceptions>
|
||||
</FloatingPointExceptions>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>..\..\lib\angelscript64.lib</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\source\as_atomic.cpp" />
|
||||
<ClCompile Include="..\..\source\as_builder.cpp" />
|
||||
<ClCompile Include="..\..\source\as_bytecode.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_arm.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_arm64.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_mips.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_ppc.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_ppc_64.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_sh4.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_x64_gcc.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_x64_mingw.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_x64_msvc.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_x86.cpp" />
|
||||
<ClCompile Include="..\..\source\as_callfunc_xenon.cpp" />
|
||||
<ClCompile Include="..\..\source\as_compiler.cpp" />
|
||||
<ClCompile Include="..\..\source\as_configgroup.cpp" />
|
||||
<ClCompile Include="..\..\source\as_context.cpp" />
|
||||
<ClCompile Include="..\..\source\as_datatype.cpp" />
|
||||
<ClCompile Include="..\..\source\as_gc.cpp" />
|
||||
<ClCompile Include="..\..\source\as_generic.cpp" />
|
||||
<ClCompile Include="..\..\source\as_globalproperty.cpp" />
|
||||
<ClCompile Include="..\..\source\as_memory.cpp" />
|
||||
<ClCompile Include="..\..\source\as_module.cpp" />
|
||||
<ClCompile Include="..\..\source\as_objecttype.cpp" />
|
||||
<ClCompile Include="..\..\source\as_outputbuffer.cpp" />
|
||||
<ClCompile Include="..\..\source\as_parser.cpp" />
|
||||
<ClCompile Include="..\..\source\as_restore.cpp" />
|
||||
<ClCompile Include="..\..\source\as_scriptcode.cpp" />
|
||||
<ClCompile Include="..\..\source\as_scriptengine.cpp" />
|
||||
<ClCompile Include="..\..\source\as_scriptfunction.cpp" />
|
||||
<ClCompile Include="..\..\source\as_scriptnode.cpp" />
|
||||
<ClCompile Include="..\..\source\as_scriptobject.cpp" />
|
||||
<ClCompile Include="..\..\source\as_string.cpp" />
|
||||
<ClCompile Include="..\..\source\as_string_util.cpp" />
|
||||
<ClCompile Include="..\..\source\as_thread.cpp" />
|
||||
<ClCompile Include="..\..\source\as_tokenizer.cpp" />
|
||||
<ClCompile Include="..\..\source\as_typeinfo.cpp" />
|
||||
<ClCompile Include="..\..\source\as_variablescope.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\include\angelscript.h" />
|
||||
<ClInclude Include="..\..\source\as_array.h" />
|
||||
<ClInclude Include="..\..\source\as_atomic.h" />
|
||||
<ClInclude Include="..\..\source\as_builder.h" />
|
||||
<ClInclude Include="..\..\source\as_bytecode.h" />
|
||||
<ClInclude Include="..\..\source\as_callfunc.h" />
|
||||
<ClInclude Include="..\..\source\as_compiler.h" />
|
||||
<ClInclude Include="..\..\source\as_config.h" />
|
||||
<ClInclude Include="..\..\source\as_configgroup.h" />
|
||||
<ClInclude Include="..\..\source\as_context.h" />
|
||||
<ClInclude Include="..\..\source\as_criticalsection.h" />
|
||||
<ClInclude Include="..\..\source\as_datatype.h" />
|
||||
<ClInclude Include="..\..\source\as_debug.h" />
|
||||
<ClInclude Include="..\..\source\as_gc.h" />
|
||||
<ClInclude Include="..\..\source\as_generic.h" />
|
||||
<ClInclude Include="..\..\source\as_map.h" />
|
||||
<ClInclude Include="..\..\source\as_memory.h" />
|
||||
<ClInclude Include="..\..\source\as_module.h" />
|
||||
<ClInclude Include="..\..\source\as_objecttype.h" />
|
||||
<ClInclude Include="..\..\source\as_outputbuffer.h" />
|
||||
<ClInclude Include="..\..\source\as_parser.h" />
|
||||
<ClInclude Include="..\..\source\as_property.h" />
|
||||
<ClInclude Include="..\..\source\as_restore.h" />
|
||||
<ClInclude Include="..\..\source\as_scriptcode.h" />
|
||||
<ClInclude Include="..\..\source\as_scriptengine.h" />
|
||||
<ClInclude Include="..\..\source\as_scriptfunction.h" />
|
||||
<ClInclude Include="..\..\source\as_scriptnode.h" />
|
||||
<ClInclude Include="..\..\source\as_scriptobject.h" />
|
||||
<ClInclude Include="..\..\source\as_string.h" />
|
||||
<ClInclude Include="..\..\source\as_string_util.h" />
|
||||
<ClInclude Include="..\..\source\as_symboltable.h" />
|
||||
<ClInclude Include="..\..\source\as_texts.h" />
|
||||
<ClInclude Include="..\..\source\as_thread.h" />
|
||||
<ClInclude Include="..\..\source\as_tokendef.h" />
|
||||
<ClInclude Include="..\..\source\as_tokenizer.h" />
|
||||
<ClInclude Include="..\..\source\as_typeinfo.h" />
|
||||
<ClInclude Include="..\..\source\as_variablescope.h" />
|
||||
<ClInclude Include="..\..\source\as_namespace.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="..\..\source\as_callfunc_x64_msvc_asm.asm">
|
||||
<FileType>Document</FileType>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ml64.exe /c /nologo /Fo"$(Configuration)\as_callfunc_x64_msvc_asm.obj" /W3 /Zi /Ta "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\as_callfunc_x64_msvc_asm.obj;%(Outputs)</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ml64.exe /c /nologo /Fo"$(Configuration)\as_callfunc_x64_msvc_asm.obj" /W3 /Zi /Ta "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">ml64.exe /c /nologo /Fo"$(Configuration)\as_callfunc_x64_msvc_asm.obj" /W3 /Zi /Ta "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\as_callfunc_x64_msvc_asm.obj;%(Outputs)</Outputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='clang_debug|x64'">$(Configuration)\as_callfunc_x64_msvc_asm.obj;%(Outputs)</Outputs>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="..\..\source\as_callfunc_arm64_msvc.asm">
|
||||
<FileType>Document</FileType>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM64'">armasm64.exe -g -o "$(Platform)\$(Configuration)\as_callfunc_arm64_msvc.obj" "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">armasm64.exe -g -o "$(Platform)\$(Configuration)\as_callfunc_arm64_msvc.obj" "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">armasm64.exe -o "$(Platform)\$(Configuration)\as_callfunc_arm64_msvc.obj" "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">$(Platform)\$(Configuration)\as_callfunc_arm64_msvc.obj;%(Outputs)</Outputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM64'">$(Platform)\$(Configuration)\as_callfunc_arm64_msvc.obj;%(Outputs)</Outputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">$(Platform)\$(Configuration)\as_callfunc_arm64_msvc.obj;%(Outputs)</Outputs>
|
||||
</CustomBuild>
|
||||
<None Include="..\..\source\as_callfunc_arm64_gcc.S" />
|
||||
<None Include="..\..\source\as_callfunc_arm_gcc.S" />
|
||||
<CustomBuild Include="..\..\source\as_callfunc_arm_msvc.asm">
|
||||
<FileType>Document</FileType>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">armasm.exe -g -32 -o "$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj" "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">armasm.exe -g -32 -o "$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj" "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj;%(Outputs)</Outputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='clang_debug|ARM'">$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj;%(Outputs)</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">armasm.exe -32 -o "$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj" "%(RootDir)%(Directory)\%(Filename)%(Extension)"</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">$(Platform)\$(Configuration)\as_callfunc_arm_msvc.obj;%(Outputs)</Outputs>
|
||||
</CustomBuild>
|
||||
<None Include="..\..\source\as_callfunc_arm_vita.S" />
|
||||
<None Include="..\..\source\as_callfunc_arm_xcode.S" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,277 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\source\as_atomic.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_builder.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_bytecode.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_mips.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_sh4.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_x86.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_compiler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_configgroup.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_context.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_datatype.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_gc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_generic.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_globalproperty.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_memory.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_module.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_objecttype.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_outputbuffer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_parser.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_restore.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_scriptcode.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_scriptengine.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_scriptfunction.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_scriptnode.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_scriptobject.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_string.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_string_util.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_thread.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_tokenizer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_typeinfo.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_variablescope.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_x64_msvc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_arm.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_ppc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_ppc_64.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_x64_gcc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_x64_mingw.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_xenon.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\as_callfunc_arm64.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\include\angelscript.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_array.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_builder.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_bytecode.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_callfunc.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_compiler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_config.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_configgroup.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_context.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_datatype.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_debug.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_generic.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_map.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_module.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_objecttype.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_outputbuffer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_parser.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_property.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_restore.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_scriptcode.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_scriptengine.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_scriptfunction.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_scriptnode.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_scriptobject.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_string.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_string_util.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_texts.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_thread.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_tokendef.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_tokenizer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_typeinfo.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_variablescope.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_gc.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_criticalsection.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_symboltable.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_atomic.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_memory.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\as_namespace.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="..\..\source\as_callfunc_x64_msvc_asm.asm">
|
||||
<Filter>Source Files</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="..\..\source\as_callfunc_arm_msvc.asm">
|
||||
<Filter>Source Files</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="..\..\source\as_callfunc_arm64_msvc.asm">
|
||||
<Filter>Source Files</Filter>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\source\as_callfunc_arm_gcc.S">
|
||||
<Filter>Source Files</Filter>
|
||||
</None>
|
||||
<None Include="..\..\source\as_callfunc_arm_xcode.S">
|
||||
<Filter>Source Files</Filter>
|
||||
</None>
|
||||
<None Include="..\..\source\as_callfunc_arm_vita.S">
|
||||
<Filter>Source Files</Filter>
|
||||
</None>
|
||||
<None Include="..\..\source\as_callfunc_arm64_gcc.S">
|
||||
<Filter>Source Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,136 @@
|
|||
TEMPLATE = lib
|
||||
|
||||
DEPENDPATH += ../../source ../../include
|
||||
INCLUDEPATH += ../../include
|
||||
|
||||
QMAKE_CXXFLAGS += -Wno-strict-aliasing
|
||||
|
||||
CONFIG -= debug debug_and_release release app_bundle qt dll
|
||||
|
||||
CONFIG += staticlib release
|
||||
|
||||
DEFINES += _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
DESTDIR = ../../lib
|
||||
|
||||
win32: LIBS += -lwinmm
|
||||
|
||||
HEADERS += ../../include/angelscript.h \
|
||||
../../source/as_array.h \
|
||||
../../source/as_atomic.h \
|
||||
../../source/as_builder.h \
|
||||
../../source/as_bytecode.h \
|
||||
../../source/as_callfunc.h \
|
||||
../../source/as_compiler.h \
|
||||
../../source/as_config.h \
|
||||
../../source/as_configgroup.h \
|
||||
../../source/as_context.h \
|
||||
../../source/as_criticalsection.h \
|
||||
../../source/as_datatype.h \
|
||||
../../source/as_debug.h \
|
||||
../../source/as_gc.h \
|
||||
../../source/as_generic.h \
|
||||
../../source/as_map.h \
|
||||
../../source/as_memory.h \
|
||||
../../source/as_module.h \
|
||||
../../source/as_objecttype.h \
|
||||
../../source/as_outputbuffer.h \
|
||||
../../source/as_parser.h \
|
||||
../../source/as_property.h \
|
||||
../../source/as_restore.h \
|
||||
../../source/as_scriptcode.h \
|
||||
../../source/as_scriptengine.h \
|
||||
../../source/as_scriptfunction.h \
|
||||
../../source/as_scriptnode.h \
|
||||
../../source/as_scriptobject.h \
|
||||
../../source/as_string.h \
|
||||
../../source/as_string_util.h \
|
||||
../../source/as_symboltable.h \
|
||||
../../source/as_texts.h \
|
||||
../../source/as_thread.h \
|
||||
../../source/as_tokendef.h \
|
||||
../../source/as_tokenizer.h \
|
||||
../../source/as_typeinfo.h \
|
||||
../../source/as_variablescope.h
|
||||
|
||||
SOURCES += ../../source/as_atomic.cpp \
|
||||
../../source/as_builder.cpp \
|
||||
../../source/as_bytecode.cpp \
|
||||
../../source/as_callfunc.cpp \
|
||||
../../source/as_callfunc_mips.cpp \
|
||||
../../source/as_callfunc_ppc.cpp \
|
||||
../../source/as_callfunc_ppc_64.cpp \
|
||||
../../source/as_callfunc_sh4.cpp \
|
||||
../../source/as_callfunc_x64_gcc.cpp \
|
||||
../../source/as_callfunc_x64_mingw.cpp \
|
||||
../../source/as_callfunc_x64_msvc.cpp \
|
||||
../../source/as_callfunc_x86.cpp \
|
||||
../../source/as_callfunc_xenon.cpp \
|
||||
../../source/as_compiler.cpp \
|
||||
../../source/as_configgroup.cpp \
|
||||
../../source/as_context.cpp \
|
||||
../../source/as_datatype.cpp \
|
||||
../../source/as_gc.cpp \
|
||||
../../source/as_generic.cpp \
|
||||
../../source/as_globalproperty.cpp \
|
||||
../../source/as_memory.cpp \
|
||||
../../source/as_module.cpp \
|
||||
../../source/as_objecttype.cpp \
|
||||
../../source/as_outputbuffer.cpp \
|
||||
../../source/as_parser.cpp \
|
||||
../../source/as_restore.cpp \
|
||||
../../source/as_scriptcode.cpp \
|
||||
../../source/as_scriptengine.cpp \
|
||||
../../source/as_scriptfunction.cpp \
|
||||
../../source/as_scriptnode.cpp \
|
||||
../../source/as_scriptobject.cpp \
|
||||
../../source/as_string.cpp \
|
||||
../../source/as_string_util.cpp \
|
||||
../../source/as_thread.cpp \
|
||||
../../source/as_tokenizer.cpp \
|
||||
../../source/as_typeinfo.cpp \
|
||||
../../source/as_variablescope.cpp
|
||||
|
||||
HEADERS += ../../../add_on/scriptany/scriptany.h \
|
||||
../../../add_on/scriptarray/scriptarray.h \
|
||||
../../../add_on/scriptdictionary/scriptdictionary.h \
|
||||
../../../add_on/scriptmath/scriptmath.h \
|
||||
../../../add_on/scripthandle/scripthandle.h \
|
||||
../../../add_on/scriptstdstring/scriptstdstring.h \
|
||||
../../../add_on/scriptbuilder/scriptbuilder.h
|
||||
|
||||
SOURCES += ../../../add_on/scriptany/scriptany.cpp \
|
||||
../../../add_on/scriptarray/scriptarray.cpp \
|
||||
../../../add_on/scriptdictionary/scriptdictionary.cpp \
|
||||
../../../add_on/scriptmath/scriptmath.cpp \
|
||||
../../../add_on/scripthandle/scripthandle.cpp \
|
||||
../../../add_on/scriptstdstring/scriptstdstring.cpp \
|
||||
../../../add_on/scriptstdstring/scriptstdstring_utils.cpp \
|
||||
../../../add_on/scriptbuilder/scriptbuilder.cpp
|
||||
|
||||
OBJECTS_DIR = tmp
|
||||
MOC_DIR = tmp
|
||||
UI_DIR = tmp
|
||||
RCC_DIR = tmp
|
||||
|
||||
!win32-g++:win32:contains(QMAKE_HOST.arch, x86_64):{
|
||||
asm_compiler.commands = ml64 /c
|
||||
asm_compiler.commands += /Fo ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
|
||||
asm_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
|
||||
asm_compiler.input = ASM_SOURCES
|
||||
asm_compiler.variable_out = OBJECTS
|
||||
asm_compiler.name = compiling[asm] ${QMAKE_FILE_IN}
|
||||
silent:asm_compiler.commands = @echo compiling[asm] ${QMAKE_FILE_IN} && $$asm_compiler.commands
|
||||
QMAKE_EXTRA_COMPILERS += asm_compiler
|
||||
|
||||
ASM_SOURCES += \
|
||||
$$PWD/angelscript/source/as_callfunc_x64_msvc_asm.asm
|
||||
|
||||
if(win32-msvc2008|win32-msvc2010):equals(TEMPLATE_PREFIX, "vc") {
|
||||
SOURCES += \
|
||||
$$PWD/angelscript/source/as_callfunc_x64_msvc_asm.asm
|
||||
}
|
||||
}
|
||||
|
||||
# QMAKE_CXXFLAGS_RELEASE += /MP
|
||||
|
|
@ -0,0 +1,768 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
6E91005C1823FC7000D59009 /* angelscript.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E91005B1823FC7000D59009 /* angelscript.h */; };
|
||||
6E91005D1823FC7000D59009 /* angelscript.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E91005B1823FC7000D59009 /* angelscript.h */; };
|
||||
6E91FF911823DA0D00D59009 /* as_array.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BCF51523FF2300EFAB3F /* as_array.h */; };
|
||||
6E91FF921823DA0D00D59009 /* as_atomic.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BCF71523FF2300EFAB3F /* as_atomic.h */; };
|
||||
6E91FF931823DA0D00D59009 /* as_builder.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BCF91523FF2300EFAB3F /* as_builder.h */; };
|
||||
6E91FF941823DA0D00D59009 /* as_bytecode.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BCFB1523FF2300EFAB3F /* as_bytecode.h */; };
|
||||
6E91FF951823DA0D00D59009 /* as_callfunc.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BCFD1523FF2300EFAB3F /* as_callfunc.h */; };
|
||||
6E91FF961823DA0D00D59009 /* as_compiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD0D1523FF2300EFAB3F /* as_compiler.h */; };
|
||||
6E91FF971823DA0D00D59009 /* as_config.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD0E1523FF2300EFAB3F /* as_config.h */; };
|
||||
6E91FF981823DA0D00D59009 /* as_configgroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD111523FF2300EFAB3F /* as_configgroup.h */; };
|
||||
6E91FF991823DA0D00D59009 /* as_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD131523FF2300EFAB3F /* as_context.h */; };
|
||||
6E91FF9A1823DA0D00D59009 /* as_criticalsection.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD141523FF2300EFAB3F /* as_criticalsection.h */; };
|
||||
6E91FF9B1823DA0D00D59009 /* as_datatype.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD161523FF2300EFAB3F /* as_datatype.h */; };
|
||||
6E91FF9C1823DA0D00D59009 /* as_debug.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD171523FF2300EFAB3F /* as_debug.h */; };
|
||||
6E91FF9D1823DA0D00D59009 /* as_gc.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD191523FF2300EFAB3F /* as_gc.h */; };
|
||||
6E91FF9E1823DA0D00D59009 /* as_generic.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD1B1523FF2300EFAB3F /* as_generic.h */; };
|
||||
6E91FF9F1823DA0D00D59009 /* as_map.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD1D1523FF2300EFAB3F /* as_map.h */; };
|
||||
6E91FFA01823DA0D00D59009 /* as_memory.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD1F1523FF2300EFAB3F /* as_memory.h */; };
|
||||
6E91FFA11823DA0D00D59009 /* as_module.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD211523FF2300EFAB3F /* as_module.h */; };
|
||||
6E91FFA21823DA0D00D59009 /* as_objecttype.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD231523FF2300EFAB3F /* as_objecttype.h */; };
|
||||
6E91FFA31823DA0D00D59009 /* as_outputbuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD251523FF2300EFAB3F /* as_outputbuffer.h */; };
|
||||
6E91FFA41823DA0D00D59009 /* as_parser.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD271523FF2300EFAB3F /* as_parser.h */; };
|
||||
6E91FFA51823DA0D00D59009 /* as_property.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD281523FF2300EFAB3F /* as_property.h */; };
|
||||
6E91FFA61823DA0D00D59009 /* as_restore.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD2A1523FF2300EFAB3F /* as_restore.h */; };
|
||||
6E91FFA71823DA0D00D59009 /* as_scriptcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD2C1523FF2300EFAB3F /* as_scriptcode.h */; };
|
||||
6E91FFA81823DA0D00D59009 /* as_scriptengine.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD2E1523FF2300EFAB3F /* as_scriptengine.h */; };
|
||||
6E91FFA91823DA0D00D59009 /* as_scriptfunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD301523FF2300EFAB3F /* as_scriptfunction.h */; };
|
||||
6E91FFAA1823DA0D00D59009 /* as_scriptnode.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD321523FF2300EFAB3F /* as_scriptnode.h */; };
|
||||
6E91FFAB1823DA0D00D59009 /* as_scriptobject.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD341523FF2300EFAB3F /* as_scriptobject.h */; };
|
||||
6E91FFAC1823DA0D00D59009 /* as_string.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD361523FF2300EFAB3F /* as_string.h */; };
|
||||
6E91FFAD1823DA0D00D59009 /* as_string_util.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD381523FF2300EFAB3F /* as_string_util.h */; };
|
||||
6E91FFAE1823DA0D00D59009 /* as_texts.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD391523FF2300EFAB3F /* as_texts.h */; };
|
||||
6E91FFAF1823DA0D00D59009 /* as_thread.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD3B1523FF2300EFAB3F /* as_thread.h */; };
|
||||
6E91FFB01823DA0D00D59009 /* as_tokendef.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD3C1523FF2300EFAB3F /* as_tokendef.h */; };
|
||||
6E91FFB11823DA0D00D59009 /* as_tokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD3E1523FF2300EFAB3F /* as_tokenizer.h */; };
|
||||
6E91FFB21823DA0D00D59009 /* as_typeinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD401523FF2300EFAB3F /* as_typeinfo.h */; };
|
||||
6E91FFB31823DA0D00D59009 /* as_variablescope.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD421523FF2300EFAB3F /* as_variablescope.h */; };
|
||||
6E91FFB51823DA0D00D59009 /* as_atomic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BCF61523FF2300EFAB3F /* as_atomic.cpp */; };
|
||||
6E91FFB61823DA0D00D59009 /* as_builder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BCF81523FF2300EFAB3F /* as_builder.cpp */; };
|
||||
6E91FFB71823DA0D00D59009 /* as_bytecode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BCFA1523FF2300EFAB3F /* as_bytecode.cpp */; };
|
||||
6E91FFB81823DA0D00D59009 /* as_callfunc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BCFC1523FF2300EFAB3F /* as_callfunc.cpp */; };
|
||||
6E91FFB91823DA0D00D59009 /* as_callfunc_arm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BCFE1523FF2300EFAB3F /* as_callfunc_arm.cpp */; };
|
||||
6E91FFBA1823DA0D00D59009 /* as_callfunc_arm_gcc.S in Sources */ = {isa = PBXBuildFile; fileRef = 7547BCFF1523FF2300EFAB3F /* as_callfunc_arm_gcc.S */; };
|
||||
6E91FFBC1823DA0D00D59009 /* as_callfunc_arm_xcode.S in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD011523FF2300EFAB3F /* as_callfunc_arm_xcode.S */; };
|
||||
6E91FFBD1823DA0D00D59009 /* as_callfunc_mips.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD021523FF2300EFAB3F /* as_callfunc_mips.cpp */; };
|
||||
6E91FFBE1823DA0D00D59009 /* as_callfunc_ppc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD031523FF2300EFAB3F /* as_callfunc_ppc.cpp */; };
|
||||
6E91FFBF1823DA0D00D59009 /* as_callfunc_ppc_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD041523FF2300EFAB3F /* as_callfunc_ppc_64.cpp */; };
|
||||
6E91FFC01823DA0D00D59009 /* as_callfunc_sh4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD051523FF2300EFAB3F /* as_callfunc_sh4.cpp */; };
|
||||
6E91FFC11823DA0D00D59009 /* as_callfunc_x64_gcc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD061523FF2300EFAB3F /* as_callfunc_x64_gcc.cpp */; };
|
||||
6E91FFC51823DA0D00D59009 /* as_callfunc_x86.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD0A1523FF2300EFAB3F /* as_callfunc_x86.cpp */; };
|
||||
6E91FFC71823DA0D00D59009 /* as_compiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD0C1523FF2300EFAB3F /* as_compiler.cpp */; };
|
||||
6E91FFC81823DA0D00D59009 /* as_configgroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD101523FF2300EFAB3F /* as_configgroup.cpp */; };
|
||||
6E91FFC91823DA0D00D59009 /* as_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD121523FF2300EFAB3F /* as_context.cpp */; };
|
||||
6E91FFCA1823DA0D00D59009 /* as_datatype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD151523FF2300EFAB3F /* as_datatype.cpp */; };
|
||||
6E91FFCB1823DA0D00D59009 /* as_gc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD181523FF2300EFAB3F /* as_gc.cpp */; };
|
||||
6E91FFCC1823DA0D00D59009 /* as_generic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD1A1523FF2300EFAB3F /* as_generic.cpp */; };
|
||||
6E91FFCD1823DA0D00D59009 /* as_globalproperty.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD1C1523FF2300EFAB3F /* as_globalproperty.cpp */; };
|
||||
6E91FFCE1823DA0D00D59009 /* as_memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD1E1523FF2300EFAB3F /* as_memory.cpp */; };
|
||||
6E91FFCF1823DA0D00D59009 /* as_module.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD201523FF2300EFAB3F /* as_module.cpp */; };
|
||||
6E91FFD01823DA0D00D59009 /* as_objecttype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD221523FF2300EFAB3F /* as_objecttype.cpp */; };
|
||||
6E91FFD11823DA0D00D59009 /* as_outputbuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD241523FF2300EFAB3F /* as_outputbuffer.cpp */; };
|
||||
6E91FFD21823DA0D00D59009 /* as_parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD261523FF2300EFAB3F /* as_parser.cpp */; };
|
||||
6E91FFD31823DA0D00D59009 /* as_restore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD291523FF2300EFAB3F /* as_restore.cpp */; };
|
||||
6E91FFD41823DA0D00D59009 /* as_scriptcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD2B1523FF2300EFAB3F /* as_scriptcode.cpp */; };
|
||||
6E91FFD51823DA0D00D59009 /* as_scriptengine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD2D1523FF2300EFAB3F /* as_scriptengine.cpp */; };
|
||||
6E91FFD61823DA0D00D59009 /* as_scriptfunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD2F1523FF2300EFAB3F /* as_scriptfunction.cpp */; };
|
||||
6E91FFD71823DA0D00D59009 /* as_scriptnode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD311523FF2300EFAB3F /* as_scriptnode.cpp */; };
|
||||
6E91FFD81823DA0D00D59009 /* as_scriptobject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD331523FF2300EFAB3F /* as_scriptobject.cpp */; };
|
||||
6E91FFD91823DA0D00D59009 /* as_string.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD351523FF2300EFAB3F /* as_string.cpp */; };
|
||||
6E91FFDA1823DA0D00D59009 /* as_string_util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD371523FF2300EFAB3F /* as_string_util.cpp */; };
|
||||
6E91FFDB1823DA0D00D59009 /* as_thread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD3A1523FF2300EFAB3F /* as_thread.cpp */; };
|
||||
6E91FFDC1823DA0D00D59009 /* as_tokenizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD3D1523FF2300EFAB3F /* as_tokenizer.cpp */; };
|
||||
6E91FFDD1823DA0D00D59009 /* as_typeinfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD3F1523FF2300EFAB3F /* as_typeinfo.cpp */; };
|
||||
6E91FFDE1823DA0D00D59009 /* as_variablescope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD411523FF2300EFAB3F /* as_variablescope.cpp */; };
|
||||
7547BD451523FF2300EFAB3F /* as_array.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BCF51523FF2300EFAB3F /* as_array.h */; };
|
||||
7547BD461523FF2300EFAB3F /* as_atomic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BCF61523FF2300EFAB3F /* as_atomic.cpp */; };
|
||||
7547BD471523FF2300EFAB3F /* as_atomic.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BCF71523FF2300EFAB3F /* as_atomic.h */; };
|
||||
7547BD481523FF2300EFAB3F /* as_builder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BCF81523FF2300EFAB3F /* as_builder.cpp */; };
|
||||
7547BD491523FF2300EFAB3F /* as_builder.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BCF91523FF2300EFAB3F /* as_builder.h */; };
|
||||
7547BD4A1523FF2300EFAB3F /* as_bytecode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BCFA1523FF2300EFAB3F /* as_bytecode.cpp */; };
|
||||
7547BD4B1523FF2300EFAB3F /* as_bytecode.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BCFB1523FF2300EFAB3F /* as_bytecode.h */; };
|
||||
7547BD4C1523FF2300EFAB3F /* as_callfunc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BCFC1523FF2300EFAB3F /* as_callfunc.cpp */; };
|
||||
7547BD4D1523FF2300EFAB3F /* as_callfunc.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BCFD1523FF2300EFAB3F /* as_callfunc.h */; };
|
||||
7547BD4E1523FF2300EFAB3F /* as_callfunc_arm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BCFE1523FF2300EFAB3F /* as_callfunc_arm.cpp */; };
|
||||
7547BD4F1523FF2300EFAB3F /* as_callfunc_arm_gcc.S in Sources */ = {isa = PBXBuildFile; fileRef = 7547BCFF1523FF2300EFAB3F /* as_callfunc_arm_gcc.S */; };
|
||||
7547BD521523FF2300EFAB3F /* as_callfunc_mips.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD021523FF2300EFAB3F /* as_callfunc_mips.cpp */; };
|
||||
7547BD531523FF2300EFAB3F /* as_callfunc_ppc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD031523FF2300EFAB3F /* as_callfunc_ppc.cpp */; };
|
||||
7547BD541523FF2300EFAB3F /* as_callfunc_ppc_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD041523FF2300EFAB3F /* as_callfunc_ppc_64.cpp */; };
|
||||
7547BD551523FF2300EFAB3F /* as_callfunc_sh4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD051523FF2300EFAB3F /* as_callfunc_sh4.cpp */; };
|
||||
7547BD561523FF2300EFAB3F /* as_callfunc_x64_gcc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD061523FF2300EFAB3F /* as_callfunc_x64_gcc.cpp */; };
|
||||
7547BD5A1523FF2300EFAB3F /* as_callfunc_x86.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD0A1523FF2300EFAB3F /* as_callfunc_x86.cpp */; };
|
||||
7547BD5C1523FF2300EFAB3F /* as_compiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD0C1523FF2300EFAB3F /* as_compiler.cpp */; };
|
||||
7547BD5D1523FF2300EFAB3F /* as_compiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD0D1523FF2300EFAB3F /* as_compiler.h */; };
|
||||
7547BD5E1523FF2300EFAB3F /* as_config.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD0E1523FF2300EFAB3F /* as_config.h */; };
|
||||
7547BD5F1523FF2300EFAB3F /* as_configgroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD101523FF2300EFAB3F /* as_configgroup.cpp */; };
|
||||
7547BD601523FF2300EFAB3F /* as_configgroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD111523FF2300EFAB3F /* as_configgroup.h */; };
|
||||
7547BD611523FF2300EFAB3F /* as_context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD121523FF2300EFAB3F /* as_context.cpp */; };
|
||||
7547BD621523FF2300EFAB3F /* as_context.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD131523FF2300EFAB3F /* as_context.h */; };
|
||||
7547BD631523FF2300EFAB3F /* as_criticalsection.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD141523FF2300EFAB3F /* as_criticalsection.h */; };
|
||||
7547BD641523FF2300EFAB3F /* as_datatype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD151523FF2300EFAB3F /* as_datatype.cpp */; };
|
||||
7547BD651523FF2300EFAB3F /* as_datatype.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD161523FF2300EFAB3F /* as_datatype.h */; };
|
||||
7547BD661523FF2300EFAB3F /* as_debug.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD171523FF2300EFAB3F /* as_debug.h */; };
|
||||
7547BD671523FF2300EFAB3F /* as_gc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD181523FF2300EFAB3F /* as_gc.cpp */; };
|
||||
7547BD681523FF2300EFAB3F /* as_gc.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD191523FF2300EFAB3F /* as_gc.h */; };
|
||||
7547BD691523FF2300EFAB3F /* as_generic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD1A1523FF2300EFAB3F /* as_generic.cpp */; };
|
||||
7547BD6A1523FF2300EFAB3F /* as_generic.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD1B1523FF2300EFAB3F /* as_generic.h */; };
|
||||
7547BD6B1523FF2300EFAB3F /* as_globalproperty.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD1C1523FF2300EFAB3F /* as_globalproperty.cpp */; };
|
||||
7547BD6C1523FF2300EFAB3F /* as_map.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD1D1523FF2300EFAB3F /* as_map.h */; };
|
||||
7547BD6D1523FF2300EFAB3F /* as_memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD1E1523FF2300EFAB3F /* as_memory.cpp */; };
|
||||
7547BD6E1523FF2300EFAB3F /* as_memory.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD1F1523FF2300EFAB3F /* as_memory.h */; };
|
||||
7547BD6F1523FF2300EFAB3F /* as_module.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD201523FF2300EFAB3F /* as_module.cpp */; };
|
||||
7547BD701523FF2300EFAB3F /* as_module.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD211523FF2300EFAB3F /* as_module.h */; };
|
||||
7547BD711523FF2300EFAB3F /* as_objecttype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD221523FF2300EFAB3F /* as_objecttype.cpp */; };
|
||||
7547BD721523FF2300EFAB3F /* as_objecttype.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD231523FF2300EFAB3F /* as_objecttype.h */; };
|
||||
7547BD731523FF2300EFAB3F /* as_outputbuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD241523FF2300EFAB3F /* as_outputbuffer.cpp */; };
|
||||
7547BD741523FF2300EFAB3F /* as_outputbuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD251523FF2300EFAB3F /* as_outputbuffer.h */; };
|
||||
7547BD751523FF2300EFAB3F /* as_parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD261523FF2300EFAB3F /* as_parser.cpp */; };
|
||||
7547BD761523FF2300EFAB3F /* as_parser.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD271523FF2300EFAB3F /* as_parser.h */; };
|
||||
7547BD771523FF2300EFAB3F /* as_property.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD281523FF2300EFAB3F /* as_property.h */; };
|
||||
7547BD781523FF2300EFAB3F /* as_restore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD291523FF2300EFAB3F /* as_restore.cpp */; };
|
||||
7547BD791523FF2300EFAB3F /* as_restore.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD2A1523FF2300EFAB3F /* as_restore.h */; };
|
||||
7547BD7A1523FF2300EFAB3F /* as_scriptcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD2B1523FF2300EFAB3F /* as_scriptcode.cpp */; };
|
||||
7547BD7B1523FF2300EFAB3F /* as_scriptcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD2C1523FF2300EFAB3F /* as_scriptcode.h */; };
|
||||
7547BD7C1523FF2300EFAB3F /* as_scriptengine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD2D1523FF2300EFAB3F /* as_scriptengine.cpp */; };
|
||||
7547BD7D1523FF2300EFAB3F /* as_scriptengine.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD2E1523FF2300EFAB3F /* as_scriptengine.h */; };
|
||||
7547BD7E1523FF2300EFAB3F /* as_scriptfunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD2F1523FF2300EFAB3F /* as_scriptfunction.cpp */; };
|
||||
7547BD7F1523FF2300EFAB3F /* as_scriptfunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD301523FF2300EFAB3F /* as_scriptfunction.h */; };
|
||||
7547BD801523FF2300EFAB3F /* as_scriptnode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD311523FF2300EFAB3F /* as_scriptnode.cpp */; };
|
||||
7547BD811523FF2300EFAB3F /* as_scriptnode.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD321523FF2300EFAB3F /* as_scriptnode.h */; };
|
||||
7547BD821523FF2300EFAB3F /* as_scriptobject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD331523FF2300EFAB3F /* as_scriptobject.cpp */; };
|
||||
7547BD831523FF2300EFAB3F /* as_scriptobject.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD341523FF2300EFAB3F /* as_scriptobject.h */; };
|
||||
7547BD841523FF2300EFAB3F /* as_string.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD351523FF2300EFAB3F /* as_string.cpp */; };
|
||||
7547BD851523FF2300EFAB3F /* as_string.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD361523FF2300EFAB3F /* as_string.h */; };
|
||||
7547BD861523FF2300EFAB3F /* as_string_util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD371523FF2300EFAB3F /* as_string_util.cpp */; };
|
||||
7547BD871523FF2300EFAB3F /* as_string_util.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD381523FF2300EFAB3F /* as_string_util.h */; };
|
||||
7547BD881523FF2300EFAB3F /* as_texts.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD391523FF2300EFAB3F /* as_texts.h */; };
|
||||
7547BD891523FF2300EFAB3F /* as_thread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD3A1523FF2300EFAB3F /* as_thread.cpp */; };
|
||||
7547BD8A1523FF2300EFAB3F /* as_thread.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD3B1523FF2300EFAB3F /* as_thread.h */; };
|
||||
7547BD8B1523FF2300EFAB3F /* as_tokendef.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD3C1523FF2300EFAB3F /* as_tokendef.h */; };
|
||||
7547BD8C1523FF2300EFAB3F /* as_tokenizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD3D1523FF2300EFAB3F /* as_tokenizer.cpp */; };
|
||||
7547BD8D1523FF2300EFAB3F /* as_tokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD3E1523FF2300EFAB3F /* as_tokenizer.h */; };
|
||||
7547BD8E1523FF2300EFAB3F /* as_typeinfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD3F1523FF2300EFAB3F /* as_typeinfo.cpp */; };
|
||||
7547BD8F1523FF2300EFAB3F /* as_typeinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD401523FF2300EFAB3F /* as_typeinfo.h */; };
|
||||
7547BD901523FF2300EFAB3F /* as_variablescope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7547BD411523FF2300EFAB3F /* as_variablescope.cpp */; };
|
||||
7547BD911523FF2300EFAB3F /* as_variablescope.h in Headers */ = {isa = PBXBuildFile; fileRef = 7547BD421523FF2300EFAB3F /* as_variablescope.h */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
6E91005B1823FC7000D59009 /* angelscript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = angelscript.h; sourceTree = "<group>"; };
|
||||
6E91FFE31823DA0D00D59009 /* libangelscript.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libangelscript.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
7547BCF51523FF2300EFAB3F /* as_array.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_array.h; sourceTree = "<group>"; };
|
||||
7547BCF61523FF2300EFAB3F /* as_atomic.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_atomic.cpp; sourceTree = "<group>"; };
|
||||
7547BCF71523FF2300EFAB3F /* as_atomic.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_atomic.h; sourceTree = "<group>"; };
|
||||
7547BCF81523FF2300EFAB3F /* as_builder.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_builder.cpp; sourceTree = "<group>"; };
|
||||
7547BCF91523FF2300EFAB3F /* as_builder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_builder.h; sourceTree = "<group>"; };
|
||||
7547BCFA1523FF2300EFAB3F /* as_bytecode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_bytecode.cpp; sourceTree = "<group>"; };
|
||||
7547BCFB1523FF2300EFAB3F /* as_bytecode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_bytecode.h; sourceTree = "<group>"; };
|
||||
7547BCFC1523FF2300EFAB3F /* as_callfunc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_callfunc.cpp; sourceTree = "<group>"; };
|
||||
7547BCFD1523FF2300EFAB3F /* as_callfunc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_callfunc.h; sourceTree = "<group>"; };
|
||||
7547BCFE1523FF2300EFAB3F /* as_callfunc_arm.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_callfunc_arm.cpp; sourceTree = "<group>"; };
|
||||
7547BCFF1523FF2300EFAB3F /* as_callfunc_arm_gcc.S */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.asm; path = as_callfunc_arm_gcc.S; sourceTree = "<group>"; };
|
||||
7547BD001523FF2300EFAB3F /* as_callfunc_arm_msvc.asm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.asm.asm; path = as_callfunc_arm_msvc.asm; sourceTree = "<group>"; };
|
||||
7547BD011523FF2300EFAB3F /* as_callfunc_arm_xcode.S */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.asm; path = as_callfunc_arm_xcode.S; sourceTree = "<group>"; };
|
||||
7547BD021523FF2300EFAB3F /* as_callfunc_mips.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_callfunc_mips.cpp; sourceTree = "<group>"; };
|
||||
7547BD031523FF2300EFAB3F /* as_callfunc_ppc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_callfunc_ppc.cpp; sourceTree = "<group>"; };
|
||||
7547BD041523FF2300EFAB3F /* as_callfunc_ppc_64.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_callfunc_ppc_64.cpp; sourceTree = "<group>"; };
|
||||
7547BD051523FF2300EFAB3F /* as_callfunc_sh4.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_callfunc_sh4.cpp; sourceTree = "<group>"; };
|
||||
7547BD061523FF2300EFAB3F /* as_callfunc_x64_gcc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_callfunc_x64_gcc.cpp; sourceTree = "<group>"; };
|
||||
7547BD071523FF2300EFAB3F /* as_callfunc_x64_mingw.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_callfunc_x64_mingw.cpp; sourceTree = "<group>"; };
|
||||
7547BD081523FF2300EFAB3F /* as_callfunc_x64_msvc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_callfunc_x64_msvc.cpp; sourceTree = "<group>"; };
|
||||
7547BD091523FF2300EFAB3F /* as_callfunc_x64_msvc_asm.asm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.asm.asm; path = as_callfunc_x64_msvc_asm.asm; sourceTree = "<group>"; };
|
||||
7547BD0A1523FF2300EFAB3F /* as_callfunc_x86.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_callfunc_x86.cpp; sourceTree = "<group>"; };
|
||||
7547BD0B1523FF2300EFAB3F /* as_callfunc_xenon.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_callfunc_xenon.cpp; sourceTree = "<group>"; };
|
||||
7547BD0C1523FF2300EFAB3F /* as_compiler.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_compiler.cpp; sourceTree = "<group>"; };
|
||||
7547BD0D1523FF2300EFAB3F /* as_compiler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_compiler.h; sourceTree = "<group>"; };
|
||||
7547BD0E1523FF2300EFAB3F /* as_config.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_config.h; sourceTree = "<group>"; };
|
||||
7547BD101523FF2300EFAB3F /* as_configgroup.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_configgroup.cpp; sourceTree = "<group>"; };
|
||||
7547BD111523FF2300EFAB3F /* as_configgroup.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_configgroup.h; sourceTree = "<group>"; };
|
||||
7547BD121523FF2300EFAB3F /* as_context.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_context.cpp; sourceTree = "<group>"; };
|
||||
7547BD131523FF2300EFAB3F /* as_context.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_context.h; sourceTree = "<group>"; };
|
||||
7547BD141523FF2300EFAB3F /* as_criticalsection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_criticalsection.h; sourceTree = "<group>"; };
|
||||
7547BD151523FF2300EFAB3F /* as_datatype.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_datatype.cpp; sourceTree = "<group>"; };
|
||||
7547BD161523FF2300EFAB3F /* as_datatype.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_datatype.h; sourceTree = "<group>"; };
|
||||
7547BD171523FF2300EFAB3F /* as_debug.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_debug.h; sourceTree = "<group>"; };
|
||||
7547BD181523FF2300EFAB3F /* as_gc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_gc.cpp; sourceTree = "<group>"; };
|
||||
7547BD191523FF2300EFAB3F /* as_gc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_gc.h; sourceTree = "<group>"; };
|
||||
7547BD1A1523FF2300EFAB3F /* as_generic.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_generic.cpp; sourceTree = "<group>"; };
|
||||
7547BD1B1523FF2300EFAB3F /* as_generic.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_generic.h; sourceTree = "<group>"; };
|
||||
7547BD1C1523FF2300EFAB3F /* as_globalproperty.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_globalproperty.cpp; sourceTree = "<group>"; };
|
||||
7547BD1D1523FF2300EFAB3F /* as_map.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_map.h; sourceTree = "<group>"; };
|
||||
7547BD1E1523FF2300EFAB3F /* as_memory.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_memory.cpp; sourceTree = "<group>"; };
|
||||
7547BD1F1523FF2300EFAB3F /* as_memory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_memory.h; sourceTree = "<group>"; };
|
||||
7547BD201523FF2300EFAB3F /* as_module.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_module.cpp; sourceTree = "<group>"; };
|
||||
7547BD211523FF2300EFAB3F /* as_module.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_module.h; sourceTree = "<group>"; };
|
||||
7547BD221523FF2300EFAB3F /* as_objecttype.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_objecttype.cpp; sourceTree = "<group>"; };
|
||||
7547BD231523FF2300EFAB3F /* as_objecttype.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_objecttype.h; sourceTree = "<group>"; };
|
||||
7547BD241523FF2300EFAB3F /* as_outputbuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_outputbuffer.cpp; sourceTree = "<group>"; };
|
||||
7547BD251523FF2300EFAB3F /* as_outputbuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_outputbuffer.h; sourceTree = "<group>"; };
|
||||
7547BD261523FF2300EFAB3F /* as_parser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_parser.cpp; sourceTree = "<group>"; };
|
||||
7547BD271523FF2300EFAB3F /* as_parser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_parser.h; sourceTree = "<group>"; };
|
||||
7547BD281523FF2300EFAB3F /* as_property.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_property.h; sourceTree = "<group>"; };
|
||||
7547BD291523FF2300EFAB3F /* as_restore.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_restore.cpp; sourceTree = "<group>"; };
|
||||
7547BD2A1523FF2300EFAB3F /* as_restore.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_restore.h; sourceTree = "<group>"; };
|
||||
7547BD2B1523FF2300EFAB3F /* as_scriptcode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_scriptcode.cpp; sourceTree = "<group>"; };
|
||||
7547BD2C1523FF2300EFAB3F /* as_scriptcode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_scriptcode.h; sourceTree = "<group>"; };
|
||||
7547BD2D1523FF2300EFAB3F /* as_scriptengine.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_scriptengine.cpp; sourceTree = "<group>"; };
|
||||
7547BD2E1523FF2300EFAB3F /* as_scriptengine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_scriptengine.h; sourceTree = "<group>"; };
|
||||
7547BD2F1523FF2300EFAB3F /* as_scriptfunction.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_scriptfunction.cpp; sourceTree = "<group>"; };
|
||||
7547BD301523FF2300EFAB3F /* as_scriptfunction.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_scriptfunction.h; sourceTree = "<group>"; };
|
||||
7547BD311523FF2300EFAB3F /* as_scriptnode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_scriptnode.cpp; sourceTree = "<group>"; };
|
||||
7547BD321523FF2300EFAB3F /* as_scriptnode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_scriptnode.h; sourceTree = "<group>"; };
|
||||
7547BD331523FF2300EFAB3F /* as_scriptobject.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_scriptobject.cpp; sourceTree = "<group>"; };
|
||||
7547BD341523FF2300EFAB3F /* as_scriptobject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_scriptobject.h; sourceTree = "<group>"; };
|
||||
7547BD351523FF2300EFAB3F /* as_string.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_string.cpp; sourceTree = "<group>"; };
|
||||
7547BD361523FF2300EFAB3F /* as_string.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_string.h; sourceTree = "<group>"; };
|
||||
7547BD371523FF2300EFAB3F /* as_string_util.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_string_util.cpp; sourceTree = "<group>"; };
|
||||
7547BD381523FF2300EFAB3F /* as_string_util.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_string_util.h; sourceTree = "<group>"; };
|
||||
7547BD391523FF2300EFAB3F /* as_texts.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_texts.h; sourceTree = "<group>"; };
|
||||
7547BD3A1523FF2300EFAB3F /* as_thread.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_thread.cpp; sourceTree = "<group>"; };
|
||||
7547BD3B1523FF2300EFAB3F /* as_thread.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_thread.h; sourceTree = "<group>"; };
|
||||
7547BD3C1523FF2300EFAB3F /* as_tokendef.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_tokendef.h; sourceTree = "<group>"; };
|
||||
7547BD3D1523FF2300EFAB3F /* as_tokenizer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_tokenizer.cpp; sourceTree = "<group>"; };
|
||||
7547BD3E1523FF2300EFAB3F /* as_tokenizer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_tokenizer.h; sourceTree = "<group>"; };
|
||||
7547BD3F1523FF2300EFAB3F /* as_typeinfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_typeinfo.cpp; sourceTree = "<group>"; };
|
||||
7547BD401523FF2300EFAB3F /* as_typeinfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_typeinfo.h; sourceTree = "<group>"; };
|
||||
7547BD411523FF2300EFAB3F /* as_variablescope.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = as_variablescope.cpp; sourceTree = "<group>"; };
|
||||
7547BD421523FF2300EFAB3F /* as_variablescope.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = as_variablescope.h; sourceTree = "<group>"; };
|
||||
D2AAC07E0554694100DB518D /* libangelscript.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libangelscript.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
6E91FFDF1823DA0D00D59009 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
D2AAC07C0554694100DB518D /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
034768DFFF38A50411DB9C8B /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D2AAC07E0554694100DB518D /* libangelscript.a */,
|
||||
6E91FFE31823DA0D00D59009 /* libangelscript.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0867D691FE84028FC02AAC07 /* angelscript */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6E91005A1823FC7000D59009 /* include */,
|
||||
7547BCF41523FF2300EFAB3F /* source */,
|
||||
08FB77AEFE84172EC02AAC07 /* Classes */,
|
||||
0867D69AFE84028FC02AAC07 /* Frameworks */,
|
||||
034768DFFF38A50411DB9C8B /* Products */,
|
||||
);
|
||||
name = angelscript;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0867D69AFE84028FC02AAC07 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
08FB77AEFE84172EC02AAC07 /* Classes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
);
|
||||
name = Classes;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6E91005A1823FC7000D59009 /* include */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6E91005B1823FC7000D59009 /* angelscript.h */,
|
||||
);
|
||||
name = include;
|
||||
path = ../../include;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7547BCF41523FF2300EFAB3F /* source */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7547BCF51523FF2300EFAB3F /* as_array.h */,
|
||||
7547BCF61523FF2300EFAB3F /* as_atomic.cpp */,
|
||||
7547BCF71523FF2300EFAB3F /* as_atomic.h */,
|
||||
7547BCF81523FF2300EFAB3F /* as_builder.cpp */,
|
||||
7547BCF91523FF2300EFAB3F /* as_builder.h */,
|
||||
7547BCFA1523FF2300EFAB3F /* as_bytecode.cpp */,
|
||||
7547BCFB1523FF2300EFAB3F /* as_bytecode.h */,
|
||||
7547BCFC1523FF2300EFAB3F /* as_callfunc.cpp */,
|
||||
7547BCFD1523FF2300EFAB3F /* as_callfunc.h */,
|
||||
7547BCFE1523FF2300EFAB3F /* as_callfunc_arm.cpp */,
|
||||
7547BCFF1523FF2300EFAB3F /* as_callfunc_arm_gcc.S */,
|
||||
7547BD001523FF2300EFAB3F /* as_callfunc_arm_msvc.asm */,
|
||||
7547BD011523FF2300EFAB3F /* as_callfunc_arm_xcode.S */,
|
||||
7547BD021523FF2300EFAB3F /* as_callfunc_mips.cpp */,
|
||||
7547BD031523FF2300EFAB3F /* as_callfunc_ppc.cpp */,
|
||||
7547BD041523FF2300EFAB3F /* as_callfunc_ppc_64.cpp */,
|
||||
7547BD051523FF2300EFAB3F /* as_callfunc_sh4.cpp */,
|
||||
7547BD061523FF2300EFAB3F /* as_callfunc_x64_gcc.cpp */,
|
||||
7547BD071523FF2300EFAB3F /* as_callfunc_x64_mingw.cpp */,
|
||||
7547BD081523FF2300EFAB3F /* as_callfunc_x64_msvc.cpp */,
|
||||
7547BD091523FF2300EFAB3F /* as_callfunc_x64_msvc_asm.asm */,
|
||||
7547BD0A1523FF2300EFAB3F /* as_callfunc_x86.cpp */,
|
||||
7547BD0B1523FF2300EFAB3F /* as_callfunc_xenon.cpp */,
|
||||
7547BD0C1523FF2300EFAB3F /* as_compiler.cpp */,
|
||||
7547BD0D1523FF2300EFAB3F /* as_compiler.h */,
|
||||
7547BD0E1523FF2300EFAB3F /* as_config.h */,
|
||||
7547BD101523FF2300EFAB3F /* as_configgroup.cpp */,
|
||||
7547BD111523FF2300EFAB3F /* as_configgroup.h */,
|
||||
7547BD121523FF2300EFAB3F /* as_context.cpp */,
|
||||
7547BD131523FF2300EFAB3F /* as_context.h */,
|
||||
7547BD141523FF2300EFAB3F /* as_criticalsection.h */,
|
||||
7547BD151523FF2300EFAB3F /* as_datatype.cpp */,
|
||||
7547BD161523FF2300EFAB3F /* as_datatype.h */,
|
||||
7547BD171523FF2300EFAB3F /* as_debug.h */,
|
||||
7547BD181523FF2300EFAB3F /* as_gc.cpp */,
|
||||
7547BD191523FF2300EFAB3F /* as_gc.h */,
|
||||
7547BD1A1523FF2300EFAB3F /* as_generic.cpp */,
|
||||
7547BD1B1523FF2300EFAB3F /* as_generic.h */,
|
||||
7547BD1C1523FF2300EFAB3F /* as_globalproperty.cpp */,
|
||||
7547BD1D1523FF2300EFAB3F /* as_map.h */,
|
||||
7547BD1E1523FF2300EFAB3F /* as_memory.cpp */,
|
||||
7547BD1F1523FF2300EFAB3F /* as_memory.h */,
|
||||
7547BD201523FF2300EFAB3F /* as_module.cpp */,
|
||||
7547BD211523FF2300EFAB3F /* as_module.h */,
|
||||
7547BD221523FF2300EFAB3F /* as_objecttype.cpp */,
|
||||
7547BD231523FF2300EFAB3F /* as_objecttype.h */,
|
||||
7547BD241523FF2300EFAB3F /* as_outputbuffer.cpp */,
|
||||
7547BD251523FF2300EFAB3F /* as_outputbuffer.h */,
|
||||
7547BD261523FF2300EFAB3F /* as_parser.cpp */,
|
||||
7547BD271523FF2300EFAB3F /* as_parser.h */,
|
||||
7547BD281523FF2300EFAB3F /* as_property.h */,
|
||||
7547BD291523FF2300EFAB3F /* as_restore.cpp */,
|
||||
7547BD2A1523FF2300EFAB3F /* as_restore.h */,
|
||||
7547BD2B1523FF2300EFAB3F /* as_scriptcode.cpp */,
|
||||
7547BD2C1523FF2300EFAB3F /* as_scriptcode.h */,
|
||||
7547BD2D1523FF2300EFAB3F /* as_scriptengine.cpp */,
|
||||
7547BD2E1523FF2300EFAB3F /* as_scriptengine.h */,
|
||||
7547BD2F1523FF2300EFAB3F /* as_scriptfunction.cpp */,
|
||||
7547BD301523FF2300EFAB3F /* as_scriptfunction.h */,
|
||||
7547BD311523FF2300EFAB3F /* as_scriptnode.cpp */,
|
||||
7547BD321523FF2300EFAB3F /* as_scriptnode.h */,
|
||||
7547BD331523FF2300EFAB3F /* as_scriptobject.cpp */,
|
||||
7547BD341523FF2300EFAB3F /* as_scriptobject.h */,
|
||||
7547BD351523FF2300EFAB3F /* as_string.cpp */,
|
||||
7547BD361523FF2300EFAB3F /* as_string.h */,
|
||||
7547BD371523FF2300EFAB3F /* as_string_util.cpp */,
|
||||
7547BD381523FF2300EFAB3F /* as_string_util.h */,
|
||||
7547BD391523FF2300EFAB3F /* as_texts.h */,
|
||||
7547BD3A1523FF2300EFAB3F /* as_thread.cpp */,
|
||||
7547BD3B1523FF2300EFAB3F /* as_thread.h */,
|
||||
7547BD3C1523FF2300EFAB3F /* as_tokendef.h */,
|
||||
7547BD3D1523FF2300EFAB3F /* as_tokenizer.cpp */,
|
||||
7547BD3E1523FF2300EFAB3F /* as_tokenizer.h */,
|
||||
7547BD3F1523FF2300EFAB3F /* as_typeinfo.cpp */,
|
||||
7547BD401523FF2300EFAB3F /* as_typeinfo.h */,
|
||||
7547BD411523FF2300EFAB3F /* as_variablescope.cpp */,
|
||||
7547BD421523FF2300EFAB3F /* as_variablescope.h */,
|
||||
);
|
||||
name = source;
|
||||
path = ../../source;
|
||||
sourceTree = SOURCE_ROOT;
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
6E91FF901823DA0D00D59009 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
6E91FF911823DA0D00D59009 /* as_array.h in Headers */,
|
||||
6E91FF921823DA0D00D59009 /* as_atomic.h in Headers */,
|
||||
6E91FF931823DA0D00D59009 /* as_builder.h in Headers */,
|
||||
6E91FF941823DA0D00D59009 /* as_bytecode.h in Headers */,
|
||||
6E91FF951823DA0D00D59009 /* as_callfunc.h in Headers */,
|
||||
6E91FF961823DA0D00D59009 /* as_compiler.h in Headers */,
|
||||
6E91FF971823DA0D00D59009 /* as_config.h in Headers */,
|
||||
6E91FF981823DA0D00D59009 /* as_configgroup.h in Headers */,
|
||||
6E91FF991823DA0D00D59009 /* as_context.h in Headers */,
|
||||
6E91FF9A1823DA0D00D59009 /* as_criticalsection.h in Headers */,
|
||||
6E91FF9B1823DA0D00D59009 /* as_datatype.h in Headers */,
|
||||
6E91FF9C1823DA0D00D59009 /* as_debug.h in Headers */,
|
||||
6E91FF9D1823DA0D00D59009 /* as_gc.h in Headers */,
|
||||
6E91FF9E1823DA0D00D59009 /* as_generic.h in Headers */,
|
||||
6E91FF9F1823DA0D00D59009 /* as_map.h in Headers */,
|
||||
6E91FFA01823DA0D00D59009 /* as_memory.h in Headers */,
|
||||
6E91FFA11823DA0D00D59009 /* as_module.h in Headers */,
|
||||
6E91FFA21823DA0D00D59009 /* as_objecttype.h in Headers */,
|
||||
6E91FFA31823DA0D00D59009 /* as_outputbuffer.h in Headers */,
|
||||
6E91FFA41823DA0D00D59009 /* as_parser.h in Headers */,
|
||||
6E91FFA51823DA0D00D59009 /* as_property.h in Headers */,
|
||||
6E91FFA61823DA0D00D59009 /* as_restore.h in Headers */,
|
||||
6E91FFA71823DA0D00D59009 /* as_scriptcode.h in Headers */,
|
||||
6E91FFA81823DA0D00D59009 /* as_scriptengine.h in Headers */,
|
||||
6E91FFA91823DA0D00D59009 /* as_scriptfunction.h in Headers */,
|
||||
6E91005D1823FC7000D59009 /* angelscript.h in Headers */,
|
||||
6E91FFAA1823DA0D00D59009 /* as_scriptnode.h in Headers */,
|
||||
6E91FFAB1823DA0D00D59009 /* as_scriptobject.h in Headers */,
|
||||
6E91FFAC1823DA0D00D59009 /* as_string.h in Headers */,
|
||||
6E91FFAD1823DA0D00D59009 /* as_string_util.h in Headers */,
|
||||
6E91FFAE1823DA0D00D59009 /* as_texts.h in Headers */,
|
||||
6E91FFAF1823DA0D00D59009 /* as_thread.h in Headers */,
|
||||
6E91FFB01823DA0D00D59009 /* as_tokendef.h in Headers */,
|
||||
6E91FFB11823DA0D00D59009 /* as_tokenizer.h in Headers */,
|
||||
6E91FFB21823DA0D00D59009 /* as_typeinfo.h in Headers */,
|
||||
6E91FFB31823DA0D00D59009 /* as_variablescope.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
D2AAC07A0554694100DB518D /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
7547BD451523FF2300EFAB3F /* as_array.h in Headers */,
|
||||
7547BD471523FF2300EFAB3F /* as_atomic.h in Headers */,
|
||||
7547BD491523FF2300EFAB3F /* as_builder.h in Headers */,
|
||||
7547BD4B1523FF2300EFAB3F /* as_bytecode.h in Headers */,
|
||||
7547BD4D1523FF2300EFAB3F /* as_callfunc.h in Headers */,
|
||||
7547BD5D1523FF2300EFAB3F /* as_compiler.h in Headers */,
|
||||
7547BD5E1523FF2300EFAB3F /* as_config.h in Headers */,
|
||||
7547BD601523FF2300EFAB3F /* as_configgroup.h in Headers */,
|
||||
7547BD621523FF2300EFAB3F /* as_context.h in Headers */,
|
||||
7547BD631523FF2300EFAB3F /* as_criticalsection.h in Headers */,
|
||||
7547BD651523FF2300EFAB3F /* as_datatype.h in Headers */,
|
||||
7547BD661523FF2300EFAB3F /* as_debug.h in Headers */,
|
||||
7547BD681523FF2300EFAB3F /* as_gc.h in Headers */,
|
||||
7547BD6A1523FF2300EFAB3F /* as_generic.h in Headers */,
|
||||
7547BD6C1523FF2300EFAB3F /* as_map.h in Headers */,
|
||||
7547BD6E1523FF2300EFAB3F /* as_memory.h in Headers */,
|
||||
7547BD701523FF2300EFAB3F /* as_module.h in Headers */,
|
||||
7547BD721523FF2300EFAB3F /* as_objecttype.h in Headers */,
|
||||
7547BD741523FF2300EFAB3F /* as_outputbuffer.h in Headers */,
|
||||
7547BD761523FF2300EFAB3F /* as_parser.h in Headers */,
|
||||
7547BD771523FF2300EFAB3F /* as_property.h in Headers */,
|
||||
7547BD791523FF2300EFAB3F /* as_restore.h in Headers */,
|
||||
7547BD7B1523FF2300EFAB3F /* as_scriptcode.h in Headers */,
|
||||
7547BD7D1523FF2300EFAB3F /* as_scriptengine.h in Headers */,
|
||||
7547BD7F1523FF2300EFAB3F /* as_scriptfunction.h in Headers */,
|
||||
6E91005C1823FC7000D59009 /* angelscript.h in Headers */,
|
||||
7547BD811523FF2300EFAB3F /* as_scriptnode.h in Headers */,
|
||||
7547BD831523FF2300EFAB3F /* as_scriptobject.h in Headers */,
|
||||
7547BD851523FF2300EFAB3F /* as_string.h in Headers */,
|
||||
7547BD871523FF2300EFAB3F /* as_string_util.h in Headers */,
|
||||
7547BD881523FF2300EFAB3F /* as_texts.h in Headers */,
|
||||
7547BD8A1523FF2300EFAB3F /* as_thread.h in Headers */,
|
||||
7547BD8B1523FF2300EFAB3F /* as_tokendef.h in Headers */,
|
||||
7547BD8D1523FF2300EFAB3F /* as_tokenizer.h in Headers */,
|
||||
7547BD8F1523FF2300EFAB3F /* as_typeinfo.h in Headers */,
|
||||
7547BD911523FF2300EFAB3F /* as_variablescope.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
6E91FF8F1823DA0D00D59009 /* angelscript iOS */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 6E91FFE01823DA0D00D59009 /* Build configuration list for PBXNativeTarget "angelscript iOS" */;
|
||||
buildPhases = (
|
||||
6E91FF901823DA0D00D59009 /* Headers */,
|
||||
6E91FFB41823DA0D00D59009 /* Sources */,
|
||||
6E91FFDF1823DA0D00D59009 /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = "angelscript iOS";
|
||||
productName = angelscript;
|
||||
productReference = 6E91FFE31823DA0D00D59009 /* libangelscript.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
D2AAC07D0554694100DB518D /* angelscript OSX */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "angelscript OSX" */;
|
||||
buildPhases = (
|
||||
D2AAC07A0554694100DB518D /* Headers */,
|
||||
D2AAC07B0554694100DB518D /* Sources */,
|
||||
D2AAC07C0554694100DB518D /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = "angelscript OSX";
|
||||
productName = angelscript;
|
||||
productReference = D2AAC07E0554694100DB518D /* libangelscript.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
0867D690FE84028FC02AAC07 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0510;
|
||||
};
|
||||
buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "angelscript" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 1;
|
||||
knownRegions = (
|
||||
English,
|
||||
Japanese,
|
||||
French,
|
||||
German,
|
||||
);
|
||||
mainGroup = 0867D691FE84028FC02AAC07 /* angelscript */;
|
||||
productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
D2AAC07D0554694100DB518D /* angelscript OSX */,
|
||||
6E91FF8F1823DA0D00D59009 /* angelscript iOS */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
6E91FFB41823DA0D00D59009 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
6E91FFB51823DA0D00D59009 /* as_atomic.cpp in Sources */,
|
||||
6E91FFB61823DA0D00D59009 /* as_builder.cpp in Sources */,
|
||||
6E91FFB71823DA0D00D59009 /* as_bytecode.cpp in Sources */,
|
||||
6E91FFB81823DA0D00D59009 /* as_callfunc.cpp in Sources */,
|
||||
6E91FFB91823DA0D00D59009 /* as_callfunc_arm.cpp in Sources */,
|
||||
6E91FFBA1823DA0D00D59009 /* as_callfunc_arm_gcc.S in Sources */,
|
||||
6E91FFBC1823DA0D00D59009 /* as_callfunc_arm_xcode.S in Sources */,
|
||||
6E91FFBD1823DA0D00D59009 /* as_callfunc_mips.cpp in Sources */,
|
||||
6E91FFBE1823DA0D00D59009 /* as_callfunc_ppc.cpp in Sources */,
|
||||
6E91FFBF1823DA0D00D59009 /* as_callfunc_ppc_64.cpp in Sources */,
|
||||
6E91FFC01823DA0D00D59009 /* as_callfunc_sh4.cpp in Sources */,
|
||||
6E91FFC11823DA0D00D59009 /* as_callfunc_x64_gcc.cpp in Sources */,
|
||||
6E91FFC51823DA0D00D59009 /* as_callfunc_x86.cpp in Sources */,
|
||||
6E91FFC71823DA0D00D59009 /* as_compiler.cpp in Sources */,
|
||||
6E91FFC81823DA0D00D59009 /* as_configgroup.cpp in Sources */,
|
||||
6E91FFC91823DA0D00D59009 /* as_context.cpp in Sources */,
|
||||
6E91FFCA1823DA0D00D59009 /* as_datatype.cpp in Sources */,
|
||||
6E91FFCB1823DA0D00D59009 /* as_gc.cpp in Sources */,
|
||||
6E91FFCC1823DA0D00D59009 /* as_generic.cpp in Sources */,
|
||||
6E91FFCD1823DA0D00D59009 /* as_globalproperty.cpp in Sources */,
|
||||
6E91FFCE1823DA0D00D59009 /* as_memory.cpp in Sources */,
|
||||
6E91FFCF1823DA0D00D59009 /* as_module.cpp in Sources */,
|
||||
6E91FFD01823DA0D00D59009 /* as_objecttype.cpp in Sources */,
|
||||
6E91FFD11823DA0D00D59009 /* as_outputbuffer.cpp in Sources */,
|
||||
6E91FFD21823DA0D00D59009 /* as_parser.cpp in Sources */,
|
||||
6E91FFD31823DA0D00D59009 /* as_restore.cpp in Sources */,
|
||||
6E91FFD41823DA0D00D59009 /* as_scriptcode.cpp in Sources */,
|
||||
6E91FFD51823DA0D00D59009 /* as_scriptengine.cpp in Sources */,
|
||||
6E91FFD61823DA0D00D59009 /* as_scriptfunction.cpp in Sources */,
|
||||
6E91FFD71823DA0D00D59009 /* as_scriptnode.cpp in Sources */,
|
||||
6E91FFD81823DA0D00D59009 /* as_scriptobject.cpp in Sources */,
|
||||
6E91FFD91823DA0D00D59009 /* as_string.cpp in Sources */,
|
||||
6E91FFDA1823DA0D00D59009 /* as_string_util.cpp in Sources */,
|
||||
6E91FFDB1823DA0D00D59009 /* as_thread.cpp in Sources */,
|
||||
6E91FFDC1823DA0D00D59009 /* as_tokenizer.cpp in Sources */,
|
||||
6E91FFDD1823DA0D00D59009 /* as_typeinfo.cpp in Sources */,
|
||||
6E91FFDE1823DA0D00D59009 /* as_variablescope.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
D2AAC07B0554694100DB518D /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
7547BD461523FF2300EFAB3F /* as_atomic.cpp in Sources */,
|
||||
7547BD481523FF2300EFAB3F /* as_builder.cpp in Sources */,
|
||||
7547BD4A1523FF2300EFAB3F /* as_bytecode.cpp in Sources */,
|
||||
7547BD4C1523FF2300EFAB3F /* as_callfunc.cpp in Sources */,
|
||||
7547BD4E1523FF2300EFAB3F /* as_callfunc_arm.cpp in Sources */,
|
||||
7547BD4F1523FF2300EFAB3F /* as_callfunc_arm_gcc.S in Sources */,
|
||||
7547BD521523FF2300EFAB3F /* as_callfunc_mips.cpp in Sources */,
|
||||
7547BD531523FF2300EFAB3F /* as_callfunc_ppc.cpp in Sources */,
|
||||
7547BD541523FF2300EFAB3F /* as_callfunc_ppc_64.cpp in Sources */,
|
||||
7547BD551523FF2300EFAB3F /* as_callfunc_sh4.cpp in Sources */,
|
||||
7547BD561523FF2300EFAB3F /* as_callfunc_x64_gcc.cpp in Sources */,
|
||||
7547BD5A1523FF2300EFAB3F /* as_callfunc_x86.cpp in Sources */,
|
||||
7547BD5C1523FF2300EFAB3F /* as_compiler.cpp in Sources */,
|
||||
7547BD5F1523FF2300EFAB3F /* as_configgroup.cpp in Sources */,
|
||||
7547BD611523FF2300EFAB3F /* as_context.cpp in Sources */,
|
||||
7547BD641523FF2300EFAB3F /* as_datatype.cpp in Sources */,
|
||||
7547BD671523FF2300EFAB3F /* as_gc.cpp in Sources */,
|
||||
7547BD691523FF2300EFAB3F /* as_generic.cpp in Sources */,
|
||||
7547BD6B1523FF2300EFAB3F /* as_globalproperty.cpp in Sources */,
|
||||
7547BD6D1523FF2300EFAB3F /* as_memory.cpp in Sources */,
|
||||
7547BD6F1523FF2300EFAB3F /* as_module.cpp in Sources */,
|
||||
7547BD711523FF2300EFAB3F /* as_objecttype.cpp in Sources */,
|
||||
7547BD731523FF2300EFAB3F /* as_outputbuffer.cpp in Sources */,
|
||||
7547BD751523FF2300EFAB3F /* as_parser.cpp in Sources */,
|
||||
7547BD781523FF2300EFAB3F /* as_restore.cpp in Sources */,
|
||||
7547BD7A1523FF2300EFAB3F /* as_scriptcode.cpp in Sources */,
|
||||
7547BD7C1523FF2300EFAB3F /* as_scriptengine.cpp in Sources */,
|
||||
7547BD7E1523FF2300EFAB3F /* as_scriptfunction.cpp in Sources */,
|
||||
7547BD801523FF2300EFAB3F /* as_scriptnode.cpp in Sources */,
|
||||
7547BD821523FF2300EFAB3F /* as_scriptobject.cpp in Sources */,
|
||||
7547BD841523FF2300EFAB3F /* as_string.cpp in Sources */,
|
||||
7547BD861523FF2300EFAB3F /* as_string_util.cpp in Sources */,
|
||||
7547BD891523FF2300EFAB3F /* as_thread.cpp in Sources */,
|
||||
7547BD8C1523FF2300EFAB3F /* as_tokenizer.cpp in Sources */,
|
||||
7547BD8E1523FF2300EFAB3F /* as_typeinfo.cpp in Sources */,
|
||||
7547BD901523FF2300EFAB3F /* as_variablescope.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
1DEB921F08733DC00010E9CD /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "compiler-default";
|
||||
CLANG_CXX_LIBRARY = "compiler-default";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DSTROOT = /tmp/angelscript.dst;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = YES;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = angelscript_Prefix.pch;
|
||||
INSTALL_PATH = /usr/local/lib/OSX/x86_64/Debug;
|
||||
PRODUCT_NAME = angelscript;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
1DEB922008733DC00010E9CD /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "compiler-default";
|
||||
CLANG_CXX_LIBRARY = "compiler-default";
|
||||
DSTROOT = /tmp/angelscript.dst;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = angelscript_Prefix.pch;
|
||||
INSTALL_PATH = /usr/local/lib/OSX/x86_64/Release;
|
||||
PRODUCT_NAME = angelscript;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
1DEB922308733DC00010E9CD /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++98";
|
||||
CLANG_CXX_LIBRARY = "libstdc++";
|
||||
GCC_C_LANGUAGE_STANDARD = c99;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PREBINDING = NO;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
1DEB922408733DC00010E9CD /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++98";
|
||||
CLANG_CXX_LIBRARY = "libstdc++";
|
||||
GCC_C_LANGUAGE_STANDARD = c99;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PREBINDING = NO;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
6E91FFE11823DA0D00D59009 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DSTROOT = /tmp/angelscript.dst;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = YES;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = angelscript_Prefix.pch;
|
||||
INSTALL_PATH = /usr/local/lib/iOS/arm64/Debug;
|
||||
"INSTALL_PATH[sdk=iphonesimulator*]" = /usr/local/lib/iOS/x86_64/Debug;
|
||||
PRODUCT_NAME = angelscript;
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
6E91FFE21823DA0D00D59009 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
DSTROOT = /tmp/angelscript.dst;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = angelscript_Prefix.pch;
|
||||
INSTALL_PATH = /usr/local/lib/iOS/arm64/Release;
|
||||
"INSTALL_PATH[sdk=iphonesimulator*]" = /usr/local/lib/iOS/x86_64/Release;
|
||||
PRODUCT_NAME = angelscript;
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "angelscript OSX" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
1DEB921F08733DC00010E9CD /* Debug */,
|
||||
1DEB922008733DC00010E9CD /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "angelscript" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
1DEB922308733DC00010E9CD /* Debug */,
|
||||
1DEB922408733DC00010E9CD /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
6E91FFE01823DA0D00D59009 /* Build configuration list for PBXNativeTarget "angelscript iOS" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
6E91FFE11823DA0D00D59009 /* Debug */,
|
||||
6E91FFE21823DA0D00D59009 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 0867D690FE84028FC02AAC07 /* Project object */;
|
||||
}
|
7
angelscript/projects/xcode/angelscript.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
angelscript/projects/xcode/angelscript.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:angelscript.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildLocationStyle</key>
|
||||
<string>CustomLocation</string>
|
||||
<key>CustomBuildIntermediatesPath</key>
|
||||
<string>tmp</string>
|
||||
<key>CustomBuildLocationType</key>
|
||||
<string>RelativeToWorkspace</string>
|
||||
<key>CustomBuildProductsPath</key>
|
||||
<string>../../lib/</string>
|
||||
<key>DerivedDataLocationStyle</key>
|
||||
<string>Default</string>
|
||||
<key>HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges</key>
|
||||
<true/>
|
||||
<key>IssueFilterStyle</key>
|
||||
<string>ShowActiveSchemeOnly</string>
|
||||
<key>LiveSourceIssuesEnabled</key>
|
||||
<true/>
|
||||
<key>SnapshotAutomaticallyBeforeSignificantChanges</key>
|
||||
<true/>
|
||||
<key>SnapshotLocationStyle</key>
|
||||
<string>Default</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,59 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0510"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "D2AAC07D0554694100DB518D"
|
||||
BuildableName = "libangelscript.a"
|
||||
BlueprintName = "angelscript OSX"
|
||||
ReferencedContainer = "container:angelscript.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES">
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
|
@ -0,0 +1,59 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0510"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "6E91FF8F1823DA0D00D59009"
|
||||
BuildableName = "libangelscript.a"
|
||||
BlueprintName = "angelscript iOS"
|
||||
ReferencedContainer = "container:angelscript.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES">
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>SchemeUserState</key>
|
||||
<dict>
|
||||
<key>angelscript OSX.xcscheme</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>angelscript iOS.xcscheme</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
<key>6E91FF8F1823DA0D00D59009</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>D2AAC07D0554694100DB518D</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,7 @@
|
|||
//
|
||||
// Prefix header for all source files of the 'CocoaTouchStaticLibrary' target in the 'CocoaTouchStaticLibrary' project.
|
||||
//
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <Foundation/Foundation.h>
|
||||
#endif
|
|
@ -0,0 +1,528 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2015 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
The original version of this library can be located at:
|
||||
http://www.angelcode.com/angelscript/
|
||||
|
||||
Andreas Jonsson
|
||||
andreas@angelcode.com
|
||||
*/
|
||||
|
||||
#ifndef AS_ARRAY_H
|
||||
#define AS_ARRAY_H
|
||||
|
||||
#if !defined(AS_NO_MEMORY_H)
|
||||
#include <memory.h>
|
||||
#endif
|
||||
#include <string.h> // some compilers declare memcpy() here
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4345) // warning about a change in how the code is handled in this version
|
||||
#endif
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
template <class T> class asCArray
|
||||
{
|
||||
public:
|
||||
asCArray();
|
||||
asCArray(const asCArray<T> &);
|
||||
asCArray(asUINT reserve);
|
||||
~asCArray();
|
||||
|
||||
void Allocate(asUINT numElements, bool keepData);
|
||||
void AllocateNoConstruct(asUINT numElements, bool keepData);
|
||||
asUINT GetCapacity() const;
|
||||
|
||||
void PushLast(const T &element);
|
||||
T PopLast();
|
||||
|
||||
bool SetLength(asUINT numElements);
|
||||
bool SetLengthNoConstruct(asUINT numElements);
|
||||
asUINT GetLength() const;
|
||||
|
||||
void Copy(const T*, asUINT count);
|
||||
asCArray<T> &operator =(const asCArray<T> &);
|
||||
void SwapWith(asCArray<T> &other);
|
||||
|
||||
const T &operator [](asUINT index) const;
|
||||
T &operator [](asUINT index);
|
||||
T *AddressOf();
|
||||
const T *AddressOf() const;
|
||||
|
||||
bool Concatenate(const asCArray<T> &);
|
||||
void Concatenate(T*, unsigned int count);
|
||||
|
||||
bool Exists(const T &element) const;
|
||||
int IndexOf(const T &element) const;
|
||||
void RemoveIndex(asUINT index); // Removes the entry without reordering the array
|
||||
void RemoveValue(const T &element); // Removes the value without reordering the array
|
||||
void RemoveIndexUnordered(asUINT index); // Removes the entry without keeping the order
|
||||
|
||||
bool operator==(const asCArray<T> &) const;
|
||||
bool operator!=(const asCArray<T> &) const;
|
||||
|
||||
protected:
|
||||
T *array;
|
||||
asUINT length; // 32bits is enough for all uses of this array
|
||||
asUINT maxLength;
|
||||
char buf[2*4*AS_PTR_SIZE]; // Avoid dynamically allocated memory for tiny arrays
|
||||
};
|
||||
|
||||
// Implementation
|
||||
|
||||
template <class T>
|
||||
T *asCArray<T>::AddressOf()
|
||||
{
|
||||
return array;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const T *asCArray<T>::AddressOf() const
|
||||
{
|
||||
return array;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
asCArray<T>::asCArray(void)
|
||||
{
|
||||
array = 0;
|
||||
length = 0;
|
||||
maxLength = 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
asCArray<T>::asCArray(const asCArray<T> ©)
|
||||
{
|
||||
array = 0;
|
||||
length = 0;
|
||||
maxLength = 0;
|
||||
|
||||
*this = copy;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
asCArray<T>::asCArray(asUINT reserve)
|
||||
{
|
||||
array = 0;
|
||||
length = 0;
|
||||
maxLength = 0;
|
||||
|
||||
Allocate(reserve, false);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
asCArray<T>::~asCArray(void)
|
||||
{
|
||||
// Allocating a zero length array will free all memory
|
||||
Allocate(0,0);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
asUINT asCArray<T>::GetLength() const
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const T &asCArray<T>::operator [](asUINT index) const
|
||||
{
|
||||
asASSERT(index < length);
|
||||
|
||||
return array[index];
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T &asCArray<T>::operator [](asUINT index)
|
||||
{
|
||||
asASSERT(index < length);
|
||||
|
||||
return array[index];
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void asCArray<T>::PushLast(const T &element)
|
||||
{
|
||||
if( length == maxLength )
|
||||
{
|
||||
if( maxLength == 0 )
|
||||
Allocate(1, false);
|
||||
else
|
||||
Allocate(2*maxLength, true);
|
||||
|
||||
if( length == maxLength )
|
||||
{
|
||||
// Out of memory. Return without doing anything
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
array[length++] = element;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T asCArray<T>::PopLast()
|
||||
{
|
||||
asASSERT(length > 0);
|
||||
|
||||
return array[--length];
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void asCArray<T>::Allocate(asUINT numElements, bool keepData)
|
||||
{
|
||||
// We have 4 situations
|
||||
// 1. The previous array is 8 bytes or smaller and the new array is also 8 bytes or smaller
|
||||
// 2. The previous array is 8 bytes or smaller and the new array is larger than 8 bytes
|
||||
// 3. The previous array is larger than 8 bytes and the new array is 8 bytes or smaller
|
||||
// 4. The previous array is larger than 8 bytes and the new array is also larger than 8 bytes
|
||||
|
||||
T *tmp = 0;
|
||||
if( numElements )
|
||||
{
|
||||
if( sizeof(T)*numElements <= sizeof(buf) )
|
||||
// Use the internal buffer
|
||||
tmp = reinterpret_cast<T*>(buf);
|
||||
else
|
||||
{
|
||||
// Allocate the array and construct each of the elements
|
||||
tmp = asNEWARRAY(T,numElements);
|
||||
if( tmp == 0 )
|
||||
{
|
||||
// Out of memory. Return without doing anything
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if( array == tmp )
|
||||
{
|
||||
// Construct only the newly allocated elements
|
||||
for( asUINT n = length; n < numElements; n++ )
|
||||
new (&tmp[n]) T();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Construct all elements
|
||||
for( asUINT n = 0; n < numElements; n++ )
|
||||
new (&tmp[n]) T();
|
||||
}
|
||||
}
|
||||
|
||||
if( array )
|
||||
{
|
||||
asUINT oldLength = length;
|
||||
|
||||
if( array == tmp )
|
||||
{
|
||||
if( keepData )
|
||||
{
|
||||
if( length > numElements )
|
||||
length = numElements;
|
||||
}
|
||||
else
|
||||
length = 0;
|
||||
|
||||
// Call the destructor for elements that are no longer used
|
||||
for( asUINT n = length; n < oldLength; n++ )
|
||||
array[n].~T();
|
||||
}
|
||||
else
|
||||
{
|
||||
if( keepData )
|
||||
{
|
||||
if( length > numElements )
|
||||
length = numElements;
|
||||
|
||||
for( asUINT n = 0; n < length; n++ )
|
||||
tmp[n] = array[n];
|
||||
}
|
||||
else
|
||||
length = 0;
|
||||
|
||||
// Call the destructor for all elements
|
||||
for( asUINT n = 0; n < oldLength; n++ )
|
||||
array[n].~T();
|
||||
|
||||
if( array != reinterpret_cast<T*>(buf) )
|
||||
asDELETEARRAY(array);
|
||||
}
|
||||
}
|
||||
|
||||
array = tmp;
|
||||
maxLength = numElements;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void asCArray<T>::AllocateNoConstruct(asUINT numElements, bool keepData)
|
||||
{
|
||||
// We have 4 situations
|
||||
// 1. The previous array is 8 bytes or smaller and the new array is also 8 bytes or smaller
|
||||
// 2. The previous array is 8 bytes or smaller and the new array is larger than 8 bytes
|
||||
// 3. The previous array is larger than 8 bytes and the new array is 8 bytes or smaller
|
||||
// 4. The previous array is larger than 8 bytes and the new array is also larger than 8 bytes
|
||||
|
||||
T *tmp = 0;
|
||||
if( numElements )
|
||||
{
|
||||
if( sizeof(T)*numElements <= sizeof(buf) )
|
||||
// Use the internal buffer
|
||||
tmp = reinterpret_cast<T*>(buf);
|
||||
else
|
||||
{
|
||||
// Allocate the array and construct each of the elements
|
||||
tmp = asNEWARRAY(T,numElements);
|
||||
if( tmp == 0 )
|
||||
{
|
||||
// Out of memory. Return without doing anything
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( array )
|
||||
{
|
||||
if( array == tmp )
|
||||
{
|
||||
if( keepData )
|
||||
{
|
||||
if( length > numElements )
|
||||
length = numElements;
|
||||
}
|
||||
else
|
||||
length = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( keepData )
|
||||
{
|
||||
if( length > numElements )
|
||||
length = numElements;
|
||||
|
||||
memcpy(tmp, array, sizeof(T)*length);
|
||||
}
|
||||
else
|
||||
length = 0;
|
||||
|
||||
if( array != reinterpret_cast<T*>(buf) )
|
||||
asDELETEARRAY(array);
|
||||
}
|
||||
}
|
||||
|
||||
array = tmp;
|
||||
maxLength = numElements;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
asUINT asCArray<T>::GetCapacity() const
|
||||
{
|
||||
return maxLength;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool asCArray<T>::SetLength(asUINT numElements)
|
||||
{
|
||||
if( numElements > maxLength )
|
||||
{
|
||||
Allocate(numElements, true);
|
||||
if( numElements > maxLength )
|
||||
{
|
||||
// Out of memory. Return without doing anything
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
length = numElements;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool asCArray<T>::SetLengthNoConstruct(asUINT numElements)
|
||||
{
|
||||
if( numElements > maxLength )
|
||||
{
|
||||
AllocateNoConstruct(numElements, true);
|
||||
if( numElements > maxLength )
|
||||
{
|
||||
// Out of memory. Return without doing anything
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
length = numElements;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void asCArray<T>::Copy(const T *data, asUINT count)
|
||||
{
|
||||
if( maxLength < count )
|
||||
{
|
||||
Allocate(count, false);
|
||||
if( maxLength < count )
|
||||
{
|
||||
// Out of memory. Return without doing anything
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for( asUINT n = 0; n < count; n++ )
|
||||
array[n] = data[n];
|
||||
|
||||
length = count;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
asCArray<T> &asCArray<T>::operator =(const asCArray<T> ©)
|
||||
{
|
||||
Copy(copy.array, copy.length);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void asCArray<T>::SwapWith(asCArray<T> &other)
|
||||
{
|
||||
T *tmpArray = array;
|
||||
asUINT tmpLength = length;
|
||||
asUINT tmpMaxLength = maxLength;
|
||||
char tmpBuf[sizeof(buf)];
|
||||
memcpy(tmpBuf, buf, sizeof(buf));
|
||||
|
||||
array = other.array;
|
||||
length = other.length;
|
||||
maxLength = other.maxLength;
|
||||
memcpy(buf, other.buf, sizeof(buf));
|
||||
|
||||
other.array = tmpArray;
|
||||
other.length = tmpLength;
|
||||
other.maxLength = tmpMaxLength;
|
||||
memcpy(other.buf, tmpBuf, sizeof(buf));
|
||||
|
||||
// If the data is in the internal buffer, then the array pointer must refer to it
|
||||
if( array == reinterpret_cast<T*>(other.buf) )
|
||||
array = reinterpret_cast<T*>(buf);
|
||||
if( other.array == reinterpret_cast<T*>(buf) )
|
||||
other.array = reinterpret_cast<T*>(other.buf);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool asCArray<T>::operator ==(const asCArray<T> &other) const
|
||||
{
|
||||
if( length != other.length ) return false;
|
||||
|
||||
for( asUINT n = 0; n < length; n++ )
|
||||
if( array[n] != other.array[n] )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool asCArray<T>::operator !=(const asCArray<T> &other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
|
||||
// Returns false if the concatenation wasn't successful due to out of memory
|
||||
template <class T>
|
||||
bool asCArray<T>::Concatenate(const asCArray<T> &other)
|
||||
{
|
||||
if( maxLength < length + other.length )
|
||||
{
|
||||
Allocate(length + other.length, true);
|
||||
if( maxLength < length + other.length )
|
||||
{
|
||||
// Out of memory
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for( asUINT n = 0; n < other.length; n++ )
|
||||
array[length+n] = other.array[n];
|
||||
|
||||
length += other.length;
|
||||
|
||||
// Success
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void asCArray<T>::Concatenate(T* other, unsigned int count)
|
||||
{
|
||||
for( unsigned int c = 0; c < count; c++ )
|
||||
PushLast(other[c]);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool asCArray<T>::Exists(const T &e) const
|
||||
{
|
||||
return IndexOf(e) == -1 ? false : true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int asCArray<T>::IndexOf(const T &e) const
|
||||
{
|
||||
for( asUINT n = 0; n < length; n++ )
|
||||
if( array[n] == e ) return static_cast<int>(n);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void asCArray<T>::RemoveIndex(asUINT index)
|
||||
{
|
||||
if( index < length )
|
||||
{
|
||||
for( asUINT n = index; n < length-1; n++ )
|
||||
array[n] = array[n+1];
|
||||
|
||||
PopLast();
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void asCArray<T>::RemoveValue(const T &e)
|
||||
{
|
||||
for( asUINT n = 0; n < length; n++ )
|
||||
{
|
||||
if( array[n] == e )
|
||||
{
|
||||
RemoveIndex(n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void asCArray<T>::RemoveIndexUnordered(asUINT index)
|
||||
{
|
||||
if( index == length - 1 )
|
||||
PopLast();
|
||||
else if( index < length )
|
||||
array[index] = PopLast();
|
||||
}
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2014 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
The original version of this library can be located at:
|
||||
http://www.angelcode.com/angelscript/
|
||||
|
||||
Andreas Jonsson
|
||||
andreas@angelcode.com
|
||||
*/
|
||||
|
||||
//
|
||||
// as_atomic.cpp
|
||||
//
|
||||
// The implementation of the atomic class for thread safe reference counting
|
||||
//
|
||||
|
||||
#include "as_atomic.h"
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
asCAtomic::asCAtomic()
|
||||
{
|
||||
value = 0;
|
||||
}
|
||||
|
||||
asDWORD asCAtomic::get() const
|
||||
{
|
||||
// A very high ref count is highly unlikely. It most likely a problem with
|
||||
// memory that has been overwritten or is being accessed after it was deleted.
|
||||
asASSERT(value < 1000000);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void asCAtomic::set(asDWORD val)
|
||||
{
|
||||
// A very high ref count is highly unlikely. It most likely a problem with
|
||||
// memory that has been overwritten or is being accessed after it was deleted.
|
||||
asASSERT(value < 1000000);
|
||||
|
||||
value = val;
|
||||
}
|
||||
|
||||
asDWORD asCAtomic::atomicInc()
|
||||
{
|
||||
// A very high ref count is highly unlikely. It most likely a problem with
|
||||
// memory that has been overwritten or is being accessed after it was deleted.
|
||||
asASSERT(value < 1000000);
|
||||
|
||||
return asAtomicInc((int&)value);
|
||||
}
|
||||
|
||||
asDWORD asCAtomic::atomicDec()
|
||||
{
|
||||
// A very high ref count is highly unlikely. It most likely a problem with
|
||||
// memory that has been overwritten or is being accessed after it was deleted.
|
||||
asASSERT(value < 1000000);
|
||||
|
||||
return asAtomicDec((int&)value);
|
||||
}
|
||||
|
||||
//
|
||||
// The following code implements the atomicInc and atomicDec on different platforms
|
||||
//
|
||||
#if defined(AS_NO_THREADS) || defined(AS_NO_ATOMIC)
|
||||
|
||||
int asAtomicInc(int &value)
|
||||
{
|
||||
return ++value;
|
||||
}
|
||||
|
||||
int asAtomicDec(int &value)
|
||||
{
|
||||
return --value;
|
||||
}
|
||||
|
||||
#elif defined(AS_XENON) /// XBox360
|
||||
|
||||
END_AS_NAMESPACE
|
||||
#include <xtl.h>
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
int asAtomicInc(int &value)
|
||||
{
|
||||
return InterlockedIncrement((LONG*)&value);
|
||||
}
|
||||
|
||||
int asAtomicDec(int &value)
|
||||
{
|
||||
return InterlockedDecrement((LONG*)&value);
|
||||
}
|
||||
|
||||
#elif defined(AS_WIN)
|
||||
|
||||
END_AS_NAMESPACE
|
||||
#define WIN32_MEAN_AND_LEAN
|
||||
#include <windows.h>
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
int asAtomicInc(int &value)
|
||||
{
|
||||
return InterlockedIncrement((LONG*)&value);
|
||||
}
|
||||
|
||||
int asAtomicDec(int &value)
|
||||
{
|
||||
asASSERT(value > 0);
|
||||
return InterlockedDecrement((LONG*)&value);
|
||||
}
|
||||
|
||||
#elif defined(AS_LINUX) || defined(AS_BSD) || defined(AS_ILLUMOS) || defined(AS_ANDROID)
|
||||
|
||||
//
|
||||
// atomic_inc_and_test() and atomic_dec_and_test() from asm/atomic.h is not meant
|
||||
// to be used outside the Linux kernel. Instead we should use the GNUC provided
|
||||
// __sync_add_and_fetch() and __sync_sub_and_fetch() functions.
|
||||
//
|
||||
// Reference: http://golubenco.org/blog/atomic-operations/
|
||||
//
|
||||
// These are only available in GCC 4.1 and above, so for older versions we
|
||||
// use the critical sections, though it is a lot slower.
|
||||
//
|
||||
|
||||
int asAtomicInc(int &value)
|
||||
{
|
||||
return __sync_add_and_fetch(&value, 1);
|
||||
}
|
||||
|
||||
int asAtomicDec(int &value)
|
||||
{
|
||||
return __sync_sub_and_fetch(&value, 1);
|
||||
}
|
||||
|
||||
#elif defined(AS_MAC) || defined(AS_IPHONE)
|
||||
|
||||
END_AS_NAMESPACE
|
||||
#include <libkern/OSAtomic.h>
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
int asAtomicInc(int &value)
|
||||
{
|
||||
return OSAtomicIncrement32((int32_t*)&value);
|
||||
}
|
||||
|
||||
int asAtomicDec(int &value)
|
||||
{
|
||||
return OSAtomicDecrement32((int32_t*)&value);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// If we get here, then the configuration in as_config.h
|
||||
// is wrong for the compiler/platform combination.
|
||||
int ERROR_PleaseFixTheConfig[-1];
|
||||
|
||||
#endif
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2013 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
The original version of this library can be located at:
|
||||
http://www.angelcode.com/angelscript/
|
||||
|
||||
Andreas Jonsson
|
||||
andreas@angelcode.com
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// as_atomic.h
|
||||
//
|
||||
// The asCAtomic class provides methods for performing threadsafe
|
||||
// operations on a single dword, e.g. reference counting and
|
||||
// bitfields.
|
||||
//
|
||||
|
||||
|
||||
|
||||
#ifndef AS_ATOMIC_H
|
||||
#define AS_ATOMIC_H
|
||||
|
||||
#include "as_config.h"
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
class asCAtomic
|
||||
{
|
||||
public:
|
||||
asCAtomic();
|
||||
|
||||
asDWORD get() const;
|
||||
void set(asDWORD val);
|
||||
|
||||
// Increase and return new value
|
||||
asDWORD atomicInc();
|
||||
|
||||
// Decrease and return new value
|
||||
asDWORD atomicDec();
|
||||
|
||||
protected:
|
||||
asDWORD value;
|
||||
};
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2019 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
The original version of this library can be located at:
|
||||
http://www.angelcode.com/angelscript/
|
||||
|
||||
Andreas Jonsson
|
||||
andreas@angelcode.com
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// as_builder.h
|
||||
//
|
||||
// This is the class that manages the compilation of the scripts
|
||||
//
|
||||
|
||||
|
||||
#ifndef AS_BUILDER_H
|
||||
#define AS_BUILDER_H
|
||||
|
||||
#include "as_config.h"
|
||||
#include "as_symboltable.h"
|
||||
#include "as_scriptengine.h"
|
||||
#include "as_module.h"
|
||||
#include "as_array.h"
|
||||
#include "as_scriptcode.h"
|
||||
#include "as_scriptnode.h"
|
||||
#include "as_datatype.h"
|
||||
#include "as_property.h"
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
#ifdef AS_NO_COMPILER
|
||||
// Forward declare the structure, as it is part of some function signatures used even without the compiler
|
||||
struct sGlobalVariableDescription;
|
||||
#endif
|
||||
|
||||
#ifndef AS_NO_COMPILER
|
||||
|
||||
struct sFunctionDescription
|
||||
{
|
||||
asCScriptCode *script;
|
||||
asCScriptNode *node;
|
||||
asCString name;
|
||||
asCObjectType *objType;
|
||||
asCArray<asCString> paramNames;
|
||||
int funcId;
|
||||
bool isExistingShared;
|
||||
};
|
||||
|
||||
struct sGlobalVariableDescription
|
||||
{
|
||||
asCScriptCode *script;
|
||||
asCScriptNode *declaredAtNode;
|
||||
asCScriptNode *initializationNode;
|
||||
asCString name;
|
||||
asCGlobalProperty *property;
|
||||
asCDataType datatype;
|
||||
asSNameSpace *ns;
|
||||
int index;
|
||||
bool isCompiled;
|
||||
bool isPureConstant;
|
||||
bool isEnumValue;
|
||||
asQWORD constantValue;
|
||||
};
|
||||
|
||||
struct sPropertyInitializer
|
||||
{
|
||||
sPropertyInitializer() : declNode(0), initNode(0), file(0) {}
|
||||
sPropertyInitializer(const asCString &nm, asCScriptNode *decl, asCScriptNode *init, asCScriptCode *f) : name(nm), declNode(decl), initNode(init), file(f) {}
|
||||
sPropertyInitializer &operator=(const sPropertyInitializer &o) {name = o.name; declNode = o.declNode; initNode = o.initNode; file = o.file; return *this;}
|
||||
|
||||
asCString name;
|
||||
asCScriptNode *declNode;
|
||||
asCScriptNode *initNode;
|
||||
asCScriptCode *file;
|
||||
};
|
||||
|
||||
struct sClassDeclaration
|
||||
{
|
||||
sClassDeclaration() {script = 0; node = 0; validState = 0; typeInfo = 0; isExistingShared = false; isFinal = false;}
|
||||
|
||||
asCScriptCode *script;
|
||||
asCScriptNode *node;
|
||||
asCString name;
|
||||
int validState;
|
||||
asCTypeInfo *typeInfo;
|
||||
bool isExistingShared;
|
||||
bool isFinal;
|
||||
|
||||
asCArray<sPropertyInitializer> propInits;
|
||||
};
|
||||
|
||||
struct sFuncDef
|
||||
{
|
||||
asCScriptCode *script;
|
||||
asCScriptNode *node;
|
||||
asCString name;
|
||||
int idx;
|
||||
};
|
||||
|
||||
struct sMixinClass
|
||||
{
|
||||
asCScriptCode *script;
|
||||
asCScriptNode *node;
|
||||
asCString name;
|
||||
asSNameSpace *ns;
|
||||
};
|
||||
|
||||
#endif // AS_NO_COMPILER
|
||||
|
||||
class asCBuilder
|
||||
{
|
||||
public:
|
||||
asCBuilder(asCScriptEngine *engine, asCModule *module);
|
||||
~asCBuilder();
|
||||
|
||||
// These methods are used by the application interface
|
||||
int VerifyProperty(asCDataType *dt, const char *decl, asCString &outName, asCDataType &outType, asSNameSpace *ns);
|
||||
int ParseDataType(const char *datatype, asCDataType *result, asSNameSpace *implicitNamespace, bool isReturnType = false);
|
||||
int ParseTemplateDecl(const char *decl, asCString *name, asCArray<asCString> &subtypeNames);
|
||||
int ParseFunctionDeclaration(asCObjectType *type, const char *decl, asCScriptFunction *func, bool isSystemFunction, asCArray<bool> *paramAutoHandles = 0, bool *returnAutoHandle = 0, asSNameSpace *ns = 0, asCScriptNode **outListPattern = 0, asCObjectType **outParentClass = 0);
|
||||
int ParseVariableDeclaration(const char *decl, asSNameSpace *implicitNamespace, asCString &outName, asSNameSpace *&outNamespace, asCDataType &outDt);
|
||||
int CheckNameConflict(const char *name, asCScriptNode *node, asCScriptCode *code, asSNameSpace *ns, bool isProperty, bool isVirtualProperty);
|
||||
int CheckNameConflictMember(asCTypeInfo *type, const char *name, asCScriptNode *node, asCScriptCode *code, bool isProperty, bool isVirtualProperty);
|
||||
int ValidateVirtualProperty(asCScriptFunction *func);
|
||||
|
||||
#ifndef AS_NO_COMPILER
|
||||
int AddCode(const char *name, const char *code, int codeLength, int lineOffset, int sectionIdx, bool makeCopy);
|
||||
asCScriptCode *FindOrAddCode(const char *name, const char *code, size_t length);
|
||||
int Build();
|
||||
|
||||
int CompileFunction(const char *sectionName, const char *code, int lineOffset, asDWORD compileFlags, asCScriptFunction **outFunc);
|
||||
int CompileGlobalVar(const char *sectionName, const char *code, int lineOffset);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
friend class asCModule;
|
||||
friend class asCParser;
|
||||
friend class asCScriptFunction;
|
||||
friend class asCScriptEngine;
|
||||
|
||||
void Reset();
|
||||
|
||||
void WriteInfo(const asCString &scriptname, const asCString &msg, int r, int c, bool preMessage);
|
||||
void WriteInfo(const asCString &msg, asCScriptCode *file, asCScriptNode *node);
|
||||
void WriteError(const asCString &scriptname, const asCString &msg, int r, int c);
|
||||
void WriteError(const asCString &msg, asCScriptCode *file, asCScriptNode *node);
|
||||
void WriteWarning(const asCString &scriptname, const asCString &msg, int r, int c);
|
||||
void WriteWarning(const asCString &msg, asCScriptCode *file, asCScriptNode *node);
|
||||
|
||||
bool DoesGlobalPropertyExist(const char *prop, asSNameSpace *ns, asCGlobalProperty **outProp = 0, sGlobalVariableDescription **outDesc = 0, bool *isAppProp = 0);
|
||||
asCGlobalProperty *GetGlobalProperty(const char *prop, asSNameSpace *ns, bool *isCompiled, bool *isPureConstant, asQWORD *constantValue, bool *isAppProp);
|
||||
int ValidateDefaultArgs(asCScriptCode *script, asCScriptNode *node, asCScriptFunction *func);
|
||||
asCString GetCleanExpressionString(asCScriptNode *n, asCScriptCode *file);
|
||||
|
||||
asSNameSpace *GetNameSpaceFromNode(asCScriptNode *node, asCScriptCode *script, asSNameSpace *implicitNs, asCScriptNode **next, asCObjectType **objType = 0);
|
||||
asSNameSpace *GetNameSpaceByString(const asCString &nsName, asSNameSpace *implicitNs, asCScriptNode *errNode, asCScriptCode *script, asCTypeInfo **scopeType = 0, bool isRequired = true);
|
||||
asCString GetScopeFromNode(asCScriptNode *n, asCScriptCode *script, asCScriptNode **next = 0);
|
||||
|
||||
asCTypeInfo *GetType(const char *type, asSNameSpace *ns, asCObjectType *parentType);
|
||||
asCObjectType *GetObjectType(const char *type, asSNameSpace *ns);
|
||||
asCFuncdefType *GetFuncDef(const char *type, asSNameSpace *ns, asCObjectType *parentType);
|
||||
asCTypeInfo *GetTypeFromTypesKnownByObject(const char *type, asCObjectType *currentType);
|
||||
asCDataType CreateDataTypeFromNode(asCScriptNode *node, asCScriptCode *file, asSNameSpace *implicitNamespace, bool acceptHandleForScope = false, asCObjectType *currentType = 0, bool reportError = true, bool *isValid = 0);
|
||||
asCObjectType *GetTemplateInstanceFromNode(asCScriptNode *node, asCScriptCode *file, asCObjectType *templateType, asSNameSpace *implicitNamespace, asCObjectType *currentType, asCScriptNode **next = 0);
|
||||
asCDataType ModifyDataTypeFromNode(const asCDataType &type, asCScriptNode *node, asCScriptCode *file, asETypeModifiers *inOutFlag, bool *autoHandle);
|
||||
|
||||
int numErrors;
|
||||
int numWarnings;
|
||||
bool silent;
|
||||
|
||||
asCScriptEngine *engine;
|
||||
asCModule *module;
|
||||
|
||||
#ifndef AS_NO_COMPILER
|
||||
protected:
|
||||
friend class asCCompiler;
|
||||
|
||||
int CheckForConflictsDueToDefaultArgs(asCScriptCode *script, asCScriptNode *node, asCScriptFunction *func, asCObjectType *objType);
|
||||
int GetNamespaceAndNameFromNode(asCScriptNode *n, asCScriptCode *script, asSNameSpace *implicitNs, asSNameSpace *&outNs, asCString &outName);
|
||||
int RegisterMixinClass(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
|
||||
sMixinClass *GetMixinClass(const char *name, asSNameSpace *ns);
|
||||
void IncludePropertiesFromMixins(sClassDeclaration *decl);
|
||||
void IncludeMethodsFromMixins(sClassDeclaration *decl);
|
||||
void AddInterfaceToClass(sClassDeclaration *decl, asCScriptNode *errNode, asCObjectType *intf);
|
||||
void AddInterfaceFromMixinToClass(sClassDeclaration *decl, asCScriptNode *errNode, sMixinClass *mixin);
|
||||
|
||||
int RegisterScriptFunctionFromNode(asCScriptNode *node, asCScriptCode *file, asCObjectType *object = 0, bool isInterface = false, bool isGlobalFunction = false, asSNameSpace *ns = 0, bool isExistingShared = false, bool isMixin = false);
|
||||
int RegisterScriptFunction(asCScriptNode *node, asCScriptCode *file, asCObjectType *objType, bool isInterface, bool isGlobalFunction, asSNameSpace *ns, bool isExistingShared, bool isMixin, asCString &name, asCDataType &returnType, asCArray<asCString> ¶meterNames, asCArray<asCDataType> ¶meterTypes, asCArray<asETypeModifiers> &inOutFlags, asCArray<asCString *> &defaultArgs, asSFunctionTraits funcTraits);
|
||||
int RegisterVirtualProperty(asCScriptNode *node, asCScriptCode *file, asCObjectType *object = 0, bool isInterface = false, bool isGlobalFunction = false, asSNameSpace *ns = 0, bool isExistingShared = false);
|
||||
int RegisterImportedFunction(int funcID, asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
|
||||
int RegisterGlobalVar(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
|
||||
int RegisterClass(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
|
||||
int RegisterInterface(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
|
||||
int RegisterEnum(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
|
||||
int RegisterTypedef(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns);
|
||||
int RegisterFuncDef(asCScriptNode *node, asCScriptCode *file, asSNameSpace *ns, asCObjectType *parent);
|
||||
asCScriptFunction *RegisterLambda(asCScriptNode *node, asCScriptCode *file, asCScriptFunction *funcDef, const asCString &name, asSNameSpace *ns);
|
||||
void CompleteFuncDef(sFuncDef *funcDef);
|
||||
void CompileInterfaces();
|
||||
void CompileClasses(asUINT originalNumTempl);
|
||||
void DetermineTypeRelations();
|
||||
void GetParsedFunctionDetails(asCScriptNode *node, asCScriptCode *file, asCObjectType *objType, asCString &name, asCDataType &returnType, asCArray<asCString> ¶meterNames, asCArray<asCDataType> ¶meterTypes, asCArray<asETypeModifiers> &inOutFlags, asCArray<asCString *> &defaultArgs, asSFunctionTraits &traits, asSNameSpace *implicitNamespace);
|
||||
bool DoesMethodExist(asCObjectType *objType, int methodId, asUINT *methodIndex = 0);
|
||||
void AddDefaultConstructor(asCObjectType *objType, asCScriptCode *file);
|
||||
asCObjectProperty *AddPropertyToClass(sClassDeclaration *c, const asCString &name, const asCDataType &type, bool isPrivate, bool isProtected, bool isInherited, asCScriptCode *file = 0, asCScriptNode *node = 0);
|
||||
int CreateVirtualFunction(asCScriptFunction *func, int idx);
|
||||
void ParseScripts();
|
||||
void RegisterTypesFromScript(asCScriptNode *node, asCScriptCode *script, asSNameSpace *ns);
|
||||
void RegisterNonTypesFromScript(asCScriptNode *node, asCScriptCode *script, asSNameSpace *ns);
|
||||
void CompileFunctions();
|
||||
void CompileGlobalVariables();
|
||||
int GetEnumValueFromType(asCEnumType *type, const char *name, asCDataType &outDt, asDWORD &outValue);
|
||||
int GetEnumValue(const char *name, asCDataType &outDt, asDWORD &outValue, asSNameSpace *ns);
|
||||
bool DoesTypeExist(const asCString &type);
|
||||
asCObjectProperty *GetObjectProperty(asCDataType &obj, const char *prop);
|
||||
asCScriptFunction *GetFunctionDescription(int funcId);
|
||||
void GetFunctionDescriptions(const char *name, asCArray<int> &funcs, asSNameSpace *ns);
|
||||
void GetObjectMethodDescriptions(const char *name, asCObjectType *objectType, asCArray<int> &methods, bool objIsConst, const asCString &scope = "", asCScriptNode *errNode = 0, asCScriptCode *script = 0);
|
||||
void EvaluateTemplateInstances(asUINT startIdx, bool keepSilent);
|
||||
void CleanupEnumValues();
|
||||
|
||||
asCArray<asCScriptCode *> scripts;
|
||||
asCArray<sFunctionDescription *> functions;
|
||||
asCSymbolTable<sGlobalVariableDescription> globVariables;
|
||||
asCArray<sClassDeclaration *> classDeclarations;
|
||||
asCArray<sClassDeclaration *> interfaceDeclarations;
|
||||
asCArray<sClassDeclaration *> namedTypeDeclarations;
|
||||
asCArray<sFuncDef *> funcDefs;
|
||||
asCArray<sMixinClass *> mixinClasses;
|
||||
|
||||
// For use with the DoesTypeExists() method
|
||||
bool hasCachedKnownTypes;
|
||||
asCMap<asCString, bool> knownTypes;
|
||||
#endif
|
||||
};
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,205 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2018 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
The original version of this library can be located at:
|
||||
http://www.angelcode.com/angelscript/
|
||||
|
||||
Andreas Jonsson
|
||||
andreas@angelcode.com
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// as_bytecode.h
|
||||
//
|
||||
// A class for constructing the final byte code
|
||||
//
|
||||
|
||||
|
||||
|
||||
#ifndef AS_BYTECODE_H
|
||||
#define AS_BYTECODE_H
|
||||
|
||||
#include "as_config.h"
|
||||
|
||||
#ifndef AS_NO_COMPILER
|
||||
|
||||
#include "as_array.h"
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
#define BYTECODE_SIZE 4
|
||||
#define MAX_DATA_SIZE 8
|
||||
#define MAX_INSTR_SIZE (BYTECODE_SIZE+MAX_DATA_SIZE)
|
||||
|
||||
class asCScriptEngine;
|
||||
class asCScriptFunction;
|
||||
class asCByteInstruction;
|
||||
|
||||
class asCByteCode
|
||||
{
|
||||
public:
|
||||
asCByteCode(asCScriptEngine *engine);
|
||||
~asCByteCode();
|
||||
|
||||
void ClearAll();
|
||||
|
||||
int GetSize();
|
||||
|
||||
void Finalize(const asCArray<int> &tempVariableOffsets);
|
||||
|
||||
void Optimize();
|
||||
void OptimizeLocally(const asCArray<int> &tempVariableOffsets);
|
||||
void ExtractLineNumbers();
|
||||
void ExtractObjectVariableInfo(asCScriptFunction *outFunc);
|
||||
void ExtractTryCatchInfo(asCScriptFunction *outFunc);
|
||||
int ResolveJumpAddresses();
|
||||
int FindLabel(int label, asCByteInstruction *from, asCByteInstruction **dest, int *positionDelta);
|
||||
|
||||
void AddPath(asCArray<asCByteInstruction *> &paths, asCByteInstruction *instr, int stackSize);
|
||||
|
||||
void Output(asDWORD *array);
|
||||
void AddCode(asCByteCode *bc);
|
||||
|
||||
void PostProcess();
|
||||
|
||||
#ifdef AS_DEBUG
|
||||
void DebugOutput(const char *name, asCScriptFunction *func);
|
||||
#endif
|
||||
|
||||
int GetLastInstr();
|
||||
int RemoveLastInstr();
|
||||
asDWORD GetLastInstrValueDW();
|
||||
|
||||
void InsertIfNotExists(asCArray<int> &vars, int var);
|
||||
void GetVarsUsed(asCArray<int> &vars);
|
||||
bool IsVarUsed(int offset);
|
||||
void ExchangeVar(int oldOffset, int newOffset);
|
||||
bool IsSimpleExpression();
|
||||
|
||||
void Label(short label);
|
||||
void Line(int line, int column, int scriptIdx);
|
||||
void ObjInfo(int offset, int info);
|
||||
void Block(bool start);
|
||||
void TryBlock(short catchLabel);
|
||||
|
||||
void VarDecl(int varDeclIdx);
|
||||
void Call(asEBCInstr bc, int funcID, int pop);
|
||||
void CallPtr(asEBCInstr bc, int funcPtrVar, int pop);
|
||||
void Alloc(asEBCInstr bc, void *objID, int funcID, int pop);
|
||||
void Ret(int pop);
|
||||
void JmpP(int var, asDWORD max);
|
||||
|
||||
int InsertFirstInstrDWORD(asEBCInstr bc, asDWORD param);
|
||||
int InsertFirstInstrQWORD(asEBCInstr bc, asQWORD param);
|
||||
int Instr(asEBCInstr bc);
|
||||
int InstrQWORD(asEBCInstr bc, asQWORD param);
|
||||
int InstrDOUBLE(asEBCInstr bc, double param);
|
||||
int InstrPTR(asEBCInstr bc, void *param);
|
||||
int InstrDWORD(asEBCInstr bc, asDWORD param);
|
||||
int InstrWORD(asEBCInstr bc, asWORD param);
|
||||
int InstrSHORT(asEBCInstr bc, short param);
|
||||
int InstrFLOAT(asEBCInstr bc, float param);
|
||||
int InstrINT(asEBCInstr bc, int param);
|
||||
int InstrW_W_W(asEBCInstr bc, int a, int b, int c);
|
||||
int InstrSHORT_B(asEBCInstr bc, short a, asBYTE b);
|
||||
int InstrSHORT_W(asEBCInstr bc, short a, asWORD b);
|
||||
int InstrSHORT_DW(asEBCInstr bc, short a, asDWORD b);
|
||||
int InstrSHORT_QW(asEBCInstr bc, short a, asQWORD b);
|
||||
int InstrW_DW(asEBCInstr bc, asWORD a, asDWORD b);
|
||||
int InstrW_QW(asEBCInstr bc, asWORD a, asQWORD b);
|
||||
int InstrW_PTR(asEBCInstr bc, short a, void *param);
|
||||
int InstrW_FLOAT(asEBCInstr bc, asWORD a, float b);
|
||||
int InstrW_W(asEBCInstr bc, int w, int b);
|
||||
int InstrSHORT_DW_DW(asEBCInstr bc, short a, asDWORD b, asDWORD c);
|
||||
|
||||
asCScriptEngine *GetEngine() const { return engine; };
|
||||
|
||||
asCArray<int> lineNumbers;
|
||||
asCArray<int> sectionIdxs;
|
||||
int largestStackUsed;
|
||||
|
||||
protected:
|
||||
// Assignments are not allowed
|
||||
void operator=(const asCByteCode &) {}
|
||||
|
||||
// Helpers for Optimize
|
||||
bool CanBeSwapped(asCByteInstruction *curr);
|
||||
asCByteInstruction *ChangeFirstDeleteNext(asCByteInstruction *curr, asEBCInstr bc);
|
||||
asCByteInstruction *DeleteFirstChangeNext(asCByteInstruction *curr, asEBCInstr bc);
|
||||
asCByteInstruction *DeleteInstruction(asCByteInstruction *instr);
|
||||
void RemoveInstruction(asCByteInstruction *instr);
|
||||
asCByteInstruction *GoBack(asCByteInstruction *curr);
|
||||
asCByteInstruction *GoForward(asCByteInstruction *curr);
|
||||
void InsertBefore(asCByteInstruction *before, asCByteInstruction *instr);
|
||||
bool RemoveUnusedValue(asCByteInstruction *curr, asCByteInstruction **next);
|
||||
bool IsTemporary(int offset);
|
||||
bool IsTempRegUsed(asCByteInstruction *curr);
|
||||
bool IsTempVarRead(asCByteInstruction *curr, int offset);
|
||||
bool PostponeInitOfTemp(asCByteInstruction *curr, asCByteInstruction **next);
|
||||
bool IsTempVarReadByInstr(asCByteInstruction *curr, int var);
|
||||
bool IsTempVarOverwrittenByInstr(asCByteInstruction *curr, int var);
|
||||
bool IsInstrJmpOrLabel(asCByteInstruction *curr);
|
||||
|
||||
int AddInstruction();
|
||||
int AddInstructionFirst();
|
||||
|
||||
asCByteInstruction *first;
|
||||
asCByteInstruction *last;
|
||||
|
||||
const asCArray<int> *temporaryVariables;
|
||||
|
||||
asCScriptEngine *engine;
|
||||
};
|
||||
|
||||
class asCByteInstruction
|
||||
{
|
||||
public:
|
||||
asCByteInstruction();
|
||||
|
||||
void AddAfter(asCByteInstruction *nextCode);
|
||||
void AddBefore(asCByteInstruction *nextCode);
|
||||
void Remove();
|
||||
|
||||
int GetSize();
|
||||
int GetStackIncrease();
|
||||
|
||||
asCByteInstruction *next;
|
||||
asCByteInstruction *prev;
|
||||
|
||||
asEBCInstr op;
|
||||
asQWORD arg;
|
||||
short wArg[3];
|
||||
int size;
|
||||
int stackInc;
|
||||
|
||||
// Testing
|
||||
bool marked;
|
||||
int stackSize;
|
||||
};
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif // AS_NO_COMPILER
|
||||
|
||||
#endif
|
|
@ -0,0 +1,921 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2020 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
The original version of this library can be located at:
|
||||
http://www.angelcode.com/angelscript/
|
||||
|
||||
Andreas Jonsson
|
||||
andreas@angelcode.com
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// as_callfunc.cpp
|
||||
//
|
||||
// These functions handle the actual calling of system functions
|
||||
//
|
||||
|
||||
|
||||
|
||||
#include "as_config.h"
|
||||
#include "as_callfunc.h"
|
||||
#include "as_scriptengine.h"
|
||||
#include "as_texts.h"
|
||||
#include "as_context.h"
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
// ref: Member Function Pointers and the Fastest Possible C++ Delegates
|
||||
// describes the structure of class method pointers for most compilers
|
||||
// http://www.codeproject.com/Articles/7150/Member-Function-Pointers-and-the-Fastest-Possible
|
||||
|
||||
// ref: The code comments for ItaniumCXXABI::EmitLoadOfMemberFunctionPointer in the LLVM compiler
|
||||
// describes the structure for class method pointers on Itanium and arm64 ABI
|
||||
// http://clang.llvm.org/doxygen/CodeGen_2ItaniumCXXABI_8cpp_source.html#l00937
|
||||
|
||||
int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv, void *auxiliary, asSSystemFunctionInterface *internal)
|
||||
{
|
||||
memset(internal, 0, sizeof(asSSystemFunctionInterface));
|
||||
|
||||
internal->func = ptr.ptr.f.func;
|
||||
internal->auxiliary = 0;
|
||||
|
||||
// Was a compatible calling convention specified?
|
||||
if( internal->func )
|
||||
{
|
||||
if( ptr.flag == 1 && callConv != asCALL_GENERIC )
|
||||
return asWRONG_CALLING_CONV;
|
||||
else if( ptr.flag == 2 && (callConv == asCALL_GENERIC || callConv == asCALL_THISCALL || callConv == asCALL_THISCALL_ASGLOBAL || callConv == asCALL_THISCALL_OBJFIRST || callConv == asCALL_THISCALL_OBJLAST) )
|
||||
return asWRONG_CALLING_CONV;
|
||||
else if( ptr.flag == 3 && !(callConv == asCALL_THISCALL || callConv == asCALL_THISCALL_ASGLOBAL || callConv == asCALL_THISCALL_OBJFIRST || callConv == asCALL_THISCALL_OBJLAST) )
|
||||
return asWRONG_CALLING_CONV;
|
||||
}
|
||||
|
||||
asDWORD base = callConv;
|
||||
if( !isMethod )
|
||||
{
|
||||
if( base == asCALL_CDECL )
|
||||
internal->callConv = ICC_CDECL;
|
||||
else if( base == asCALL_STDCALL )
|
||||
internal->callConv = ICC_STDCALL;
|
||||
else if( base == asCALL_THISCALL_ASGLOBAL )
|
||||
{
|
||||
if(auxiliary == 0)
|
||||
return asINVALID_ARG;
|
||||
internal->auxiliary = auxiliary;
|
||||
internal->callConv = ICC_THISCALL;
|
||||
|
||||
// This is really a thiscall, so it is necessary to check for virtual method pointers
|
||||
base = asCALL_THISCALL;
|
||||
isMethod = true;
|
||||
}
|
||||
else if (base == asCALL_GENERIC)
|
||||
{
|
||||
internal->callConv = ICC_GENERIC_FUNC;
|
||||
|
||||
// The auxiliary object is optional for generic calling convention
|
||||
internal->auxiliary = auxiliary;
|
||||
}
|
||||
else
|
||||
return asNOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if( isMethod )
|
||||
{
|
||||
#ifndef AS_NO_CLASS_METHODS
|
||||
if( base == asCALL_THISCALL || base == asCALL_THISCALL_OBJFIRST || base == asCALL_THISCALL_OBJLAST )
|
||||
{
|
||||
internalCallConv thisCallConv;
|
||||
if( base == asCALL_THISCALL )
|
||||
{
|
||||
if(callConv != asCALL_THISCALL_ASGLOBAL && auxiliary)
|
||||
return asINVALID_ARG;
|
||||
|
||||
thisCallConv = ICC_THISCALL;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
return asNOT_SUPPORTED;
|
||||
#else
|
||||
if(auxiliary == 0)
|
||||
return asINVALID_ARG;
|
||||
|
||||
internal->auxiliary = auxiliary;
|
||||
if( base == asCALL_THISCALL_OBJFIRST )
|
||||
thisCallConv = ICC_THISCALL_OBJFIRST;
|
||||
else //if( base == asCALL_THISCALL_OBJLAST )
|
||||
thisCallConv = ICC_THISCALL_OBJLAST;
|
||||
#endif
|
||||
}
|
||||
|
||||
internal->callConv = thisCallConv;
|
||||
#ifdef GNU_STYLE_VIRTUAL_METHOD
|
||||
if( (size_t(ptr.ptr.f.func) & 1) )
|
||||
internal->callConv = (internalCallConv)(thisCallConv + 2);
|
||||
#endif
|
||||
internal->baseOffset = ( int )MULTI_BASE_OFFSET(ptr);
|
||||
#if (defined(AS_ARM64) || defined(AS_ARM) || defined(AS_MIPS)) && (defined(__GNUC__) || defined(AS_PSVITA))
|
||||
// As the least significant bit in func is used to switch to THUMB mode
|
||||
// on ARM processors, the LSB in the __delta variable is used instead of
|
||||
// the one in __pfn on ARM processors.
|
||||
// MIPS also appear to use the base offset to indicate virtual method.
|
||||
if( (size_t(internal->baseOffset) & 1) )
|
||||
internal->callConv = (internalCallConv)(thisCallConv + 2);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_VIRTUAL_BASE_OFFSET
|
||||
// We don't support virtual inheritance
|
||||
if( VIRTUAL_BASE_OFFSET(ptr) != 0 )
|
||||
return asNOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if( base == asCALL_CDECL_OBJLAST )
|
||||
internal->callConv = ICC_CDECL_OBJLAST;
|
||||
else if( base == asCALL_CDECL_OBJFIRST )
|
||||
internal->callConv = ICC_CDECL_OBJFIRST;
|
||||
else if (base == asCALL_GENERIC)
|
||||
{
|
||||
internal->callConv = ICC_GENERIC_METHOD;
|
||||
internal->auxiliary = auxiliary;
|
||||
}
|
||||
else
|
||||
return asNOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This function should prepare system functions so that it will be faster to call them
|
||||
int PrepareSystemFunctionGeneric(asCScriptFunction *func, asSSystemFunctionInterface *internal, asCScriptEngine *engine)
|
||||
{
|
||||
asASSERT(internal->callConv == ICC_GENERIC_METHOD || internal->callConv == ICC_GENERIC_FUNC);
|
||||
|
||||
// Calculate the size needed for the parameters
|
||||
internal->paramSize = func->GetSpaceNeededForArguments();
|
||||
|
||||
// Prepare the clean up instructions for the function arguments
|
||||
internal->cleanArgs.SetLength(0);
|
||||
int offset = 0;
|
||||
for( asUINT n = 0; n < func->parameterTypes.GetLength(); n++ )
|
||||
{
|
||||
asCDataType &dt = func->parameterTypes[n];
|
||||
|
||||
if( (dt.IsObject() || dt.IsFuncdef()) && !dt.IsReference() )
|
||||
{
|
||||
if (dt.IsFuncdef())
|
||||
{
|
||||
// If the generic call mode is set to old behaviour then always release handles
|
||||
// else only release the handle if the function is declared with auto handles
|
||||
if (engine->ep.genericCallMode == 0 || (internal->paramAutoHandles.GetLength() > n && internal->paramAutoHandles[n]))
|
||||
{
|
||||
asSSystemFunctionInterface::SClean clean;
|
||||
clean.op = 0; // call release
|
||||
clean.ot = &engine->functionBehaviours;
|
||||
clean.off = short(offset);
|
||||
internal->cleanArgs.PushLast(clean);
|
||||
}
|
||||
}
|
||||
else if( dt.GetTypeInfo()->flags & asOBJ_REF )
|
||||
{
|
||||
// If the generic call mode is set to old behaviour then always release handles
|
||||
// else only release the handle if the function is declared with auto handles
|
||||
if (!dt.IsObjectHandle() ||
|
||||
engine->ep.genericCallMode == 0 ||
|
||||
(internal->paramAutoHandles.GetLength() > n && internal->paramAutoHandles[n]) )
|
||||
{
|
||||
asSTypeBehaviour *beh = &CastToObjectType(dt.GetTypeInfo())->beh;
|
||||
asASSERT((dt.GetTypeInfo()->flags & asOBJ_NOCOUNT) || beh->release);
|
||||
if (beh->release)
|
||||
{
|
||||
asSSystemFunctionInterface::SClean clean;
|
||||
clean.op = 0; // call release
|
||||
clean.ot = CastToObjectType(dt.GetTypeInfo());
|
||||
clean.off = short(offset);
|
||||
internal->cleanArgs.PushLast(clean);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
asSSystemFunctionInterface::SClean clean;
|
||||
clean.op = 1; // call free
|
||||
clean.ot = CastToObjectType(dt.GetTypeInfo());
|
||||
clean.off = short(offset);
|
||||
|
||||
// Call the destructor then free the memory
|
||||
asSTypeBehaviour *beh = &CastToObjectType(dt.GetTypeInfo())->beh;
|
||||
if( beh->destruct )
|
||||
clean.op = 2; // call destruct, then free
|
||||
|
||||
internal->cleanArgs.PushLast(clean);
|
||||
}
|
||||
}
|
||||
|
||||
if( dt.IsObject() && !dt.IsObjectHandle() && !dt.IsReference() )
|
||||
offset += AS_PTR_SIZE;
|
||||
else
|
||||
offset += dt.GetSizeOnStackDWords();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This function should prepare system functions so that it will be faster to call them
|
||||
int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *internal, asCScriptEngine *engine)
|
||||
{
|
||||
#ifdef AS_MAX_PORTABILITY
|
||||
UNUSED_VAR(func);
|
||||
UNUSED_VAR(internal);
|
||||
UNUSED_VAR(engine);
|
||||
|
||||
// This should never happen, as when AS_MAX_PORTABILITY is on, all functions
|
||||
// are asCALL_GENERIC, which are prepared by PrepareSystemFunctionGeneric
|
||||
asASSERT(false);
|
||||
#else
|
||||
// References are always returned as primitive data
|
||||
if( func->returnType.IsReference() || func->returnType.IsObjectHandle() )
|
||||
{
|
||||
internal->hostReturnInMemory = false;
|
||||
internal->hostReturnSize = sizeof(void*)/4;
|
||||
internal->hostReturnFloat = false;
|
||||
}
|
||||
// Registered types have special flags that determine how they are returned
|
||||
else if( func->returnType.IsObject() )
|
||||
{
|
||||
asDWORD objType = func->returnType.GetTypeInfo()->flags;
|
||||
|
||||
// Only value types can be returned by value
|
||||
asASSERT( objType & asOBJ_VALUE );
|
||||
|
||||
if( !(objType & (asOBJ_APP_CLASS | asOBJ_APP_PRIMITIVE | asOBJ_APP_FLOAT | asOBJ_APP_ARRAY)) )
|
||||
{
|
||||
// If the return is by value then we need to know the true type
|
||||
engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, func->GetDeclarationStr().AddressOf());
|
||||
|
||||
asCString str;
|
||||
str.Format(TXT_CANNOT_RET_TYPE_s_BY_VAL, func->returnType.GetTypeInfo()->name.AddressOf());
|
||||
engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
|
||||
engine->ConfigError(asINVALID_CONFIGURATION, 0, 0, 0);
|
||||
}
|
||||
else if( objType & asOBJ_APP_ARRAY )
|
||||
{
|
||||
// Array types are always returned in memory
|
||||
internal->hostReturnInMemory = true;
|
||||
internal->hostReturnSize = sizeof(void*)/4;
|
||||
internal->hostReturnFloat = false;
|
||||
}
|
||||
else if( objType & asOBJ_APP_CLASS )
|
||||
{
|
||||
internal->hostReturnFloat = false;
|
||||
if( objType & COMPLEX_RETURN_MASK )
|
||||
{
|
||||
internal->hostReturnInMemory = true;
|
||||
internal->hostReturnSize = sizeof(void*)/4;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef HAS_128_BIT_PRIMITIVES
|
||||
if( func->returnType.GetSizeInMemoryDWords() > 4 )
|
||||
#else
|
||||
if( func->returnType.GetSizeInMemoryDWords() > 2 )
|
||||
#endif
|
||||
{
|
||||
internal->hostReturnInMemory = true;
|
||||
internal->hostReturnSize = sizeof(void*)/4;
|
||||
}
|
||||
else
|
||||
{
|
||||
internal->hostReturnInMemory = false;
|
||||
internal->hostReturnSize = func->returnType.GetSizeInMemoryDWords();
|
||||
#ifdef SPLIT_OBJS_BY_MEMBER_TYPES
|
||||
if( func->returnType.GetTypeInfo()->flags & asOBJ_APP_CLASS_ALLFLOATS )
|
||||
internal->hostReturnFloat = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef THISCALL_RETURN_SIMPLE_IN_MEMORY
|
||||
if((internal->callConv == ICC_THISCALL ||
|
||||
#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
internal->callConv == ICC_VIRTUAL_THISCALL) &&
|
||||
#else
|
||||
internal->callConv == ICC_VIRTUAL_THISCALL ||
|
||||
internal->callConv == ICC_THISCALL_OBJFIRST ||
|
||||
internal->callConv == ICC_THISCALL_OBJLAST) &&
|
||||
#endif
|
||||
func->returnType.GetSizeInMemoryDWords() >= THISCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE)
|
||||
{
|
||||
internal->hostReturnInMemory = true;
|
||||
internal->hostReturnSize = sizeof(void*)/4;
|
||||
}
|
||||
#endif
|
||||
#ifdef CDECL_RETURN_SIMPLE_IN_MEMORY
|
||||
if((internal->callConv == ICC_CDECL ||
|
||||
internal->callConv == ICC_CDECL_OBJLAST ||
|
||||
internal->callConv == ICC_CDECL_OBJFIRST) &&
|
||||
func->returnType.GetSizeInMemoryDWords() >= CDECL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE)
|
||||
{
|
||||
internal->hostReturnInMemory = true;
|
||||
internal->hostReturnSize = sizeof(void*)/4;
|
||||
}
|
||||
#endif
|
||||
#ifdef STDCALL_RETURN_SIMPLE_IN_MEMORY
|
||||
if( internal->callConv == ICC_STDCALL &&
|
||||
func->returnType.GetSizeInMemoryDWords() >= STDCALL_RETURN_SIMPLE_IN_MEMORY_MIN_SIZE)
|
||||
{
|
||||
internal->hostReturnInMemory = true;
|
||||
internal->hostReturnSize = sizeof(void*)/4;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef SPLIT_OBJS_BY_MEMBER_TYPES
|
||||
// It's not safe to return objects by value because different registers
|
||||
// will be used depending on the memory layout of the object.
|
||||
// Ref: http://www.x86-64.org/documentation/abi.pdf
|
||||
// Ref: http://www.agner.org/optimize/calling_conventions.pdf
|
||||
// If the application informs that the class should be treated as all integers, then we allow it
|
||||
if( !internal->hostReturnInMemory &&
|
||||
!(func->returnType.GetTypeInfo()->flags & (asOBJ_APP_CLASS_ALLINTS | asOBJ_APP_CLASS_ALLFLOATS)) )
|
||||
{
|
||||
engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, func->GetDeclarationStr().AddressOf());
|
||||
|
||||
asCString str;
|
||||
str.Format(TXT_DONT_SUPPORT_RET_TYPE_s_BY_VAL, func->returnType.Format(func->nameSpace).AddressOf());
|
||||
engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
|
||||
engine->ConfigError(asINVALID_CONFIGURATION, 0, 0, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if( objType & asOBJ_APP_PRIMITIVE )
|
||||
{
|
||||
internal->hostReturnInMemory = false;
|
||||
internal->hostReturnSize = func->returnType.GetSizeInMemoryDWords();
|
||||
internal->hostReturnFloat = false;
|
||||
}
|
||||
else if( objType & asOBJ_APP_FLOAT )
|
||||
{
|
||||
internal->hostReturnInMemory = false;
|
||||
internal->hostReturnSize = func->returnType.GetSizeInMemoryDWords();
|
||||
internal->hostReturnFloat = true;
|
||||
}
|
||||
}
|
||||
// Primitive types can easily be determined
|
||||
#ifdef HAS_128_BIT_PRIMITIVES
|
||||
else if( func->returnType.GetSizeInMemoryDWords() > 4 )
|
||||
{
|
||||
// Shouldn't be possible to get here
|
||||
asASSERT(false);
|
||||
}
|
||||
else if( func->returnType.GetSizeInMemoryDWords() == 4 )
|
||||
{
|
||||
internal->hostReturnInMemory = false;
|
||||
internal->hostReturnSize = 4;
|
||||
internal->hostReturnFloat = false;
|
||||
}
|
||||
#else
|
||||
else if( func->returnType.GetSizeInMemoryDWords() > 2 )
|
||||
{
|
||||
// Shouldn't be possible to get here
|
||||
asASSERT(false);
|
||||
}
|
||||
#endif
|
||||
else if( func->returnType.GetSizeInMemoryDWords() == 2 )
|
||||
{
|
||||
internal->hostReturnInMemory = false;
|
||||
internal->hostReturnSize = 2;
|
||||
internal->hostReturnFloat = func->returnType.IsEqualExceptConst(asCDataType::CreatePrimitive(ttDouble, true));
|
||||
}
|
||||
else if( func->returnType.GetSizeInMemoryDWords() == 1 )
|
||||
{
|
||||
internal->hostReturnInMemory = false;
|
||||
internal->hostReturnSize = 1;
|
||||
internal->hostReturnFloat = func->returnType.IsEqualExceptConst(asCDataType::CreatePrimitive(ttFloat, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
internal->hostReturnInMemory = false;
|
||||
internal->hostReturnSize = 0;
|
||||
internal->hostReturnFloat = false;
|
||||
}
|
||||
|
||||
// Calculate the size needed for the parameters
|
||||
internal->paramSize = func->GetSpaceNeededForArguments();
|
||||
|
||||
// Verify if the function takes any objects by value
|
||||
asUINT n;
|
||||
internal->takesObjByVal = false;
|
||||
for( n = 0; n < func->parameterTypes.GetLength(); n++ )
|
||||
{
|
||||
if( func->parameterTypes[n].IsObject() && !func->parameterTypes[n].IsObjectHandle() && !func->parameterTypes[n].IsReference() )
|
||||
{
|
||||
internal->takesObjByVal = true;
|
||||
|
||||
// Can't pass objects by value unless the application type is informed
|
||||
if( !(func->parameterTypes[n].GetTypeInfo()->flags & (asOBJ_APP_CLASS | asOBJ_APP_PRIMITIVE | asOBJ_APP_FLOAT | asOBJ_APP_ARRAY)) )
|
||||
{
|
||||
engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, func->GetDeclarationStr().AddressOf());
|
||||
|
||||
asCString str;
|
||||
str.Format(TXT_CANNOT_PASS_TYPE_s_BY_VAL, func->parameterTypes[n].GetTypeInfo()->name.AddressOf());
|
||||
engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
|
||||
engine->ConfigError(asINVALID_CONFIGURATION, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
#ifdef SPLIT_OBJS_BY_MEMBER_TYPES
|
||||
// It's not safe to pass objects by value because different registers
|
||||
// will be used depending on the memory layout of the object
|
||||
// Ref: http://www.x86-64.org/documentation/abi.pdf
|
||||
// Ref: http://www.agner.org/optimize/calling_conventions.pdf
|
||||
if(
|
||||
#ifdef COMPLEX_OBJS_PASSED_BY_REF
|
||||
!(func->parameterTypes[n].GetTypeInfo()->flags & COMPLEX_MASK) &&
|
||||
#endif
|
||||
#ifdef LARGE_OBJS_PASS_BY_REF
|
||||
func->parameterTypes[n].GetSizeInMemoryDWords() < AS_LARGE_OBJ_MIN_SIZE &&
|
||||
#endif
|
||||
!(func->parameterTypes[n].GetTypeInfo()->flags & (asOBJ_APP_PRIMITIVE | asOBJ_APP_FLOAT | asOBJ_APP_CLASS_ALLINTS | asOBJ_APP_CLASS_ALLFLOATS)) )
|
||||
{
|
||||
engine->WriteMessage("", 0, 0, asMSGTYPE_INFORMATION, func->GetDeclarationStr().AddressOf());
|
||||
|
||||
asCString str;
|
||||
str.Format(TXT_DONT_SUPPORT_TYPE_s_BY_VAL, func->parameterTypes[n].GetTypeInfo()->name.AddressOf());
|
||||
engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, str.AddressOf());
|
||||
engine->ConfigError(asINVALID_CONFIGURATION, 0, 0, 0);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare the clean up instructions for the function arguments
|
||||
internal->cleanArgs.SetLength(0);
|
||||
int offset = 0;
|
||||
for( n = 0; n < func->parameterTypes.GetLength(); n++ )
|
||||
{
|
||||
asCDataType &dt = func->parameterTypes[n];
|
||||
|
||||
#if defined(COMPLEX_OBJS_PASSED_BY_REF) || defined(AS_LARGE_OBJS_PASSED_BY_REF)
|
||||
bool needFree = false;
|
||||
#ifdef COMPLEX_OBJS_PASSED_BY_REF
|
||||
if( dt.GetTypeInfo() && dt.GetTypeInfo()->flags & COMPLEX_MASK ) needFree = true;
|
||||
#endif
|
||||
#ifdef AS_LARGE_OBJS_PASSED_BY_REF
|
||||
if( dt.GetSizeInMemoryDWords() >= AS_LARGE_OBJ_MIN_SIZE ) needFree = true;
|
||||
#endif
|
||||
if( needFree &&
|
||||
dt.IsObject() &&
|
||||
!dt.IsObjectHandle() &&
|
||||
!dt.IsReference() )
|
||||
{
|
||||
asSSystemFunctionInterface::SClean clean;
|
||||
clean.op = 1; // call free
|
||||
clean.ot = CastToObjectType(dt.GetTypeInfo());
|
||||
clean.off = short(offset);
|
||||
|
||||
#ifndef AS_CALLEE_DESTROY_OBJ_BY_VAL
|
||||
// If the called function doesn't destroy objects passed by value we must do so here
|
||||
asSTypeBehaviour *beh = &CastToObjectType(dt.GetTypeInfo())->beh;
|
||||
if( beh->destruct )
|
||||
clean.op = 2; // call destruct, then free
|
||||
#endif
|
||||
|
||||
internal->cleanArgs.PushLast(clean);
|
||||
}
|
||||
#endif
|
||||
|
||||
if( n < internal->paramAutoHandles.GetLength() && internal->paramAutoHandles[n] )
|
||||
{
|
||||
asSSystemFunctionInterface::SClean clean;
|
||||
clean.op = 0; // call release
|
||||
if (dt.IsFuncdef())
|
||||
clean.ot = &engine->functionBehaviours;
|
||||
else
|
||||
clean.ot = CastToObjectType(dt.GetTypeInfo());
|
||||
clean.off = short(offset);
|
||||
internal->cleanArgs.PushLast(clean);
|
||||
}
|
||||
|
||||
if( dt.IsObject() && !dt.IsObjectHandle() && !dt.IsReference() )
|
||||
offset += AS_PTR_SIZE;
|
||||
else
|
||||
offset += dt.GetSizeOnStackDWords();
|
||||
}
|
||||
#endif // !defined(AS_MAX_PORTABILITY)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef AS_MAX_PORTABILITY
|
||||
|
||||
int CallSystemFunction(int id, asCContext *context)
|
||||
{
|
||||
asCScriptEngine *engine = context->m_engine;
|
||||
asCScriptFunction *func = engine->scriptFunctions[id];
|
||||
asSSystemFunctionInterface *sysFunc = func->sysFuncIntf;
|
||||
int callConv = sysFunc->callConv;
|
||||
if( callConv == ICC_GENERIC_FUNC || callConv == ICC_GENERIC_METHOD )
|
||||
return context->CallGeneric(func);
|
||||
|
||||
context->SetInternalException(TXT_INVALID_CALLING_CONVENTION);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
//
|
||||
// CallSystemFunctionNative
|
||||
//
|
||||
// This function is implemented for each platform where the native calling conventions is supported.
|
||||
// See the various as_callfunc_xxx.cpp files for their implementation. It is responsible for preparing
|
||||
// the arguments for the function call, calling the function, and then retrieving the return value.
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// context - This is the context that can be used to retrieve specific information from the engine
|
||||
// descr - This is the script function object that holds the information on how to call the function
|
||||
// obj - This is the object pointer, if the call is for a class method, otherwise it is null
|
||||
// args - This is the function arguments, which are packed as in AngelScript
|
||||
// retPointer - This points to a the memory buffer where the return object is to be placed, if the function returns the value in memory rather than in registers
|
||||
// retQW2 - This output parameter should be used if the function returns a value larger than 64bits in registers
|
||||
// secondObj - This is the object pointer that the proxy method should invoke its method on when the call convention is THISCALL_OBJFIRST/LAST
|
||||
//
|
||||
// Return value:
|
||||
//
|
||||
// The function should return the value that is returned in registers.
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &retQW2, void *secondObj);
|
||||
|
||||
|
||||
int CallSystemFunction(int id, asCContext *context)
|
||||
{
|
||||
asCScriptEngine *engine = context->m_engine;
|
||||
asCScriptFunction *descr = engine->scriptFunctions[id];
|
||||
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
|
||||
|
||||
int callConv = sysFunc->callConv;
|
||||
if( callConv == ICC_GENERIC_FUNC || callConv == ICC_GENERIC_METHOD )
|
||||
return context->CallGeneric(descr);
|
||||
|
||||
asQWORD retQW = 0;
|
||||
asQWORD retQW2 = 0;
|
||||
asDWORD *args = context->m_regs.stackPointer;
|
||||
void *retPointer = 0;
|
||||
int popSize = sysFunc->paramSize;
|
||||
|
||||
// TODO: clean-up: CallSystemFunctionNative should have two arguments for object pointers
|
||||
// objForThiscall is the object pointer that should be used for the thiscall
|
||||
// objForArg is the object pointer that should be passed as argument when using OBJFIRST or OBJLAST
|
||||
|
||||
// Used to save two object pointers with THISCALL_OBJLAST or THISCALL_OBJFIRST
|
||||
void *obj = 0;
|
||||
void *secondObj = 0;
|
||||
|
||||
#ifdef AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
if( callConv >= ICC_THISCALL )
|
||||
{
|
||||
if(sysFunc->auxiliary)
|
||||
{
|
||||
// This class method is being called as if it is a global function
|
||||
obj = sysFunc->auxiliary;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The object pointer should be popped from the context stack
|
||||
popSize += AS_PTR_SIZE;
|
||||
|
||||
// Check for null pointer
|
||||
obj = (void*)*(asPWORD*)(args);
|
||||
if( obj == 0 )
|
||||
{
|
||||
context->SetInternalException(TXT_NULL_POINTER_ACCESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Skip the object pointer
|
||||
args += AS_PTR_SIZE;
|
||||
}
|
||||
|
||||
// Add the base offset for multiple inheritance
|
||||
#if (defined(__GNUC__) && (defined(AS_ARM64) || defined(AS_ARM) || defined(AS_MIPS))) || defined(AS_PSVITA)
|
||||
// On GNUC + ARM the lsb of the offset is used to indicate a virtual function
|
||||
// and the whole offset is thus shifted one bit left to keep the original
|
||||
// offset resolution
|
||||
// MIPS also work like ARM in this regard
|
||||
obj = (void*)(asPWORD(obj) + (sysFunc->baseOffset>>1));
|
||||
#else
|
||||
obj = (void*)(asPWORD(obj) + sysFunc->baseOffset);
|
||||
#endif
|
||||
}
|
||||
#else // !defined(AS_NO_THISCALL_FUNCTOR_METHOD)
|
||||
|
||||
if( callConv >= ICC_THISCALL )
|
||||
{
|
||||
bool continueCheck = true; // True if need check objectPointer or context stack for object
|
||||
int continueCheckIndex = 0; // Index into objectsPtrs to save the object if continueCheck
|
||||
|
||||
if( callConv >= ICC_THISCALL_OBJLAST )
|
||||
{
|
||||
asASSERT( sysFunc->auxiliary != 0 );
|
||||
// This class method is being called as object method (sysFunc->auxiliary must be set).
|
||||
obj = sysFunc->auxiliary;
|
||||
continueCheckIndex = 1;
|
||||
}
|
||||
else if(sysFunc->auxiliary)
|
||||
{
|
||||
// This class method is being called as if it is a global function
|
||||
obj = sysFunc->auxiliary;
|
||||
continueCheck = false;
|
||||
}
|
||||
|
||||
if( obj )
|
||||
{
|
||||
// Add the base offset for multiple inheritance
|
||||
#if (defined(__GNUC__) && (defined(AS_ARM64) || defined(AS_ARM) || defined(AS_MIPS))) || defined(AS_PSVITA)
|
||||
// On GNUC + ARM the lsb of the offset is used to indicate a virtual function
|
||||
// and the whole offset is thus shifted one bit left to keep the original
|
||||
// offset resolution
|
||||
// MIPS also work like ARM in this regard
|
||||
obj = (void*)(asPWORD(obj) + (sysFunc->baseOffset>>1));
|
||||
#else
|
||||
obj = (void*)(asPWORD(obj) + sysFunc->baseOffset);
|
||||
#endif
|
||||
}
|
||||
|
||||
if( continueCheck )
|
||||
{
|
||||
void *tempPtr = 0;
|
||||
|
||||
// The object pointer should be popped from the context stack
|
||||
popSize += AS_PTR_SIZE;
|
||||
|
||||
// Check for null pointer
|
||||
tempPtr = (void*)*(asPWORD*)(args);
|
||||
if( tempPtr == 0 )
|
||||
{
|
||||
context->SetInternalException(TXT_NULL_POINTER_ACCESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Add the base offset for multiple inheritance
|
||||
#if (defined(__GNUC__) && (defined(AS_ARM64) || defined(AS_ARM) || defined(AS_MIPS))) || defined(AS_PSVITA)
|
||||
// On GNUC + ARM the lsb of the offset is used to indicate a virtual function
|
||||
// and the whole offset is thus shifted one bit left to keep the original
|
||||
// offset resolution
|
||||
// MIPS also work like ARM in this regard
|
||||
tempPtr = (void*)(asPWORD(tempPtr) + (sysFunc->baseOffset>>1));
|
||||
#else
|
||||
tempPtr = (void*)(asPWORD(tempPtr) + sysFunc->baseOffset);
|
||||
#endif
|
||||
|
||||
// Skip the object pointer
|
||||
args += AS_PTR_SIZE;
|
||||
|
||||
if( continueCheckIndex )
|
||||
secondObj = tempPtr;
|
||||
else
|
||||
{
|
||||
asASSERT( obj == 0 );
|
||||
obj = tempPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // AS_NO_THISCALL_FUNCTOR_METHOD
|
||||
|
||||
if( descr->DoesReturnOnStack() )
|
||||
{
|
||||
// Get the address of the location for the return value from the stack
|
||||
retPointer = (void*)*(asPWORD*)(args);
|
||||
popSize += AS_PTR_SIZE;
|
||||
args += AS_PTR_SIZE;
|
||||
|
||||
// When returning the value on the location allocated by the called
|
||||
// we shouldn't set the object type in the register
|
||||
context->m_regs.objectType = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set the object type of the reference held in the register
|
||||
context->m_regs.objectType = descr->returnType.GetTypeInfo();
|
||||
}
|
||||
|
||||
// For composition we need to add the offset and/or dereference the pointer
|
||||
if(obj)
|
||||
{
|
||||
obj = (void*) ((char*) obj + sysFunc->compositeOffset);
|
||||
if(sysFunc->isCompositeIndirect) obj = *((void**)obj);
|
||||
}
|
||||
|
||||
context->m_callingSystemFunction = descr;
|
||||
bool cppException = false;
|
||||
#ifdef AS_NO_EXCEPTIONS
|
||||
retQW = CallSystemFunctionNative(context, descr, obj, args, sysFunc->hostReturnInMemory ? retPointer : 0, retQW2, secondObj);
|
||||
#else
|
||||
// This try/catch block is to catch potential exception that may
|
||||
// be thrown by the registered function. The implementation of the
|
||||
// CallSystemFunctionNative() must make sure not to have any manual
|
||||
// clean-up after the call to the real function, or that won't be
|
||||
// executed in case of an exception.
|
||||
try
|
||||
{
|
||||
retQW = CallSystemFunctionNative(context, descr, obj, args, sysFunc->hostReturnInMemory ? retPointer : 0, retQW2, secondObj);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
cppException = true;
|
||||
|
||||
// Convert the exception to a script exception so the VM can
|
||||
// properly report the error to the application and then clean up
|
||||
context->HandleAppException();
|
||||
}
|
||||
#endif
|
||||
context->m_callingSystemFunction = 0;
|
||||
|
||||
// Store the returned value in our stack
|
||||
if( (descr->returnType.IsObject() || descr->returnType.IsFuncdef()) && !descr->returnType.IsReference() )
|
||||
{
|
||||
if( descr->returnType.IsObjectHandle() )
|
||||
{
|
||||
#if defined(AS_BIG_ENDIAN) && AS_PTR_SIZE == 1
|
||||
// Since we're treating the system function as if it is returning a QWORD we are
|
||||
// actually receiving the value in the high DWORD of retQW.
|
||||
retQW >>= 32;
|
||||
#endif
|
||||
|
||||
context->m_regs.objectRegister = (void*)(asPWORD)retQW;
|
||||
|
||||
if( sysFunc->returnAutoHandle && context->m_regs.objectRegister )
|
||||
{
|
||||
asASSERT( !(descr->returnType.GetTypeInfo()->flags & asOBJ_NOCOUNT) );
|
||||
engine->CallObjectMethod(context->m_regs.objectRegister, CastToObjectType(descr->returnType.GetTypeInfo())->beh.addref);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
asASSERT( retPointer );
|
||||
|
||||
if( !sysFunc->hostReturnInMemory )
|
||||
{
|
||||
// Copy the returned value to the pointer sent by the script engine
|
||||
if( sysFunc->hostReturnSize == 1 )
|
||||
{
|
||||
#if defined(AS_BIG_ENDIAN) && AS_PTR_SIZE == 1
|
||||
// Since we're treating the system function as if it is returning a QWORD we are
|
||||
// actually receiving the value in the high DWORD of retQW.
|
||||
retQW >>= 32;
|
||||
#endif
|
||||
|
||||
*(asDWORD*)retPointer = (asDWORD)retQW;
|
||||
}
|
||||
else if( sysFunc->hostReturnSize == 2 )
|
||||
*(asQWORD*)retPointer = retQW;
|
||||
else if( sysFunc->hostReturnSize == 3 )
|
||||
{
|
||||
*(asQWORD*)retPointer = retQW;
|
||||
*(((asDWORD*)retPointer) + 2) = (asDWORD)retQW2;
|
||||
}
|
||||
else // if( sysFunc->hostReturnSize == 4 )
|
||||
{
|
||||
*(asQWORD*)retPointer = retQW;
|
||||
*(((asQWORD*)retPointer) + 1) = retQW2;
|
||||
}
|
||||
}
|
||||
|
||||
if( context->m_status == asEXECUTION_EXCEPTION && !cppException )
|
||||
{
|
||||
// If the function raised a script exception it really shouldn't have
|
||||
// initialized the object. However, as it is a soft exception there is
|
||||
// no way for the application to not return a value, so instead we simply
|
||||
// destroy it here, to pretend it was never created.
|
||||
if(CastToObjectType(descr->returnType.GetTypeInfo())->beh.destruct )
|
||||
engine->CallObjectMethod(retPointer, CastToObjectType(descr->returnType.GetTypeInfo())->beh.destruct);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Store value in value register
|
||||
if( sysFunc->hostReturnSize == 1 )
|
||||
{
|
||||
#if defined(AS_BIG_ENDIAN)
|
||||
// Since we're treating the system function as if it is returning a QWORD we are
|
||||
// actually receiving the value in the high DWORD of retQW.
|
||||
retQW >>= 32;
|
||||
|
||||
// Due to endian issues we need to handle return values that are
|
||||
// less than a DWORD (32 bits) in size specially
|
||||
int numBytes = descr->returnType.GetSizeInMemoryBytes();
|
||||
if( descr->returnType.IsReference() ) numBytes = 4;
|
||||
switch( numBytes )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
// 8 bits
|
||||
asBYTE *val = (asBYTE*)&context->m_regs.valueRegister;
|
||||
val[0] = (asBYTE)retQW;
|
||||
val[1] = 0;
|
||||
val[2] = 0;
|
||||
val[3] = 0;
|
||||
val[4] = 0;
|
||||
val[5] = 0;
|
||||
val[6] = 0;
|
||||
val[7] = 0;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
// 16 bits
|
||||
asWORD *val = (asWORD*)&context->m_regs.valueRegister;
|
||||
val[0] = (asWORD)retQW;
|
||||
val[1] = 0;
|
||||
val[2] = 0;
|
||||
val[3] = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
// 32 bits
|
||||
asDWORD *val = (asDWORD*)&context->m_regs.valueRegister;
|
||||
val[0] = (asDWORD)retQW;
|
||||
val[1] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#else
|
||||
*(asDWORD*)&context->m_regs.valueRegister = (asDWORD)retQW;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
context->m_regs.valueRegister = retQW;
|
||||
}
|
||||
|
||||
// Clean up arguments
|
||||
const asUINT cleanCount = sysFunc->cleanArgs.GetLength();
|
||||
if( cleanCount )
|
||||
{
|
||||
args = context->m_regs.stackPointer;
|
||||
|
||||
// Skip the hidden argument for the return pointer
|
||||
// TODO: runtime optimize: This check and increment should have been done in PrepareSystemFunction
|
||||
if( descr->DoesReturnOnStack() )
|
||||
args += AS_PTR_SIZE;
|
||||
|
||||
// Skip the object pointer on the stack
|
||||
// TODO: runtime optimize: This check and increment should have been done in PrepareSystemFunction
|
||||
if( callConv >= ICC_THISCALL && sysFunc->auxiliary == 0 )
|
||||
args += AS_PTR_SIZE;
|
||||
|
||||
asSSystemFunctionInterface::SClean *clean = sysFunc->cleanArgs.AddressOf();
|
||||
for( asUINT n = 0; n < cleanCount; n++, clean++ )
|
||||
{
|
||||
void **addr = (void**)&args[clean->off];
|
||||
if( clean->op == 0 )
|
||||
{
|
||||
if( *addr != 0 )
|
||||
{
|
||||
engine->CallObjectMethod(*addr, clean->ot->beh.release);
|
||||
*addr = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
asASSERT( clean->op == 1 || clean->op == 2 );
|
||||
asASSERT( *addr );
|
||||
|
||||
if( clean->op == 2 )
|
||||
engine->CallObjectMethod(*addr, clean->ot->beh.destruct);
|
||||
|
||||
engine->CallFree(*addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return popSize;
|
||||
}
|
||||
|
||||
#endif // AS_MAX_PORTABILITY
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2020 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
The original version of this library can be located at:
|
||||
http://www.angelcode.com/angelscript/
|
||||
|
||||
Andreas Jonsson
|
||||
andreas@angelcode.com
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// as_callfunc.h
|
||||
//
|
||||
// These functions handle the actual calling of system functions
|
||||
//
|
||||
|
||||
|
||||
#ifndef AS_CALLFUNC_H
|
||||
#define AS_CALLFUNC_H
|
||||
|
||||
#include "as_array.h"
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
class asCContext;
|
||||
class asCScriptEngine;
|
||||
class asCScriptFunction;
|
||||
class asCObjectType;
|
||||
struct asSSystemFunctionInterface;
|
||||
|
||||
int DetectCallingConvention(bool isMethod, const asSFuncPtr &ptr, int callConv, void *auxiliary, asSSystemFunctionInterface *internal);
|
||||
|
||||
int PrepareSystemFunctionGeneric(asCScriptFunction *func, asSSystemFunctionInterface *internal, asCScriptEngine *engine);
|
||||
|
||||
int PrepareSystemFunction(asCScriptFunction *func, asSSystemFunctionInterface *internal, asCScriptEngine *engine);
|
||||
|
||||
int CallSystemFunction(int id, asCContext *context);
|
||||
|
||||
inline asPWORD FuncPtrToUInt(asFUNCTION_t func)
|
||||
{
|
||||
// A little trickery as the C++ standard doesn't allow direct
|
||||
// conversion between function pointer and data pointer
|
||||
union { asFUNCTION_t func; asPWORD idx; } u;
|
||||
u.func = func;
|
||||
|
||||
return u.idx;
|
||||
}
|
||||
|
||||
enum internalCallConv
|
||||
{
|
||||
ICC_GENERIC_FUNC,
|
||||
ICC_GENERIC_FUNC_RETURNINMEM, // never used
|
||||
ICC_CDECL,
|
||||
ICC_CDECL_RETURNINMEM,
|
||||
ICC_STDCALL,
|
||||
ICC_STDCALL_RETURNINMEM,
|
||||
ICC_THISCALL,
|
||||
ICC_THISCALL_RETURNINMEM,
|
||||
ICC_VIRTUAL_THISCALL,
|
||||
ICC_VIRTUAL_THISCALL_RETURNINMEM,
|
||||
ICC_CDECL_OBJLAST,
|
||||
ICC_CDECL_OBJLAST_RETURNINMEM,
|
||||
ICC_CDECL_OBJFIRST,
|
||||
ICC_CDECL_OBJFIRST_RETURNINMEM,
|
||||
ICC_GENERIC_METHOD,
|
||||
ICC_GENERIC_METHOD_RETURNINMEM, // never used
|
||||
ICC_THISCALL_OBJLAST,
|
||||
ICC_THISCALL_OBJLAST_RETURNINMEM,
|
||||
ICC_VIRTUAL_THISCALL_OBJLAST,
|
||||
ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM,
|
||||
ICC_THISCALL_OBJFIRST,
|
||||
ICC_THISCALL_OBJFIRST_RETURNINMEM,
|
||||
ICC_VIRTUAL_THISCALL_OBJFIRST,
|
||||
ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM
|
||||
};
|
||||
|
||||
struct asSSystemFunctionInterface
|
||||
{
|
||||
asFUNCTION_t func;
|
||||
int baseOffset;
|
||||
internalCallConv callConv;
|
||||
bool hostReturnInMemory;
|
||||
bool hostReturnFloat;
|
||||
int hostReturnSize;
|
||||
int paramSize;
|
||||
bool takesObjByVal;
|
||||
asCArray<bool> paramAutoHandles; // TODO: Should be able to remove this array. Perhaps the flags can be stored together with the inOutFlags in asCScriptFunction?
|
||||
bool returnAutoHandle;
|
||||
int compositeOffset;
|
||||
bool isCompositeIndirect;
|
||||
void *auxiliary; // can be used for functors, e.g. by asCALL_THISCALL_ASGLOBAL or asCALL_THISCALL_OBJFIRST
|
||||
|
||||
struct SClean
|
||||
{
|
||||
asCObjectType *ot; // argument type for clean up
|
||||
short op; // clean up operation: 0 = release, 1 = free, 2 = destruct then free
|
||||
short off; // argument offset on the stack
|
||||
};
|
||||
asCArray<SClean> cleanArgs;
|
||||
|
||||
asSSystemFunctionInterface() : func(0), baseOffset(0), callConv(ICC_GENERIC_FUNC), hostReturnInMemory(false), hostReturnFloat(false), hostReturnSize(0), paramSize(0), takesObjByVal(false), returnAutoHandle(false), compositeOffset(0), isCompositeIndirect(false), auxiliary(0) {}
|
||||
|
||||
asSSystemFunctionInterface(const asSSystemFunctionInterface &in)
|
||||
{
|
||||
*this = in;
|
||||
}
|
||||
|
||||
asSSystemFunctionInterface &operator=(const asSSystemFunctionInterface &in)
|
||||
{
|
||||
func = in.func;
|
||||
baseOffset = in.baseOffset;
|
||||
callConv = in.callConv;
|
||||
hostReturnInMemory = in.hostReturnInMemory;
|
||||
hostReturnFloat = in.hostReturnFloat;
|
||||
hostReturnSize = in.hostReturnSize;
|
||||
paramSize = in.paramSize;
|
||||
takesObjByVal = in.takesObjByVal;
|
||||
paramAutoHandles = in.paramAutoHandles;
|
||||
returnAutoHandle = in.returnAutoHandle;
|
||||
compositeOffset = in.compositeOffset;
|
||||
isCompositeIndirect = in.isCompositeIndirect;
|
||||
auxiliary = in.auxiliary;
|
||||
cleanArgs = in.cleanArgs;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,665 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2015 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
The original version of this library can be located at:
|
||||
http://www.angelcode.com/angelscript/
|
||||
|
||||
Andreas Jonsson
|
||||
andreas@angelcode.com
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// as_callfunc_arm.cpp
|
||||
//
|
||||
// These functions handle the actual calling of system functions on the arm platform
|
||||
//
|
||||
// Written by Fredrik Ehnbom in June 2009, based on as_callfunc_x86.cpp
|
||||
//
|
||||
// The code was complemented to support Linux with ARM by Carlos Luna in December, 2012.
|
||||
//
|
||||
// Added support for functor methods by Jordi Oliveras Rovira in April, 2014.
|
||||
|
||||
|
||||
// This code has to conform to both AAPCS and the modified ABI for iOS
|
||||
//
|
||||
// Reference:
|
||||
//
|
||||
// AAPCS: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf
|
||||
// iOS: http://developer.apple.com/library/ios/documentation/Xcode/Conceptual/iPhoneOSABIReference/iPhoneOSABIReference.pdf
|
||||
|
||||
#include "as_config.h"
|
||||
|
||||
#ifndef AS_MAX_PORTABILITY
|
||||
#ifdef AS_ARM
|
||||
|
||||
#include "as_callfunc.h"
|
||||
#include "as_scriptengine.h"
|
||||
#include "as_texts.h"
|
||||
#include "as_tokendef.h"
|
||||
#include "as_context.h"
|
||||
|
||||
#if defined(AS_SOFTFP)
|
||||
|
||||
// This code supports the soft-float ABI, i.e. g++ -mfloat-abi=softfp
|
||||
//
|
||||
// The code for iOS, Android, Marmalade and Windows Phone goes here
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
extern "C" asQWORD armFunc (const asDWORD *, int, asFUNCTION_t);
|
||||
extern "C" asQWORD armFuncR0 (const asDWORD *, int, asFUNCTION_t, asDWORD r0);
|
||||
extern "C" asQWORD armFuncR0R1 (const asDWORD *, int, asFUNCTION_t, asDWORD r0, asDWORD r1);
|
||||
extern "C" asQWORD armFuncObjLast (const asDWORD *, int, asFUNCTION_t, asDWORD obj);
|
||||
extern "C" asQWORD armFuncR0ObjLast (const asDWORD *, int, asFUNCTION_t, asDWORD r0, asDWORD obj);
|
||||
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void *secondObject)
|
||||
{
|
||||
asCScriptEngine *engine = context->m_engine;
|
||||
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
|
||||
int callConv = sysFunc->callConv;
|
||||
|
||||
asQWORD retQW = 0;
|
||||
asFUNCTION_t func = sysFunc->func;
|
||||
int paramSize = sysFunc->paramSize;
|
||||
asFUNCTION_t *vftable;
|
||||
|
||||
if( sysFunc->hostReturnInMemory )
|
||||
{
|
||||
// The return is made in memory
|
||||
callConv++;
|
||||
}
|
||||
bool isThisCallMethod = callConv >= ICC_THISCALL_OBJLAST;
|
||||
|
||||
|
||||
asDWORD paramBuffer[64+2];
|
||||
// Android & Linux needs to align 64bit types on even registers, but this isn't done on iOS or Windows Phone
|
||||
// TODO: optimize runtime: There should be a check for this in PrepareSystemFunction() so this
|
||||
// doesn't have to be done for functions that don't have any 64bit types
|
||||
#if !defined(AS_ANDROID) && !defined(AS_LINUX)
|
||||
// In cases of thiscall methods, the callstack is configured as a standard thiscall
|
||||
// adding the secondObject as first or last element in callstack
|
||||
if( sysFunc->takesObjByVal || isThisCallMethod )
|
||||
#endif
|
||||
{
|
||||
#if defined(AS_ANDROID) || defined(AS_LINUX)
|
||||
// mask is used as a toggler to skip uneven registers.
|
||||
int mask = 1;
|
||||
|
||||
if( isThisCallMethod )
|
||||
{
|
||||
mask = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check for object pointer as first argument
|
||||
switch( callConv )
|
||||
{
|
||||
case ICC_THISCALL:
|
||||
case ICC_CDECL_OBJFIRST:
|
||||
case ICC_VIRTUAL_THISCALL:
|
||||
case ICC_THISCALL_RETURNINMEM:
|
||||
case ICC_CDECL_OBJFIRST_RETURNINMEM:
|
||||
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
|
||||
mask = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for hidden address in case of return by value
|
||||
if( sysFunc->hostReturnInMemory )
|
||||
mask = !mask;
|
||||
#endif
|
||||
paramSize = 0;
|
||||
int spos = 0;
|
||||
int dpos = 2;
|
||||
|
||||
if( isThisCallMethod && (callConv >= ICC_THISCALL_OBJFIRST &&
|
||||
callConv <= ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM) )
|
||||
{
|
||||
// Add the object pointer as the first parameter
|
||||
paramBuffer[dpos++] = (asDWORD)secondObject;
|
||||
paramSize++;
|
||||
}
|
||||
|
||||
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
|
||||
{
|
||||
// TODO: runtime optimize: Declare a reference to descr->parameterTypes[n] so the array doesn't have to be access all the time
|
||||
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() )
|
||||
{
|
||||
#ifdef COMPLEX_OBJS_PASSED_BY_REF
|
||||
if( descr->parameterTypes[n].GetTypeInfo()->flags & COMPLEX_MASK )
|
||||
{
|
||||
paramBuffer[dpos++] = args[spos++];
|
||||
paramSize++;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#if defined(AS_ANDROID) || defined(AS_LINUX)
|
||||
if( (descr->parameterTypes[n].GetTypeInfo()->flags & asOBJ_APP_CLASS_ALIGN8) &&
|
||||
((dpos & 1) == mask) )
|
||||
{
|
||||
// 64 bit value align
|
||||
dpos++;
|
||||
paramSize++;
|
||||
}
|
||||
#endif
|
||||
// Copy the object's memory to the buffer
|
||||
memcpy(¶mBuffer[dpos], *(void**)(args+spos), descr->parameterTypes[n].GetSizeInMemoryBytes());
|
||||
|
||||
// Delete the original memory
|
||||
engine->CallFree(*(char**)(args+spos));
|
||||
spos++;
|
||||
dpos += descr->parameterTypes[n].GetSizeInMemoryDWords();
|
||||
paramSize += descr->parameterTypes[n].GetSizeInMemoryDWords();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(AS_ANDROID) || defined(AS_LINUX)
|
||||
// Should an alignment be performed?
|
||||
if( !descr->parameterTypes[n].IsObjectHandle() &&
|
||||
!descr->parameterTypes[n].IsReference() &&
|
||||
descr->parameterTypes[n].GetSizeOnStackDWords() == 2 &&
|
||||
((dpos & 1) == mask) )
|
||||
{
|
||||
// 64 bit value align
|
||||
dpos++;
|
||||
paramSize++;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Copy the value directly
|
||||
paramBuffer[dpos++] = args[spos++];
|
||||
if( descr->parameterTypes[n].GetSizeOnStackDWords() > 1 )
|
||||
paramBuffer[dpos++] = args[spos++];
|
||||
paramSize += descr->parameterTypes[n].GetSizeOnStackDWords();
|
||||
}
|
||||
}
|
||||
|
||||
if( isThisCallMethod && (callConv >= ICC_THISCALL_OBJLAST &&
|
||||
callConv <= ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM) )
|
||||
{
|
||||
// Add the object pointer as the last parameter
|
||||
paramBuffer[dpos++] = (asDWORD)secondObject;
|
||||
paramSize++;
|
||||
}
|
||||
|
||||
// Keep a free location at the beginning
|
||||
args = ¶mBuffer[2];
|
||||
}
|
||||
|
||||
switch( callConv )
|
||||
{
|
||||
case ICC_CDECL_RETURNINMEM: // fall through
|
||||
case ICC_STDCALL_RETURNINMEM:
|
||||
retQW = armFuncR0(args, paramSize<<2, func, (asDWORD)retPointer);
|
||||
break;
|
||||
case ICC_CDECL: // fall through
|
||||
case ICC_STDCALL:
|
||||
retQW = armFunc(args, paramSize<<2, func);
|
||||
break;
|
||||
case ICC_THISCALL: // fall through
|
||||
case ICC_CDECL_OBJFIRST:
|
||||
case ICC_THISCALL_OBJFIRST:
|
||||
case ICC_THISCALL_OBJLAST:
|
||||
retQW = armFuncR0(args, paramSize<<2, func, (asDWORD)obj);
|
||||
break;
|
||||
case ICC_THISCALL_RETURNINMEM:
|
||||
case ICC_THISCALL_OBJFIRST_RETURNINMEM:
|
||||
case ICC_THISCALL_OBJLAST_RETURNINMEM:
|
||||
#ifdef __GNUC__
|
||||
// On GNUC the address where the return value will be placed should be put in R0
|
||||
retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
|
||||
#else
|
||||
// On Windows the R0 should always hold the object pointer, and the address for the return value comes after
|
||||
retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)obj, (asDWORD)retPointer);
|
||||
#endif
|
||||
break;
|
||||
case ICC_CDECL_OBJFIRST_RETURNINMEM:
|
||||
retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
|
||||
break;
|
||||
case ICC_VIRTUAL_THISCALL:
|
||||
case ICC_VIRTUAL_THISCALL_OBJFIRST:
|
||||
case ICC_VIRTUAL_THISCALL_OBJLAST:
|
||||
// Get virtual function table from the object pointer
|
||||
vftable = *(asFUNCTION_t**)obj;
|
||||
retQW = armFuncR0(args, paramSize<<2, vftable[FuncPtrToUInt(func)>>2], (asDWORD)obj);
|
||||
break;
|
||||
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
|
||||
case ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM:
|
||||
case ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM:
|
||||
// Get virtual function table from the object pointer
|
||||
vftable = *(asFUNCTION_t**)obj;
|
||||
#ifdef __GNUC__
|
||||
// On GNUC the address where the return value will be placed should be put in R0
|
||||
retQW = armFuncR0R1(args, (paramSize+1)<<2, vftable[FuncPtrToUInt(func)>>2], (asDWORD)retPointer, (asDWORD)obj);
|
||||
#else
|
||||
// On Windows the R0 should always hold the object pointer, and the address for the return value comes after
|
||||
retQW = armFuncR0R1(args, (paramSize+1)<<2, vftable[FuncPtrToUInt(func)>>2], (asDWORD)obj, (asDWORD)retPointer);
|
||||
#endif
|
||||
break;
|
||||
case ICC_CDECL_OBJLAST:
|
||||
retQW = armFuncObjLast(args, paramSize<<2, func, (asDWORD)obj);
|
||||
break;
|
||||
case ICC_CDECL_OBJLAST_RETURNINMEM:
|
||||
retQW = armFuncR0ObjLast(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
|
||||
break;
|
||||
default:
|
||||
context->SetInternalException(TXT_INVALID_CALLING_CONVENTION);
|
||||
}
|
||||
|
||||
return retQW;
|
||||
}
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#elif !defined(AS_SOFTFP)
|
||||
|
||||
// This code supports the hard-float ABI, i.e. g++ -mfloat-abi=hard
|
||||
// The main difference is that the floating point values are passed in the fpu registers
|
||||
|
||||
#define VFP_OFFSET 70
|
||||
#define STACK_OFFSET 6
|
||||
#define PARAM_BUFFER_SIZE 104
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
extern "C" asQWORD armFunc (const asDWORD *, int, asFUNCTION_t);
|
||||
extern "C" asQWORD armFuncR0 (const asDWORD *, int, asFUNCTION_t, asDWORD r0);
|
||||
extern "C" asQWORD armFuncR0R1 (const asDWORD *, int, asFUNCTION_t, asDWORD r0, asDWORD r1);
|
||||
extern "C" asQWORD armFuncObjLast (const asDWORD *, int, asFUNCTION_t, asDWORD obj);
|
||||
extern "C" asQWORD armFuncR0ObjLast (const asDWORD *, int, asFUNCTION_t, asDWORD r0, asDWORD obj);
|
||||
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &/*retQW2*/, void *secondObject)
|
||||
{
|
||||
asCScriptEngine *engine = context->m_engine;
|
||||
asSSystemFunctionInterface *sysFunc = descr->sysFuncIntf;
|
||||
int callConv = sysFunc->callConv;
|
||||
|
||||
asQWORD retQW = 0;
|
||||
asFUNCTION_t func = sysFunc->func;
|
||||
int paramSize = sysFunc->paramSize;
|
||||
asFUNCTION_t *vftable;
|
||||
|
||||
//---------------------------------------------------------------------------- RPi
|
||||
int freeFloatSlot = VFP_OFFSET;
|
||||
int freeDoubleSlot = VFP_OFFSET;
|
||||
int stackPos = STACK_OFFSET;
|
||||
int stackSize = 0;
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//---------------------------------------------------------------------------- RPi
|
||||
// We´ll divide paramBuffer into several segments:
|
||||
//
|
||||
// 0-1 Unused
|
||||
// 2-5 (+8 / +0 asm) values that should be placed in R0 - R3
|
||||
// 6-67 (+24 / +16 asm) values that should be placed on the stack
|
||||
// 68 (+272 / +264 asm) number of values stored in r registers (R0 - R3)
|
||||
// 69 (+276 / +268 asm) number of args stored on the stack
|
||||
// 70-85 (+280 / +272 asm) values that should be placed in VFP registers (16)
|
||||
// 86-87 (+344 / +336 asm) sp original value - sp final value - for debugging
|
||||
// 88-103 (+352 / +344 asm) Check area for free-used VFP registers
|
||||
//
|
||||
// Total number of elements: 104
|
||||
//
|
||||
// When passing the paramBuffer to the asm routines via the args pointer we are
|
||||
// offsetting the start of the array to being at element # 2. That´s why in asm
|
||||
// all addresses must have an offset of -2 words (-8 bytes).
|
||||
//---------------------------------------------------------------------------- RPi
|
||||
|
||||
asDWORD paramBuffer[PARAM_BUFFER_SIZE];
|
||||
memset(paramBuffer, 0, sizeof(asDWORD) * PARAM_BUFFER_SIZE);
|
||||
|
||||
if( sysFunc->hostReturnInMemory )
|
||||
{
|
||||
// TODO: runtime optimize: This check should be done in PrepareSystemFunction
|
||||
if ( !( descr->returnType.GetTypeInfo()->flags & COMPLEX_RETURN_MASK ) &&
|
||||
( descr->returnType.GetTypeInfo()->flags & asOBJ_APP_CLASS_ALLFLOATS ) &&
|
||||
descr->returnType.GetSizeInMemoryBytes() <= 8 )
|
||||
callConv--;
|
||||
|
||||
// The return is made in memory
|
||||
callConv++;
|
||||
}
|
||||
|
||||
bool isThisCallMethod = callConv >= ICC_THISCALL_OBJLAST;
|
||||
|
||||
// Linux needs to align 64bit types on even registers, but this isn't done on iOS or Windows Phone
|
||||
// TODO: optimize runtime: There should be a check for this in PrepareSystemFunction() so this
|
||||
// doesn't have to be done for functions that don't have any 64bit types
|
||||
{
|
||||
// mask is used as a toggler to skip uneven registers.
|
||||
int mask = 1;
|
||||
|
||||
if( isThisCallMethod )
|
||||
{
|
||||
mask = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check for object pointer as first argument
|
||||
switch( callConv )
|
||||
{
|
||||
case ICC_THISCALL:
|
||||
case ICC_CDECL_OBJFIRST:
|
||||
case ICC_VIRTUAL_THISCALL:
|
||||
case ICC_THISCALL_RETURNINMEM:
|
||||
case ICC_CDECL_OBJFIRST_RETURNINMEM:
|
||||
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
|
||||
mask = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Check for hidden address in case of return by value
|
||||
if( sysFunc->hostReturnInMemory )
|
||||
mask = !mask;
|
||||
|
||||
paramSize = 0;
|
||||
int spos = 0;
|
||||
int dpos = 2;
|
||||
|
||||
if( isThisCallMethod && (callConv >= ICC_THISCALL_OBJFIRST &&
|
||||
callConv <= ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM) )
|
||||
{
|
||||
// Add the object pointer as the first parameter
|
||||
paramBuffer[dpos++] = (asDWORD)secondObject;
|
||||
paramSize++;
|
||||
}
|
||||
|
||||
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
|
||||
{
|
||||
// TODO: runtime optimize: Declare a reference to descr->parameterTypes[n] so the array doesn't have to be access all the time
|
||||
if( descr->parameterTypes[n].IsObject() && !descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() &&
|
||||
!(descr->parameterTypes[n].GetTypeInfo()->flags & asOBJ_APP_ARRAY) )
|
||||
{
|
||||
#ifdef COMPLEX_OBJS_PASSED_BY_REF
|
||||
if( descr->parameterTypes[n].GetTypeInfo()->flags & COMPLEX_MASK )
|
||||
{
|
||||
paramBuffer[dpos++] = args[spos++];
|
||||
paramSize++;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if( (descr->parameterTypes[n].GetTypeInfo()->flags & asOBJ_APP_CLASS_ALIGN8) )
|
||||
{
|
||||
if ( (dpos & 1) == mask )
|
||||
{
|
||||
// 64 bit value align
|
||||
dpos++;
|
||||
paramSize++;
|
||||
}
|
||||
|
||||
if ( (stackPos & 1) == mask )
|
||||
{
|
||||
// 64 bit value align
|
||||
stackPos++;
|
||||
stackSize++;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the object's memory to the buffer
|
||||
if (descr->parameterTypes[n].GetTypeInfo()->flags & asOBJ_APP_CLASS_ALLFLOATS)
|
||||
{
|
||||
int target = (freeFloatSlot > freeDoubleSlot) ? freeFloatSlot : freeDoubleSlot;
|
||||
|
||||
if ( descr->parameterTypes[n].GetSizeInMemoryDWords() <= ( (VFP_OFFSET + 16) - target) )
|
||||
{
|
||||
memcpy(¶mBuffer[target], *(void**)(args+spos), descr->parameterTypes[n].GetSizeInMemoryBytes());
|
||||
memset(¶mBuffer[target + 18], (asDWORD)1, descr->parameterTypes[n].GetSizeInMemoryDWords());
|
||||
target += descr->parameterTypes[n].GetSizeInMemoryDWords();
|
||||
freeFloatSlot = freeDoubleSlot = target;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(¶mBuffer[stackPos], *(void**)(args+spos), descr->parameterTypes[n].GetSizeInMemoryBytes());
|
||||
stackPos += descr->parameterTypes[n].GetSizeInMemoryDWords();
|
||||
stackSize += descr->parameterTypes[n].GetSizeOnStackDWords();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(¶mBuffer[dpos], *(void**)(args+spos), descr->parameterTypes[n].GetSizeInMemoryBytes());
|
||||
dpos += descr->parameterTypes[n].GetSizeInMemoryDWords();
|
||||
paramSize += descr->parameterTypes[n].GetSizeInMemoryDWords();
|
||||
}
|
||||
|
||||
// Delete the original memory
|
||||
engine->CallFree(*(char**)(args+spos));
|
||||
spos++;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
else if( descr->parameterTypes[n].IsFloatType() && !descr->parameterTypes[n].IsReference() )
|
||||
{
|
||||
// Are there any "s" registers available?
|
||||
if ( freeFloatSlot < (VFP_OFFSET + 16) )
|
||||
{
|
||||
if (freeFloatSlot == freeDoubleSlot)
|
||||
freeDoubleSlot += 2;
|
||||
|
||||
paramBuffer[freeFloatSlot + 18] = (asDWORD)1;
|
||||
paramBuffer[freeFloatSlot++] = args[spos++];
|
||||
|
||||
while(freeFloatSlot < (VFP_OFFSET + 16) && paramBuffer[freeFloatSlot + 18] != 0)
|
||||
freeFloatSlot++;
|
||||
}
|
||||
// If not, then store the float arg in the stack area
|
||||
else
|
||||
{
|
||||
paramBuffer[stackPos++] = args[spos++];
|
||||
stackSize++;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
else if( descr->parameterTypes[n].IsDoubleType() && !descr->parameterTypes[n].IsReference() )
|
||||
{
|
||||
// Are there any "d" registers available?
|
||||
if ( freeDoubleSlot < (VFP_OFFSET + 15) )
|
||||
{
|
||||
if (freeFloatSlot == freeDoubleSlot)
|
||||
freeFloatSlot += 2;
|
||||
|
||||
// Copy two dwords for the double
|
||||
paramBuffer[freeDoubleSlot + 18] = (asDWORD)1;
|
||||
paramBuffer[freeDoubleSlot + 19] = (asDWORD)1;
|
||||
paramBuffer[freeDoubleSlot++] = args[spos++];
|
||||
paramBuffer[freeDoubleSlot++] = args[spos++];
|
||||
|
||||
while(freeDoubleSlot < (VFP_OFFSET + 15) && paramBuffer[freeDoubleSlot + 18] != 0)
|
||||
freeDoubleSlot += 2;
|
||||
}
|
||||
// If not, then store the double arg in the stack area
|
||||
else
|
||||
{
|
||||
if ( (stackPos & 1) == mask )
|
||||
{
|
||||
// 64 bit value align
|
||||
stackPos++;
|
||||
stackSize++;
|
||||
}
|
||||
|
||||
paramBuffer[stackPos++] = args[spos++];
|
||||
paramBuffer[stackPos++] = args[spos++];
|
||||
stackSize += 2;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Copy the value directly to "r" registers or the stack, checking for alignment
|
||||
if (paramSize < 4)
|
||||
{
|
||||
// Should an alignment be performed?
|
||||
if( (dpos & 1) == mask && descr->parameterTypes[n].GetSizeOnStackDWords() == 2 &&
|
||||
!descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() &&
|
||||
!descr->parameterTypes[n].IsAnyType() )
|
||||
{
|
||||
// 64 bit value align
|
||||
dpos++;
|
||||
paramSize++;
|
||||
}
|
||||
|
||||
paramBuffer[dpos++] = args[spos++];
|
||||
paramSize += descr->parameterTypes[n].GetSizeOnStackDWords();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Should an alignment be performed?
|
||||
if( (stackPos & 1) == mask && descr->parameterTypes[n].GetSizeOnStackDWords() == 2 &&
|
||||
!descr->parameterTypes[n].IsObjectHandle() && !descr->parameterTypes[n].IsReference() &&
|
||||
!descr->parameterTypes[n].IsAnyType() )
|
||||
{
|
||||
// 64 bit value align
|
||||
stackPos++;
|
||||
stackSize++;
|
||||
}
|
||||
|
||||
paramBuffer[stackPos++] = args[spos++];
|
||||
stackSize += descr->parameterTypes[n].GetSizeOnStackDWords();
|
||||
}
|
||||
|
||||
if( descr->parameterTypes[n].GetSizeOnStackDWords() > 1 )
|
||||
{
|
||||
if (paramSize < 5)
|
||||
paramBuffer[dpos++] = args[spos++];
|
||||
else
|
||||
paramBuffer[stackPos++] = args[spos++];
|
||||
}
|
||||
}// else...
|
||||
}// Loop
|
||||
|
||||
if( isThisCallMethod && (callConv >= ICC_THISCALL_OBJLAST &&
|
||||
callConv <= ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM) )
|
||||
{
|
||||
if (paramSize < 4)
|
||||
{
|
||||
paramBuffer[dpos++] = (asDWORD)secondObject;
|
||||
paramSize++;
|
||||
}
|
||||
else
|
||||
{
|
||||
paramBuffer[stackPos++] = (asDWORD)secondObject;
|
||||
stackSize++;
|
||||
}
|
||||
}
|
||||
|
||||
// Keep a free location at the beginning
|
||||
args = ¶mBuffer[2];
|
||||
}
|
||||
|
||||
paramBuffer[69] = static_cast<asDWORD>(stackSize<<2);
|
||||
|
||||
switch( callConv )
|
||||
{
|
||||
case ICC_CDECL_RETURNINMEM: // fall through
|
||||
case ICC_STDCALL_RETURNINMEM:
|
||||
retQW = armFuncR0(args, paramSize<<2, func, (asDWORD)retPointer);
|
||||
break;
|
||||
case ICC_CDECL: // fall through
|
||||
case ICC_STDCALL:
|
||||
retQW = armFunc(args, paramSize<<2, func);
|
||||
break;
|
||||
case ICC_THISCALL: // fall through
|
||||
case ICC_CDECL_OBJFIRST:
|
||||
case ICC_THISCALL_OBJFIRST:
|
||||
case ICC_THISCALL_OBJLAST:
|
||||
retQW = armFuncR0(args, paramSize<<2, func, (asDWORD)obj);
|
||||
break;
|
||||
case ICC_THISCALL_RETURNINMEM:
|
||||
case ICC_THISCALL_OBJFIRST_RETURNINMEM:
|
||||
case ICC_THISCALL_OBJLAST_RETURNINMEM:
|
||||
// On GNUC the address where the return value will be placed should be put in R0
|
||||
retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
|
||||
break;
|
||||
case ICC_CDECL_OBJFIRST_RETURNINMEM:
|
||||
retQW = armFuncR0R1(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
|
||||
break;
|
||||
case ICC_VIRTUAL_THISCALL:
|
||||
case ICC_VIRTUAL_THISCALL_OBJFIRST:
|
||||
case ICC_VIRTUAL_THISCALL_OBJLAST:
|
||||
// Get virtual function table from the object pointer
|
||||
vftable = *(asFUNCTION_t**)obj;
|
||||
retQW = armFuncR0(args, paramSize<<2, vftable[FuncPtrToUInt(func)>>2], (asDWORD)obj);
|
||||
break;
|
||||
case ICC_VIRTUAL_THISCALL_RETURNINMEM:
|
||||
case ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM:
|
||||
case ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM:
|
||||
// Get virtual function table from the object pointer
|
||||
vftable = *(asFUNCTION_t**)obj;
|
||||
// On GNUC the address where the return value will be placed should be put in R0
|
||||
retQW = armFuncR0R1(args, (paramSize+1)<<2, vftable[FuncPtrToUInt(func)>>2], (asDWORD)retPointer, (asDWORD)obj);
|
||||
break;
|
||||
case ICC_CDECL_OBJLAST:
|
||||
retQW = armFuncObjLast(args, paramSize<<2, func, (asDWORD)obj);
|
||||
break;
|
||||
case ICC_CDECL_OBJLAST_RETURNINMEM:
|
||||
retQW = armFuncR0ObjLast(args, paramSize<<2, func, (asDWORD)retPointer, (asDWORD)obj);
|
||||
break;
|
||||
default:
|
||||
context->SetInternalException(TXT_INVALID_CALLING_CONVENTION);
|
||||
}
|
||||
|
||||
// On Linux with arm the float and double values are returns in the
|
||||
// floating point registers, s0 and s1. Objects that contain only
|
||||
// float types and are not considered complex are also returned in the
|
||||
// floating point registers.
|
||||
if( sysFunc->hostReturnFloat )
|
||||
{
|
||||
retQW = paramBuffer[VFP_OFFSET];
|
||||
|
||||
if ( sysFunc->hostReturnSize > 1 )
|
||||
retQW = *( (asQWORD*)¶mBuffer[VFP_OFFSET] );
|
||||
}
|
||||
else if ( descr->returnType.IsObject() )
|
||||
{
|
||||
// TODO: runtime optimize: This should be identified with a flag determined in PrepareSystemFunction
|
||||
if ( !descr->returnType.IsObjectHandle() &&
|
||||
!descr->returnType.IsReference() &&
|
||||
!(descr->returnType.GetTypeInfo()->flags & COMPLEX_RETURN_MASK) &&
|
||||
(descr->returnType.GetTypeInfo()->flags & asOBJ_APP_CLASS_ALLFLOATS) )
|
||||
memcpy( retPointer, ¶mBuffer[VFP_OFFSET], descr->returnType.GetSizeInMemoryBytes() );
|
||||
}
|
||||
|
||||
return retQW;
|
||||
}
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif // AS_LINUX
|
||||
|
||||
#endif // AS_ARM
|
||||
#endif // AS_MAX_PORTABILITY
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,329 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2020-2020 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
The original version of this library can be located at:
|
||||
http://www.angelcode.com/angelscript/
|
||||
|
||||
Andreas Jonsson
|
||||
andreas@angelcode.com
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// as_callfunc_arm64.cpp
|
||||
//
|
||||
// These functions handle the actual calling of system functions on the arm64 platform
|
||||
//
|
||||
// Written by Max Waine in July 2020, based on as_callfunc_arm.cpp
|
||||
//
|
||||
|
||||
|
||||
#include "as_config.h"
|
||||
|
||||
#ifndef AS_MAX_PORTABILITY
|
||||
#ifdef AS_ARM64
|
||||
|
||||
#include "as_callfunc.h"
|
||||
#include "as_scriptengine.h"
|
||||
#include "as_texts.h"
|
||||
#include "as_tokendef.h"
|
||||
#include "as_context.h"
|
||||
|
||||
// ARM64 targets use has no software floating-point ABI, it's all hardware (or totally disabled)
|
||||
|
||||
#define HFA_RET_REGISTERS 4 // s0-s3/d0-d3
|
||||
#define GP_ARG_REGISTERS 8 // x0-x7
|
||||
#define FLOAT_ARG_REGISTERS 8 // v0-v7
|
||||
|
||||
BEGIN_AS_NAMESPACE
|
||||
|
||||
// x0-7: Argument registers (pass params or return results. OK as volatile local variables)
|
||||
// x8: Indirect result register (e.g. address of large returned struct)
|
||||
// x9-15: Volatile local variable registers
|
||||
// x16-17: Intra-procedure-call temporary registers
|
||||
// x18: Platform register (reserved for use of platform ABIs)
|
||||
// x19-29: Non-volatile variable registers (must be saved and restored if modified)
|
||||
// x29: Frame pointer register
|
||||
// x30: Link register (where to return to)
|
||||
|
||||
extern "C" void GetHFAReturnDouble(asQWORD *out1, asQWORD *out2, asQWORD returnSize);
|
||||
extern "C" void GetHFAReturnFloat(asQWORD *out1, asQWORD *out2, asQWORD returnSize);
|
||||
|
||||
extern "C" asQWORD CallARM64RetInMemory(
|
||||
const asQWORD *gpRegArgs, asQWORD numGPRegArgs,
|
||||
const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
|
||||
const asQWORD *stackArgs, asQWORD numStackArgs,
|
||||
void *retPointer, asFUNCTION_t func
|
||||
);
|
||||
extern "C" double CallARM64Double(
|
||||
const asQWORD *gpRegArgs, asQWORD numGPRegArgs,
|
||||
const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
|
||||
const asQWORD *stackArgs, asQWORD numStackArgs,
|
||||
asFUNCTION_t func
|
||||
);
|
||||
extern "C" float CallARM64Float(
|
||||
const asQWORD *gpRegArgs, asQWORD numGPRegArgs,
|
||||
const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
|
||||
const asQWORD *stackArgs, asQWORD numStackArgs,
|
||||
asFUNCTION_t func
|
||||
);
|
||||
extern "C" asQWORD CallARM64(
|
||||
const asQWORD *gpRegArgs, asQWORD numGPRegArgs,
|
||||
const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
|
||||
const asQWORD *stackArgs, asQWORD numStackArgs,
|
||||
asFUNCTION_t func
|
||||
);
|
||||
extern "C" asQWORD CallARM64Ret128(
|
||||
const asQWORD *gpRegArgs, asQWORD numGPRegArgs,
|
||||
const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
|
||||
const asQWORD *stackArgs, asQWORD numStackArgs,
|
||||
asQWORD *higherQWORD, asFUNCTION_t func
|
||||
);
|
||||
|
||||
//
|
||||
// If it's possible to fit in registers,
|
||||
// there may not be enough float register space even if true is returned
|
||||
//
|
||||
static inline bool IsRegisterHFA(const asCDataType &type)
|
||||
{
|
||||
const asCTypeInfo *const typeInfo = type.GetTypeInfo();
|
||||
|
||||
if( typeInfo == nullptr ||
|
||||
(typeInfo->flags & asOBJ_APP_CLASS_ALLFLOATS) == 0 ||
|
||||
type.IsObjectHandle() && type.IsReference() )
|
||||
return false;
|
||||
|
||||
const bool doubles = (typeInfo->flags & asOBJ_APP_CLASS_ALIGN8) != 0;
|
||||
const int maxAllowedSize = doubles ? sizeof(double) * HFA_RET_REGISTERS : sizeof(float) * HFA_RET_REGISTERS;
|
||||
|
||||
return type.GetSizeInMemoryBytes() <= maxAllowedSize;
|
||||
}
|
||||
|
||||
//
|
||||
// If it's possible to fit it in registers,
|
||||
// if true is returned there is enough space to fit
|
||||
//
|
||||
static inline bool IsRegisterHFAParameter(const asCDataType &type, const asQWORD numFloatRegArgs)
|
||||
{
|
||||
if( !IsRegisterHFA(type) )
|
||||
return false;
|
||||
|
||||
const bool doubles = (type.GetTypeInfo()->flags & asOBJ_APP_CLASS_ALIGN8) != 0;
|
||||
const int registersUsed = type.GetSizeInMemoryDWords() / (doubles ? sizeof(double) : sizeof(float));
|
||||
|
||||
return numFloatRegArgs + registersUsed <= FLOAT_ARG_REGISTERS;
|
||||
}
|
||||
|
||||
asQWORD CallSystemFunctionNative(asCContext *context, asCScriptFunction *descr, void *obj, asDWORD *args, void *retPointer, asQWORD &retQW2, void *secondObject)
|
||||
{
|
||||
asCScriptEngine *engine = context->m_engine;
|
||||
const asSSystemFunctionInterface *const sysFunc = descr->sysFuncIntf;
|
||||
const asCDataType &retType = descr->returnType;
|
||||
const asCTypeInfo *const retTypeInfo = retType.GetTypeInfo();
|
||||
asFUNCTION_t func = sysFunc->func;
|
||||
int callConv = sysFunc->callConv;
|
||||
asQWORD retQW = 0;
|
||||
|
||||
asQWORD gpRegArgs[GP_ARG_REGISTERS];
|
||||
asQWORD floatRegArgs[FLOAT_ARG_REGISTERS];
|
||||
asQWORD stackArgs[64]; // It's how many x64 users can have
|
||||
asQWORD numGPRegArgs = 0;
|
||||
asQWORD numFloatRegArgs = 0;
|
||||
asQWORD numStackArgs = 0;
|
||||
|
||||
asFUNCTION_t *vftable;
|
||||
|
||||
// Optimization to avoid check 12 values (all ICC_ that contains THISCALL)
|
||||
if( (callConv >= ICC_THISCALL && callConv <= ICC_VIRTUAL_THISCALL_RETURNINMEM) ||
|
||||
(callConv >= ICC_THISCALL_OBJLAST && callConv <= ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM) )
|
||||
{
|
||||
// Add the object pointer as the first parameter
|
||||
gpRegArgs[numGPRegArgs++] = (asQWORD)obj;
|
||||
}
|
||||
|
||||
if( callConv == ICC_CDECL_OBJFIRST || callConv == ICC_CDECL_OBJFIRST_RETURNINMEM )
|
||||
{
|
||||
// Add the object pointer as the first parameter
|
||||
gpRegArgs[numGPRegArgs++] = (asQWORD)obj;
|
||||
}
|
||||
else if( callConv == ICC_THISCALL_OBJFIRST || callConv == ICC_THISCALL_OBJFIRST_RETURNINMEM ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST || callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM )
|
||||
{
|
||||
// Add the object pointer as the first parameter
|
||||
gpRegArgs[numGPRegArgs++] = (asQWORD)secondObject;
|
||||
}
|
||||
|
||||
if( callConv == ICC_VIRTUAL_THISCALL || callConv == ICC_VIRTUAL_THISCALL_RETURNINMEM || callConv == ICC_VIRTUAL_THISCALL_OBJFIRST ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJFIRST_RETURNINMEM || callConv == ICC_VIRTUAL_THISCALL_OBJLAST || callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM )
|
||||
{
|
||||
// Get virtual function table from the object pointer
|
||||
vftable = *(asFUNCTION_t**)obj;
|
||||
func = vftable[FuncPtrToUInt(func)/sizeof(void*)];
|
||||
}
|
||||
|
||||
asUINT argsPos = 0;
|
||||
for( asUINT n = 0; n < descr->parameterTypes.GetLength(); n++ )
|
||||
{
|
||||
const asCDataType &parmType = descr->parameterTypes[n];
|
||||
const asCTypeInfo *const parmTypeInfo = parmType.GetTypeInfo();
|
||||
|
||||
if( parmType.IsObject() && !parmType.IsObjectHandle() && !parmType.IsReference() )
|
||||
{
|
||||
const asUINT parmDWords = parmType.GetSizeInMemoryDWords();
|
||||
const asUINT parmQWords = (parmDWords >> 1) + (parmDWords & 1);
|
||||
|
||||
const bool passedAsPointer = parmQWords <= 2;
|
||||
const bool fitsInRegisters = passedAsPointer ? (numGPRegArgs < GP_ARG_REGISTERS) : (numGPRegArgs + parmQWords <= GP_ARG_REGISTERS);
|
||||
asQWORD *const argsArray = fitsInRegisters ? gpRegArgs : stackArgs;
|
||||
asQWORD &numArgs = fitsInRegisters ? numGPRegArgs : numStackArgs;
|
||||
|
||||
if( (parmTypeInfo->flags & COMPLEX_MASK) )
|
||||
{
|
||||
argsArray[numArgs++] = *(asQWORD*)&args[argsPos];
|
||||
argsPos += AS_PTR_SIZE;
|
||||
}
|
||||
else if( IsRegisterHFAParameter(parmType, numFloatRegArgs) )
|
||||
{
|
||||
if( (parmTypeInfo->flags & asOBJ_APP_CLASS_ALIGN8) != 0 )
|
||||
{
|
||||
const asQWORD *const contents = *(asQWORD**)&args[argsPos];
|
||||
for( asUINT i = 0; i < parmQWords; i++ )
|
||||
floatRegArgs[numFloatRegArgs++] = *(asQWORD*)&contents[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
const asDWORD *const contents = *(asDWORD**)&args[argsPos];
|
||||
for( asUINT i = 0; i < parmDWords; i++ )
|
||||
floatRegArgs[numFloatRegArgs++] = *(asQWORD*)&contents[i];
|
||||
}
|
||||
engine->CallFree(*(char**)(args+argsPos));
|
||||
argsPos += AS_PTR_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Copy the object's memory to the buffer
|
||||
memcpy(&argsArray[numArgs], *(void**)(args+argsPos), parmType.GetSizeInMemoryBytes());
|
||||
|
||||
// Delete the original memory
|
||||
engine->CallFree(*(char**)(args+argsPos));
|
||||
argsPos += AS_PTR_SIZE;
|
||||
numArgs += parmQWords;
|
||||
}
|
||||
}
|
||||
else if( parmType.IsFloatType() && !parmType.IsReference() )
|
||||
{
|
||||
if( numFloatRegArgs >= FLOAT_ARG_REGISTERS )
|
||||
stackArgs[numStackArgs++] = args[argsPos];
|
||||
else
|
||||
floatRegArgs[numFloatRegArgs++] = args[argsPos];
|
||||
argsPos++;
|
||||
}
|
||||
else if( parmType.IsDoubleType() && !parmType.IsReference() )
|
||||
{
|
||||
if( numFloatRegArgs >= FLOAT_ARG_REGISTERS )
|
||||
stackArgs[numStackArgs++] = *(asQWORD*)&args[argsPos];
|
||||
else
|
||||
floatRegArgs[numFloatRegArgs++] = *(asQWORD*)&args[argsPos];
|
||||
argsPos += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Copy the value directly
|
||||
const asUINT parmDWords = parmType.GetSizeOnStackDWords();
|
||||
const asUINT parmQWords = (parmDWords >> 1) + (parmDWords & 1);
|
||||
|
||||
const bool fitsInRegisters = numGPRegArgs + parmQWords <= GP_ARG_REGISTERS;
|
||||
asQWORD *const argsArray = fitsInRegisters ? gpRegArgs : stackArgs;
|
||||
asQWORD &numArgs = fitsInRegisters ? numGPRegArgs : numStackArgs;
|
||||
|
||||
memcpy(&argsArray[numArgs], (void*)(args+argsPos), parmDWords * 4);
|
||||
argsPos += parmDWords;
|
||||
numArgs += parmQWords;
|
||||
}
|
||||
}
|
||||
|
||||
if( callConv == ICC_CDECL_OBJLAST || callConv == ICC_CDECL_OBJLAST_RETURNINMEM )
|
||||
{
|
||||
// Add the object pointer as the last parameter
|
||||
if( numGPRegArgs < GP_ARG_REGISTERS )
|
||||
gpRegArgs[numGPRegArgs++] = (asQWORD)obj;
|
||||
else
|
||||
stackArgs[numStackArgs++] = (asQWORD)obj;
|
||||
}
|
||||
else if( callConv == ICC_THISCALL_OBJLAST || callConv == ICC_THISCALL_OBJLAST_RETURNINMEM ||
|
||||
callConv == ICC_VIRTUAL_THISCALL_OBJLAST || callConv == ICC_VIRTUAL_THISCALL_OBJLAST_RETURNINMEM )
|
||||
{
|
||||
// Add the object pointer as the last parameter
|
||||
if( numGPRegArgs < GP_ARG_REGISTERS )
|
||||
gpRegArgs[numGPRegArgs++] = (asQWORD)secondObject;
|
||||
else
|
||||
stackArgs[numStackArgs++] = (asQWORD)secondObject;
|
||||
}
|
||||
|
||||
if( IsRegisterHFA(retType) && !(retTypeInfo->flags & COMPLEX_MASK) )
|
||||
{
|
||||
// This is to deal with HFAs (Homogeneous Floating-point Aggregates):
|
||||
// ARM64 will place all-float composite types (of equal precision)
|
||||
// with <= 4 members in the float return registers
|
||||
|
||||
const int structSize = retType.GetSizeInMemoryBytes();
|
||||
|
||||
CallARM64(gpRegArgs, numGPRegArgs, floatRegArgs, numFloatRegArgs, stackArgs, numStackArgs, func);
|
||||
if( (retTypeInfo->flags & asOBJ_APP_CLASS_ALIGN8) != 0 )
|
||||
{
|
||||
if( structSize <= sizeof(double) * 2 )
|
||||
GetHFAReturnDouble(&retQW, &retQW2, structSize);
|
||||
else
|
||||
GetHFAReturnDouble((asQWORD*)retPointer, ((asQWORD*)retPointer) + 1, structSize);
|
||||
}
|
||||
else
|
||||
GetHFAReturnFloat(&retQW, &retQW2, structSize);
|
||||
}
|
||||
else if( sysFunc->hostReturnFloat )
|
||||
{
|
||||
if( sysFunc->hostReturnSize == 1 )
|
||||
*(float*)&retQW = CallARM64Float(gpRegArgs, numGPRegArgs, floatRegArgs, numFloatRegArgs, stackArgs, numStackArgs, func);
|
||||
else
|
||||
*(double*)&retQW = CallARM64Double(gpRegArgs, numGPRegArgs, floatRegArgs, numFloatRegArgs, stackArgs, numStackArgs, func);
|
||||
}
|
||||
else if( sysFunc->hostReturnInMemory )
|
||||
retQW = CallARM64RetInMemory(gpRegArgs, numGPRegArgs, floatRegArgs, numFloatRegArgs, stackArgs, numStackArgs, retPointer, func);
|
||||
else
|
||||
{
|
||||
if( retType.GetSizeInMemoryBytes() > sizeof(asQWORD) )
|
||||
retQW = CallARM64Ret128(gpRegArgs, numGPRegArgs, floatRegArgs, numFloatRegArgs, stackArgs, numStackArgs, &retQW2, func);
|
||||
else
|
||||
retQW = CallARM64(gpRegArgs, numGPRegArgs, floatRegArgs, numFloatRegArgs, stackArgs, numStackArgs, func);
|
||||
}
|
||||
|
||||
return retQW;
|
||||
}
|
||||
|
||||
END_AS_NAMESPACE
|
||||
|
||||
#endif // AS_ARM64
|
||||
#endif // AS_MAX_PORTABILITY
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,219 @@
|
|||
//
|
||||
// AngelCode Scripting Library
|
||||
// Copyright (c) 2020-2020 Andreas Jonsson
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any
|
||||
// damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any
|
||||
// purpose, including commercial applications, and to alter it and
|
||||
// redistribute it freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented// you
|
||||
// must not claim that you wrote the original software. If you use
|
||||
// this software in a product, an acknowledgment in the product
|
||||
// documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and
|
||||
// must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
// The original version of this library can be located at:
|
||||
// http://www.angelcode.com/angelscript/
|
||||
//
|
||||
// Andreas Jonsson
|
||||
// andreas@angelcode.com
|
||||
//
|
||||
|
||||
|
||||
// Assembly routines for the ARM64/AArch64 call convention used for Linux
|
||||
// Written by Max Waine in July 2020, based on as_callfunc_arm_msvc.asm,
|
||||
// with assistance & guidance provided by Sir Kane
|
||||
|
||||
// Compile with GCC/GAS
|
||||
|
||||
.arch armv8-a
|
||||
.text
|
||||
|
||||
.global GetHFAReturnDouble
|
||||
.global GetHFAReturnFloat
|
||||
.global CallARM64Ret128
|
||||
.global CallARM64RetInMemory
|
||||
.global CallARM64Double
|
||||
.global CallARM64Float
|
||||
.global CallARM64
|
||||
|
||||
.type GetHFAReturnDouble, %function
|
||||
.type GetHFAReturnFloat, %function
|
||||
.type CallARM64Ret128, %function
|
||||
.type CallARM64RetInMemory, %function
|
||||
.type CallARM64Double, %function
|
||||
.type CallARM64Float, %function
|
||||
.type CallARM64, %function
|
||||
|
||||
.align 2
|
||||
GetHFAReturnDouble:
|
||||
adr x9, populateDoubles
|
||||
sub x9, x9, x1, lsr 1 // x9 -= returnSize >> 1; (/2 because double is 2x instruction size)
|
||||
br x9
|
||||
|
||||
str d3, [x0, #0x18]
|
||||
str d2, [x0, #0x10]
|
||||
str d1, [x1]
|
||||
str d0, [x0]
|
||||
populateDoubles:
|
||||
|
||||
ret
|
||||
|
||||
.align 2
|
||||
GetHFAReturnFloat:
|
||||
adr x9, populateFloats
|
||||
sub x9, x9, x2 // x9 -= returnSize; (already 4 bytes per return)
|
||||
br x9
|
||||
|
||||
str s3, [x1, #0x4]
|
||||
str s2, [x1]
|
||||
str s1, [x0, #0x4]
|
||||
str s0, [x0]
|
||||
populateFloats:
|
||||
|
||||
ret
|
||||
|
||||
|
||||
//[returnType] CallARM64[type](
|
||||
// const asQWORD *gpRegArgs, asQWORD numGPRegArgs,
|
||||
// const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
|
||||
// const asQWORD *stackArgs, asQWORD numStackArgs,
|
||||
// asFUNCTION_t func
|
||||
//)
|
||||
.align 2
|
||||
CallARM64Double:
|
||||
CallARM64Float:
|
||||
CallARM64:
|
||||
.cfi_startproc
|
||||
stp fp, lr, [sp,#-0x20]!
|
||||
str x20, [sp,#0x10]
|
||||
.cfi_def_cfa_offset 0x20
|
||||
.cfi_offset 20, 0x10
|
||||
.cfi_offset fp, -0x20
|
||||
.cfi_offset lr, -0x18
|
||||
mov fp, sp
|
||||
|
||||
mov x20, #0
|
||||
|
||||
cbz x5, stackArgsLoopEnd
|
||||
|
||||
// Align count to 2, then multiply by 8, resulting in a size aligned to 16
|
||||
add x20, x5, #1
|
||||
lsl x20, x20, #3
|
||||
and x20, x20, #-0x10
|
||||
// Multiply count by 8
|
||||
lsl x10, x5, #3
|
||||
sub sp, sp, x20
|
||||
stackArgsLoopStart:
|
||||
ldp x9,x11, [x4],#16
|
||||
stp x9,x11, [sp],#16
|
||||
subs x10, x10, #16
|
||||
bgt stackArgsLoopStart
|
||||
stackArgsLoopEnd:
|
||||
|
||||
// Calculate amount to jump forward, avoiding pointless instructions
|
||||
adr x9, populateFloatRegisterArgsEnd
|
||||
sub x9, x9, x3, lsl 2 // x9 -= numFloatRegArgs * 4
|
||||
br x9
|
||||
|
||||
ldr d7, [x2, #0x38]
|
||||
ldr d6, [x2, #0x30]
|
||||
ldr d5, [x2, #0x28]
|
||||
ldr d4, [x2, #0x20]
|
||||
ldr d3, [x2, #0x18]
|
||||
ldr d2, [x2, #0x10]
|
||||
ldr d1, [x2, #0x08]
|
||||
ldr d0, [x2]
|
||||
populateFloatRegisterArgsEnd:
|
||||
|
||||
mov x15, x6
|
||||
// Calculate amount to jump forward, avoiding pointless instructions
|
||||
adr x9, populateGPRegisterArgsEnd
|
||||
sub x9, x9, x1, lsl 2 // x9 -= numGPRegArgs * 4
|
||||
br x9
|
||||
|
||||
ldr x7, [x0, #0x38]
|
||||
ldr x6, [x0, #0x30]
|
||||
ldr x5, [x0, #0x28]
|
||||
ldr x4, [x0, #0x20]
|
||||
ldr x3, [x0, #0x18]
|
||||
ldr x2, [x0, #0x10]
|
||||
ldr x1, [x0, #0x08]
|
||||
ldr x0, [x0]
|
||||
populateGPRegisterArgsEnd:
|
||||
|
||||
// Actually call function
|
||||
sub sp, sp, x20
|
||||
blr x15
|
||||
add sp, sp, x20
|
||||
|
||||
ldr x20, [sp,#0x10]
|
||||
ldp fp, lr, [sp],#0x20
|
||||
|
||||
.cfi_restore lr
|
||||
.cfi_restore fp
|
||||
.cfi_restore 20
|
||||
.cfi_def_cfa_offset 0
|
||||
ret
|
||||
.cfi_endproc
|
||||
|
||||
.align 2
|
||||
CallARM64Ret128:
|
||||
.cfi_startproc
|
||||
stp fp, lr, [sp,#-0x20]!
|
||||
str x20, [sp,#0x10]
|
||||
.cfi_def_cfa_offset 0x20
|
||||
.cfi_offset 20, 0x10
|
||||
.cfi_offset fp, -0x20
|
||||
.cfi_offset lr, -0x18
|
||||
mov fp, sp
|
||||
|
||||
mov x20, x6
|
||||
mov x6, x7
|
||||
mov x7, #0
|
||||
bl CallARM64
|
||||
|
||||
str x1, [x20]
|
||||
|
||||
ldr x20, [sp,#0x10]
|
||||
ldp fp, lr, [sp],#0x20
|
||||
|
||||
.cfi_restore lr
|
||||
.cfi_restore fp
|
||||
.cfi_restore 20
|
||||
.cfi_def_cfa_offset 0
|
||||
ret
|
||||
.cfi_endproc
|
||||
|
||||
.align 2
|
||||
CallARM64RetInMemory:
|
||||
.cfi_startproc
|
||||
stp fp, lr, [sp,#-0x10]!
|
||||
mov fp, sp
|
||||
.cfi_def_cfa_offset 0x10
|
||||
.cfi_offset fp, -0x10
|
||||
.cfi_offset lr, -0x08
|
||||
|
||||
mov x8, x6
|
||||
mov x6, x7
|
||||
mov x7, #0
|
||||
bl CallARM64
|
||||
|
||||
mov x0, x8
|
||||
|
||||
ldp fp, lr, [sp],#0x10
|
||||
|
||||
.cfi_restore lr
|
||||
.cfi_restore fp
|
||||
.cfi_def_cfa_offset 0
|
||||
ret
|
||||
.cfi_endproc
|
|
@ -0,0 +1,205 @@
|
|||
;
|
||||
; AngelCode Scripting Library
|
||||
; Copyright (c) 2020-2020 Andreas Jonsson
|
||||
;
|
||||
; This software is provided 'as-is', without any express or implied
|
||||
; warranty. In no event will the authors be held liable for any
|
||||
; damages arising from the use of this software.
|
||||
;
|
||||
; Permission is granted to anyone to use this software for any
|
||||
; purpose, including commercial applications, and to alter it and
|
||||
; redistribute it freely, subject to the following restrictions:
|
||||
;
|
||||
; 1. The origin of this software must not be misrepresented; you
|
||||
; must not claim that you wrote the original software. If you use
|
||||
; this software in a product, an acknowledgment in the product
|
||||
; documentation would be appreciated but is not required.
|
||||
;
|
||||
; 2. Altered source versions must be plainly marked as such, and
|
||||
; must not be misrepresented as being the original software.
|
||||
;
|
||||
; 3. This notice may not be removed or altered from any source
|
||||
; distribution.
|
||||
;
|
||||
; The original version of this library can be located at:
|
||||
; http://www.angelcode.com/angelscript/
|
||||
;
|
||||
; Andreas Jonsson
|
||||
; andreas@angelcode.com
|
||||
;
|
||||
|
||||
|
||||
; Assembly routines for the ARM64/AArch64 call convention used for Windows 10 on ARM
|
||||
; Written by Max Waine in July 2020, based on as_callfunc_arm_msvc.asm
|
||||
|
||||
; MSVC currently doesn't support inline assembly for the ARM64 platform,
|
||||
; and if they're treating it like x64 /won't/ ever support inline assembly,
|
||||
; so this separate file is needed.
|
||||
|
||||
; Compile with Microsoft ARM64 assembler (armasm64)
|
||||
; http://msdn.microsoft.com/en-us/library/hh873190.aspx
|
||||
|
||||
AREA |.rdata|, DATA, READONLY
|
||||
EXPORT GetHFAReturnDouble
|
||||
EXPORT GetHFAReturnFloat
|
||||
EXPORT CallARM64Ret128
|
||||
EXPORT CallARM64RetInMemory
|
||||
EXPORT CallARM64Double
|
||||
EXPORT CallARM64Float
|
||||
EXPORT CallARM64
|
||||
|
||||
AREA |.text|, CODE, ALIGN=2
|
||||
|
||||
ALIGN 4
|
||||
GetHFAReturnDouble PROC
|
||||
adr x9, |populateDoubles|
|
||||
sub x9, x9, x1, lsr 1 ; x9 -= returnSize >> 1; (/2 because double is 2x instruction size)
|
||||
br x9
|
||||
|
||||
str d3, [x0, #0x18]
|
||||
str d2, [x0, #0x10]
|
||||
str d1, [x1]
|
||||
str d0, [x0]
|
||||
|populateDoubles|
|
||||
|
||||
ret
|
||||
ENDP ; GetHFAReturnDouble
|
||||
|
||||
ALIGN 4
|
||||
GetHFAReturnFloat PROC
|
||||
adr x9, |populateFloats|
|
||||
sub x9, x9, x2 // x9 -= returnSize; (already 4 bytes per return)
|
||||
br x9
|
||||
|
||||
str s3, [x1, #0x4]
|
||||
str s2, [x1]
|
||||
str s1, [x0, #0x4]
|
||||
str s0, [x0]
|
||||
|populateFloats|
|
||||
|
||||
ret
|
||||
ENDP ; GetHFAReturnFloat
|
||||
|
||||
|
||||
;[returnType] CallARM64[type](
|
||||
; const asQWORD *gpRegArgs, asQWORD numGPRegArgs,
|
||||
; const asQWORD *floatRegArgs, asQWORD numFloatRegArgs,
|
||||
; const asQWORD *stackArgs, asQWORD numStackArgs,
|
||||
; asFUNCTION_t func
|
||||
;)
|
||||
ALIGN 4
|
||||
CallARM64Double PROC
|
||||
stp fp, lr, [sp,#-0x10]!
|
||||
bl CallARM64
|
||||
ldp fp, lr, [sp,#-0x10]!
|
||||
ret
|
||||
ENDP ; CallARM64Double
|
||||
|
||||
ALIGN 4
|
||||
CallARM64Float PROC
|
||||
stp fp, lr, [sp,#-0x10]!
|
||||
bl CallARM64
|
||||
ldp fp, lr, [sp,#-0x10]!
|
||||
ret
|
||||
ENDP ; CallARM64Float
|
||||
|
||||
ALIGN 4
|
||||
CallARM64 PROC
|
||||
stp fp, lr, [sp,#-0x20]!
|
||||
str x20, [sp,#0x10]
|
||||
|
||||
mov x20, #0;
|
||||
|
||||
cbz x5, |stackArgsLoopEnd|
|
||||
|
||||
; Align count to 2, then multiply by 8, resulting in a size aligned to 16
|
||||
add x20, x5, #1
|
||||
lsl x20, x20, #3
|
||||
and x20, x20, #-0x10
|
||||
; Multiply count by 8
|
||||
lsl x10, x5, #3
|
||||
sub sp, sp, x20
|
||||
|stackArgsLoopStart|
|
||||
ldp x9,x11, [x4],#16
|
||||
stp x9,x11, [sp],#16
|
||||
subs x10, x10, #16
|
||||
bgt |stackArgsLoopStart|
|
||||
|stackArgsLoopEnd|
|
||||
|
||||
; Calculate amount to jump forward, avoiding pointless instructions
|
||||
adr x9, |populateFloatRegisterArgsEnd|
|
||||
sub x9, x9, x3, lsl 2 ; x9 -= numFloatRegArgs * 4
|
||||
br x9
|
||||
|
||||
ldr d7, [x2, #0x38]
|
||||
ldr d6, [x2, #0x30]
|
||||
ldr d5, [x2, #0x28]
|
||||
ldr d4, [x2, #0x20]
|
||||
ldr d3, [x2, #0x18]
|
||||
ldr d2, [x2, #0x10]
|
||||
ldr d1, [x2, #0x08]
|
||||
ldr d0, [x2]
|
||||
|populateFloatRegisterArgsEnd|
|
||||
|
||||
mov x15, x6
|
||||
; Calculate amount to jump forward, avoiding pointless instructions
|
||||
adr x9, |populateGPRegisterArgsEnd|
|
||||
sub x9, x9, x1, lsl 2 ; x9 -= numGPRegArgs * 4
|
||||
br x9
|
||||
|
||||
ldr x7, [x0, #0x38]
|
||||
ldr x6, [x0, #0x30]
|
||||
ldr x5, [x0, #0x28]
|
||||
ldr x4, [x0, #0x20]
|
||||
ldr x3, [x0, #0x18]
|
||||
ldr x2, [x0, #0x10]
|
||||
ldr x1, [x0, #0x08]
|
||||
ldr x0, [x0]
|
||||
|populateGPRegisterArgsEnd|
|
||||
|
||||
; Actually call function
|
||||
sub sp, sp, x20
|
||||
blr x15
|
||||
add sp, sp, x20
|
||||
|
||||
ldr x20, [sp,#0x10]
|
||||
ldp fp, lr, [sp],#0x20
|
||||
|
||||
ret
|
||||
ENDP ; CallARM64
|
||||
|
||||
ALIGN 4
|
||||
CallARM64Ret128 PROC
|
||||
stp fp, lr, [sp,#-0x20]!
|
||||
str x20, [sp,#0x10]
|
||||
mov fp, sp
|
||||
|
||||
mov x20, x6
|
||||
mov x6, x7
|
||||
mov x7, #0
|
||||
bl CallARM64
|
||||
|
||||
str x1, [x20]
|
||||
|
||||
ldr x20, [sp,#0x10]
|
||||
ldp fp, lr, [sp],#0x20
|
||||
|
||||
ret ; CallARM64Ret128
|
||||
|
||||
ALIGN 4
|
||||
CallARM64RetInMemory PROC
|
||||
stp fp, lr, [sp,#-0x10]!
|
||||
mov fp, sp
|
||||
|
||||
mov x8, x6
|
||||
mov x6, x7
|
||||
mov x7, #0
|
||||
bl CallARM64
|
||||
|
||||
mov x0, x8
|
||||
|
||||
ldp fp, lr, [sp],#0x10
|
||||
|
||||
ret ; CallARM64RetInMemory
|
||||
|
||||
END
|
|
@ -0,0 +1,730 @@
|
|||
/*
|
||||
AngelCode Scripting Library
|
||||
Copyright (c) 2003-2020 Andreas Jonsson
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
The original version of this library can be located at:
|
||||
http://www.angelcode.com/angelscript/
|
||||
|
||||
Andreas Jonsson
|
||||
andreas@angelcode.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Assembly routines for the ARM call convention
|
||||
Written by Fredrik Ehnbom in June 2009
|
||||
|
||||
Adapted to GNUC by darktemplar216 in September 2009
|
||||
|
||||
Modified by Lasse Oorni for 8-byte stack alignment in May 2012
|
||||
|
||||
The assembler routines for Linux were written by Carlos Luna in December 2012
|
||||
*/
|
||||
|
||||
#if !defined(AS_MAX_PORTABILITY)
|
||||
|
||||
#if defined(__arm__) || defined(__ARM__) || defined(I3D_ARCH_ARM)
|
||||
|
||||
#if !defined(__linux__) || defined(__ANDROID__) || defined(ANDROID) || defined(__SOFTFP__) || defined(__ARM_PCS)
|
||||
|
||||
/* iOS, Android, Marmalade, and Linux with soft-float ABI goes here */
|
||||
|
||||
.global armFunc
|
||||
.global armFuncR0
|
||||
.global armFuncR0R1
|
||||
.global armFuncObjLast
|
||||
.global armFuncR0ObjLast
|
||||
|
||||
/* --------------------------------------------------------------------------------------------*/
|
||||
armFunc:
|
||||
stmdb sp!, {r4-r8, lr}
|
||||
mov r6, r0 /* arg table */
|
||||
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
|
||||
mov r4, r2 /* function address */
|
||||
mov r8, #0
|
||||
|
||||
beq nomoreargs
|
||||
|
||||
/* Load the first 4 arguments into r0-r3 */
|
||||
cmp r7, #4
|
||||
ldrge r0, [r6],#4
|
||||
cmp r7, #2*4
|
||||
ldrge r1, [r6],#4
|
||||
cmp r7, #3*4
|
||||
ldrge r2, [r6],#4
|
||||
cmp r7, #4*4
|
||||
ldrge r3, [r6],#4
|
||||
ble nomoreargs
|
||||
|
||||
/* Load the rest of the arguments onto the stack */
|
||||
sub r7, r7, #4*4 /* skip the 4 registers already loaded into r0-r3 */
|
||||
add r8, r7, #4 /* ensure 8-byte stack alignment */
|
||||
bic r8, r8, #4
|
||||
sub sp, sp, r8
|
||||
mov r12, sp /* copy size != frame size, so store frame start sp */
|
||||
stackargsloop:
|
||||
ldr r5, [r6], #4
|
||||
str r5, [sp], #4
|
||||
subs r7, r7, #4
|
||||
bne stackargsloop
|
||||
mov sp, r12
|
||||
nomoreargs:
|
||||
#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
|
||||
mov lr, pc /* older ARM didn't support blx */
|
||||
mov pc, r4
|
||||
#else
|
||||
blx r4
|
||||
#endif
|
||||
add sp, sp, r8
|
||||
ldmia sp!, {r4-r8, pc}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------*/
|
||||
armFuncObjLast:
|
||||
stmdb sp!, {r4-r8, lr}
|
||||
mov r6, r0 /* arg table */
|
||||
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
|
||||
mov r4, r2 /* function address */
|
||||
mov r8, #0
|
||||
|
||||
mov r0, r3 /* objlast. might get overwritten */
|
||||
mov r5, r3 /* objlast to temp reg */
|
||||
|
||||
beq nomoreargsarmFuncObjLast
|
||||
|
||||
/* Load the first 4 arguments into r0-r3 */
|
||||
cmp r7, #4
|
||||
ldrge r0, [r6],#4
|
||||
cmp r7, #2*4
|
||||
ldrge r1, [r6],#4
|
||||
movlt r1, r5
|
||||
cmp r7, #3*4
|
||||
ldrge r2, [r6],#4
|
||||
movlt r2, r5
|
||||
cmp r7, #4*4
|
||||
ldrge r3, [r6],#4
|
||||
movlt r3, r5
|
||||
blt nomoreargsarmFuncObjLast
|
||||
|
||||
/* Load the rest of the arguments onto the stack */
|
||||
sub r7, r7, #4*4 /* skip the 4 registers already loaded into r0-r3 */
|
||||
add r8, r7, #8 /* account for the objlast pointer, ensure 8-byte stack alignment */
|
||||
bic r8, r8, #4
|
||||
str r5, [sp,#-4] /* store the objlast on stack, twice in case we adjusted alignment */
|
||||
str r5, [sp,#-8]
|
||||
sub sp, sp, r8 /* adjust frame */
|
||||
cmp r7, #0 /* we may also have come here with no extra params */
|
||||
beq nomoreargsarmFuncObjLast
|
||||
mov r12, sp /* copy size != frame size, so store frame start sp */
|
||||
stackargslooparmFuncObjLast:
|
||||
ldr r5, [r6], #4
|
||||
str r5, [sp], #4
|
||||
subs r7, r7, #4
|
||||
bne stackargslooparmFuncObjLast
|
||||
mov sp, r12
|
||||
nomoreargsarmFuncObjLast:
|
||||
#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
|
||||
mov lr, pc /* older ARM didn't support blx */
|
||||
mov pc, r4
|
||||
#else
|
||||
blx r4
|
||||
#endif
|
||||
add sp, sp, r8
|
||||
ldmia sp!, {r4-r8, pc}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------*/
|
||||
armFuncR0ObjLast:
|
||||
stmdb sp!, {r4-r8, lr}
|
||||
ldr r5, [sp,#6*4] /* objlast to temp reg */
|
||||
|
||||
mov r6, r0 /* arg table */
|
||||
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
|
||||
mov r4, r2 /* function address */
|
||||
mov r8, #0
|
||||
|
||||
mov r0, r3 /* r0 explicitly set */
|
||||
mov r1, r5 /* objlast. might get overwritten */
|
||||
|
||||
beq nomoreargsarmFuncR0ObjLast
|
||||
|
||||
/* Load the first 3 arguments into r1-r3 */
|
||||
cmp r7, #1*4
|
||||
ldrge r1, [r6],#4
|
||||
cmp r7, #2*4
|
||||
ldrge r2, [r6],#4
|
||||
movlt r2, r5
|
||||
cmp r7, #3*4
|
||||
ldrge r3, [r6],#4
|
||||
movlt r3, r5
|
||||
blt nomoreargsarmFuncR0ObjLast
|
||||
|
||||
/* Load the rest of the arguments onto the stack */
|
||||
sub r7, r7, #3*4 /* skip the 3 registers already loaded into r1-r3 */
|
||||
add r8, r7, #8 /* account for the objlast pointer, ensure 8-byte stack alignment */
|
||||
bic r8, r8, #4
|
||||
str r5, [sp,#-4] /* store the objlast on stack, twice in case we adjusted alignment */
|
||||
str r5, [sp,#-8]
|
||||
sub sp, sp, r8 /* adjust frame */
|
||||
cmp r7, #0 /* we may also have come here with no extra params */
|
||||
beq nomoreargsarmFuncR0ObjLast
|
||||
mov r12, sp /* copy size != frame size, so store frame start sp */
|
||||
stackargslooparmFuncR0ObjLast:
|
||||
ldr r5, [r6], #4
|
||||
str r5, [sp], #4
|
||||
subs r7, r7, #4
|
||||
bne stackargslooparmFuncR0ObjLast
|
||||
mov sp, r12
|
||||
nomoreargsarmFuncR0ObjLast:
|
||||
#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
|
||||
mov lr, pc /* older ARM didn't support blx */
|
||||
mov pc, r4
|
||||
#else
|
||||
blx r4
|
||||
#endif
|
||||
add sp, sp, r8
|
||||
ldmia sp!, {r4-r8, pc}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------*/
|
||||
armFuncR0:
|
||||
stmdb sp!, {r4-r8, lr}
|
||||
mov r6, r0 /* arg table */
|
||||
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
|
||||
mov r4, r2 /* function address */
|
||||
mov r8, #0
|
||||
|
||||
mov r0, r3 /* r0 explicitly set */
|
||||
|
||||
beq nomoreargsarmFuncR0
|
||||
|
||||
/* Load the first 3 arguments into r1-r3 */
|
||||
cmp r7, #1*4
|
||||
ldrge r1, [r6],#4
|
||||
cmp r7, #2*4
|
||||
ldrge r2, [r6],#4
|
||||
cmp r7, #3*4
|
||||
ldrge r3, [r6],#4
|
||||
ble nomoreargsarmFuncR0
|
||||
|
||||
/* Load the rest of the arguments onto the stack */
|
||||
sub r7, r7, #3*4 /* skip the 3 registers already loaded into r1-r3 */
|
||||
add r8, r7, #4 /* ensure 8-byte stack alignment */
|
||||
bic r8, r8, #4
|
||||
sub sp, sp, r8
|
||||
mov r12, sp /* copy size != frame size, so store frame start sp */
|
||||
stackargslooparmFuncR0:
|
||||
ldr r5, [r6], #4
|
||||
str r5, [sp], #4
|
||||
subs r7, r7, #4
|
||||
bne stackargslooparmFuncR0
|
||||
mov sp, r12
|
||||
nomoreargsarmFuncR0:
|
||||
#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
|
||||
mov lr, pc /* older ARM didn't support blx */
|
||||
mov pc, r4
|
||||
#else
|
||||
blx r4
|
||||
#endif
|
||||
add sp, sp, r8
|
||||
ldmia sp!, {r4-r8, pc}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------*/
|
||||
armFuncR0R1:
|
||||
stmdb sp!, {r4-r8, lr}
|
||||
mov r6, r0 /* arg table */
|
||||
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
|
||||
mov r4, r2 /* function address */
|
||||
mov r8, #0
|
||||
|
||||
mov r0, r3 /* r0 explicitly set */
|
||||
ldr r1, [sp, #6*4] /* r1 explicitly set too */
|
||||
|
||||
beq nomoreargsarmFuncR0R1
|
||||
|
||||
/* Load the first 2 arguments into r2-r3 */
|
||||
cmp r7, #1*4
|
||||
ldrge r2, [r6],#4
|
||||
cmp r7, #2*4
|
||||
ldrge r3, [r6],#4
|
||||
ble nomoreargsarmFuncR0R1
|
||||
|
||||
/* Load the rest of the arguments onto the stack */
|
||||
sub r7, r7, #2*4 /* skip the 2 registers already loaded into r2-r3 */
|
||||
add r8, r7, #4 /* ensure 8-byte stack alignment */
|
||||
bic r8, r8, #4
|
||||
sub sp, sp, r8
|
||||
mov r12, sp /* copy size != frame size, so store frame start sp */
|
||||
stackargslooparmFuncR0R1:
|
||||
ldr r5, [r6], #4
|
||||
str r5, [sp], #4
|
||||
subs r7, r7, #4
|
||||
bne stackargslooparmFuncR0R1
|
||||
mov sp, r12
|
||||
nomoreargsarmFuncR0R1:
|
||||
#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
|
||||
mov lr, pc /* older ARM didn't support blx */
|
||||
mov pc, r4
|
||||
#else
|
||||
blx r4
|
||||
#endif
|
||||
add sp, sp, r8
|
||||
ldmia sp!, {r4-r8, pc}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------*/
|
||||
#elif defined(__linux__) && !defined(__SOFTFP__) && !defined(__ARM_PCS)
|
||||
|
||||
/* The Linux with hard-float ABI code goes here */
|
||||
|
||||
|
||||
/* These codes are suitable for armeabi + vfp / armeabihf */
|
||||
/* when using armeabi + vfp, please set C_FLAGS -mfloat-abi=softfp -mfpu=vfp */
|
||||
/* using armeabihf, please set C_FLAGS -mfloat-abi=hard -mfpu=vfpv3-d16 */
|
||||
|
||||
/* if you prefer to run in ARM mode, please add -marm to C_FLAGS */
|
||||
/* while using thumb mode, please add -mthumb -Wa,-mimplicit-it=thumb */
|
||||
|
||||
|
||||
/* SP is a multiple of 8 when control first enters a program.*/
|
||||
/* This places an obligation on authors of low level OS, RTOS, and runtime library code to align SP at all points */
|
||||
/* at which control first enters a body of (AAPCS-conforming) code. (please read "ARM IHI 0046B" document)*/
|
||||
|
||||
|
||||
.section .text
|
||||
|
||||
.align 2 /* Align the function code to a 4-byte (2^n) word boundary. */
|
||||
#if defined(__thumb__) || defined(__thumb2__)
|
||||
.thumb
|
||||
.syntax unified
|
||||
#else
|
||||
.arm /* Use ARM instructions instead of Thumb.*/
|
||||
#endif
|
||||
.globl armFunc /* Make the function globally accessible.*/
|
||||
armFunc:
|
||||
push {r4-r8, r10, r11, lr} /* sp must be 8-byte alignment for ABI compliance, so the pushed registers must be even */
|
||||
|
||||
mov r6, r0 /* arg table */
|
||||
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
|
||||
mov r4, r2 /* function address */
|
||||
|
||||
/* Load float and double args into d0-d7 and s0-s15 */
|
||||
add r10, r6, #272 /* r10 (r6 + 272) points to the first value for the VFP registers */
|
||||
mov r8, #0
|
||||
vldmia.64 r10, {d0-d7} /* Load contents starting at r10 into registers d0-d7 */
|
||||
|
||||
/* If there are no arguments to set into r0-r3 */
|
||||
/* go check if there are arguments for the stack */
|
||||
beq stackargs
|
||||
|
||||
/* Load the first 4 arguments into r0-r3 */
|
||||
cmp r7, #4
|
||||
ldrge r0, [r6]
|
||||
cmp r7, #8
|
||||
ldrge r1, [r6, #4]
|
||||
cmp r7, #12
|
||||
ldrge r2, [r6, #8]
|
||||
cmp r7, #16
|
||||
ldrge r3, [r6, #12]
|
||||
|
||||
stackargs:
|
||||
ldr r5, [r6, #268] /* Load stack size into r5 */
|
||||
movs r7, r5 /* Load stack size into r7, checking for 0 args */
|
||||
|
||||
/* If there are no args for the stack, branch */
|
||||
beq nomoreargs
|
||||
|
||||
/* Load the rest of the arguments onto the stack */
|
||||
/* Ensure 8-byte stack alignment */
|
||||
mov r8, sp
|
||||
sub sp, sp, r7
|
||||
add r6, r6, #16 /* Set r6 to point to the first arg to be placed on the stack */
|
||||
|
||||
sub r12, sp, #8
|
||||
bic r12, r12, #7 /* thumb mode couldn't support "bic sp, sp, #7" instruction */
|
||||
sub r8, r8, r12
|
||||
mov sp, r12 /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
|
||||
|
||||
stackargsloop:
|
||||
ldr r5, [r6], #4
|
||||
subs r7, r7, #4
|
||||
str r5, [sp], #4
|
||||
bne stackargsloop
|
||||
mov sp, r12
|
||||
|
||||
nomoreargs:
|
||||
#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
|
||||
mov lr, pc /* older ARM didn't support blx */
|
||||
mov pc, r4
|
||||
#else
|
||||
blx r4
|
||||
#endif
|
||||
add sp, sp, r8
|
||||
vstmia.64 r10, {d0-d7} /* Copy contents of registers d0-d7 to the address stored in r10 */
|
||||
|
||||
pop {r4-r8, r10, r11, pc}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------*/
|
||||
.align 2 /* Align the function code to a 4-byte (2^n) word boundary. */
|
||||
#if defined(__thumb__) || defined(__thumb2__)
|
||||
.thumb
|
||||
.syntax unified
|
||||
#else
|
||||
.arm /* Use ARM instructions instead of Thumb.*/
|
||||
#endif
|
||||
.globl armFuncObjLast /* Make the function globally accessible.*/
|
||||
armFuncObjLast:
|
||||
push {r4-r8, r10, r11, lr} /* We´re storing r11 just to keep the stack aligned to an 8 byte boundary */
|
||||
|
||||
mov r6, r0 /* arg table */
|
||||
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
|
||||
mov r4, r2 /* function address */
|
||||
|
||||
mov r0, r3 /* objlast. might get overwritten */
|
||||
mov r5, #0 /* This will hold an offset of #4 only if objlast couldn´t be placed into an "r" register */
|
||||
|
||||
/* Load float and double args into d0-d7 and s0-s15 (r10 holds pointer to first float value) */
|
||||
add r10, r6, #272 /* r10 (r6 + 272) points to the first value for the VFP registers */
|
||||
mov r8, #0
|
||||
vldmia.64 r10, {d0-d7} /* Load contents starting at r10 into registers d0-d7 */
|
||||
|
||||
/* If there are no arguments to set into r0-r3 */
|
||||
/* go check if there are arguments for the stack */
|
||||
beq stackargsFuncObjLast
|
||||
|
||||
mov r5, r3 /* store objlast in r5 temporarily */
|
||||
|
||||
/* Load the first 4 arguments into r0-r3 */
|
||||
cmp r7, #4
|
||||
ldrge r0, [r6]
|
||||
cmp r7, #8
|
||||
ldrge r1, [r6,#4]
|
||||
movlt r1, r5
|
||||
cmp r7, #12
|
||||
ldrge r2, [r6,#8]
|
||||
movlt r2, r5
|
||||
cmp r7, #16
|
||||
ldrge r3, [r6,#12]
|
||||
movlt r3, r5
|
||||
movlt r5, #0 /* If objlast got placed into a register, r5 = 0 */
|
||||
blt stackargsFuncObjLast /* If objlast got placed into a register, go to stackargsFuncObjLast */
|
||||
|
||||
str r5, [r6, #12] /* Put objlast in r6 + 12 */
|
||||
mov r5, #4 /* Set r5 with an offset of #4, so objlast can be loaded into the stack */
|
||||
|
||||
stackargsFuncObjLast:
|
||||
ldr r7, [r6, #268] /* Load stack size into r7 */
|
||||
add r7, r7, r5 /* Add the offset placed in r5 (could be #0 or #4) */
|
||||
cmp r7, #0 /* Check for 0 args */
|
||||
|
||||
/* If there are no args for the stack, branch */
|
||||
beq nomoreargsarmFuncObjLast
|
||||
|
||||
/* Load the rest of the arguments onto the stack */
|
||||
/* Ensure 8-byte stack alignment */
|
||||
mov r8, sp
|
||||
sub sp, sp, r7
|
||||
add r6, r6, #16 /* Set r6 to point to the first arg to be placed on the stack */
|
||||
|
||||
sub r12, sp, #8
|
||||
sub r6, r6, r5 /* r6 = r6 - r5 (r5 can be #0 or #4) */
|
||||
bic r12, r12, #7 /* thumb mode couldn't support "bic sp, sp, #7" instruction */
|
||||
sub r8, r8, r12
|
||||
mov sp, r12 /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
|
||||
|
||||
stackargslooparmFuncObjLast:
|
||||
ldr r5, [r6], #4
|
||||
subs r7, r7, #4
|
||||
str r5, [sp], #4
|
||||
bne stackargslooparmFuncObjLast
|
||||
mov sp, r12
|
||||
|
||||
nomoreargsarmFuncObjLast:
|
||||
#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
|
||||
mov lr, pc /* older ARM didn't support blx */
|
||||
mov pc, r4
|
||||
#else
|
||||
blx r4
|
||||
#endif
|
||||
add sp, sp, r8
|
||||
vstmia.64 r10, {d0-d7} /* Copy contents of registers d0-d10 to the address stored in r10 */
|
||||
|
||||
pop {r4-r8, r10,r11, pc}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------- */
|
||||
.align 2 /* Align the function code to a 4-byte (2^n) word boundary. */
|
||||
#if defined(__thumb__) || defined(__thumb2__)
|
||||
.thumb
|
||||
.syntax unified
|
||||
#else
|
||||
.arm /* Use ARM instructions instead of Thumb.*/
|
||||
#endif
|
||||
.globl armFuncR0ObjLast /* Make the function globally accessible.*/
|
||||
armFuncR0ObjLast:
|
||||
push {r4-r8, r10, r11, lr}
|
||||
|
||||
ldr r5, [sp,#32] /* objlast to temp reg */
|
||||
|
||||
mov r6, r0 /* arg table */
|
||||
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
|
||||
mov r4, r2 /* function address */
|
||||
|
||||
mov r0, r3 /* r0 explicitly set */
|
||||
mov r1, r5 /* objlast. might get overwritten */
|
||||
mov r5, #0 /* This will hold an offset of #4 or #8 if objlast or one arg couldn´t be placed into an "r" register */
|
||||
|
||||
/* Load float and double args into d0-d7 and s0-s15 (r10 holds pointer to first float value) */
|
||||
add r10, r6, #272 /* r10 (r6 + 272) points to the first value for the VFP registers */
|
||||
mov r8, #0
|
||||
vldmia.64 r10, {d0-d7} /* Load contents starting at r10 into registers d0-d7 */
|
||||
|
||||
/* If there are no arguments to set into r0-r3 */
|
||||
/* go check if there are arguments for the stack */
|
||||
beq stackargsFuncR0ObjLast
|
||||
|
||||
mov r5, r1 /* store objlast in r5 temporarily */
|
||||
|
||||
/* Load the first 3 arguments into r1-r3 */
|
||||
cmp r7, #4
|
||||
ldrge r1, [r6]
|
||||
cmp r7, #8
|
||||
ldrge r2, [r6,#4]
|
||||
movlt r2, r5
|
||||
cmp r7, #12
|
||||
ldrge r3, [r6,#8]
|
||||
movlt r3, r5
|
||||
movlt r5, #0 /* If objlast got placed into a register, r5 = 0 */
|
||||
blt stackargsFuncR0ObjLast /* If objlast got placed into a register, go to stackargsFuncR0ObjLast */
|
||||
|
||||
cmp r7, #16 /* Else if we have one last arg set the offset accordingly and store the arg in the array */
|
||||
ldrge r7, [r6, #12]
|
||||
strge r7, [r6, #8]
|
||||
|
||||
str r5, [r6, #12] /* Put objlast in r6 + 12 */
|
||||
mov r5, #0
|
||||
|
||||
movge r5, #4 /* Set r5 with an offset of #4 if there´s one last arg that couldn´t be placed in r registers */
|
||||
add r5, r5, #4 /* Set r5 with an offset of + #4, so objlast can be loaded into the stack */
|
||||
|
||||
stackargsFuncR0ObjLast:
|
||||
ldr r7, [r6, #268] /* Load stack size into r7 */
|
||||
add r7, r7, r5 /* Add the offset placed in r5 (could be #0 or #4) */
|
||||
cmp r7, #0 /* Check for 0 args */
|
||||
|
||||
/* If there are no args for the stack, branch */
|
||||
beq nomoreargsarmFuncR0ObjLast
|
||||
|
||||
/* Load the rest of the arguments onto the stack */
|
||||
/* Ensure 8-byte stack alignment */
|
||||
mov r8, sp
|
||||
sub sp, sp, r7
|
||||
add r6, r6, #16 /* Set r6 to point to the first arg to be placed on the stack */
|
||||
|
||||
sub r12, sp, #8
|
||||
sub r6, r6, r5 /* r6 = r6 - r5 (r5 can be #0 or #4) */
|
||||
bic r12, r12, #7 /* thumb mode couldn't support "bic sp, sp, #7" instruction */
|
||||
sub r8, r8, r12
|
||||
mov sp, r12 /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
|
||||
|
||||
stackargslooparmFuncR0ObjLast:
|
||||
ldr r5, [r6], #4
|
||||
subs r7, r7, #4
|
||||
str r5, [sp], #4
|
||||
bne stackargslooparmFuncR0ObjLast
|
||||
mov sp, r12
|
||||
|
||||
nomoreargsarmFuncR0ObjLast:
|
||||
#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
|
||||
mov lr, pc /* older ARM didn't support blx */
|
||||
mov pc, r4
|
||||
#else
|
||||
blx r4
|
||||
#endif
|
||||
add sp, sp, r8
|
||||
vstmia.64 r10, {d0-d7} /* Copy contents of registers d0-d10 to the address stored in r10 */
|
||||
|
||||
pop {r4-r8, r10, r11, pc}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------- */
|
||||
.align 2 /* Align the function code to a 4-byte (2^n) word boundary. */
|
||||
#if defined(__thumb__) || defined(__thumb2__)
|
||||
.thumb
|
||||
.syntax unified
|
||||
#else
|
||||
.arm /* Use ARM instructions instead of Thumb.*/
|
||||
#endif
|
||||
.globl armFuncR0 /* Make the function globally accessible.*/
|
||||
armFuncR0:
|
||||
push {r4-r8, r10, r11, lr}
|
||||
|
||||
mov r6, r0 /* arg table */
|
||||
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
|
||||
mov r4, r2 /* function address */
|
||||
mov r11, #0 /* This will hold an offset of #4 only if the last arg that should have been placed into an "r" reg needs to go to the stack */
|
||||
mov r0, r3 /* r0 explicitly set */
|
||||
|
||||
/* Load float and double args into d0-d7 and s0-s15 (r10 holds pointer to first float value) */
|
||||
add r10, r6, #272 /* r10 (r6 + 272) points to the first value for the VFP registers */
|
||||
mov r8, #0
|
||||
vldmia.64 r10, {d0-d7} /* Load contents starting at r10 into registers d0-d7 */
|
||||
|
||||
/* If there are no arguments to set into r0-r3 */
|
||||
/* go check if there are arguments for the stack */
|
||||
beq stackargsarmFuncR0
|
||||
|
||||
/* Load the first 3 arguments into r1-r3 */
|
||||
cmp r7, #4
|
||||
ldrge r1, [r6]
|
||||
cmp r7, #8
|
||||
ldrge r2, [r6, #4]
|
||||
cmp r7, #12
|
||||
ldrge r3, [r6, #8]
|
||||
cmp r7, #16
|
||||
movge r11, #4 /* If there is still one arg to be placed, set the offset in r11 to #4 */
|
||||
|
||||
stackargsarmFuncR0:
|
||||
ldr r5, [r6, #268] /* Load stack size into r5 */
|
||||
add r5, r11 /* Add the offset placed in r11 (could be #0 or #4) */
|
||||
movs r7, r5 /* Load stack size into r7, checking for 0 args */
|
||||
|
||||
/* If there are no args for the stack, branch */
|
||||
beq nomoreargsarmFuncR0
|
||||
|
||||
/* Load the rest of the arguments onto the stack */
|
||||
/* Ensure 8-byte stack alignment */
|
||||
mov r8, sp
|
||||
sub sp, sp, r7
|
||||
add r6, r6, #16 /* Set r6 to point to the first arg to be placed on the stack */
|
||||
|
||||
sub r12, sp, #8
|
||||
sub r6, r6, r11 /* r6 = r6 - r11 (r11 can be #0 or #4) */
|
||||
bic r12, r12, #7 /* thumb mode couldn't support "bic sp, sp, #7" instruction */
|
||||
sub r8, r8, r12
|
||||
mov sp, r12 /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
|
||||
|
||||
stackargslooparmFuncR0:
|
||||
ldr r5, [r6], #4
|
||||
subs r7, r7, #4
|
||||
str r5, [sp], #4
|
||||
bne stackargslooparmFuncR0
|
||||
mov sp, r12
|
||||
|
||||
nomoreargsarmFuncR0:
|
||||
#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
|
||||
mov lr, pc /* older ARM didn't support blx */
|
||||
mov pc, r4
|
||||
#else
|
||||
blx r4
|
||||
#endif
|
||||
add sp, sp, r8
|
||||
vstmia.64 r10, {d0-d7} /* Copy contents of registers d0-d10 to the address stored in r10 */
|
||||
|
||||
pop {r4-r8, r10, r11, pc}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------- */
|
||||
.align 2 /* Align the function code to a 4-byte (2^n) word boundary. */
|
||||
#if defined(__thumb__) || defined(__thumb2__)
|
||||
.thumb
|
||||
.syntax unified
|
||||
#else
|
||||
.arm /* Use ARM instructions instead of Thumb.*/
|
||||
#endif
|
||||
.globl armFuncR0R1 /* Make the function globally accessible.*/
|
||||
armFuncR0R1:
|
||||
push {r4-r8, r10, r11, lr}
|
||||
|
||||
mov r6, r0 /* arg table */
|
||||
movs r7, r1 /* arg size (also set the condition code flags so that we detect if there are no arguments) */
|
||||
mov r4, r2 /* function address */
|
||||
mov r11, #0 /* This will hold an offset of #4 or #8 only if the last arg (or last 2 args) that should have been placed into "r" regs need to go to the stack */
|
||||
|
||||
mov r0, r3 /* r0 explicitly set */
|
||||
ldr r1, [sp, #32] /* r1 explicitly set too */
|
||||
|
||||
/* Load float and double args into d0-d7 and s0-s15 (r10 holds pointer to first float value) */
|
||||
add r10, r6, #272 /* r10 (r6 + 272) points to the first value for the VFP registers */
|
||||
mov r8, #0
|
||||
vldmia.64 r10, {d0-d7} /* Load contents starting at r10 into registers d0-d7 */
|
||||
|
||||
/* If there are no arguments to set into r2-r3 */
|
||||
/* go check if there are arguments for the stack */
|
||||
beq stackargsarmFuncR0R1
|
||||
|
||||
/* Load the first 2 arguments into r2-r3 */
|
||||
cmp r7, #4
|
||||
ldrge r2, [r6]
|
||||
cmp r7, #8
|
||||
ldrge r3, [r6, #4]
|
||||
cmp r7, #12
|
||||
movge r11, #4 /* If there is a third arg to be placed, set the offset in r11 to #4 */
|
||||
cmp r7, #16
|
||||
movge r11, #8 /* If there is a fourth arg to be placed, set the offset in r11 to #8 */
|
||||
ldrlt r7, [r6, #8] /* Else copy the third arg to the correct place in the array */
|
||||
strlt r7, [r6, #12]
|
||||
|
||||
stackargsarmFuncR0R1:
|
||||
ldr r5, [r6, #268] /* Load stack size into r5 */
|
||||
add r5, r11 /* Add the offset placed in r11 (could be #0 or #4 or #8) */
|
||||
movs r7, r5 /* Load stack size into r7, checking for 0 args */
|
||||
|
||||
/* If there are no args for the stack, branch */
|
||||
beq nomoreargsarmFuncR0R1
|
||||
|
||||
/* Load the rest of the arguments onto the stack */
|
||||
/* Ensure 8-byte stack alignment */
|
||||
mov r8, sp
|
||||
sub sp, sp, r7
|
||||
add r6, r6, #16 /* Set r6 to point to the first arg to be placed on the stack */
|
||||
|
||||
sub r12, sp, #8
|
||||
sub r6, r6, r11 /* r6 = r6 - r11 (r11 can be #0 or #4 or #8) */
|
||||
bic r12, r12, #7 /* thumb mode couldn't support "bic sp, sp, #7" instruction */
|
||||
sub r8, r8, r12
|
||||
mov sp, r12 /* copy size != frame size, so store frame start sp, r12(ip) is not callee saved register */
|
||||
|
||||
stackargslooparmFuncR0R1:
|
||||
ldr r5, [r6], #4
|
||||
subs r7, r7, #4
|
||||
str r5, [sp], #4
|
||||
bne stackargslooparmFuncR0R1
|
||||
mov sp, r12
|
||||
|
||||
nomoreargsarmFuncR0R1:
|
||||
#if defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_4__)
|
||||
mov lr, pc /* older ARM didn't support blx */
|
||||
mov pc, r4
|
||||
#else
|
||||
blx r4
|
||||
#endif
|
||||
add sp, sp, r8
|
||||
vstmia.64 r10, {d0-d7} /* Copy contents of registers d0-d10 to the address stored in r10 */
|
||||
|
||||
pop {r4-r8, r10, r11, pc}
|
||||
|
||||
#endif /* hard float abi */
|
||||
|
||||
#endif /* arm */
|
||||
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
/* ref: http://hardened.gentoo.org/gnu-stack.xml
|
||||
ref: https://wiki.gentoo.org/wiki/Hardened/GNU_stack_quickstart */
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
|
||||
#endif /* !AS_MAX_PORTABILITY */
|
||||
|
||||
|
|
@ -0,0 +1,249 @@
|
|||
;
|
||||
; AngelCode Scripting Library
|
||||
; Copyright (c) 2003-2014 Andreas Jonsson
|
||||
;
|
||||
; This software is provided 'as-is', without any express or implied
|
||||
; warranty. In no event will the authors be held liable for any
|
||||
; damages arising from the use of this software.
|
||||
;
|
||||
; Permission is granted to anyone to use this software for any
|
||||
; purpose, including commercial applications, and to alter it and
|
||||
; redistribute it freely, subject to the following restrictions:
|
||||
;
|
||||
; 1. The origin of this software must not be misrepresented; you
|
||||
; must not claim that you wrote the original software. If you use
|
||||
; this software in a product, an acknowledgment in the product
|
||||
; documentation would be appreciated but is not required.
|
||||
;
|
||||
; 2. Altered source versions must be plainly marked as such, and
|
||||
; must not be misrepresented as being the original software.
|
||||
;
|
||||
; 3. This notice may not be removed or altered from any source
|
||||
; distribution.
|
||||
;
|
||||
; The original version of this library can be located at:
|
||||
; http://www.angelcode.com/angelscript/
|
||||
;
|
||||
; Andreas Jonsson
|
||||
; andreas@angelcode.com
|
||||
;
|
||||
|
||||
|
||||
; Assembly routines for the ARM call convention used for Windows CE
|
||||
; Written by Fredrik Ehnbom in June 2009
|
||||
|
||||
; MSVC currently doesn't support inline assembly for the ARM platform
|
||||
; so this separate file is needed.
|
||||
|
||||
; Compile with Microsoft ARM assembler (armasm)
|
||||
; http://msdn.microsoft.com/en-us/library/hh873190.aspx
|
||||
|
||||
|
||||
AREA |.rdata|, DATA, READONLY
|
||||
EXPORT armFunc
|
||||
EXPORT armFuncR0
|
||||
EXPORT armFuncR0R1
|
||||
EXPORT armFuncObjLast
|
||||
EXPORT armFuncR0ObjLast
|
||||
|
||||
AREA |.text|, CODE, ARM, ALIGN=3
|
||||
|
||||
ALIGN 8
|
||||
armFunc PROC
|
||||
stmdb sp!, {r4-r8, lr}
|
||||
mov r6, r0 ; arg table
|
||||
movs r7, r1 ; arg size (also set the condition code flags so that we detect if there are no arguments)
|
||||
mov r4, r2 ; function address
|
||||
mov r8, #0
|
||||
|
||||
beq |nomoreargs|
|
||||
|
||||
; Load the first 4 arguments into r0-r3
|
||||
cmp r7, #4
|
||||
ldrge r0, [r6],#4
|
||||
cmp r7, #2*4
|
||||
ldrge r1, [r6],#4
|
||||
cmp r7, #3*4
|
||||
ldrge r2, [r6],#4
|
||||
cmp r7, #4*4
|
||||
ldrge r3, [r6],#4
|
||||
ble |nomoreargs|
|
||||
|
||||
; Load the rest of the arguments onto the stack
|
||||
sub r7, r7, #4*4 ; skip the 4 registers already loaded into r0-r3
|
||||
sub sp, sp, r7
|
||||
mov r8, r7
|
||||
|stackargsloop|
|
||||
ldr r5, [r6], #4
|
||||
str r5, [sp], #4
|
||||
subs r7, r7, #4
|
||||
bne |stackargsloop|
|
||||
|nomoreargs|
|
||||
sub sp, sp, r8
|
||||
blx r4
|
||||
add sp, sp, r8
|
||||
ldmia sp!, {r4-r8, pc}
|
||||
ENDP
|
||||
|
||||
ALIGN 8
|
||||
armFuncObjLast PROC
|
||||
stmdb sp!, {r4-r8, lr}
|
||||
mov r6, r0 ; arg table
|
||||
movs r7, r1 ; arg size (also set the condition code flags so that we detect if there are no arguments)
|
||||
mov r4, r2 ; function address
|
||||
mov r8, #0
|
||||
|
||||
mov r0, r3 ; objlast. might get overwritten
|
||||
str r3, [sp, #-4]! ; objlast again.
|
||||
|
||||
beq |nomoreargs@armFuncObjLast|
|
||||
|
||||
; Load the first 4 arguments into r0-r3
|
||||
cmp r7, #4
|
||||
ldrge r0, [r6],#4
|
||||
cmp r7, #2*4
|
||||
ldrge r1, [r6],#4
|
||||
ldrlt r1, [sp]
|
||||
cmp r7, #3*4
|
||||
ldrge r2, [r6],#4
|
||||
ldrlt r2, [sp]
|
||||
cmp r7, #4*4
|
||||
ldrge r3, [r6],#4
|
||||
ldrlt r3, [sp]
|
||||
ble |nomoreargs@armFuncObjLast|
|
||||
|
||||
; Load the rest of the arguments onto the stack
|
||||
sub r7, r7, #4*4 ; skip the 4 registers already loaded into r0-r3
|
||||
sub sp, sp, r7
|
||||
mov r8, r7
|
||||
|stackargsloop@armFuncObjLast|
|
||||
ldr r5, [r6], #4
|
||||
str r5, [sp], #4
|
||||
subs r7, r7, #4
|
||||
bne |stackargsloop@armFuncObjLast|
|
||||
|nomoreargs@armFuncObjLast|
|
||||
sub sp, sp, r8
|
||||
blx r4
|
||||
add sp, sp, r8
|
||||
add sp, sp, #4
|
||||
ldmia sp!, {r4-r8, pc}
|
||||
ENDP
|
||||
|
||||
ALIGN 8
|
||||
armFuncR0ObjLast PROC
|
||||
stmdb sp!, {r4-r8, lr}
|
||||
ldr r7, [sp,#6*4]
|
||||
str r7, [sp,#-4]!
|
||||
|
||||
mov r6, r0 ; arg table
|
||||
movs r7, r1 ; arg size (also set the condition code flags so that we detect if there are no arguments)
|
||||
mov r4, r2 ; function address
|
||||
mov r8, #0
|
||||
|
||||
mov r0, r3 ; r0 explicitly set
|
||||
ldr r1, [sp] ; objlast. might get overwritten
|
||||
|
||||
beq |nomoreargs@armFuncR0ObjLast|
|
||||
|
||||
; Load the first 3 arguments into r1-r3
|
||||
cmp r7, #1*4
|
||||
ldrge r1, [r6],#4
|
||||
cmp r7, #2*4
|
||||
ldrge r2, [r6],#4
|
||||
ldrlt r2, [sp]
|
||||
cmp r7, #3*4
|
||||
ldrge r3, [r6],#4
|
||||
ldrlt r3, [sp]
|
||||
ble |nomoreargs@armFuncR0ObjLast|
|
||||
|
||||
; Load the rest of the arguments onto the stack
|
||||
sub r7, r7, #3*4 ; skip the 3 registers already loaded into r1-r3
|
||||
sub sp, sp, r7
|
||||
mov r8, r7
|
||||
|stackargsloop@armFuncR0ObjLast|
|
||||
ldr r5, [r6], #4
|
||||
str r5, [sp], #4
|
||||
subs r7, r7, #4
|
||||
bne |stackargsloop@armFuncR0ObjLast|
|
||||
|nomoreargs@armFuncR0ObjLast|
|
||||
sub sp, sp, r8
|
||||
blx r4
|
||||
add sp, sp, r8
|
||||
add sp, sp, #4
|
||||
ldmia sp!, {r4-r8, pc}
|
||||
ENDP
|
||||
|
||||
ALIGN 8
|
||||
armFuncR0 PROC
|
||||
stmdb sp!, {r4-r8, lr}
|
||||
mov r6, r0 ; arg table
|
||||
movs r7, r1 ; arg size (also set the condition code flags so that we detect if there are no arguments)
|
||||
mov r4, r2 ; function address
|
||||
mov r8, #0
|
||||
|
||||
mov r0, r3 ; r0 explicitly set
|
||||
|
||||
beq |nomoreargs@armFuncR0|
|
||||
|
||||
; Load the first 3 arguments into r1-r3
|
||||
cmp r7, #1*4
|
||||
ldrge r1, [r6],#4
|
||||
cmp r7, #2*4
|
||||
ldrge r2, [r6],#4
|
||||
cmp r7, #3*4
|
||||
ldrge r3, [r6],#4
|
||||
ble |nomoreargs@armFuncR0|
|
||||
|
||||
; Load the rest of the arguments onto the stack
|
||||
sub r7, r7, #3*4 ; skip the 3 registers already loaded into r1-r3
|
||||
sub sp, sp, r7
|
||||
mov r8, r7
|
||||
|stackargsloop@armFuncR0|
|
||||
ldr r5, [r6], #4
|
||||
str r5, [sp], #4
|
||||
subs r7, r7, #4
|
||||
bne |stackargsloop@armFuncR0|
|
||||
|nomoreargs@armFuncR0|
|
||||
sub sp, sp, r8
|
||||
blx r4
|
||||
add sp, sp, r8
|
||||
ldmia sp!, {r4-r8, pc}
|
||||
ENDP
|
||||
|
||||
ALIGN 8
|
||||
armFuncR0R1 PROC
|
||||
stmdb sp!, {r4-r8, lr}
|
||||
mov r6, r0 ; arg table
|
||||
movs r7, r1 ; arg size (also set the condition code flags so that we detect if there are no arguments)
|
||||
mov r4, r2 ; function address
|
||||
mov r8, #0
|
||||
|
||||
mov r0, r3 ; r0 explicitly set
|
||||
ldr r1, [sp, #6*4] ; r1 explicitly set too
|
||||
|
||||
beq |nomoreargs@armFuncR0R1|
|
||||
|
||||
; Load the first 2 arguments into r2-r3
|
||||
cmp r7, #1*4
|
||||
ldrge r2, [r6],#4
|
||||
cmp r7, #2*4
|
||||
ldrge r3, [r6],#4
|
||||
ble |nomoreargs@armFuncR0R1|
|
||||
|
||||
; Load the rest of the arguments onto the stack
|
||||
sub r7, r7, #2*4 ; skip the 2 registers already loaded into r2-r3
|
||||
sub sp, sp, r7
|
||||
mov r8, r7
|
||||
|stackargsloop@armFuncR0R1|
|
||||
ldr r5, [r6], #4
|
||||
str r5, [sp], #4
|
||||
subs r7, r7, #4
|
||||
bne |stackargsloop@armFuncR0R1|
|
||||
|nomoreargs@armFuncR0R1|
|
||||
sub sp, sp, r8
|
||||
blx r4
|
||||
add sp, sp, r8
|
||||
ldmia sp!, {r4-r8, pc}
|
||||
ENDP
|
||||
|
||||
END
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue