wns9778.com_威尼斯wns.9778官网

热门关键词: wns9778.com,威尼斯wns.9778官网
wns9778.com > 计算机教程 > wns9778.comJavaScript引擎--SpiderMonkey 的使用(转)-

原标题:wns9778.comJavaScript引擎--SpiderMonkey 的使用(转)-

浏览次数:90 时间:2019-06-29

4.  Webkit JavaScriptCore

一般说来,当你用JS引擎操纵字符串时,你应该用JS API串处理函数来创建和复制字符串。有字符串管理程序用于创建NULL结尾的字符串或者指定长度的字符串。同时,也有程序用于计算字符串长度、比较字符串。

2.  Google V8

管理RunTime

2.2. C 调用JavaScript

使用V8,在C 中访问Javascript脚本中的内容,首先要调用Context::GetCurrent()->Global()获取到Global全局对象,再通过Global全局对象的Get函数来提取Javascript的全局变量、全局函数、全局复杂对象。C 代码示例如下:

//获取Global对象

Handle<Object>globalObj = Context::GetCurrent()->Global();

 

//获取Javascrip全局变量

Handle<Value>value = globalObj->Get(String::New("JavaScript变量名"));

intn = value ->ToInt32()->Value();

 

//获取Javascrip全局函数,并调用全局函数

Handle<Value>value = globalObj->Get(String::New("JavaScript函数名"));

Handle<Function> func = Handle<Function>::Cast(value) ;//转换为函数

Local<Value> v1 = Int32::New(0);
    Local<Value> v2 = Int32::New(1);

Handle<Value> args[2] = { v1, v2 }; //函数参数

func->Call(globalObj, 2, args);

 

//获取Javascrip全局对象,并调用对象的函数

Handle<Value>value = globalObj->Get(String::New("JavaScript复杂对象名"));

Handle<Object> obj = Handle<Object>::Cast(value);//转换为复杂对象

Handle<Value> objFunc = obj ->Get(String::New("JavaScript对象函数名"));

Handle<Value> args[] = {String::New("callobject function ")};//函数参数

objFunc->Call(globalObj, 1, args);

如上面这个例子所示,调用JS引擎的应用程序必须首先创建JS RunTime,而且在终止程序之前要释放这个RunTime。在实例化RunTime后,即可创建自己的JS对象模型。对象模型决定了JS对象之间的关系,JS对象本质上是一种层次结构。缺省情况下,所有的JS对象都与全局对象相关联,它们都是全局对象的后代。当初始化标准的JS类时,你自动地得到一个全局对象:

3.2. C 调用JavaScript

使用SpiderMonkey,在C 中访问Javascript脚本中的内容,首先要调用JS_GetGlobalObject获取到Global全局对象,再调用JS_GetProperty函数来提取Javascript的全局变量、全局函数、全局复杂对象。示例如下:

JSRuntime *rt;

    JSContext*cx;

JSObject *glob;

//新建JSRuntime

rt = JS_NewRuntime(64L * 1024L* 1024L);

//新建JavaScript全局上下文

cx = JS_NewContext(rt,gStackChunkSize);

//新建JavaScript全局Global对象

glob = JS_NewObject(cx,&global_class, NULL,NULL);

JS_SetGlobalObject(cx, glob);

 

//获取JavaScript的全局变量

jsval var;

JSBool success = JS_GetProperty(cx, glob, "JavaScript全局变量名", &var);

long value = JSVAL_TO_INT(var);

 

//调用全局函数

jsval args[1]; //函数参数

arg[0] = INT_TO_JSVAL(1);

jsval ret;

success= JS_CallFunctionName(cx,glob, "JavaScript全局函数名", 1, args, &ret);

//处理返回值

long value = JSVAL_TO_INT(ret);

 

//获取JS复杂对象

sval object;

    success = JS_GetProperty(cx,glob, "JS复杂对象名", & object);

    JSObject* obj = JSVAL_TO_OBJECT(var);

jsval retValue;

//调用对象的方法,这里省略了参数和返回值的处理

success = JS_CallFunctionName(cx,obj, "JS复杂对象的方法名", 0, 0, &retValue);

例如,假定你在使用JS引擎自动化应用程序,脚本应用程序鉴别用户并设置权限。首先,应用程序创建JS对象,该对象描述用户信息,包括姓名、ID、权限和可用的函数列表。在这种情况下,应用程序首先调用JS_NewObject创建对象。当JS引擎创建对象后,返回一个指针给应用程序。应用程序再调用JS引擎执行脚本。在创建用户对象后,应用程序即刻传递脚本给JS_EvaluateScript以便编译和运行。脚本或许取得并效验用户信息,然后建立用户存取的权利。

2.3. JavaScript调用C

使用V8,在Javascript脚本中想要访问C 中的内容,必须先将C 的变量、函数、类注入到Javacsript中。注入时,首先要调用Context::GetCurrent()->Global()获取到Global对象,再通过Global对象的Set函数来注入全局变量、全局函数、类对象。

全局变量、全局函数的注入过程与上一节的代码类似,这里就省略不写了。比较麻烦的是将C 的类、类对象注入到Javascript中。其基本的过程如下:

1.   首先定义一个C 类,定义一个类对象指针

2.  定义一组C 全局函数,封装V8对C 类的调用,提供给V8进行CALLBACK回调。

3.   最后调用V8 API,将定义的C 类和C 函数注入到Javascript中

 

在V8的API接口中,还提供了一个“内部数据”(Internal Field)的概念,“内部数据”就是允许V8对象保存一个C 的void*指针。当V8回调C 全局函数时,C 可以设置或者获取该void*指针。

 

下面是一个将C 类、类变量注入到Javascript中的C 代码示例。

//一个C 类test、

class test

{

public:

    test(){number=0;};

    voidfunc(){number ;}

    int number;

};

//一个全局对象g_test

//目的是:在Javascript中可以直接使用这个对象,例如g_test.func()

test g_test;

 

//封装V8调用test类构造函数

//在Javascript中如果执行:var t = new test;V8就会调用这个C 函数

//在C 中执行NewInstance函数注入对象时,也会调用这个函数

//默认的test类的构造函数没有参数,C 注入对象时,提供一个额外的参数

v8::Handle<v8::Value> testConstructor(constv8::Arguments& args)

