/*************************************************************************** * Copyright (C) 2006 by TAM(Teppei Tamra) * * tam-t@par.odn.ne.jp * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "jsproc.h" #define XP_UNIX 1 #define SVR4 1 #define SYSV 1 #define _BSD_SOURCE 1 #define POSIX_SOURCE 1 #define DARWIN 1 #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <sys/mman.h> #include <jsapi.h> #include <string.h> namespace Honoka { class JSProcPriv { public: JSRuntime *jsrt; JSContext *jsct; JSObject *jsobj; JSClass jscs; JSProcPriv() { jscs.name = "global"; jscs.flags = JSCLASS_NEW_RESOLVE; jscs.addProperty = JS_PropertyStub; jscs.delProperty = JS_PropertyStub; jscs.getProperty = JS_PropertyStub; jscs.setProperty = JS_PropertyStub; jscs.enumerate = enumerate; jscs.resolve = (JSResolveOp)resolve; jscs.convert = JS_ConvertStub; jscs.finalize = JS_FinalizeStub; jsrt = NULL; jsct = NULL; jsobj = NULL; }; static JSBool resolve(JSContext *context,JSObject *obj,jsval id,uintN flags,JSObject **objp) { return JS_TRUE; }; static JSBool enumerate(JSContext *context,JSObject *obj) { return JS_EnumerateStandardClasses(context,obj); }; }; } JSProc::JSProc(const string &filename) { jspriv = new JSProcPriv(); init(filename); } void JSProc::init(const string &filename) { if (jspriv->jsct) JS_DestroyContext(jspriv->jsct); if (jspriv->jsrt) JS_DestroyRuntime(jspriv->jsrt); int fd = open(filename.c_str(),O_RDONLY); if (fd == -1) return; off_t mmapsize = lseek(fd,0,SEEK_END); char * mmapptr = (char *)mmap(0,mmapsize,PROT_READ,MAP_PRIVATE,fd,0); jspriv->jsrt = JS_NewRuntime(64L * 1024L * 1024L); if (!jspriv->jsrt) return; jspriv->jsct = JS_NewContext(jspriv->jsrt, 8192); if (!jspriv->jsct) { JS_DestroyRuntime(jspriv->jsrt); jspriv->jsrt = NULL; munmap(mmapptr,mmapsize); close(fd); return; } jspriv->jsobj = JS_NewObject(jspriv->jsct,&jspriv->jscs, NULL, NULL); if (!jspriv->jsobj) { JS_DestroyContext(jspriv->jsct); jspriv->jsct = NULL; JS_DestroyRuntime(jspriv->jsrt); jspriv->jsrt = NULL; munmap(mmapptr,mmapsize); close(fd); return; } if (!JS_InitStandardClasses(jspriv->jsct,jspriv->jsobj)) { JS_DestroyContext(jspriv->jsct); jspriv->jsct = NULL; JS_DestroyRuntime(jspriv->jsrt); jspriv->jsrt = NULL; munmap(mmapptr,mmapsize); close(fd); return; } jsval rval; JSString *str; uintN lino; if (!JS_EvaluateScript(jspriv->jsct,jspriv->jsobj,mmapptr,mmapsize,"script",lino, &rval)) { JS_DestroyContext(jspriv->jsct); jspriv->jsct = NULL; JS_DestroyRuntime(jspriv->jsrt); jspriv->jsrt = NULL; munmap(mmapptr,mmapsize); close(fd); return; } munmap(mmapptr,mmapsize); close(fd); return; } JSProc::~JSProc() { if (jspriv->jsct) JS_DestroyContext(jspriv->jsct); if (jspriv->jsrt) JS_DestroyRuntime(jspriv->jsrt); delete jspriv; } /*! \fn JSProc::eval(const string &script) */ string JSProc::eval(const string &script) { if (!jspriv->jsct) return string(); jsval rval; JSString *str; char fn[] = "(inline)"; uintN lino = 0; if (!JS_EvaluateScript(jspriv->jsct,jspriv->jsobj,script.c_str(),strlen(script.c_str()),fn,lino, &rval)) { return string(); } str = JS_ValueToString(jspriv->jsct,rval); return string(JS_GetStringBytes(str),strlen(JS_GetStringBytes(str))); }