配置了在BCB下的SpiderMonkey编译器,记录下来方便以后查看:
下载:
在https://developer.mozilla.org/En/SpiderMonkey/Getting_SpiderMonkey_source_code上可以下载到SpiderMonkey的最新源码。
编译fdlibm.lib
根据JS的依赖关系,需要先编译fdlibm这个文件,新建立一个BCBLib工程,叫fdlibm,在解压后的SpiderMonkey文件夹里SRC下的fdlibm中所有c和h文件添加到工程中,这一步,不需要对编译进行什么设置,直接就可以生成fdlibm.lib。
编译js32.lib
新建一个BCBLi工程js32,将SRC下的所有C和H文件添加到工程中,还需将js.msg、jsshell.msg、jsopcode.tbl以及刚才生成的fdlibm.lib也添加进来,打开Project->Options,在Directories/Conditionals中打开Conditional defines页面,在里面添加如下定义:XP_WIN、EXPORT_JS_API、JSFILE、WIN32及_X86_=1,点击OK,对工程进行编译,就会生成所需要的js32.lib文件了,编译的时候可以会出lib文件过大的错误提示,在Project->Options->TLib中将Page size 设置为0x8000就可以了。
在应用程序中使用SpiderMonkey
新建一个BCB控制台程序,将SRC中的所有H文件包含进来,并将js32.lib添加到工程里,新建一个CPP,添加如下代码:
#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------
#include <string.h> //for strlen
#include <stdio.h>
#include <cstdlib> //for system("PAUSE")
#include "jsapi.h"
#pragma comment(lib, "js32.lib")
#pragma comment(lib, "fdlibm.lib")
#pragma argsused
//---------------------------------------------------------------
static JSFunctionSpec my_functions[] = {
{0}
};
char* VersionToString(JSVersion v)
{
switch(v) {
case JSVERSION_1_0: return "JavaScript 1.0";
case JSVERSION_1_1: return "JavaScript 1.1";
case JSVERSION_1_2: return "JavaScript 1.2";
case JSVERSION_1_3: return "JavaScript 1.3";
case JSVERSION_1_4: return "JavaScript 1.4";
case JSVERSION_ECMA_3: return "ECMA 262 Edition 3";
case JSVERSION_1_5: return "JavaScript 1.5";
case JSVERSION_DEFAULT: return "Default JavaScript Version";
case JSVERSION_UNKNOWN: return "Unknown JavaScript version";
default: return "Unknown JavaScript version";
}
}
int main(int agc, const char* agv[])
{
JSVersion version; // 版本号
JSRuntime *rt; // 运行时的内存空间
JSContext *cx; // 环境句柄
JSObject *glob; // 对象(函数,类等)
JSBool builtins;
JSClass global_class = {// 全局对象
"global",0,
JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,
JS_EnumerateStub,JS_ResolveStub,JS_ConvertStub,JS_FinalizeStub
};
rt = JS_NewRuntime(8L * 1024L * 1024L); //8M
if (!rt) return 1;
cx = JS_NewContext(rt, 8192); //0x2000
if (cx == NULL) return 1;
version = JS_GetVersion(cx);
printf("Script Version: %s/n", VersionToString(version));
/* 初始化全局对象和标准类 */
glob = JS_NewObject(cx, &global_class, NULL, NULL);
builtins = JS_InitStandardClasses(cx, glob);
/* 定义全局对象的方法 */
JS_DefineFunctions(cx, glob, my_functions);
/* 执行一段js代码 */
char* szScript = "var i; var res; i = 1; res = 1; while (i <= 10){ res = res * i; i = i + 1; }";
jsval rval;
JSString *str;
char* pFileName = NULL;
int nLines = 0;
char chBufBegin[50] = {'/0'};
char chBufEnd[50] = {'/0'};
SYSTEMTIME stBegin;
SYSTEMTIME stEnd;
//get the begin time
GetLocalTime(&stBegin);
for (unsigned int i=0; i<100000; i++)
{
if (JS_EvaluateScript(cx, glob, szScript, strlen(szScript), pFileName, nLines, &rval) == JS_FALSE) {
printf("Error Occured while Run Script Engine./n");
system("PASUE");
return 1;
}
}
//get the end time
GetLocalTime(&stEnd);
//begin time
sprintf(chBufBegin, ("Begin: %u/%u/%u %u:%u:%u:%u %d/n"),
stBegin.wYear, stBegin.wMonth, stBegin.wDay,
stBegin.wHour, stBegin.wMinute, stBegin.wSecond,
stBegin.wMilliseconds,stBegin.wDayOfWeek);
//end time
sprintf(chBufEnd, ("End : %u/%u/%u %u:%u:%u:%u %d/n"),
stEnd.wYear, stEnd.wMonth, stEnd.wDay,
stEnd.wHour, stEnd.wMinute, stEnd.wSecond,
stEnd.wMilliseconds,stEnd.wDayOfWeek);
//display the result
printf(chBufBegin);
printf(chBufEnd);
//str = JS_ValueToString(cx, rval); //rval返回脚本最后执行的那个变量的值
printf("Script Result: %s/n", JS_GetStringBytes(str));
JS_DestroyContext(cx);
JS_DestroyRuntime(rt);
//JS_ShutDown();
system("PAUSE");
return 0;
}
//---------------------------------------------------------------
js程序实现一个10的阶乘,在外边的循环使SpiderMonkey被调用100000,获取执行前后的时间。可以看出引擎的执行速度十分的快,Mozilla名不虚传。