mirror of https://github.com/mono/CppSharp.git
7 changed files with 501 additions and 6 deletions
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
#include "CppSharp_QuickJS.h" |
||||
|
||||
extern "C" |
||||
{ |
||||
|
||||
extern void register_signal(JSContext *ctx, JSModuleDef *m, bool set, int phase); |
||||
|
||||
void register_CppSharp_QuickJS(JSContext *ctx, JSModuleDef *m, bool set, int phase) |
||||
{ |
||||
register_signal(ctx, m, set, phase); |
||||
} |
||||
|
||||
} // extern "C"
|
@ -0,0 +1,257 @@
@@ -0,0 +1,257 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This is autogenerated code by CppSharp.
|
||||
// Do not edit this file or all your changes will be lost after re-generation.
|
||||
// </auto-generated>
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
extern "C" |
||||
{ |
||||
|
||||
#include <quickjs.h> |
||||
#include <cutils.h> |
||||
|
||||
#if defined(__GNUC__) || defined(__clang__) |
||||
#define js_force_inline inline __attribute__((always_inline)) |
||||
#else |
||||
#define js_force_inline inline |
||||
#endif |
||||
|
||||
#define countof(x) (sizeof(x) / sizeof((x)[0])) |
||||
|
||||
enum |
||||
{ |
||||
__JS_ATOM_NULL = JS_ATOM_NULL, |
||||
#define DEF(name, str) JS_ATOM_ ## name, |
||||
#include <quickjs-atom.h> |
||||
#undef DEF |
||||
JS_ATOM_END, |
||||
}; |
||||
|
||||
struct JS_SignalContext |
||||
{ |
||||
// TODO: List
|
||||
JSValue function; |
||||
JSValue link; |
||||
JSContext *ctx; |
||||
}; |
||||
|
||||
typedef int JS_EventId; |
||||
typedef int JS_ClassId; |
||||
typedef DynBuf JS_EventMap; |
||||
|
||||
struct JS_EventEntry |
||||
{ |
||||
JS_EventId eventId; |
||||
JSValue value; |
||||
}; |
||||
|
||||
static JS_EventMap* JS_Interop_InitEventMap(JS_EventMap* map) |
||||
{ |
||||
dbuf_init(map); |
||||
return map; |
||||
} |
||||
|
||||
static void JS_Interop_FreeEventMap(JSContext* ctx, JS_EventMap* map) |
||||
{ |
||||
JS_EventEntry* events = (JS_EventEntry*) map->buf; |
||||
int numEvents = (map->size / sizeof(JS_EventEntry)); |
||||
for (int i = 0; i < numEvents; i++) |
||||
if (!JS_IsUndefined(events[i].value)) |
||||
JS_FreeValue(ctx, events[i].value); |
||||
|
||||
dbuf_free(map); |
||||
} |
||||
|
||||
static int JS_Interop_BinarySearch(JS_EventEntry* arr, int l, int r, JS_EventId id) |
||||
{ |
||||
if (r >= l) { |
||||
int mid = l + (r - l) / 2; |
||||
|
||||
// If the element is present at the middle itself
|
||||
if (arr[mid].eventId == id) |
||||
return mid; |
||||
|
||||
// If element is smaller than mid, then it can only be present in left subarray
|
||||
if (arr[mid].eventId > id) |
||||
return JS_Interop_BinarySearch(arr, l, mid - 1, id); |
||||
|
||||
// Else the element can only be present in right subarray
|
||||
return JS_Interop_BinarySearch(arr, mid + 1, r, id); |
||||
} |
||||
|
||||
// We reach here when element is not present in array
|
||||
return -1; |
||||
} |
||||
|
||||
static JSValue JS_Interop_FindEvent(JS_EventMap* map, JS_EventId eventId) |
||||
{ |
||||
JS_EventEntry* events = (JS_EventEntry*) map->buf; |
||||
int numEvents = (map->size / sizeof(JS_EventEntry)); |
||||
if (numEvents == 0) |
||||
return JS_UNDEFINED; |
||||
|
||||
int index = JS_Interop_BinarySearch(events, 0, numEvents, eventId); |
||||
return index >= 0 ? events[index].value : JS_UNDEFINED; |
||||
} |
||||
|
||||
static int JS_Interop_InsertEvent(JS_EventMap* map, JS_EventId eventId, |
||||
JSValue value) |
||||
{ |
||||
JS_EventEntry* events = (JS_EventEntry*) map->buf; |
||||
int numEvents = (map->size / sizeof(JS_EventEntry)); |
||||
|
||||
int index = 0; |
||||
for (int i = 0; i < numEvents; i++) |
||||
{ |
||||
if (events[i].eventId == eventId) { index=-1; break; } |
||||
if (events[i].eventId > eventId) { index = i; break; } |
||||
index++; |
||||
} |
||||
|
||||
if (index == -1) |
||||
return -1; |
||||
|
||||
JS_EventEntry entry; |
||||
entry.eventId = eventId; |
||||
entry.value = value; |
||||
|
||||
dbuf_write(map, index * sizeof(JS_EventEntry), (const uint8_t*) &entry, |
||||
sizeof(JS_EventEntry)); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static JSValue JS_Interop_InvokeConstructor(JSContext *ctx, JS_ClassId eventId, |
||||
JSValue argv[], int argc) |
||||
{ |
||||
// TODO: Error handling.
|
||||
JSValue proto = JS_GetClassProto(ctx, eventId); |
||||
JSValue ctor = JS_GetProperty(ctx, proto, JS_ATOM_constructor); |
||||
JSValue instance = JS_CallConstructor(ctx, ctor, argc, argv); |
||||
JS_FreeValue(ctx, ctor); |
||||
JS_FreeValue(ctx, proto); |
||||
|
||||
return instance; |
||||
} |
||||
|
||||
enum JS_Interop_InstanceKind |
||||
{ |
||||
JS_INTEROP_INSTANCE_RAW_POINTER = 1, |
||||
JS_INTEROP_INSTANCE_SIGNAL_CONTEXT, |
||||
}; |
||||
|
||||
struct JS_Interop_ClassData |
||||
{ |
||||
void* instance; |
||||
JSContext* ctx; |
||||
JS_EventMap events; |
||||
}; |
||||
|
||||
static JSValue JS_Interop_InitObject(JSContext *ctx, JSValue obj, JS_Interop_InstanceKind kind, |
||||
void* instance) |
||||
{ |
||||
switch (kind) |
||||
{ |
||||
case JS_INTEROP_INSTANCE_RAW_POINTER: |
||||
JS_SetOpaque(obj, instance); |
||||
return obj; |
||||
case JS_INTEROP_INSTANCE_SIGNAL_CONTEXT: |
||||
JS_Interop_ClassData* data = (JS_Interop_ClassData*) js_mallocz(ctx, \ |
||||
sizeof(JS_Interop_ClassData)); |
||||
data->ctx = ctx; |
||||
data->instance = instance; |
||||
JS_Interop_InitEventMap(&data->events); |
||||
JS_SetOpaque(obj, data); |
||||
return obj; |
||||
} |
||||
|
||||
return JS_UNDEFINED; |
||||
} |
||||
|
||||
static JSValue JS_Interop_CleanupObject(JSValue obj, JS_Interop_InstanceKind kind) |
||||
{ |
||||
switch (kind) |
||||
{ |
||||
case JS_INTEROP_INSTANCE_SIGNAL_CONTEXT: |
||||
JS_Interop_ClassData* data = (JS_Interop_ClassData*) JS_GetOpaque(obj, 0); |
||||
JS_Interop_FreeEventMap(data->ctx, &data->events); |
||||
js_free(data->ctx, data); |
||||
} |
||||
|
||||
return JS_UNDEFINED; |
||||
} |
||||
|
||||
static void* JS_Interop_GetInstance(JSValue obj, JS_ClassId classId, JS_Interop_InstanceKind kind) |
||||
{ |
||||
switch (kind) |
||||
{ |
||||
case JS_INTEROP_INSTANCE_RAW_POINTER: |
||||
return JS_GetOpaque(obj, classId); |
||||
case JS_INTEROP_INSTANCE_SIGNAL_CONTEXT: |
||||
JS_Interop_ClassData* data = (JS_Interop_ClassData*) JS_GetOpaque(obj, classId); |
||||
return data != nullptr ? data->instance : nullptr; |
||||
} |
||||
|
||||
return nullptr; |
||||
} |
||||
|
||||
static JSValue JS_Interop_CreateFromInstance(JSContext* ctx, JS_ClassId classId, |
||||
JS_Interop_InstanceKind kind, void* instance) |
||||
{ |
||||
if (instance == nullptr) |
||||
return JS_NULL; |
||||
|
||||
// TODO: Error handling.
|
||||
JSValue obj = JS_NewObjectClass(ctx, classId); |
||||
JS_Interop_InitObject(ctx, obj, kind, instance); |
||||
|
||||
return obj; |
||||
} |
||||
|
||||
static inline JS_BOOL JS_IsInt(JSValueConst v) |
||||
{ |
||||
return JS_IsNumber(v); |
||||
} |
||||
|
||||
static inline JS_BOOL JS_IsInt8(JSValueConst v) |
||||
{ |
||||
return JS_IsInt(v); |
||||
} |
||||
|
||||
static inline JS_BOOL JS_IsUInt8(JSValueConst v) |
||||
{ |
||||
return JS_IsInt(v); |
||||
} |
||||
|
||||
static inline JS_BOOL JS_IsInt16(JSValueConst v) |
||||
{ |
||||
return JS_IsInt(v); |
||||
} |
||||
|
||||
static inline JS_BOOL JS_IsUInt16(JSValueConst v) |
||||
{ |
||||
return JS_IsInt(v); |
||||
} |
||||
|
||||
static inline JS_BOOL JS_IsInt32(JSValueConst v) |
||||
{ |
||||
return JS_IsInt(v); |
||||
} |
||||
|
||||
static inline JS_BOOL JS_IsUInt32(JSValueConst v) |
||||
{ |
||||
return JS_IsInt(v); |
||||
} |
||||
|
||||
static inline JS_BOOL JS_IsFloat(JSValueConst v) |
||||
{ |
||||
int tag = JS_VALUE_GET_TAG(v); |
||||
return JS_TAG_IS_FLOAT64(tag); |
||||
} |
||||
|
||||
void register_CppSharp_QuickJS(JSContext *ctx, JSModuleDef *m, bool set, int phase); |
||||
|
||||
#undef js_force_inline |
||||
|
||||
} // extern "C"
|
@ -0,0 +1,202 @@
@@ -0,0 +1,202 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This is autogenerated code by CppSharp.
|
||||
// Do not edit this file or all your changes will be lost after re-generation.
|
||||
// </auto-generated>
|
||||
// ----------------------------------------------------------------------------
|
||||
#include <CppSharp_QuickJS.h> |
||||
#include <assert.h> |
||||
|
||||
extern "C" { |
||||
|
||||
JSClassID classId__Signal; |
||||
|
||||
// Signal::Signal
|
||||
static JSValue callback_method_Signal_Signal(JSContext* ctx, JSValueConst this_val, |
||||
int argc, JSValueConst* argv) |
||||
{ |
||||
// if (argc != 1)
|
||||
// {
|
||||
// return JS_ThrowRangeError(ctx, "Unsupported number of arguments");
|
||||
// }
|
||||
|
||||
wrap: |
||||
JSValue proto; |
||||
if (JS_IsUndefined(this_val)) |
||||
proto = JS_GetClassProto(ctx, classId__Signal); |
||||
else |
||||
proto = JS_GetPropertyStr(ctx, this_val, "prototype"); |
||||
|
||||
if (JS_IsException(proto)) |
||||
return proto; |
||||
|
||||
JSValue __obj = JS_NewObjectProtoClass(ctx, proto, classId__Signal); |
||||
JS_FreeValue(ctx, proto); |
||||
|
||||
JS_SignalContext* signalCtx = new JS_SignalContext; |
||||
signalCtx->ctx = ctx; |
||||
signalCtx->function = JS_UNDEFINED; |
||||
signalCtx->link = JS_UNDEFINED; |
||||
|
||||
if (argc >= 1) |
||||
{ |
||||
JSValue link = argv[0]; |
||||
assert(JS_IsObject(link)); |
||||
//JS_FreeValue(ctx, link);
|
||||
signalCtx->link = link; |
||||
} |
||||
|
||||
JS_SetOpaque(__obj, signalCtx); |
||||
|
||||
return __obj; |
||||
} |
||||
|
||||
// Signal::connect
|
||||
static JSValue callback_method_Signal_connect(JSContext* ctx, JSValueConst this_val, |
||||
int argc, JSValueConst* argv) |
||||
{ |
||||
if (argc < 1 || argc > 1) |
||||
{ |
||||
return JS_ThrowRangeError(ctx, "Expected one argument of function type"); |
||||
} |
||||
|
||||
// Signal* instance = (Signal*) JS_GetOpaque(this_val, classId__Signal);
|
||||
|
||||
if (!JS_IsFunction(ctx, argv[0])) |
||||
return JS_ThrowTypeError(ctx, "Unsupported argument type"); |
||||
|
||||
// Connect logic
|
||||
|
||||
auto signalCtx = (JS_SignalContext*) JS_GetOpaque(this_val, classId__Signal); |
||||
if (signalCtx == nullptr) |
||||
return JS_ThrowTypeError(ctx, "Could not find signal context"); |
||||
|
||||
assert(JS_IsObject(signalCtx->link)); |
||||
|
||||
if (!JS_IsUndefined(signalCtx->function)) |
||||
return JS_ThrowRangeError(ctx, "Signal already contains a connected function"); |
||||
|
||||
signalCtx->function = JS_DupValue(ctx, argv[0]); |
||||
|
||||
JSValue ____ret = JS_NewInt32(ctx, 0); |
||||
|
||||
return ____ret; |
||||
} |
||||
|
||||
// Signal::disconnect
|
||||
static JSValue callback_method_Signal_disconnect(JSContext* ctx, JSValueConst this_val, |
||||
int argc, JSValueConst* argv) |
||||
{ |
||||
if (argc < 1 || argc > 1) |
||||
{ |
||||
return JS_ThrowRangeError(ctx, "Unsupported number of arguments"); |
||||
} |
||||
|
||||
// Signal* instance = (Signal*) JS_GetOpaque(this_val, classId__Signal);
|
||||
|
||||
if (JS_IsNumber(argv[0])) |
||||
goto overload0; |
||||
|
||||
goto error; |
||||
|
||||
error: |
||||
return JS_ThrowTypeError(ctx, "Unsupported argument type"); |
||||
|
||||
// bool disconnect(Slot slot) { return 0; }
|
||||
overload0: |
||||
{ |
||||
int slot; |
||||
if (JS_ToInt32(ctx, (int32_t*) &slot, argv[0])) |
||||
return JS_EXCEPTION; |
||||
|
||||
// auto __arg0 = (::Slot)slot;
|
||||
// bool __ret = instance->disconnect(__arg0);
|
||||
|
||||
JSValue ____ret = JS_NewBool(ctx, 0); |
||||
|
||||
return ____ret; |
||||
} |
||||
} |
||||
|
||||
// Signal::isEmpty
|
||||
static JSValue callback_method_Signal_isEmpty(JSContext* ctx, JSValueConst this_val, |
||||
int argc, JSValueConst* argv) |
||||
{ |
||||
if (argc > 0) |
||||
{ |
||||
return JS_ThrowRangeError(ctx, "Unsupported number of arguments"); |
||||
} |
||||
|
||||
auto signalCtx = (JS_SignalContext*) JS_GetOpaque(this_val, classId__Signal); |
||||
|
||||
JSValue ____ret = JS_NewBool(ctx, JS_IsUndefined(signalCtx->function)); |
||||
|
||||
return ____ret; |
||||
} |
||||
|
||||
static JSValue callback_class__Signal_toString(JSContext* ctx, JSValueConst this_val, |
||||
int argc, JSValueConst* argv) |
||||
{ |
||||
return JS_NewString(ctx, "Signal"); |
||||
} |
||||
|
||||
void finalizer__Signal(JSRuntime *rt, JSValue val) |
||||
{ |
||||
auto signalCtx = (JS_SignalContext*) JS_GetOpaque(val, classId__Signal); |
||||
if (signalCtx == nullptr) |
||||
return; |
||||
|
||||
if (!JS_IsUndefined(signalCtx->function)) |
||||
return JS_FreeValue(signalCtx->ctx, signalCtx->function); |
||||
|
||||
delete signalCtx; |
||||
|
||||
JS_SetOpaque(val, nullptr); |
||||
|
||||
} |
||||
|
||||
static JSClassDef classDef__Signal |
||||
{ |
||||
"Signal", |
||||
.finalizer = finalizer__Signal |
||||
}; |
||||
|
||||
static JSCFunctionListEntry funcDef__Signal[] |
||||
{ |
||||
JS_CFUNC_DEF("connect", 1, callback_method_Signal_connect), |
||||
JS_CFUNC_DEF("disconnect", 1, callback_method_Signal_disconnect), |
||||
JS_CFUNC_DEF("isEmpty", 0, callback_method_Signal_isEmpty), |
||||
JS_CFUNC_DEF("toString", 0, callback_class__Signal_toString), |
||||
}; |
||||
|
||||
static void register_class__Signal(JSContext *ctx, JSModuleDef *m, bool set, int phase) |
||||
{ |
||||
if (!set) |
||||
{ |
||||
JS_AddModuleExport(ctx, m, "Signal"); |
||||
return; |
||||
} |
||||
|
||||
if (phase == 0) |
||||
{ |
||||
JS_NewClassID(&classId__Signal); |
||||
|
||||
JS_NewClass(JS_GetRuntime(ctx), classId__Signal, &classDef__Signal); |
||||
|
||||
JSValue proto = JS_NewObject(ctx); |
||||
JS_SetPropertyFunctionList(ctx, proto, funcDef__Signal, sizeof(funcDef__Signal) / sizeof(funcDef__Signal[0])); |
||||
JS_SetClassProto(ctx, classId__Signal, proto); |
||||
|
||||
JSValue ctor = JS_NewCFunction2(ctx, callback_method_Signal_Signal, "Signal", 1, JS_CFUNC_constructor, 0); |
||||
JS_SetConstructor(ctx, ctor, proto); |
||||
|
||||
JS_SetModuleExport(ctx, m, "Signal", ctor); |
||||
} |
||||
} |
||||
|
||||
void register_signal(JSContext *ctx, JSModuleDef *m, bool set, int phase) |
||||
{ |
||||
register_class__Signal(ctx, m, set, phase); |
||||
} |
||||
|
||||
} // extern "C"
|
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This is autogenerated code by CppSharp.
|
||||
// Do not edit this file or all your changes will be lost after re-generation.
|
||||
// </auto-generated>
|
||||
// ----------------------------------------------------------------------------
|
||||
#pragma once |
||||
|
||||
#include <quickjs.h> |
||||
|
||||
class Signal |
||||
{ |
||||
public: |
||||
|
||||
Signal(); |
||||
|
||||
~Signal(); |
||||
|
||||
int connect(void (*function)()); |
||||
|
||||
bool disconnect(int slot); |
||||
|
||||
bool isEmpty(); |
||||
}; |
Loading…
Reference in new issue