{

    v8::Local<v8::Object>self = args.Holder();

    //这里假定有两个“内部数据”(Internal Field)

    //第一个“内部数据”保存test对象的指针

    //第二个“内部数据”为1 就表示这个对象是由C 注入的

    //第二个“内部数据”为0 就表示这个对象是JS中自己建立的

    if(args.Length())

    {

        //默认为0,当C 注入对象时,会填充这个“内部数据”

        self->SetInternalField(0,v8::External::New(0));

        self->SetInternalField(1,v8::Int32::New(1));

    }

    else

    {

        self->SetInternalField(0,v8::External::New(new test));

        self->SetInternalField(1,v8::Int32::New(0));

    }

    return self;

}

 

//封装V8调用test类func方法

//在Javascript中如果执行:t.func();V8就会调用这个C 函数

v8::Handle<v8::Value> testFunc(constv8::Arguments& args)

{

    //获取构造函数testConstructor时,设置的对象指针

    v8::Local<v8::Object>self = args.Holder();

v8::Local<v8::External> wrap =v8::Local<v8::External>::Cast(self->GetInternalField(0));

    void* ptr =wrap->Value();

    //调用类方法

    static_cast<test*>(ptr)->func();

    returnv8::Undefined();

}

 

//封装V8调用test类成员变量number

//在Javascript中如果执行:t.number;V8就会调用这个C 函数

v8::Handle<v8::Value>getTestNumber(v8::Local<v8::String> property, const v8::AccessorInfo& info)

{

    //获取构造函数testConstructor时,设置的对象指针

    v8::Local<v8::Object>self = info.Holder();

v8::Local<v8::External> wrap =v8::Local<v8::External>::Cast(self->GetInternalField(0));

    void* ptr =wrap->Value();

    //返回类变量

    returnv8::Int32::New(static_cast<test*>(ptr)->number);

}

 

//C 类和全局的函数定义好以后,就可以开始将类、变量注入V8 Javascript中了

//获取global对象

v8::Handle<v8::Object> globalObj =context->Global();

 

//新建一个函数模板,testConstructor是上面定义的全局函数

v8::Handle<v8::FunctionTemplate> test_templ =v8::FunctionTemplate::New(testConstructor);

 

//设置类名称

test_templ->SetClassName(v8::String::New("test"));

 

//获取Prototype,

v8::Handle<v8::ObjectTemplate> test_proto =test_templ->PrototypeTemplate();

 

//增加类成员函数,testFunc是上面定义的全局函数

test_proto->Set("func",v8::FunctionTemplate::New(testFunc));

 

//设置两个内部数据,用于构造函数testConstructor时,存放类对象的指针。

v8::Handle<v8::ObjectTemplate> test_inst =test_templ->InstanceTemplate();

test_inst->SetInternalFieldCount(2)

 

//增加类成员变量

//getTestNumber是上面定义的全局函数

//只提供了成员变量的get操作,最后一个参数是成员变量的set操作,这里省略了

test_inst->SetAccessor(v8::String::New("number"),getTestNumber, 0);

 

//将test类的定义注入到Javascript中

v8::Handle<v8::Function> point_ctor =test_templ->GetFunction();

globalObj->Set(v8::String::New("test"),point_ctor);

 

//新建一个test对象,并使得g_test绑定新建的对象

v8::Handle<v8::Value> flag = v8::Int32::New(1);

v8::Handle<v8::Object> obj =point_ctor->NewInstance(1, &flag);

obj->SetInternalField(0, v8::External::New(&g_test));

globalObj->Set(v8::String::New("g_test"), obj);

 

将C 类和类指针注入到V8 JavaScript后,在JavaScript中就可以这样使用了:

g_test.func();

var n = g_test.number;

var t = new test;

 

如何使用引擎

5.1. 介绍

IE的Trident引擎是非开源的,微软JavaScript引擎也是非开源的。微软对外提供了一组COM接口。使用这组COM接口,能够将微软的JavaScript、VBScript嵌入到C、C 宿主语言中。

这组COM接口主要有如下一些定义:

l  IDispatch

IDispatch是COM跨语言调用的基本接口。

l  命名空间

这里的“命名空间”的意思相当于JavaScript中的Global对象,宿主语言必须要实现一个“命名空间”。当JavaScript执行脚本,遇见未知的变量、函数、类时候,就会调用该“命名空间”的IDispatch接口,来进行解析和执行。

l  IActiveScript

IActiveScript是由JavaScript脚本引擎所实现的接口,C、C 宿主语言调用该COM接口,就可以建立和初始化一个脚本的执行环境。

l  IActiveScriptParse

IActiveScriptParse是由JavaScript脚本引擎所实现的接口,该接口可以分析、执行一段JavaScript脚本,并且还可以控制JavaScript脚本的执行过程。

l  IActiveScriptSite

IActiveScriptSite是由C、C 宿主语言所实现的接口,该接口可以给JavaScript脚本提供“命名空间”,并且当JavaScript引擎出现错误、异常时,就会使用该接口进行回调通知。

 

在C 中使用这组COM接口的示例代码如下:

 

//获取JavaScript的CLSID

CLSID clsid;

CLSIDFromProgID(_T("JScript"), &clsid);

 

//创建JavaScript对象,获取IActiveScript接口指针

CComPtr<IActiveScript> activeScript = NULL;

CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_IActiveScript,(void **)&activeScript);

 

//创建宿主对象,CMyScriptSite实现了IActiveScriptSite接口

IActiveScriptSite* site = new CComObject<CMyScriptSite>;

        site->AddRef();

       

        //将宿主对象IActiveScriptSite与IActiveScript绑定

hr = activeScript->SetScriptSite(site);

 

//增加一个命名空间,会触发IActiveScriptSite的GetItemInfo方法被调用

_bstr_t name = “test”

hr=activeScript->AddNamedItem(name,SCRIPTITEM_ISVISIBLE|SCRIPTITEM_GLOBALMEMBERS);

 

//获取脚本解析和执行接口

CComQIPtr<IActiveScriptParse> activeScriptParse= activeScript;

 

//初始化一个执行环境

activeScriptParse->InitNew();

 

//解析一段JS

_bstr_t srcipt = "g_test.func()";

activeScriptParse->ParseScriptText(srcipt,name,NULL,NULL,0,0,0,NULL,NULL);

        //开始执行JS

activeScript->SetScriptState(SCRIPTSTATE_STARTED);

 

//宿主对象CMyScriptSite,必须要实现的一个方法

//与IActiveScript的AddNamedItem对应

//返回给JavaScript一个命名空间

