Mercurial > spidermonkey-playground
view spidermonkey-playground.cpp @ 77:8cf72992387d default tip
add JSONP
author | Dion Almaer <dion@mozilla.com> |
---|---|
date | Fri, 26 Jun 2009 10:13:32 -0700 |
parents | ed2cf86a7c9d |
children |
line wrap: on
line source
/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Ubiquity. * * The Initial Developer of the Original Code is Mozilla. * Portions created by the Initial Developer are Copyright (C) 2007 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Atul Varma <atul@mozilla.com> * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ // This file is based on the code in the JSAPI User Guide: // // https://developer.mozilla.org/En/SpiderMonkey/JSAPI_User_Guide #include "jsapi.h" #include "jsdbgapi.h" #include "tcb.h" #include "wrapper.h" #include "server_socket.h" #include "memory_profiler.h" // The name of our JS script containing our Trusted Code Base (TCB). #define TCB_FILENAME "tcb.js" // Global references to our TCB. static JSContext *tcb_cx; static JSObject *tcb_global; // The class of SecurableModules. static JSClass SM_global_class = { "SecurableModuleGlobal", JSCLASS_GLOBAL_FLAGS, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, JSCLASS_NO_OPTIONAL_MEMBERS }; // This native JS function is an implementation of the SecurableModule // require() function. For more information, see: // // https://wiki.mozilla.org/ServerJS/Modules/SecurableModules // // The function takes two parameters: a filename to import, and a JS // object containing objects to export into the module. The latter is // accessible from the loaded module via a global called 'imports'. // // This function returns the SecurableModule's 'exports' global. static JSBool require(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { char *filename; JSObject *exports; if (!JS_ConvertArguments(cx, argc, argv, "so", &filename, &exports)) return JS_FALSE; FILE *f = fopen(filename, "r"); if (!f) { JS_ReportError(cx, "File not found"); return JS_FALSE; } fseek(f, 0, SEEK_END); long fileSize = ftell(f); fseek(f, 0, SEEK_SET); char source[fileSize]; fread(source, fileSize, 1, f); fclose(f); // TODO: Check for return values here. JSContext *module_cx = JS_NewContext(JS_GetRuntime(cx), 8192); JS_BeginRequest(module_cx); JSObject *module_global = JS_NewObject(module_cx, &SM_global_class, NULL, NULL); JS_InitStandardClasses(module_cx, module_global); JS_DefineProperty(module_cx, module_global, "imports", OBJECT_TO_JSVAL(exports), NULL, NULL, 0); JSObject *module_exports = JS_NewObject(module_cx, NULL, NULL, module_global); JS_DefineProperty(module_cx, module_global, "exports", OBJECT_TO_JSVAL(module_exports), NULL, NULL, 0); jsval module_rval; if (!JS_EvaluateScript(module_cx, module_global, source, fileSize, filename, 1, &module_rval)) { JS_EndRequest(module_cx); JS_DestroyContext(module_cx); return JS_FALSE; } *rval = OBJECT_TO_JSVAL(module_exports); JS_EndRequest(module_cx); JS_DestroyContext(module_cx); return JS_TRUE; } // Our global checkAccess callback just checks to see if a JS function called // 'checkAccess' has been defined in the TCB, and delegates to that if so. If // not, though, we do a default checkAccess. static JSBool checkAccess(JSContext *cx, JSObject *obj, jsval id, JSAccessMode mode, jsval *vp) { jsval checkAccess; if (tcb_global && JS_GetProperty(tcb_cx, tcb_global, "checkAccess", &checkAccess) && JSVAL_IS_OBJECT(checkAccess) && JS_ObjectIsFunction(tcb_cx, JSVAL_TO_OBJECT(checkAccess))) { jsval argv[2]; argv[0] = OBJECT_TO_JSVAL(obj); argv[1] = id; return JS_CallFunctionValue(tcb_cx, tcb_global, checkAccess, 2, argv, vp); } // TODO: This doesn't work for the 'caller' attribute, and possibly other // things too. return JS_LookupPropertyById(cx, obj, id, vp); } static JSFunctionSpec tcb_global_functions[] = { JS_FS("getWrapper", getWrapper, 1, 0, 0), JS_FS("unwrap", unwrapObject, 1, 0, 0), JS_FS("wrap", wrapObject, 2, 0, 0), JS_FS("require", require, 2, 0, 0), JS_FS("profileMemory", profileMemory, 0, 0, 0), JS_FS("ServerSocket", createServerSocket, 0, 0, 0), JS_FS_END }; static JSSecurityCallbacks securityCallbacks = { checkAccess, NULL, NULL }; int main(int argc, const char *argv[]) { /* JS variables. */ JSRuntime *rt; /* Create a JS runtime. */ rt = JS_NewRuntime(8L * 1024L * 1024L); if (rt == NULL) return 1; JS_SetRuntimeSecurityCallbacks(rt, &securityCallbacks); /* Create a context. */ tcb_cx = JS_NewContext(rt, 8192); if (tcb_cx == NULL) return 1; JS_SetOptions(tcb_cx, JSOPTION_VAROBJFIX); JS_SetVersion(tcb_cx, JSVERSION_LATEST); JS_BeginRequest(tcb_cx); jsval rval; if (!TCB_init(tcb_cx, &rval)) return 1; tcb_global = JSVAL_TO_OBJECT(rval); JS_AddNamedRoot(tcb_cx, &tcb_global, "TCB Global"); if (!JS_DefineFunctions(tcb_cx, tcb_global, tcb_global_functions)) return 1; FILE *f = fopen(TCB_FILENAME, "r"); if (!f) return 1; fseek(f, 0, SEEK_END); long fileSize = ftell(f); fseek(f, 0, SEEK_SET); char source[fileSize]; fread(source, fileSize, 1, f); fclose(f); if (!JS_EvaluateScript(tcb_cx, tcb_global, source, fileSize, TCB_FILENAME, 1, &rval)) { TCB_handleError(tcb_cx, tcb_global); return 1; } /* Cleanup. */ JS_RemoveRoot(tcb_cx, &tcb_global); JS_EndRequest(tcb_cx); JS_DestroyContext(tcb_cx); JS_DestroyRuntime(rt); JS_ShutDown(); printf("Farewell.\n"); return 0; }