return CYJSUndefined(context);
} CYCatch(NULL) }
-static size_t Nonce_(0);
-
-static JSValueRef $cyq(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
- CYPool pool;
- const char *name(pool.strcat(CYPoolCString(pool, context, arguments[0]), pool.itoa(Nonce_++), NULL));
- return CYCastJSValue(context, name);
-} CYCatch(NULL) }
-
static void (*JSSynchronousGarbageCollectForDebugging$)(JSContextRef);
-void CYGarbageCollect(JSContextRef context) {
+_visible void CYGarbageCollect(JSContextRef context) {
(JSSynchronousGarbageCollectForDebugging$ ?: &JSGarbageCollect)(context);
}
JSValueRef toCYON(CYGetProperty(context, object, toCYON_s));
if (CYIsCallable(context, toCYON)) {
// XXX: this needs to be abstracted behind some kind of function
- JSValueRef arguments[1] = {CYCastJSValue(context, static_cast<double>(reinterpret_cast<uintptr_t>(&objects)))};
+ JSValueRef arguments[1] = {CYCastJSValue(context, reinterpret_cast<uintptr_t>(&objects))};
JSValueRef value(CYCallAsFunction(context, (JSObjectRef) toCYON, object, 1, arguments));
_assert(value != NULL);
return CYPoolCString(pool, context, value);
}
}
-void CYExecuteClosure(ffi_cif *cif, void *result, void **arguments, void *arg, JSValueRef (*adapter)(JSContextRef, size_t, JSValueRef[], JSObjectRef)) {
+void CYExecuteClosure(ffi_cif *cif, void *result, void **arguments, void *arg) {
Closure_privateData *internal(reinterpret_cast<Closure_privateData *>(arg));
JSContextRef context(internal->context_);
for (size_t index(0); index != count; ++index)
values[index] = CYFromFFI(context, internal->signature_.elements[1 + index].type, internal->cif_.arg_types[index], arguments[index]);
- JSValueRef value(adapter(context, count, values, internal->function_));
+ JSValueRef value(internal->adapter_(context, count, values, internal->function_));
CYPoolFFI(NULL, context, internal->signature_.elements[0].type, internal->cif_.rtype, result, value);
}
return CYCallAsFunction(context, function, NULL, count, values);
}
-static void FunctionClosure_(ffi_cif *cif, void *result, void **arguments, void *arg) {
- CYExecuteClosure(cif, result, arguments, arg, &FunctionAdapter_);
-}
-
-Closure_privateData *CYMakeFunctor_(JSContextRef context, JSObjectRef function, const sig::Signature &signature, void (*callback)(ffi_cif *, void *, void **, void *)) {
+Closure_privateData *CYMakeFunctor_(JSContextRef context, JSObjectRef function, const sig::Signature &signature, JSValueRef (*adapter)(JSContextRef, size_t, JSValueRef[], JSObjectRef)) {
// XXX: in case of exceptions this will leak
// XXX: in point of fact, this may /need/ to leak :(
- Closure_privateData *internal(new Closure_privateData(context, function, signature));
+ Closure_privateData *internal(new Closure_privateData(context, function, adapter, signature));
#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__))
void *executable;
ffi_closure *writable(reinterpret_cast<ffi_closure *>(ffi_closure_alloc(sizeof(ffi_closure), &executable)));
- ffi_status status(ffi_prep_closure_loc(writable, &internal->cif_, callback, internal, executable));
+ ffi_status status(ffi_prep_closure_loc(writable, &internal->cif_, &CYExecuteClosure, internal, executable));
_assert(status == FFI_OK);
internal->value_ = executable;
-1, 0
)));
- ffi_status status(ffi_prep_closure(closure, &internal->cif_, callback, internal));
+ ffi_status status(ffi_prep_closure(closure, &internal->cif_, &CYExecuteClosure, internal));
_assert(status == FFI_OK);
_syscall(mprotect(closure, sizeof(*closure), PROT_READ | PROT_EXEC));
}
static JSObjectRef CYMakeFunctor(JSContextRef context, JSObjectRef function, const sig::Signature &signature) {
- Closure_privateData *internal(CYMakeFunctor_(context, function, signature, &FunctionClosure_));
+ Closure_privateData *internal(CYMakeFunctor_(context, function, signature, &FunctionAdapter_));
JSObjectRef object(JSObjectMake(context, Functor_, internal));
// XXX: see above notes about needing to leak
JSValueProtect(CYGetJSContext(context), object);
static JSValueRef Type_callAsFunction_toCYON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
Type_privateData *internal(reinterpret_cast<Type_privateData *>(JSObjectGetPrivate(_this)));
CYLocalPool pool;
- std::ostringstream out;
+ std::stringbuf out;
CYOptions options;
CYOutput output(out, options);
(new(pool) CYEncodedType(Decode(pool, internal->type_)))->Output(output, CYNoFlags);
static JSObjectRef (*JSObjectMakeArray$)(JSContextRef, size_t, const JSValueRef[], JSValueRef *);
-void CYSetArgs(int argc, const char *argv[]) {
+_visible void CYSetArgs(int argc, const char *argv[]) {
JSContextRef context(CYGetJSContext());
JSValueRef args[argc];
for (int i(0); i != argc; ++i)
}
};
-const char *CYExecute(JSContextRef context, CYPool &pool, CYUTF8String code) {
+static volatile bool cancel_;
+
+static bool CYShouldTerminate(JSContextRef context, void *arg) {
+ return cancel_;
+}
+
+_visible const char *CYExecute(JSContextRef context, CYPool &pool, CYUTF8String code) {
JSValueRef exception(NULL);
+ if (false) error:
+ return CYPoolCString(pool, context, CYJSString(context, exception));
ExecutionHandle handle(context);
- JSValueRef result; try {
- result = JSEvaluateScript(context, CYJSString(code), NULL, NULL, 0, &exception);
- } catch (const char *error) {
- return error;
- }
+ cancel_ = false;
+ if (&JSContextGroupSetExecutionTimeLimit != NULL)
+ JSContextGroupSetExecutionTimeLimit(JSContextGetGroup(context), 0.5, &CYShouldTerminate, NULL);
- if (exception != NULL) error:
- return CYPoolCString(pool, context, CYJSString(context, exception));
+ JSValueRef result(JSEvaluateScript(context, CYJSString(code), NULL, NULL, 0, &exception));
+ if (exception != NULL)
+ goto error;
if (JSValueIsUndefined(context, result))
return NULL;
- const char *json; try {
- std::set<void *> objects;
- json = CYPoolCCYON(pool, context, result, objects, &exception);
- } catch (const char *error) {
- return error;
- }
-
+ std::set<void *> objects;
+ const char *json(CYPoolCCYON(pool, context, result, objects, &exception));
if (exception != NULL)
goto error;
return json;
}
+_visible void CYCancel() {
+ cancel_ = true;
+}
+
static bool initialized_ = false;
void CYInitializeDynamic() {
return reinterpret_cast<Context *>(JSObjectGetPrivate(CYCastJSObject(context, CYGetProperty(context, CYGetGlobalObject(context), cy_s))))->context_;
}
-extern "C" bool CydgetMemoryParse(const uint16_t **data, size_t *size);
-
void *CYMapFile(const char *path, size_t *psize) {
int fd(_syscall_(open(path, O_RDONLY), 1, ENOENT));
if (fd == -1)
return CYGetProperty(context, module, property);
} CYCatch(NULL) }
+extern "C" void CYDestroyWeak(JSWeakObjectMapRef weak, void *data) {
+}
+
extern "C" void CYSetupContext(JSGlobalContextRef context) {
CYInitializeDynamic();
CYSetPrototype(context, last, all);
}
- CYSetProperty(context, global, CYJSString("$cyq"), &$cyq, kJSPropertyAttributeDontEnum);
-
JSObjectRef System(JSObjectMake(context, NULL, NULL));
CYSetProperty(context, cy, CYJSString("System"), System);
#ifdef __APPLE__
if (&JSWeakObjectMapCreate != NULL) {
- JSWeakObjectMapRef weak(JSWeakObjectMapCreate(context, NULL, NULL));
+ JSWeakObjectMapRef weak(JSWeakObjectMapCreate(context, NULL, &CYDestroyWeak));
CYSetProperty(context, cy, weak_s, CYCastJSValue(context, reinterpret_cast<uintptr_t>(weak)));
}
#endif
static JSGlobalContextRef context_;
-JSGlobalContextRef CYGetJSContext() {
+_visible JSGlobalContextRef CYGetJSContext() {
CYInitializeDynamic();
if (context_ == NULL) {
return context_;
}
-void CYDestroyContext() {
+_visible void CYDestroyContext() {
if (context_ == NULL)
return;
JSGlobalContextRelease(context_);