initial commit

This commit is contained in:
Deukhoofd 2021-04-12 20:25:02 +02:00
commit 3d7202a915
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
806 changed files with 194211 additions and 0 deletions

View File

@ -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

View File

@ -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");
}

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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, &paramTypeId, &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, &paramTypeId, &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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

377
add_on/weakref/weakref.cpp Normal file
View File

@ -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

58
add_on/weakref/weakref.h Normal file
View File

@ -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

View File

@ -0,0 +1 @@
This file is only here to guarantee that unpackers don't skip creating the /lib directory.

View File

@ -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)

View File

@ -0,0 +1,3 @@
APP_ABI := mips armeabi armeabi-v7a x86
APP_PLATFORM := android-19
APP_STL := gnustl_static

View File

@ -0,0 +1,2 @@
include("${CMAKE_CURRENT_LIST_DIR}/AngelscriptTargets.cmake")

View File

@ -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()

View File

@ -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)

View File

@ -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
)

View File

@ -0,0 +1,2 @@
include("${CMAKE_CURRENT_LIST_DIR}/AngelscriptTargets.cmake")

View File

@ -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"
}

View File

@ -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) ###

View File

@ -0,0 +1,49 @@
[includedirs]
[libdirs]
[bindirs]
[resdirs]
[builddirs]
[libs]
[system_libs]
[defines]
[cppflags]
[cxxflags]
[cflags]
[sharedlinkflags]
[exelinkflags]
[sysroot]
[frameworks]
[frameworkdirs]

View File

@ -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"]

View File

@ -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]

View File

@ -0,0 +1,18 @@
{
"options": [
[
"link_std_statically",
"True"
],
[
"shared",
"True"
]
],
"root": {
"name": "AngelScript",
"version": "2.35",
"user": null,
"channel": null
}
}

View File

@ -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>

View 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

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -0,0 +1,2 @@
This file is here just in case your unarchiver does not extract empty directories.
Feel free to remove it.

View File

@ -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
}

View File

@ -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
}

View File

@ -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()

View File

@ -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')

View File

@ -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

View File

@ -0,0 +1,2 @@
This file is here just in case your unarchiver does not extract empty directories.
Feel free to remove it.

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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 */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:angelscript.xcodeproj">
</FileRef>
</Workspace>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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> &copy)
{
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(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

View File

@ -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

View File

@ -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

View File

@ -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> &parameterNames, asCArray<asCDataType> &parameterTypes, 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> &parameterNames, asCArray<asCDataType> &parameterTypes, 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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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(&paramBuffer[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 = &paramBuffer[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(&paramBuffer[target], *(void**)(args+spos), descr->parameterTypes[n].GetSizeInMemoryBytes());
memset(&paramBuffer[target + 18], (asDWORD)1, descr->parameterTypes[n].GetSizeInMemoryDWords());
target += descr->parameterTypes[n].GetSizeInMemoryDWords();
freeFloatSlot = freeDoubleSlot = target;
}
else
{
memcpy(&paramBuffer[stackPos], *(void**)(args+spos), descr->parameterTypes[n].GetSizeInMemoryBytes());
stackPos += descr->parameterTypes[n].GetSizeInMemoryDWords();
stackSize += descr->parameterTypes[n].GetSizeOnStackDWords();
}
}
else
{
memcpy(&paramBuffer[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 = &paramBuffer[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*)&paramBuffer[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, &paramBuffer[VFP_OFFSET], descr->returnType.GetSizeInMemoryBytes() );
}
return retQW;
}
END_AS_NAMESPACE
#endif // AS_LINUX
#endif // AS_ARM
#endif // AS_MAX_PORTABILITY

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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