+ *psize = size;
+
+ void *base;
+ _syscall(base = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0));
+
+ CYFile *file(new (pool) CYFile(base, size));
+ pool.atexit(&CYFileExit, file);
+
+ _syscall(close(fd));
+ return base;
+}
+
+static CYUTF8String CYPoolFileUTF8String(CYPool &pool, const char *path) {
+ CYUTF8String data;
+ data.data = reinterpret_cast<char *>(CYPoolFile(pool, path, &data.size));
+ return data;
+}
+
+static const char *CYPoolLibraryPath(CYPool &pool) {
+ Dl_info addr;
+ _assert(dladdr(reinterpret_cast<void *>(&CYPoolLibraryPath), &addr) != 0);
+ char *lib(pool.strdup(addr.dli_fname));
+
+ char *slash(strrchr(lib, '/'));
+ _assert(slash != NULL);
+ *slash = '\0';
+
+ return lib;
+}
+
+static JSValueRef require(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
+ _assert(count == 1);
+ CYPool pool;
+
+ const char *lib(CYPoolLibraryPath(pool));
+
+ CYJSString property("exports");
+ JSObjectRef module;
+
+ const char *name(CYPoolCString(pool, context, arguments[0]));
+ const char *path(pool.strcat(lib, "/cycript0.9/", name, ".cy", NULL));
+
+ CYJSString key(path);
+ JSObjectRef modules(CYGetCachedObject(context, CYJSString("modules")));
+ JSValueRef cache(CYGetProperty(context, modules, key));
+
+ if (!JSValueIsUndefined(context, cache))
+ module = CYCastJSObject(context, cache);
+ else {
+ CYUTF8String code(CYPoolFileUTF8String(pool, path));
+
+ if (code.data == NULL) {
+ if (strchr(name, '/') == NULL && (
+#ifdef __APPLE__
+ dlopen(pool.strcat("/System/Library/Frameworks/", name, ".framework/", name, NULL), RTLD_LAZY | RTLD_GLOBAL) != NULL ||
+ dlopen(pool.strcat("/System/Library/PrivateFrameworks/", name, ".framework/", name, NULL), RTLD_LAZY | RTLD_GLOBAL) != NULL ||
+#endif
+ false))
+ return CYJSUndefined(NULL);
+
+ CYThrow("Can't find module: %s", name);
+ }
+
+ module = JSObjectMake(context, NULL, NULL);
+ CYSetProperty(context, modules, key, module);
+
+ JSObjectRef exports(JSObjectMake(context, NULL, NULL));
+ CYSetProperty(context, module, property, exports);
+
+ std::stringstream wrap;
+ wrap << "(function (exports, require, module) { " << code << "\n});";
+ code = CYPoolCode(pool, *wrap.rdbuf());
+
+ JSValueRef value(_jsccall(JSEvaluateScript, context, CYJSString(code), NULL, NULL, 0));
+ JSObjectRef function(CYCastJSObject(context, value));
+
+ JSValueRef arguments[3] = { exports, JSObjectMakeFunctionWithCallback(context, CYJSString("require"), &require), module };
+ CYCallAsFunction(context, function, NULL, 3, arguments);
+ }
+
+ return CYGetProperty(context, module, property);
+} CYCatch(NULL) }
+
+static bool CYRunScript(JSGlobalContextRef context, const char *path) {
+ CYPool pool;
+ CYUTF8String code(CYPoolFileUTF8String(pool, path));
+ if (code.data == NULL)
+ return false;
+
+ CYStream stream(code.data, code.data + code.size);
+ code = CYPoolCode(pool, stream);
+ _jsccall(JSEvaluateScript, context, CYJSString(code), NULL, NULL, 0);
+ return true;
+}
+
+extern "C" void CYDestroyWeak(JSWeakObjectMapRef weak, void *data) {
+}
+
+extern "C" void CYSetupContext(JSGlobalContextRef context) {