HRESULT CMyScriptSite::GetItemInfo(LPCOLESTR pstrName, DWORDdwReturnMask, IUnknown **ppunkItem, ITypeInfo **ppti){

if (name == _bstr_t(pstrName) )

            {   //这里简单将宿主对象自己当做一个“命名空间”返回给JavaScript

                HRESULT hr =QueryInterface(IID_IUnknown, (void**)ppunkItem);

                return hr;

            }

            return E_FAIL;

}

1.处理JS数据类型

2.1. 介绍

Google Chrome是google 2008年9月发布的浏览器,Chrome的网页渲染部分使用的是Webkit的渲染引擎,Chrome的JavaScript引擎就是大名鼎鼎的V8了。V8是C 语言编写的,是开放源码的,是所有的JavaScript引擎中速度最块的。其开源项目地址为:http://code.google.com/p/v8。

V8对外的API接口是C 的接口。V8的API定义了几个基本概念:句柄(handle),作用域(scope),上下文环境(Context)。模板(Templates),了解这些基本的概念才可以使用V8。

l  上下文环境Context就是脚本的运行环境,JavaScript的变量、函数等都存在于上下文环境Context中。Context可以嵌套,即当前函数有一个Context,调用其它函数时如果又有一个Context,则在被调用的函数中javascript是以最近的Context为准的,当退出这个函数时,又恢复到了原来的Context。

l  句柄(handle)就是一个指向V8对象的指针,有点像C 的智能指针。所有的v8对象必须使用句柄来操作。没有句柄指向的V8对象,很快会被垃圾回收器回收了。

l  作用域(scope)是句柄的容器,一个作用域(scope)可以有很多句柄(handle)。当离开一个作用域(scope)时,所有在作用域(scope)里的句柄(handle)都会被释放了。

l  模板(Templates)分为函数模板和对象模板,是V8对JavaScript的函数和对象的封装。方便C 语言操作JavaScript的函数和对象。

l  V8 API定义了一组类或者模板,用来与JavaScript的语言概念一一对应。比如:

V8的 Function模板与JavaScript的函数对应

V8的Object类与JavaScript的对象对应

V8的String类与JavaScript的字符对应

V8的Script类与JavaScript的脚本文本对应,它可以编译并执行一段脚本。

JavaScript引擎提供若干个内置对象,使得你的开发任务得以简化。例如,内置数组(Array)对象使得在JS引擎中创建和操作数组结构很容易。类似地,日期(Date)对象提供了一个操作日期的统一机制。要了解内置对象支持的全部内容,请参阅JS_InitStandardClasses。 JS引擎一直使用函数和全局对象。通常,全局对象居留在幕后,为应用程序中创建和使用的其它JS对象及全局变量提供缺省范围。在创建自己的对象前,你必须初始化全局对象。函数对象使得对象具有和调用构造函数的功能。

4.2. C 调用JavaScript

使用JavaScriptCore,在C 中访问Javascript脚本中的内容,首先要调用JSContextGetGlobalObject获取到Global全局对象,再调用JSObjectGetProperty函数来提取Javascript的全局变量、全局函数、全局复杂对象。示例如下:

         //获取Global对象

    JSGlobalContextRef ctx = JSGlobalContextCreate(NULL);

    JSObjectRef globalObj = JSContextGetGlobalObject(ctx); 

 

//获取全局变量

    JSStringRef varName = JSStringCreateWithUTF8CString("JavaScript变量名");

JSValueRef var = JSObjectGetProperty(ctx, globalObj, varName,NULL); JSStringRelease(varName);

    //转化为C 类型

    int n = JSValueToNumber(ctx, var, NULL);

   

    //获取全局函数

JSStringRef funcName = JSStringCreateWithUTF8CString("JavaScript函数名");

JSValueRef func = JSObjectGetProperty(ctx, globalObj, funcName,NULL); JSStringRelease(funcName);

    //装换为函数对象

    JSObjectRef funcObject = JSValueToObject(ctx,func, NULL);

    //组织参数,将两个数值1和2作为两个参数

    JSValueRef args[2];

    args[0] = JSValueMakeNumber(ctx, 1);

    args[1] = JSValueMakeNumber(ctx, 2);

    //调用函数

JSValueRef returnValue = JSObjectCallAsFunction(ctx, funcObject,NULL, 2, args, NULL);

//处理返回值

    int ret = JSValueToNumber(ctx, returnValue, NULL);

   

    //获取复杂的对象

JSStringRef objName=JSStringCreateWithUTF8CString("JavaScript复杂对象名");

JSValueRef obj = JSObjectGetProperty(ctx, globalObj, objName,NULL); JSStringRelease(objName);

    //装换为对象

    JSObjectRef object = JSValueToObject(ctx,obj, NULL);

//获取对象的方法

JSStringRef funcObjName =JSStringCreateWithUTF8CString("JavaScript复杂对象的方法");

JSValueRef objFunc = JSObjectGetProperty(ctx, object, funcObjName,NULL); JSStringRelease(funcObjName);

//调用复杂对象的方法,这里省略了参数和返回值

JSObjectCallAsFunction(ctx, objFunc, NULL, 0, 0, NULL);

  • JSVAL_IS_OBJECT
  • JSVAL_IS_NUMBER
  • JSVAL_IS_INT
  • JSVAL_IS_DOUBLE
  • JSVAL_IS_STRING
  • JSVAL_IS_BOOLEAN

3.1. 介绍

Firefox的JavaScript引擎是SpiderMonkey,SpiderMonkey包括解析器、编译器和JIT即时编译器。JIT即时编译器是JavaScript引擎的核心部分,它决定了一个JavaScript引擎的效率和速度。Firefox的JIT即时编译器有很多个版本,最早的JIT名称是TraceMonkey,现在使用的是JägerMonkey,未来准备开发的是IonMonkey。在一些通用的JavaScript测试标准(比如SunSpider)中,Firefox的JavaScript引擎表现都不好,比IE、V8的执行速度差。Firefox的JS引擎源码地址:http://ftp.mozilla.org/pub/mozilla.org/js/

SpiderMonkey对外的API接口是C语言的。与WebkitJavaScriptCore的API比较类似,SpiderMonkeyAPI的主要数据结构有:

l JSRuntime:JSRuntime是内存空间,在执行JS函数或脚本之前,首先要调用JS_NewRunTime来初始化一个JSRuntime,JS_NewRunTime只有一个参数,就是内存的大小,当JS引擎使用的内存超出了指定的大小,垃圾回收器就会启动运行。

l JSContext:JavaScript全局上下文。也就是JavaScript的执行环境。

l jsval:JavaScript中的变量

l JSObject:JavaScript中的对象

