aboutsummaryrefslogtreecommitdiff
path: root/system
diff options
context:
space:
mode:
Diffstat (limited to 'system')
-rw-r--r--[-rwxr-xr-x]system/include/emscripten/bind.h62
-rw-r--r--system/include/emscripten/val.h116
-rw-r--r--[-rwxr-xr-x]system/include/emscripten/wire.h81
-rw-r--r--system/include/netdb.h2
-rw-r--r--system/lib/embind/bind.cpp1
-rw-r--r--system/lib/sdl.cpp13
-rw-r--r--system/lib/sdl.symbols1
7 files changed, 170 insertions, 106 deletions
diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h
index 7aa2a55e..cd465e45 100755..100644
--- a/system/include/emscripten/bind.h
+++ b/system/include/emscripten/bind.h
@@ -18,7 +18,6 @@ namespace emscripten {
};
namespace internal {
- typedef void (*GenericFunction)();
typedef long GenericEnumValue;
// Implemented in JavaScript. Don't call these directly.
@@ -60,6 +59,10 @@ namespace emscripten {
TYPEID emvalType,
const char* name);
+ void _embind_register_memory_view(
+ TYPEID memoryViewType,
+ const char* name);
+
void _embind_register_function(
const char* name,
unsigned argCount,
@@ -414,11 +417,10 @@ namespace emscripten {
// TODO: This could do a reinterpret-cast if sizeof(T) === sizeof(void*)
template<typename T>
- inline void* getContext(const T& t) {
+ inline T* getContext(const T& t) {
// not a leak because this is called once per binding
- void* p = malloc(sizeof(T));
- assert(p);
- memcpy(p, &t, sizeof(T));
+ T* p = reinterpret_cast<T*>(malloc(sizeof(T)));
+ new(p) T(t);
return p;
}
@@ -749,38 +751,19 @@ namespace emscripten {
template<typename ReturnType, typename... Args>
ReturnType call(const char* name, Args&&... args) const {
- return Caller<ReturnType, Args...>::call(wrapped, name, std::forward<Args>(args)...);
+ return wrapped.call<ReturnType>(name, std::forward<Args>(args)...);
}
template<typename ReturnType, typename... Args, typename Default>
ReturnType optional_call(const char* name, Default def, Args&&... args) const {
- if (has_function(name)) {
- return Caller<ReturnType, Args...>::call(wrapped, name, std::forward<Args>(args)...);
+ if (wrapped.has_function(name)) {
+ return call<ReturnType>(name, std::forward<Args>(args)...);
} else {
return def();
}
}
private:
- bool has_function(const char* name) const {
- return wrapped.has_function(name);
- }
-
- // this class only exists because you can't partially specialize function templates
- template<typename ReturnType, typename... Args>
- struct Caller {
- static ReturnType call(const val& v, const char* name, Args&&... args) {
- return v.call(name, std::forward<Args>(args)...).template as<ReturnType>();
- }
- };
-
- template<typename... Args>
- struct Caller<void, Args...> {
- static void call(const val& v, const char* name, Args&&... args) {
- v.call_void(name, std::forward<Args>(args)...);
- }
- };
-
val wrapped;
};
@@ -844,23 +827,8 @@ namespace emscripten {
}
};
- template<typename PointerType>
- struct ptr {
- typedef PointerType pointer_type;
- };
-
namespace internal {
template<typename T>
- struct is_ptr {
- enum { value = false };
- };
-
- template<typename T>
- struct is_ptr<ptr<T>> {
- enum { value = true };
- };
-
- template<typename T>
struct SmartPtrIfNeeded {
template<typename U>
SmartPtrIfNeeded(U& cls) {
@@ -881,7 +849,6 @@ namespace emscripten {
public:
class_() = delete;
- template<typename = typename std::enable_if<!internal::is_ptr<ClassType>::value>::type>
explicit class_(const char* name) {
using namespace internal;
@@ -927,16 +894,17 @@ namespace emscripten {
policies...);
}
- template<typename... Args, typename... Policies>
- class_& constructor(ClassType* (*factory)(Args...), Policies...) {
+ template<typename... Args, typename ReturnType, typename... Policies>
+ class_& constructor(ReturnType (*factory)(Args...), Policies...) {
using namespace internal;
- typename WithPolicies<Policies...>::template ArgTypeList<AllowedRawPointer<ClassType>, Args...> args;
+ // TODO: allows all raw pointers... policies need a rethink
+ typename WithPolicies<allow_raw_pointers, Policies...>::template ArgTypeList<ReturnType, Args...> args;
_embind_register_class_constructor(
TypeID<ClassType>::get(),
args.count,
args.types,
- reinterpret_cast<GenericFunction>(&Invoker<ClassType*, Args...>::invoke),
+ reinterpret_cast<GenericFunction>(&Invoker<ReturnType, Args...>::invoke),
reinterpret_cast<GenericFunction>(factory));
return *this;
}
diff --git a/system/include/emscripten/val.h b/system/include/emscripten/val.h
index edd070e3..b712d164 100644
--- a/system/include/emscripten/val.h
+++ b/system/include/emscripten/val.h
@@ -10,7 +10,6 @@ namespace emscripten {
extern "C" {
void _emval_register_symbol(const char*);
- typedef struct _EM_SIG* EM_SIG;
typedef struct _EM_VAL* EM_VAL;
void _emval_incref(EM_VAL value);
@@ -39,34 +38,67 @@ namespace emscripten {
unsigned argCount,
internal::TYPEID argTypes[]
/*, ... */);
- EM_VAL _emval_call_method(
- EM_VAL value,
- const char* methodName,
- unsigned argCount,
- internal::TYPEID argTypes[]
- /*, ... */);
- void _emval_call_void_method(
- EM_VAL value,
- const char* methodName,
- unsigned argCount,
- internal::TYPEID argTypes[]
- /*, ...*/);
+
+ // DO NOT call this more than once per signature. It will leak function pointer offsets!
+ GenericFunction _emval_get_method_caller(
+ unsigned argCount, // including return value
+ internal::TYPEID argTypes[]);
bool _emval_has_function(
EM_VAL value,
const char* methodName);
}
- }
- template<const char* address>
- struct symbol_registrar {
- symbol_registrar() {
- internal::_emval_register_symbol(address);
- }
- };
+ template<const char* address>
+ struct symbol_registrar {
+ symbol_registrar() {
+ internal::_emval_register_symbol(address);
+ }
+ };
+
+ template<typename ReturnType, typename... Args>
+ struct Signature {
+ typedef typename BindingType<ReturnType>::WireType (*MethodCaller)(EM_VAL value, const char* methodName, typename BindingType<Args>::WireType...);
+
+ static MethodCaller get_method_caller() {
+ static MethodCaller fp = reinterpret_cast<MethodCaller>(init_method_caller());
+ return fp;
+ }
+
+ private:
+ static GenericFunction init_method_caller() {
+ WithPolicies<>::ArgTypeList<ReturnType, Args...> args;
+ return _emval_get_method_caller(args.count, args.types);
+ }
+ };
+
+ template<typename ReturnType, typename... Args>
+ struct MethodCaller {
+ static ReturnType call(EM_VAL handle, const char* methodName, Args&&... args) {
+ auto caller = Signature<ReturnType, Args...>::get_method_caller();
+ auto wireType = caller(
+ handle,
+ methodName,
+ toWireType(std::forward<Args>(args))...);
+ WireDeleter<ReturnType> deleter(wireType);
+ return BindingType<ReturnType>::fromWireType(wireType);
+ }
+ };
+
+ template<typename... Args>
+ struct MethodCaller<void, Args...> {
+ static void call(EM_VAL handle, const char* methodName, Args&&... args) {
+ auto caller = Signature<void, Args...>::get_method_caller();
+ return caller(
+ handle,
+ methodName,
+ toWireType(std::forward<Args>(args))...);
+ }
+ };
+ }
#define EMSCRIPTEN_SYMBOL(name) \
static const char name##_symbol[] = #name; \
- static const symbol_registrar<name##_symbol> name##_registrar
+ static const ::emscripten::internal::symbol_registrar<name##_symbol> name##_registrar
class val {
public:
@@ -158,7 +190,7 @@ namespace emscripten {
}
bool hasOwnProperty(const char* key) const {
- return val::global("Object")["prototype"]["hasOwnProperty"].call("call", *this, val(key)).as<bool>();
+ return val::global("Object")["prototype"]["hasOwnProperty"].call<bool>("call", *this, val(key));
}
template<typename... Args>
@@ -211,45 +243,11 @@ namespace emscripten {
toWireType(std::forward<Args>(args))...));
}
- template<typename ...Args>
- val call(const char* name, Args&&... args) const {
+ template<typename ReturnValue, typename... Args>
+ ReturnValue call(const char* name, Args&&... args) const {
using namespace internal;
- WithPolicies<>::ArgTypeList<Args...> argList;
- typedef EM_VAL (*TypedCall)(
- EM_VAL,
- const char* name,
- unsigned,
- TYPEID argTypes[],
- typename BindingType<Args>::WireType...);
- TypedCall typedCall = reinterpret_cast<TypedCall>(&_emval_call_method);
- return val(
- typedCall(
- handle,
- name,
- argList.count,
- argList.types,
- toWireType(std::forward<Args>(args))...));
- }
-
- template<typename ...Args>
- void call_void(const char* name, Args&&... args) const {
- using namespace internal;
-
- WithPolicies<>::ArgTypeList<Args...> argList;
- typedef void (*TypedCall)(
- EM_VAL,
- const char* name,
- unsigned,
- TYPEID argTypes[],
- typename BindingType<Args>::WireType...);
- TypedCall typedCall = reinterpret_cast<TypedCall>(&_emval_call_void_method);
- return typedCall(
- handle,
- name,
- argList.count,
- argList.types,
- toWireType(std::forward<Args>(args))...);
+ return MethodCaller<ReturnValue, Args...>::call(handle, name, std::forward<Args>(args)...);
}
bool has_function(const char* name) const {
diff --git a/system/include/emscripten/wire.h b/system/include/emscripten/wire.h
index 6fb15fc7..a5892216 100755..100644
--- a/system/include/emscripten/wire.h
+++ b/system/include/emscripten/wire.h
@@ -13,6 +13,8 @@
namespace emscripten {
namespace internal {
+ typedef void (*GenericFunction)();
+
typedef const struct _TYPEID* TYPEID;
// This implementation is technically not legal, as it's not
@@ -146,6 +148,7 @@ namespace emscripten {
template<>
struct BindingType<void> {
+ typedef void WireType;
};
template<>
@@ -309,4 +312,82 @@ namespace emscripten {
WireType wt;
};
}
+
+ struct memory_view {
+ enum class Type {
+ Int8Array,
+ Uint8Array,
+ Int16Array,
+ Uint16Array,
+ Int32Array,
+ Uint32Array,
+ Float32Array,
+ Float64Array,
+ };
+
+ memory_view() = delete;
+ explicit memory_view(size_t size, const void* data)
+ : type(Type::Uint8Array)
+ , size(size)
+ , data(data)
+ {}
+ explicit memory_view(Type type, size_t size, const void* data)
+ : type(type)
+ , size(size)
+ , data(data)
+ {}
+
+ const Type type;
+ const size_t size; // in elements, not bytes
+ const void* const data;
+ };
+
+ inline memory_view typed_memory_view(size_t size, const int8_t* data) {
+ return memory_view(memory_view::Type::Int8Array, size, data);
+ }
+
+ inline memory_view typed_memory_view(size_t size, const uint8_t* data) {
+ return memory_view(memory_view::Type::Uint8Array, size, data);
+ }
+
+ inline memory_view typed_memory_view(size_t size, const int16_t* data) {
+ return memory_view(memory_view::Type::Int16Array, size, data);
+ }
+
+ inline memory_view typed_memory_view(size_t size, const uint16_t* data) {
+ return memory_view(memory_view::Type::Uint16Array, size, data);
+ }
+
+ inline memory_view typed_memory_view(size_t size, const int32_t* data) {
+ return memory_view(memory_view::Type::Int32Array, size, data);
+ }
+
+ inline memory_view typed_memory_view(size_t size, const uint32_t* data) {
+ return memory_view(memory_view::Type::Uint32Array, size, data);
+ }
+
+ inline memory_view typed_memory_view(size_t size, const float* data) {
+ return memory_view(memory_view::Type::Float32Array, size, data);
+ }
+
+ inline memory_view typed_memory_view(size_t size, const double* data) {
+ return memory_view(memory_view::Type::Float64Array, size, data);
+ }
+
+ namespace internal {
+ template<>
+ struct BindingType<memory_view> {
+ // This non-word-sized WireType only works because I
+ // happen to know that clang will pass aggregates as
+ // pointers to stack elements and we never support
+ // converting JavaScript typed arrays back into
+ // memory_view. (That is, fromWireType is not implemented
+ // on the C++ side, nor is toWireType implemented in
+ // JavaScript.)
+ typedef memory_view WireType;
+ static WireType toWireType(const memory_view& mv) {
+ return mv;
+ }
+ };
+ }
}
diff --git a/system/include/netdb.h b/system/include/netdb.h
index 147cdff4..48acdcc4 100644
--- a/system/include/netdb.h
+++ b/system/include/netdb.h
@@ -85,6 +85,8 @@ const char* hstrerror(int err);
extern int h_errno;
+#include <netinet/in.h>
+
#ifdef __cplusplus
}
#endif
diff --git a/system/lib/embind/bind.cpp b/system/lib/embind/bind.cpp
index ec1648a9..12264dfd 100644
--- a/system/lib/embind/bind.cpp
+++ b/system/lib/embind/bind.cpp
@@ -59,4 +59,5 @@ EMSCRIPTEN_BINDINGS(native_and_builtin_types) {
_embind_register_std_string(TypeID<std::string>::get(), "std::string");
_embind_register_std_wstring(TypeID<std::wstring>::get(), sizeof(wchar_t), "std::wstring");
_embind_register_emval(TypeID<val>::get(), "emscripten::val");
+ _embind_register_memory_view(TypeID<memory_view>::get(), "emscripten::memory_view");
}
diff --git a/system/lib/sdl.cpp b/system/lib/sdl.cpp
new file mode 100644
index 00000000..7038cdb1
--- /dev/null
+++ b/system/lib/sdl.cpp
@@ -0,0 +1,13 @@
+
+#include <stdlib.h>
+
+// force malloc&free to be included in from libc
+struct Force {
+ Force() {
+ void *x = malloc(10);
+ free(x);
+ }
+};
+
+static Force f;
+
diff --git a/system/lib/sdl.symbols b/system/lib/sdl.symbols
new file mode 100644
index 00000000..c2c0af42
--- /dev/null
+++ b/system/lib/sdl.symbols
@@ -0,0 +1 @@
+ W SDL_Init