1.1.Js引擎与Wasm
2.JS引擎(0):JavaScript引擎群雄演义—起底JavaScript引擎
3.TSLint 和 ESLint 是源码怎么融合在一起的
4.jsc反编译工具编写探索之路
5.华为自带浏览器内核
1.Js引擎与Wasm
Js引擎的工作原理与WebAssembly的引入 在深入解析JavaScript引擎工作原理之前,我们需要理解JavaScript引擎对于前端和服务器应用的解析重要性,以及其在处理复杂计算任务时的源码局限性。以Chorme v8和SpiderMonkey引擎为例,解析它们负责解析JavaScript代码并优化执行效率,源码直接影响着用户体验。解析理想画线指标源码然而,源码对于高密度数学计算集中的解析任务,如文档对象模型(DOM)操作或机器学习实训平台,源码JavaScript引擎的解析效率相对较低。 为了理清JavaScript引擎的源码工作原理、了解其局限性,解析并引出WebAssembly这一近几年备受关注的源码技术,本文将详细解析JavaScript引擎的解析核心机制。JavaScript引擎的源码工作原理
以最简单的函数 `a+b` 为例,让我们一起探索JavaScript引擎如何处理此函数。 1. **识别运算符**:引擎首先判断 `+` 运算符左右两边的子表达式,依据ECMA-标准完成第一步和第三步,即获得 `lref` 和 `rref`,即所谓的 `complettion record`,用于规范解析流程。 2. **递归解析**:通过标准函数 `GetValue` 分别求解 `AdditiveExpression`,得到 `lval` 和 `rval`。 3. **调用运算符函数**:使用 `ApplyStringOrNumericBInaryOperator` 调用,返回正常结束项或字符串、BigInt等。 4. **转换至基础类型**:调用 `ToPrimitive` 抽象操作,将输入参数转化为非对象类型,得到 `lprim` 和 `rprim`。 5. **字符串处理**:若 `lprim` 或 `rprim` 为字符串,则调用 `ToString` 连接结果后返回。 6. **数值化处理**:若 `lprim` 和 `rprim` 不为字符串,则通过 `ToNumeric` 分别转化为 `lnum` 和 `rnum`。 7. **执行加法**:以数字加法形式返回 `lnum + rum`。 需要注意的是,这里的 `lval`、`rval` 等标记仅为解析流程描述时的辅助概念,实际引擎内部使用的变量名、寄存器名或组件名并不相同。词法分析
词法分析阶段的主要任务是识别和提取源代码中的关键字,同时判断每种关键字的类型,包括声明变量的“let”或结束语句的“;”。这些关键字通过这一阶段被识别和提取出来,并结合类型信息,形成“Token”这一最小单位,从而构建起代码结构的基础。语法分析
语法分析阶段,结合编程语言的语法规则和词法分析阶段得到的Token信息,将源代码转换为抽象语法树(AST)形式。AST以树状结构表示源代码的语法结构,便于后续处理。 在此阶段,全民枪战PHP源码语法分析器整理和组合Token,提取语法结构,如函数定义、变量定义和表达式,最终形成树状语法表示结构。语义分析
在语义分析阶段,编译器进一步分析AST,判断源代码是否存在运行时错误。此阶段分析函数调用过程、参数个数、变量声明与使用的一致性,并优化代码。最终得到的中间代码可直接编译为平台机器码。JS引擎(0):JavaScript引擎群雄演义—起底JavaScript引擎
JavaScript,既是一门面向过程的语言,也是一门面向对象的语言。其动态特性包括运行时构造对象、可变参数列表、函数变量、动态脚本执行(通过 eval)、对象内枚举(通过 for ... in)和源码恢复。早期JavaScript引擎实现较为简单,多采用偷懒方式。随着技术发展,引擎如Mocha、SpiderMonkey、Rhino/Nashorn、JavaScriptCore、Chakra、JScript等相继诞生并演进。这些引擎在自动内存管理、JIT编译、对象布局、性能优化等方面各具特色。
在JavaScript引擎的演进历程中,早期的实现如Mocha引擎采用较为简陋的方法,如字节码解释器、引用计数方式的自动内存管理和fat discriminated union形式的值表现形式。SpiderMonkey引擎在年实现了mark-and-sweep GC、tagged value等技术,成为当时流行的native application嵌入JavaScript选择。Rhino/Nashorn引擎则为Java版的SpiderMonkey,用于纯Java实现的新版浏览器和服务器端脚本语言环境。JavaScriptCore引擎源自KJS,由苹果大力投入,性能超越KJS,支持JIT编译,广泛应用于iOS的Safari和UIWebView控件。
Chakra引擎的问世使JScript性能显著提升,其隐藏类变迁机制“type evolution”和对象布局优化,如对象头与property数组分离、日动向指标源码紧凑布局、使用tagged-value来存储值等,使得对象访问更为高效。JScript引擎,如IE8/JScript 5.8,对象存储依赖Hashtable,但在IE8版本中增加了对密集数组的优化。执行引擎则是一个简单的解释器,采用switch-threading形式的解释器主循环,优化了字符串拼接等操作。
不常见的JavaScript引擎如IronJS,采用F#与C#的混合实现方式,具有实验性对.NET 2.0和3.0的支持。IronJS使用Nan-boxing技术,虽然内存占用较大,但提高了内存局部性和效率。这些不同引擎的特性展示了JavaScript语言在不同场景下的应用潜力。
TSLint 和 ESLint 是怎么融合在一起的
Eslint 能够对 JavaScript 代码进行静态检查,涵盖逻辑错误和代码格式问题。其工作原理是将代码解析成抽象语法树(AST),然后基于 AST 检测问题。
同样,Tslint 也是一款静态检查工具,用于检测 TypeScript 代码中的逻辑错误和代码格式问题,其原理也是基于 AST。
既然两者都基于 AST 且功能相似,为何不将它们合并呢?
最终,Tslint 被整合进了 Eslint,Tslint 被标记为废弃。
然而,两者毕竟基于不同的 AST,且 Tslint 中包含一些类型检查的逻辑,这是 Eslint 所不支持的。那么,它们是如何融合的呢?接下来,我们一起来探究。
不同的 AST
Eslint 使用 espree 作为自己的解析器,并生成相应的 AST。
Typescript 和 Babel 也都有各自的解析器和相应的 AST。
这些 AST 之间存在怎样的关系呢?
最早的解析器是 esprima,它参考了 Mozilla 浏览器 SpiderMonkey 引擎的 AST 标准,并进行了扩充,形成了 estree 标准。
后续的许多解析器都是对 estree 标准的实现和扩展,如 esprima、espree、babel parser(babylon)、acorn 等。
当然,也有不是 estree 标准的,如 typescript、分时高低公式源码terser 等的解析器。
它们之间的关系如图所示:
esprima 和 acorn 都是 estree 标准的实现,而 acorn 支持插件机制来扩充语法,因此 espree 和 babel parser 是直接基于 acorn 实现的。
terser、typescript 等则是另一套。
因此,对于 JavaScript 的 AST,我们可以简单划分为两类:estree 系列、非 estree 系列。
可以使用 astexplorer.net 工具来可视化地查看不同解析器产生的 AST。
espree 就是 Eslint 自己实现的解析器,但它主要进行代码的逻辑和格式的静态检查,在新语法的实现进度上不如 babel parser。因此,Eslint 支持解析器的切换,可以在配置不同的解析器来解析代码。
配置文件中可以配置不同的解析器,并通过 parserOptions 来配置解析选项。
下面分别讲解 Eslint、typescript、babel、vue 等的解析器如何在 Eslint 中使用:
而且,在单文件组件中的 JS 部分,还可以分别指定不同的解析器。
感觉有点晕吗?typescript、babel、vue 等的解析器都有相应的用于 Eslint 的版本。其实想想也很正常,因为 lint 是基于 AST 的,如果不能解析,那么如何进行 lint,所以需要支持解析器的扩展和切换。
但是,解析器之后的 AST 可能不同,那么 lint 的规则实现也不同。为了复用规则,大家还是尽量往 estree 标准上靠比较好。
Tslint 和 Eslint 的融合也是这样的思路,下面我们来详细了解一下。
Tslint 融合进 Eslint
Tslint 是一个独立的工具,基于 TypeScript 的解析器来解析代码,并实现了基于该 AST 的一系列规则。
如果要融合进 Eslint,那么如何融合呢?主要考虑的是 AST 如何融合,因为规则是基于 AST 的。
例如,const a = 1; 这段代码,estree 系列的 AST 是这样的:
而 TypeScript 的 AST 是这样的:
由于 AST 不同,那么基于 AST 的规则肯定也要有不同的实现。
如何融合呢?转换!kd 源码 你好豆奶把一种 AST 转成另一种 AST 就行了。
没错,@typescript-eslint/parser 中确实也是这么做的,它把 TypeScript 的 AST 转换成 estree 的 AST(当然,对于类型部分,estree 中没有,就保留了该 AST,但加上了 TS 前缀)。这样,就能够用 Eslint 的规则来检查 TypeScript 代码中的问题。
下面简单看一下 @typescript-eslint/parser 的源码:
我简化了一下,是这样的:
首先通过 TypeScript 的解析器将源码解析成 AST,然后转换成 estree 的,并记录了 estree node 和 TypeScript node 的映射关系,通过两个 map 来保存。
具体的转换过程,其实就是遍历 TypeScript 的 AST,然后创建新的 estree 的 AST。
其中,对于 estree 中没有的类型相关的 AST,则直接复制,并在 AST 名字前加个 TS。
这样,就把 TypeScript 解析器产生的 AST 转成了 estree 的。
既然 AST 统一了,那么 Eslint 的规则就可以用来 lint TypeScript 代码了。
但是对于一些类型的部分,还是需要用 TypeScript 的 API 来检查 TypeScript 的 AST 怎么办呢?
还记得我们保存了两个 map 吗?estree node 到 TypeScript node 的 map,还有反过来的 map。这样,需要用到 TypeScript 的 AST 的时候,再映射回去就行了:
Eslint 的自定义解析器的返回结果中,除了有 ast,还支持返回 services,这是用于放置一些其他信息的,比如这里用到的 map,还有 TypeScript 的 program 的 API(比如 program.getTypeChecker 这种)。需要的时候就可以从 estree 的 ast 再映射回 TypeScript 的 ast 了。
通过把 TypeScript AST 映射成 estree AST,达到了复用 Eslint 规则的目的,并保存了节点映射关系和一些操作 TypeScript AST 的 API,可以基于这些单独做 TypeScript 相关的 lint。完美地融合到了一起。
可以把这种融合用“求同存异”来总结:
总结
JavaScript 有不同的解析器,分为 estree 系列、非 estree 系列:
Eslint 支持解析器的切换,可以在 babel parser、vue template parser、typescript 和 espree 中切换,当然也可以扩展其他解析器。
Tslint 是一个基于 TypeScript 解析的独立工具。它和 Eslint 都是基于 AST 检查代码中逻辑和格式错误的工具,后来进行了融合。
为了复用基于 estree 的一些规则,@typescript-eslint/parser 把 TypeScript node 转成了 estree node,但依然保留了映射关系和一些操作 TypeScript ast 的 API。
这样基于 estree AST 的规则可以正常运行,基于 TypeScript AST 的规则也可以映射回原来的 TypeScript node 然后运行。
通过这种方式,完美地把 Eslint 和 Tslint 融合在一起。还是挺巧妙的。
jsc反编译工具编写探索之路
研究逆向分析时,若遇到使用Cocos2dx编写的JavaScript游戏,理解其打包流程与开发工具是关键。Cocos2dx支持多种语言进行游戏开发,其中JavaScript与C++的结合尤其常见。在新版本中,编写的JavaScript代码经过编译生成jsc文件,这种二进制优化提升了游戏性能,同时也增加了逆向分析的难度。本篇内容将探索如何编写一款针对jsc文件的二进制反编译器。
首先,理解Cocos2dx+JavaScript的创建与打包流程是基础。通过下载Cocos2dx,配置环境,执行相关命令,可以创建并编译一个JavaScript游戏工程。此过程生成的jsc文件是经过编译与优化的,用于提升游戏性能。
在进行逆向分析时,首先要分析正向过程。以Cocos2dx+JavaScript的游戏为例,通过下载并运行测试工程,观察生成的MyJSGame-desktop.app游戏程序,发现默认生成的js文件未加密,但需要通过jscompile命令将js编译为jsc格式。
网络上搜索jsc反编译工具时,发现可能存在工具限制或兼容性问题。在尝试使用dead仓库中的工具进行反编译时,遇到了失败的情况。这提示我们,寻找现成工具并非万能,可能需要深入理解底层技术。
SpiderMonkey作为一款由Mozilla公司开发的JavaScript执行引擎,提供了方便的API接口,用于执行和编译JavaScript脚本文件。通过研究dead.c文件中的相关代码,可以初步了解jsc反编译的工作流程。核心在于JS_DecompileScript()函数,它负责完成反编译工作。然而,Cocos2dx在编译jsc时并未包含源代码数据,导致反编译工具无法获取有效的源代码信息。
深入分析Cocos2dx中关于jscompile的调用插件,发现其底层调用的是bin/jsbcc程序来编译js脚本。通过GitHub上的记录可以找到其实现代码,关键在于JS::Compile()函数,它负责生成script对象,并调用JS_EncodeScript()编码生成jsc文件。在编译选项中,设置了不包含源代码的选项,因此生成的jsc文件在反编译时会返回"[no source]"。
尽管如此,通过调用JS_DecodeScript()解码指令与js_Disassemble()进行反汇编,可以实现部分反汇编功能。然而,要实现完整的反编译功能,需要深入理解jsc文件的结构与编码方式。这涉及到高级的逆向工程知识与技术,是未来探讨的方向。
探索之路并未结束,尽管完成了一些初步的反汇编功能,但真正的反编译挑战在于理解和解析机器码到可读的源代码。这需要深入研究JavaScript编译器与解释器的底层实现,以及Cocos2dx在编译过程中对JavaScript代码的特定处理。未来,期待能与更多开发者一起探讨这一高级话题,共同推进游戏安全逆向分析领域的发展。
华为自带浏览器内核
前几天,华为又上热搜了。原因是有媒体发出了这样一个信息:华为要开发自己的浏览器内核,做一个真正属于国人的浏览器。
现在的浏览器核心都是国外的,我们没有话语权。我们期待华为打破垄断!
如果华为决定从底层开始自己的研究,确实相当于填补了一个行业空白。
但说实话,我看到这个新闻后的第一反应是:
没必要,只要华为不傻,他就不干。
为什么这么说?我们以后再谈吧。
果不其然,这个消息很快就被大家捡到了源头。
原来,在一次座谈会上,华为浏览器的“高级经理”透露,两年后我们可以看到更好的华为浏览器问世。
这个“更好”可以在很多方面更好,比如可以让UI更好看,支持第三方扩展,增加更多实用功能等等。
但不一定对应华为自研的浏览器内核,也不代表华为计划两年内拿到自研的浏览器内核。
虽然原博客第二段涉及了一些“主流浏览器内核”相关内容,但明眼人一眼就能发现:
里面提到的Trident和Presto,这两个分别内置在IE和Opera浏览器中的排版引擎,已经死了很多年了。
火狐Firefox浏览器也早在年就将内置排版引擎从Gecko升级到了Quantum。
Safari的Webkit排版引擎拼错为Webkiticon。
至于市场份额最大的谷歌浏览器Chrome使用的Blink引擎,则完全没有提及。
讲道理,虽然这次座谈会我不在,但如果华为浏览器的“高级经理”能亲口说出这句话,那就像筛子一样漏了。
我不太相信。(猜测是博主自己贴出的“补充资料”)
然而,就是这样一条推文,渐渐变成了:
我已经决定做自研,我正在做自研,两年后我会完成自研,两年后我会发表。
很经典。它属于它。
而且刚才我也看到华为的“消息人士”今天通过几家媒体做了一个辟谣。
这算是结束了。
不,我不是,别瞎说
因此.事情到此结束。
但我肯定还是有一些朋友在思考我之前说的话:
华为为什么没有必要开发自己的浏览器?你想看着我们被外国扼杀吗?
好吧,在说这个之前,差评君想问问大家,不知道大家还记不记得当年“知名人士”经常提起的一件事:
中国生产不出圆珠笔。
这件事现在已经被大家当笑话讲了,估计很多穷朋友都知道了。
大概是说我们国家以前圆珠笔尖完全依赖进口,一年要花一个多亿。
于是有人拿这个说我们技术不行,卡脖子了。
但其实我们想做也能做,只是经济效益不值得。一天的产量就够一年了,相对于原来万亿美元的钢产量。
这是一种损失。不值得。
同样,自研的浏览器内核其实相当于自研的圆珠笔尖:可以,但不是必须的。
而且不赚钱。
这么想吧,华为真的做不出自己的浏览器内核吗?
开玩笑,华为本身就是做网络设备起家的。如今,万研发人员的专业化领域;d人员横跨软硬件生态。
鸿蒙系统可以向你展示整个过程。华为要开发自己的浏览器内核,就要抽调名高级工程师,立下军令状。
别说两年了。如果六个月后你还不能擦掉,我就输了。
但是这有什么意义呢?
首先我们要知道,浏览器的本质是浏览网页的工具。
而我们访问的每一个网页,本质上都是一堆由纯文本组成的超文本标记。
其实浏览器的作用就是利用内置的浏览器内核“排版引擎”和“JavaScript引擎”将文本标记渲染成精美的网页。
就像一个输入法。你把英语输入电脑。"
cha'ping ”,它却能给你解析成汉字的 “ 差评 ” 一样。而且浏览器干的活也和输入法很像:你必须按照大家约定俗成的规范( W3C )去解释原始网页的文本标记。
不能自己 瞎吉儿 发挥,想怎么解释就怎么解释。
不然人家浏览器用户看到的网页都是正常的,就你家浏览器排版不对,谁还用你?
所以即使几千个华为工程师从头写了一个全新的浏览器内核,干的事也和现在所有的浏览器内核干的事。。。
完全一致。
还得搭进去几十亿的研发、维护和宣传费用。
而且。。。浏览器内核本身也没有任何的保密属性。
不论是谷歌的 Blink / V8 引擎,还是火狐的 Quantum / SpiderMonkey 引擎,他们都是完全开源的。
每一行源代码都是公开的,还送成套开发学习资料。
所以强如微软,也早在三年前放弃了自研的浏览器内核,改成了基于谷歌浏览器的 Chromium 开源项目打造自家的浏览器。
既省研发经费,用户还喜欢用。
换句话说,浏览器内核这个东西啊,就好像是一本词典,它本质就是公开的,不存在任何秘密的。
并且释义是唯一,且约定成俗的。
从头打造一个浏览器内核呢,就好比是是说别人已经写好一本词典了,不要钱。
我说不行,我得再花二十个亿,用我自己造的例句再写一本。
咱家底再厚,也不能这么撒啊!
现在你们知道,为什么我说 “ 假如华为不蠢,就不会干这事 ” 了吧。
的确,最近两年我们发现,在科技行业当中,我们还是存在着一些个短板的。
就比方像是 EDA、光刻机、指令集架构生态等等。
所以像包括华为在内的一众企业,这两年也是在朝着这几个方向发力、补齐短板的。
但有些我们以为是短板的地方,其实就和当年的圆珠笔头一样。
不是不做,而是真的没必要做。
假如真的把几十亿花在这些事上面,那才是真的。。。
令人心疼。
相关问答:谷歌访问助手显示网络异常电脑上
<strong>解决办法如下:</strong> 1、用户可以打开“设置”,接着打开“应用管理选项”。2、打开后搜索备份,然后将谷歌服务助手卸载。 3、卸载后下拉界面搜索备份,然后点击恢复。4、从内部储存恢复页面恢复后点击谷歌服务助手就可以正常进去了。 谷歌公司(Google Inc.)成立于年9月4日,由拉里·佩奇和谢尔盖·布林共同创建,被公认为全球最大的搜索引擎公司 。谷歌是一家位于美国的跨国科技企业,业务包括互联网搜索、云计算、广告技术等,同时开发并提供大量基于互联网的产品与服务,其主要利润来自于AdWords等广告服务。