l JSFunction:JavaScript中的函数

l JSString:JavaScript中的字符

 

SpiderMonkey API的主要函数有:

l  JS_NewRuntime JS_DestroyRuntime:新建和销毁JSRuntime

l  JS_NewContext JS_DestroyContext:新建和销毁JSContext

l  JS_NewObject:新建一个对象

l  JS_SetGlobalObject JS_GetGlobalObject:设置和获取全局对象

l  JS_GetProperty JS_SetProperty:JavaScript对象的属性操作

l  JS_CallFunctionName:调用JavaScript函数

l  JS_DefineFunctions:定义一组JavaScript函数

l  JS_InitClass:定义一个JavaScript类

l  JS_ExecuteScript:执行JavaScript脚本

 

SpiderMonkey API还定义了一些宏,用来在jsval与C 类型之间装换

l  JSVAL_TO_OBJECT  JSVAL_TO_STRING JSVAL_TO_INT:将jsval装换为C 类型

l  OBJECT_TO_JSVAL STRING_TO_JSVAL JSVAL_TO_INT:将C 类型装换为jsval

  1. 程序中包含jsapi.h。
  2. 程序中提供结构和变量声明。例如,如果你计划传递一个脚本给JS引擎,提供一个脚本字符串变量。用jsapi.h中定义的JS数据类型来声明变量。
  3. 使用JavaScript的脚本应用对象。通常这些对象与C程序中的结构和方法相对应。
  4. 将JS引擎API函数调用和变量引用插入到程序中,包括初始化内置JS对象、创建并配置用户自定义对象。
  5. 大多数JS引擎调用返回一个值。如果该值是NULL,一般表示错误发生。如果非NULL,表示成功,返回值一般是指针,程序需要使用或留到将来使用。应用程序应检查JS引擎调用的返回值。

1.  概要

JavaScript是一种广泛用于Web客户端开发的脚本语言,常用来控制浏览器的DOM树,给HTML网页添加动态功能。目前JavaScript遵循的web标准的是ECMAScript262。由于JavaScript提供了丰富的内置函数、良好的对象机制。所以JavaScript还可以嵌入到某一种宿主语言中,弥补宿主语言的表现力,从而实现快速、灵活、可定制的开发。

现有的主流浏览器基本上都实现了一个自己的JavaScript引擎。这些JavaScript引擎可以分析、编译和执行JavaScript脚本。这些JavaScript引擎都是用C或者C 语言写的,都对外提供了API接口。所以在C、C 语言中使用这些JavaScript引擎,嵌入JavaScript是非常方便的。有一些著名的开源项目都使用了这一种方式,来进行混合的编程,比如Node.js, K-3D等。

已知著名的JavaScript引擎有Google的V8引擎、IE的Trident引擎、Firefox的SpiderMonkey引擎、Webkit的JavaScriptCore引擎、Opera的Carakan引擎(非开源的,本文没有分析)等。这些JavaScript引擎对外提供的API接口在细节上各不相同,但是这些API的一个基本的设计思路都类似。C、C 要使用这些引擎,首先要获得一个全局的Global对象。这个全局的Global对象有属性、方法、事件。比如在JavaScript环境中有一个window窗口对象。它描述的是一个浏览器窗口。一般JavaScript要引用它的属性和方法时,不需要用“window.xxx”这种形式,而直接使用“xxx”。 它是JavaScript中最大的对象,所有的其他JavaScript对象、函数或者是它的子对象,或者是子对象的子对象。C、C 通过对这个最大的Global对象调用get、set操作就可以实现与JavaScript进行双向交互了。

下面的介绍涉及到比较多的代码细节,先给个结论吧,不想看C 细节代码可以不看了。

 

编写语言

API接口

C、C 与JavaScript交互(变量、函数、类)

Windows xp

vc2005编译

静态库的大小

示例EXE的大小

执行、解析JavaScript的速度

Google V8

C

C

可以

23.1M

1.1M

最快

Firefox3.5以前 SpiderMonkey

C

C

可以

1.3M

500K

Firefox高版本SpiderMonkey

C

C

可以

15.3M

1.7M

一般

Webkit  JavaScriptCore

C

C

可以

26.2M

1.4M

一般

IE

未知

COM

可以

未知

100K(没有链接库)

一般

如果优先考虑库的体积,建议使用Firefox的老版本。对执行效率有要求的话,建议使用V8。

除了JS数据类型以外,JS引擎也使用JS值,称其为jsvals。一个jsval本质上是一个指针,指向除了整型以外的JS数据类型。对于整型,一个jsval包含这个值自身。其它情况,指针被编码成包含额外信息。利用jsvals提高引擎的效率,允许API函数处理大量的潜在数据类型。 引擎API包含一组宏,用于测试一个jsval的JS数据类型。他们是:

5.  微软JavaScript

要让应用程序能解释JavaScript,你必须遵循某些JS API嵌入习惯。下面的例子简要说明需要嵌入到你的应用程序中去的一些API调用函数。大部分情况下,这些函数的插入顺序是很重要的。例如,在调用其他JS API之前必须初始化JS RunTime,同样在终止程序之前必须释放JS RunTime。

3.3. JavaScript调用C

在Javascript脚本中想要访问C 中的内容,必须先将C 的变量、函数、类注入到Javacsript中。注入时,首先要调用JS_GetGlobalObjec获取到Global全局对象,调用JS_SetProperty函数来注入全局变量,调用JS_DefineFunctions注入全局函数、调用JS_InitClass注入类。

全局变量注入过程与上一节的代码类似,这里就省略不写了。

注入全局函数的示例:

//C 全局函数,功能:将传入的两个参数相加

//cx 上下文,obj 目标对象,argc 参数个数,argv参数,rval返回值

