Newer
Older
scim-wnn / honoka-plugins / jsfilter / src / jsproc.cpp
@tamra tamra on 2 Sep 2006 4 KB JSClassを保持。
/***************************************************************************
 *   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;

    };
    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();
    jspriv->jsrt = NULL;
    jspriv->jsct = NULL;
    jspriv->jsobj = NULL;
    
    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;
        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;
        return;
    }
    if (!JS_InitStandardClasses(jspriv->jsct,jspriv->jsobj)) {
        JS_DestroyContext(jspriv->jsct);
        jspriv->jsct = NULL;
        JS_DestroyRuntime(jspriv->jsrt);
        jspriv->jsrt = NULL;
        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;
        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)));
}