SpiderMonkey学习笔记(2)--封装JSAPI

2024-01-26 06:32

本文主要是介绍SpiderMonkey学习笔记(2)--封装JSAPI,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

上一篇文章搭建好了一个简单的SpiderMonkey测试环境,并且把JSAPI User Guide里的样板代码直接拷贝到了工程里。在这篇文章里,我将对JSAPI做一个简单的封装,以方便后续的学习和试验。

1)添加一个C++类,名字估且就叫JsEngine吧

右键点击SpiderMonkeyTest Group,在弹出菜单中点击New Files... 菜单项:

选择iOS -> C and C++ -> C++ Class,然后点Next:

填上JsEngine,然后按Create按钮:

这样一个空白的类就创建好了:

2)设计JsEngine类

我们的JsEngine设计的很简单,除了构造和析构函数,只有一个execJS(...)方法用来执行一段JS脚本:

#include <string>
#include "jsapi.h"class JsEngine {
public:JsEngine();virtual ~JsEngine();void execJS(const std::string& script);
protected:/* JS variables. */JSRuntime *rt;JSContext *cx;JSObject *global;
};

如果不明白JSRuntime、JSContext以及JSObject是什么,建议再看一下JSAPI User Guide,里面讲的很清楚。

3)JsEngine构造函数:初始化SpiderMonkey

#include "JsEngine.h"// =============================================================================
// global_class & reportError
// =============================================================================/* The class of the global object. */
static JSClass global_class = {"global",JSCLASS_GLOBAL_FLAGS,JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,JS_StrictPropertyStub,JS_EnumerateStub,JS_ResolveStub,JS_ConvertStub,NULL,JSCLASS_NO_OPTIONAL_MEMBERS
};/* The error reporter callback. */
static void reportError(JSContext *cx, const char *message, JSErrorReport *report) {fprintf(stderr, "%s:%u:%s\n",report->filename ? report->filename : "<no filename="">",(unsigned int) report->lineno,message);
}// =============================================================================
// JsEngine impl
// =============================================================================JsEngine::JsEngine() {/* Create a JS runtime. */rt = JS_NewRuntime(8L * 1024L * 1024L);if (rt == NULL)return;/* Create a context. */cx = JS_NewContext(rt, 8192);if (cx == NULL)return;JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_METHODJIT);JS_SetVersion(cx, JSVERSION_LATEST);JS_SetErrorReporter(cx, reportError);/* Create the global object in a new compartment. */global = JS_NewGlobalObject(cx, &global_class, NULL);if (global == NULL)return;/* Populate the global object with the standard globals,like Object and Array. */if (!JS_InitStandardClasses(cx, global))return;
}

代码稍微有点长(基本上也是从JSAPI User Guide里抄过来的),但实际上并不难理解。先是创建了一个JSRuntime的实例(为其分配了8m内存),然后创建JSContext实例,并告诉它,当脚本解释执行遇到问题的时候,调用reportError函数报告错误紧接着创建出JS Global Object,然后初始化标准的JS类和函数。


4)JsEngine析构函数:清理SpiderMonkey

析构函数比较简单,销毁JSContext和JSRuntime,然后关掉SpiderMonkey引擎:

JsEngine::~JsEngine() {JS_DestroyContext(cx);JS_DestroyRuntime(rt);JS_ShutDown();
}

5)execJS方法

void JsEngine::execJS(const std::string& script) {jsval rval;/*JSBool ok = */JS_EvaluateScript(cx, global, script.c_str(), script.size(),"script", 1, &rval);
}
这个方法也没什么好说的,关于JS_EvaluateScript的详细说明,请看 这里。

6)修改ViewController.mm

最后让我们修改ViewController.mm,测试一下新鲜出炉的JsEngine类:
#import "ViewController.h"
#import "JsEngine.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad
{[super viewDidLoad];// Do any additional setup after loading the view, typically from a nib.JsEngine engine;engine.execJS("alert('Hello World!');");
}- (void)didReceiveMemoryWarning
{[super didReceiveMemoryWarning];// Dispose of any resources that can be recreated.
}@end

7)测试JsEngine

点击Run,在模拟器里运行程序:


看起来一切正常,但是输出窗口中输出了这句话:


不要担心,因为alert()并不是标准的JavaScript函数,只在浏览器环境中才有。而我们的JsEngine并没有实现这个函数,所以,SpiderMonkey报了错。看到这个输出就证明SpiderMonkey顺利解释并执行了我们的HelloWorld脚本。

好吧,先到此为止了,下一篇文章中我们再来看一下怎样实现alert()函数。


这篇关于SpiderMonkey学习笔记(2)--封装JSAPI的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/645915

相关文章

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

C++实现封装的顺序表的操作与实践

《C++实现封装的顺序表的操作与实践》在程序设计中,顺序表是一种常见的线性数据结构,通常用于存储具有固定顺序的元素,与链表不同,顺序表中的元素是连续存储的,因此访问速度较快,但插入和删除操作的效率可能... 目录一、顺序表的基本概念二、顺序表类的设计1. 顺序表类的成员变量2. 构造函数和析构函数三、顺序表

Go语言利用泛型封装常见的Map操作

《Go语言利用泛型封装常见的Map操作》Go语言在1.18版本中引入了泛型,这是Go语言发展的一个重要里程碑,它极大地增强了语言的表达能力和灵活性,本文将通过泛型实现封装常见的Map操作,感... 目录什么是泛型泛型解决了什么问题Go泛型基于泛型的常见Map操作代码合集总结什么是泛型泛型是一种编程范式,允

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学