JSBool Add (JSContext *cx, JSObject *obj, uintN argc, jsval*argv, jsval *rval){

    long value = JSVAL_TO_INT(argv[0]) JSVAL_TO_INT(argv[1);

    *rval = INT_TO_JSVAL(value);

    return JS_TRUE;

}

//需要注入到JS中的函数,可以有多个,最后一个必须是{0}

static JSFunctionSpec functions[] =

{

{" Add ", Add, 0},

        {0}

};

//注入C 全局函数函数

JS_DefineFunctions(cx, glob, functions);

 

函数注入后,在JavaScript中可以直接调用这个函数,例如:

var n = Add(100, 100);

 

使用SpiderMonkey注入C 类的过程和使用V8注入C 类的过程类似。SpiderMonkey的API也提供了一个类似于V8的“内部数据”的结构。可以给某个JavaScript对象指定一个void*数据,当SpiderMonkey CallBack回调C 时,就可以获取该void*数据进行操作了。

下面是一个示例代码:

//C 类定义

class test

{         

public:

    test(){number=0;};

    voidfunc(){number ;}

    int number;

};

test g_test;//变量定义

//定义一个结构,表示对象的“内部数据”

struct testPrivate

{

    test* t;    //test指针

    bool externObject;//是否是C 注入的对象

};

//test类构造函数

//在Javascript中如果执行:var t = new test;V8就会CallBack调用这个C 函数

//在C 中执行NewInstance函数注入对象时,也会调用这个函数

//默认的test类的构造函数没有参数,C 注入对象时,提供一个额外的参数,这个参数就是C 类的指针

JSBool testConstructor(JSContext *cx, JSObject *obj, uintNargc, jsval *argv, jsval *rval)

{

    testPrivate* tp =new testPrivate;

    if(argc)

    {

        tp->t =(test*)JSVAL_TO_PRIVATE(argv[0]);//注入的对象

        tp->externObject= true;

    }

    else

    {

        tp->t = newtest;//不是注入的对象就新建一个

        tp->externObject= false;

    }

    //设置“内部数据”

    if ( !JS_SetPrivate(cx, obj, tp) )

        return JS_FALSE;

    *rval =OBJECT_TO_JSVAL(obj);

    return JS_TRUE;

}

 

//test类析构造函数,JavaScript垃圾回收时,会CallBack调用这个函数

void testDestructor(JSContext *cx, JSObject *obj)

{

    //获取设置“内部数据

    testPrivate* tp =(testPrivate*)JS_GetPrivate(cx, obj);

    if(tp==NULL)

        return;

    if(!tp->externObject)//注入的对象,不删除

        delete tp->t;

    delete tp;

}

//封装test类func方法

//在Javascript中如果执行:t.func();就会CallBack调用这个C 函数

JSBool testFunc(JSContext *cx, JSObject *obj, uintN argc,jsval *argv, jsval *rval)

{

    //获取设置“内部数据

    testPrivate* tp =(testPrivate*)JS_GetPrivate(cx, obj);

    tp->t->func();

    return JS_TRUE;

}

//定义一个枚举,每个枚举值表示一个test类的成员变量。

enum

{

    test_number,

};

//test类的成员变量,可以有多个

JSPropertySpec testProperties[] =

{

    {"number", test_number, JSPROP_ENUMERATE },

    { 0 }

};

//test类的成员变量的get操作

//在Javascript中如果执行:var n= t.number; 就会调用这个C 函数

JSBool testGetProperty(JSContext *cx, JSObject *wns9778.com,obj, jsvalid, jsval *vp)

{

    if(JSVAL_IS_INT(id))

    {

        testPrivate* tp= (testPrivate*)JS_GetPrivate(cx, obj);

        switch(JSVAL_TO_INT(id))

        {

        casetest_number:

            *vp =INT_TO_JSVAL(tp->t->number);

            break;

        }

    }

    return JS_TRUE;

}

//test类的成员变量的set操作

//在Javascript中如果执行:t.number= 100; 就会调用这个C 函数

JSBool testSetProperty(JSContext *cx, JSObject *obj, jsvalid, jsval *vp)

{

    if(JSVAL_IS_INT(id))

    {

        testPrivate* tp= (testPrivate*)JS_GetPrivate(cx, obj);

        switch(JSVAL_TO_INT(id))

        {

        casetest_number:

            tp->t->number= JSVAL_TO_INT(*vp);

            break;

        }

    }

    return JS_TRUE;

}

 

//test类方法列表,可以有多个

static JSFunctionSpec testMethods[] = {

    {"func",testFunc, 0},

    {0}

};

 

JSClass testClass =

{

    "test",JSCLASS_HAS_PRIVATE,

    JS_PropertyStub,JS_PropertyStub,

    testGetProperty,testSetProperty,

    JS_EnumerateStub,JS_ResolveStub,

    JS_ConvertStub,testDestructor

};

//将test类定义注入JavaScript中

JSObject *newTestObj = JS_InitClass(cx, glob, NULL,&testClass,

        testConstructor,0,

        NULL,testMethods,

        NULL, NULL);

JS_DefineProperties(cx, newTestObj, testProperties);

 

//在JavaScript脚本中注入一个新对象,并使这个新对象与g_test绑定

jsval arg = PRIVATE_TO_JSVAL(&g_test);

JSObject* gtestObj = JS_ConstructObjectWithArguments(cx,&testClass, NULL, NULL, 1, &arg);

jsval vp = OBJECT_TO_JSVAL(gtestObj);

JS_SetProperty(cx, glob, "g_test", &vp);

 

将C 类和类指针注入到V8 JavaScript后,在JavaScript中就可以这样使用了:

g_test.func();

var n = g_test.number;

var t = new test;

一个简单的API调用,JS_InitStandardClasses,初始化全局和函数对象、内置引擎对象,方便应用程序使用它们:

3.  Firefox SpiderMonkey

people.name="John";

4.1. 介绍

WebKit是一个开源的浏览器引擎。很多浏览器都使用了WebKit浏览器引擎,比如苹果的Safari、Google的Chrome(只使用了排版和渲染部分)。WebKit包含一个网页排版渲染引擎WebCore和一个脚本引擎JavaScriptCore。JavaScriptCore引擎的API接口是C语言的API接口。关于JavaScriptCoreAPI的文档资料比较少,不过可以参考苹果公司的JSCocoa文档(基于Objective-C语言的)。苹果的Safari浏览器重写了JavaScriptCore,新的项目名称是SquirrelFish Extreme。SquirrelFish Extreme的对外API与JavaScriptCore是一样的。Webkit源码SVN地址:http://svn.webkit.org/repository/webkit/trunk

JavaScriptCore API的主要数据结构有:

l JSGlobalContextRef:JavaScript全局上下文。也就是JavaScript的执行环境。

l JSValueRef:JavaScript的一个值,可以是变量、object、函数。

l JSObjectRef:JavaScript的一个object或函数。

l JSStringRef:JavaScript的一个字符串。

l JSClassRef:JavaScript的类。

l JSClassDefinition:JavaScript的类定义,使用这个结构,C、C 可以定义和注入JavaScript的类。

 

JavaScriptCore API的主要函数有:

l JSGlobalContextCreateJSGlobalContextRelease:创建和销毁JavaScript全局上下文。

l JSContextGetGlobalObject:获取JavaScript的Global对象。

l JSObjectSetPropertyJSObjectGetProperty:JavaScript对象的属性操作。

l JSEvaluateScript:执行一段JS脚本。

l JSClassCreate:创建一个JavaScript类。

l JSObjectMake:创建一个JavaScript对象。

l JSObjectCallAsFunction:调用一个JavaScript函数。

l JSStringCreateWithUTF8CstringJSStringRelease:创建、销毁一个JavaScript字符串

l JSValueToBooleanJSValueToNumber JSValueToStringCopy:JSValueRef转为C 类型

l JSValueMakeBooleanJSValueMakeNumber JSValueMakeString:C 类型转为JSValueRef

JS引擎收到初始化请求后,给JS RunTime分配内存,应用程序使用的变量、对象和上下文(上下文)都保存在RunTime中。一个上下文是脚本的执行状态(JS引擎使用的)。每个同时存在的脚本或线程都必须有自己的上下文。单个的JS RunTime可以包含多个上下文、对象和变量。 几乎所有的JS引擎调用都需要一个上下文变量,应用程序在创建RunTime后,首先应调用至少一次JS_NewContext来创建一个上下文。上下文的实际数量依赖于程序中同时使用的脚本数。程序中每个同时存在的脚本都需要一个上下文。另一方面,如果某个时刻只有一个脚本编译和运行,那么你只需一个上下文给每个脚本重复使用即可。

4.3. JavaScript调用C

在Javascript脚本中想要访问C 中的内容,必须先将C 的变量、函数、类注入到Javacsript中。注入时,首先要调用JSContextGetGlobalObject获取到Global全局对象,再调用JSObjectSetProperty函数来注入全局变量、全局函数、类对象。

全局变量、全局函数的注入过程与上一节的代码类似,这里就省略不写了。

将C 的类、类对象注入到Javascript中。其基本的过程如下:

1.   首先定义一个C 类,

2.  定义一组C 全局函数,封装JavaScriptCore对C 类的调用,提供给JavaScriptCore进行CALLBACK回调。

3.   最后调用JSClassCreate函数,将定义的C 类和C 函数注入到Javascript中

 

C 示例代码如下

//C 类定义

class test

{         

public:

    test(){number=0;};

    voidfunc(){number ;}

    int number;

};

test g_test;//变量定义

 

//全局函数,封装test类的func方法调用

JSValueRef testFunc(JSContextRef ctx, JSObjectRef ,JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[],JSValueRef*)

{

    test* t =static_cast<test*>(JSObjectGetPrivate(thisObject));

    t->func();

    returnJSValueMakeUndefined(ctx);

}

//全局函数,封装test类的成员变量number的get操作

JSValueRef getTestNumber(JSContextRef ctx, JSObjectRefthisObject, JSStringRef, JSValueRef*)

{

    test* t =static_cast<test*>(JSObjectGetPrivate(thisObject));

    returnJSValueMakeNumber(ctx, t->number);

}

 

//使用一个函数, 创建JavaScript类

JSClassRef createTestClass()

{

    //类成员变量定义,可以有多个,最后一个必须是{ 0, 0, 0 }

//也可以指定set操作

    static JSStaticValuetestValues[] = {

        {"number", getTestNumber, 0, kJSPropertyAttributeNone },

        { 0, 0, 0, 0}

    };

    //类的方法定义,可以有多个,最后一个必须是{ 0, 0, 0 }

    staticJSStaticFunction testFunctions[] = {

        {"func", testFunc, kJSPropertyAttributeNone },

        { 0, 0, 0 }

    };

    //定义一个类

    staticJSClassDefinition classDefinition = {

        0,kJSClassAttributeNone, "test", 0, testValues, testFunctions,

        0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0

    };

    // JSClassCreate执行后,就创建一个了JavaScript test类

    staticJSClassRef t = JSClassCreate(&classDefinition);

    return t;

}

 

//创建JavaScript类

createTestClass ();

 

JSGlobalContextRef ctx = JSGlobalContextCreate(NULL);

    JSObjectRef globalObj = JSContextGetGlobalObject(ctx); 

   

//新建一个JavaScript类对象,并使之绑定g_test变量

  JSObjectRef classObj= JSObjectMake(ctx,testClass(), &g_test);

 

//将新建的对象注入JavaScript中

  JSStringRef objName= JSStringCreateWithUTF8CString("g_test");

JSObjectSetProperty(ctx,globalObj,objName,classObj,kJSPropertyAttributeNone,NULL);

 

将C 类和类指针注入到JavaScript后,在JavaScript中就可以这样使用了:

g_test.func();

var n = g_test.number;

var t = new test;

回页首

C、C 与JavaScript的互调用

  • 创建一个JSPropertySpec数据类型,将对象的属性信息指派给它,包括属性的GET和PUT方法名字。
  • 创建一个JSFunctionSpec数据类型,将被你的对象所使用的方法信息指派给它。
  • 创建实际的C函数,它们在响应你的对象方法调用时被执行。
  • 调用JS_NewObject和JS_ConstructObject函数,以便实例化该对象。
  • 调用JS_DefineFunctions函数来创建对象的方法。
  • 调用JS_DefineProperties函数来创建对象的属性。

5.2. JavaScript与C 的交互

在上一节中,宿主对象返回给JavaScript一个“命名空间”,这个“命名空间”必须实现IDispatch接口。同样的,宿主对象通过调用IActiveScript的GetScriptDispatch方法,也可以获得JavaScript的IDispatch接口指针。C、C 宿主对象和JavaScript脚本对象都互相持有对方的IDispatch接口。所以C、C 调用JavaScript,实际上就转化为IDispatch接口的调用。JavaScript调用宿主C、C ,实际上就转化为宿主语言C、C 对IDispatch接口的实现。

IDispatch是微软跨语言调用的一个标准COM接口。对于这个接口的调用、实现,网上到处都有,这里就忽略不写了。

 

版权声明:本文为博主原创文章,未经博主允许不得转载。


对于JavaScript1.3,JS引擎增加了安全增强型API函数,用于编译和运行传递给引擎的脚本或函数。JS安全模型是基于Java安全模型的。这个模型提供了一个通用的安全接口,但是,具体的安全实现是由应用程序自己来完成的。

SpiderMonkey是由C语言操作的JavaScript引擎,它支持JS1.4和ECMAScript-262规范。该引擎分析、编译和执行脚本,根据JS数据类型和对象的需要进行内存分配及释放操作。利用该引擎可以让你的应用程序具有解释JavaScript脚本的能力,目前已有若干个项目都采用了SpiderMonkey引擎,像K-3D、WebCrossing、WebMerger等。K-3D是用C 实现的3D建模与仿真系统,该系统内嵌SpiderMonkey引擎来提供自定义脚本(用户创建脚本生成像齿轮一样具有重复特性的复杂形体),也可用来驱动交互式的教学系统(用户可以使用一段JS脚本程序记录其交互过程,如移动鼠标、选择菜单、点击鼠标等)。WebCrossing利用SpiderMonkey实现了服务器端的脚本环境,提供了完全的Web-server脚本环境,服务器端的实现允许你在内置的、面向对象的数据库中创建永久对象,这样即可根据自己的需要扩展服务器环境。

这个RunTime必须已经存在。你指派给上下文的栈空间必须足够大以便提供给使用该上下文的脚本所创建的变量和对象。注意,因为需要一些与分配和维护上下文相关的overhead,你必须做到:在应用程序中必须根据需要来确定创建上下文的数量;要确保上下文在被应用程序所需要时存在,而不是反复销毁和需要时重新创建。

创建私有数据并将其与对象关联的方法:

调用函数JS_NewContext为某个脚本创建一个新的上下文。这个函数需要两个参数:一个与该上下文相关的RunTime指针,分配给该上下文的栈空间字节数。如果调用成功,函数返回一个指针,它指向这个新建立的上下文。例如:

2.处理JS值

 

4)在运行时间环境中,编译与执行全部脚本和函数。下面列出了这些API函数和它们的目的:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* 包含JS引擎的API头文件 */
#include "jsapi.h"
.
.
.
//主程序声明全局JS变量,包括RunTime、一个Context和一个全局对象,然后初始化JS RunTime、创建一个Context。
int main(int argc, char **argv)
{
  int c, i;
  /*声明全局JS变量,包括全局和自定义对象*/
  JSVersion version;
  JSRuntime *rt;
  JSContext *cx;
  JSObject  *glob, *it;
  JSBool builtins;
  /* 初始化JS RunTime,返回结果给rt */
  rt = JS_NewRuntime(8L * 1024L * 1024L);
  /* 如果rt为空,程序终止 */
  if (!rt)
    return 1;
  /* 创建一个Context,并将其与JS RunTime关联起来 */
  cx = JS_NewContext(rt, 8192);
  /* 如果cx为空,程序终止 */
  if (cx == NULL)
    return 1;
  /* 创建全局对象 */
  glob = JS_NewObject(cx, clasp, NULL, NULL);
  /* 实例化内置对象和全局对象*/
  builtins = JS_InitStandardClasses(cx, glob);
  .
  .
  .
  return 0;
}

描述持续的、自定义的JS对象的代码必须放在靠近程序执行的开始部分,在那些依耐于先前已存在对象的代码之前。

rt=JS_GetRuntime(cx);

如果你的应用程序创建了多个RunTime,那么,应用程序可能需要知道某个上下文是与哪个RunTime相关联的。这种情况下,可以调用函数JS_GetRuntime,同时传递该上下文作为参数。JS_GetRuntime返回一个指针,它指向合适的RunTime(如果存在的话):

JS_InitStandardClasses函数返回一个JS布尔值,表示初始化成功与否。

回页首

简介: JavaScript在浏览器中的应用几乎是尽人皆知的。实际上,JavaScript技术也可以使用在非浏览器应用程序当中,从而让应用程序具有自动的脚本功能。本文介绍了一种功能非常强大的JavaScript引擎SpiderMonkey。这个引擎是Mozilla 浏览器的 JavaScript引擎。该引擎接口定义清晰,模块化好。本文简要介绍了 SpiderMonkey的基本结构,并讲解了如何在自己的应用程序中使用该引擎,最后给出了一个样例程序。该程序能够解释执行JavaScript脚本完成简单的脚本功能。

像其他API调用一样,具有Unicode能力的API字符串函数的名字与标准的引擎API字符串函数的名字是一一对应的。例如,如果一个标准函数名为JS_NewStringCopyN,对应的Unicode版函数就是JS_NewUCStringCopN。具有Unicode处理能力的API字符串函数对于interned字符串也是可行的。

pdata=JS_GetContextPrivate(cx);

你在JavaScript中做的许多事情都会涉及到字符串,JS引擎实现了一个称为JSString的字符串数据类型和一个指向JS字符数组的指针类型即jschar,用类处理Unicode编码的字符串。这个引擎也实现了一组通用的Unicode字符串程序。最后,JS引擎也提供内置串的支持,两个或多个独立的字符串在内存中能共享一个串。对于JSString类型的字符串,这个引擎跟踪并管理串资源。

2)实现将给数组提供安全信息的函数。这些函数包括:给你的应用程序提供一个principals数组,用一套给定的规则对JS对象的引用数进行加减操作的机制。

如果一个jsval指向一个JSObject、 jsdouble或 jsstr等JS数据类型,你可利用JSVAL_TO_OBJECT、 JSVAL_TO_DOUBLE、 JSVAL_TO_STRING将jsval转为它的潜在类型。

  1. 写一个JS脚本,它创建一个对象、性质、方法、构造函数,然后将这个脚本传递给JS引擎。
  2. 将代码插入到你的应用程序中,它定义了对象的性质和方法,调用引擎来初始化一个新对象,然后通过额外的引擎调用设置对象的性质。这种方法的好处是,应用程序能包含操作对象的本地方法。

有两种方法来创建JS引擎能使用的自定义对象:

你也可测试jsval指向的值是否为NULL(JSVAL_IS_NULL)或void(JSVAL_IS_VOID)。

 

正常情况下,一个程序只需一个RunTime。当然,根据需要创建多个RunTime并将它们保存在不同指针上也是可以的。

随后要获取这个数据指针,请调用JS_GetContextPrivate,并传递这个上下文作为参数。这个函数返回指向私有数据的指针:

要创建私有数据并将其与上下文相关联:首先,创建私有数据,即常规的C语言void* 变量;然后,调用JS_SetContextPrivate函数,并指定创建私有数据的上下文和指向该数据的指针。例如:

如上所示,JS_NewRuntime返回一个指向RunTime的指针。非NULL表示创建成功。

builtins = JS_InitStandardClasses(cx, glob);

JSBool builtins;
      .
      .
      .
builtins = JS_InitStandardClasses(cx, glob);

除了测试一个jsval的潜在数据类型外,也能测试它看是否是原始JS数据类型(JSVAL_IS_PRIMITIVE)。原始数据类型是undefined、null、boolean、numeric和string类型。

JavaScript定义了自己的数据类型。有些数据类型直接对应于C语言中的副本。其它的,如JSObject、jsdouble和JSString,都是JavaScript独有的。

为了节约空间,JS引擎为共享单个字符串实例提供支持。这种共享的字符串称为"interned strings"。当你事先知道程序中会创建一个特定的、文本字符串并且要多次使用它时,请利用interned字符串。

<?xml encoding="US-ASCII"?>
<!ELEMENT order (header,item ,price)>
<!ELEMENT header (billing,shipping)>
<!ELEMENT billing (name,address,creditCard)>
<!ELEMENT shipping (name,address)>
<!ELEMENT name EMPTY>

JS RunTime是内存空间,JS引擎利用它来管理上下文、对象和与JS函数及脚本相关的变量。在执行JS函数或脚本之前,首先要调用JS_NewRunTime来初始化一个RunTime。JS_NewRunTime函数携带一个unsigned整型参数,这个参数指定了在碎片收集之前分配给RunTime内存的最大字节数。例如:

除了使用引擎内置对象外,你还可以创建、初始化并使用自己的JS对象。特别是你在使用JS引擎用脚本来自动化应用程序时更是如此。自定义的JS对象能提供直接的程序服务,或者作为你的程序服务的接口。

几乎所有的JS API调用都要求你传递一个上下文参数。在JavaScript引擎中一个上下文代表一个脚本,引擎传递上下文信息给运行脚本的线程。每个同时运行的脚本必须指派一个唯一的上下文。当一个脚本运行完后,它的上下文也不再有用,因此这个上下文可以重新指派给一个新的脚本,或将其释放。

5.安全控制

#include "js.h"
enum tagMY_PEOPLE {MY_NAME,MY_ADDRESS};
static JSBool GetPeopleProperty (JSContext *cx, JSObject *obj, jsval id, jsval *vp);
static JSBool SetPeopleProperty (JSContext *cx, JSObject *obj, jsval id, jsval *vp);
static JSBool PeoplePrint(JSContext *cx, JSObject *obj, uintN argc, 
        jsval *argv, jsval *rval);
typedef struct{
    char name[16];
    char addr[64];}PeopleInfo;
static PeopleInfo m_ainfo={"myName","myAddress"};
/*定义属性的 GETTER*/
static JSBool GetPeopleProperty (JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
    if (JSVAL_IS_INT(id)) {
        switch (JSVAL_TO_INT(id)) {
            case MY_NAME:
                *vp=STRING_TO_JSVAL (JS_NewStringCopyZ (cx,m_ainfo.name));
                break;
            case MY_ADDRESS:
                *vp=STRING_TO_JSVAL (JS_NewStringCopyZ (cx,m_ainfo.addr));
                break;
            }
    }
    return JS_TRUE;
}
/*定义属性的SETTER*/
static JSBool SetPeopleProperty (JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
    if (JSVAL_IS_INT(id)) {
        switch (JSVAL_TO_INT(id)) {
            case MY_NAME:
                strncpy (m_ainfo.name, JS_GetStringBytes (jss), 15);
                break;
            case MY_ADDRESS:
                strncpy (m_ainfo.addr, JS_GetStringBytes (jss), 63);
                break;
            }
    }
    return JS_TRUE;
}
/*定义print方法*/
static JSBool PeoplePrint(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, 
   jsval *rval)
{
    fprintf(stdout,"My Name is %s.nMy Addr is %s.n",m_ainfo.name,m_ainfo.addr);
    return JS_TRUE;
}
void main()
{
    JSString* jss;
    char buf[5120];
    int len;
    jsval rval;
    JSRuntime *rt;
    JSContext *cx;
    JSObject *globalObj,*PeopleObj;
    JSClass global_class = {
            "global",0,
            JS_PropertyStub, JS_PropertyStub,JS_PropertyStub, JS_PropertyStub,
            JS_EnumerateStub, JS_ResolveStub,JS_ConvertStub, JS_FinalizeStub };
/*定义People类的属性数组*/
static JSPropertySpec PeopleProperties[] =
  {
    {"name", MY_NAME,    JSPROP_ENUMERATE },
    {"address",  MY_ADDRESS,     JSPROP_ENUMERATE },
    {0}
  } ;
/*定义People类的方法数组*/
static JSFunctionSpec PeopleMethods[] =
{
    {"print",          PeoplePrint,     0},
             {0}
        };
/*定义People类*/
static JSClass PeopleClass = {
        "people",0,
  JS_PropertyStub,JS_PropertyStub, GetPeopleProperty, SetPeopleProperty,
  JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
};
    typedef struct{}
      /* 初始化JS RunTime,返回结果给rt */
rt = JS_Init(1000000L);
    if (!rt)return;
  /* 创建一个上下文,并将其与JS RunTime关联起来 */
    cx = JS_NewContext(rt, 5120);
    if (!cx)return;
  /* 创建全局对象 */
    if (!(globalObj = JS_NewObject (cx, &global_class, NULL, NULL)))return;
      /* 实例化内置对象和全局对象*/
JS_InitStandardClasses (cx, globalObj);
/*实例化People对象*/
PeopleObj = JS_DefineObject (cx, globalObj, "People", &PeopleClass, 0,JSPROP_ENUMERATE);
/*创建对象的属性*/
JS_DefineProperties (cx,PeopleObj, PeopleProperties);
/*创建对象的方法*/
JS_DefineFunctions (cx,PeopleObj, PeopleMethods);
FILE* fp;
/*打开文件,读入脚本*/
    if (!(fp = fopen ("test.js", "r")))return;
    len = fread (buf, 1, 5120, fp);
    fclose (fp);
    if (len <= 0)return;
/*执行一段脚本*/
    JS_EvaluateScript (cx, globalObj, buf, len, "", 1, &rval);
    jss = JS_ValueToString (cx, rval);
    fprintf(stdout,"The result is: %s",JS_GetStringBytes (jss));
/*释放上下文*/
JS_DestroyContext(cx);
/*释放RunTime*/
JS_DestroyRuntime(rt);
return;
}

参考资料

people.address="Beijing";

rt = JS_NewRuntime(8L * 1024L * 1024L);

本文由wns9778.com发布于计算机教程,转载请注明出处:wns9778.comJavaScript引擎--SpiderMonkey 的使用(转)-

关键词: wns9778.com

上一篇:Bootstrap 学习日志(一)wns9778.com

下一篇:没有了