转自http://blog.sunchrome.com/?p=33

一个web页面需要使用到JS的场景

Parser阶段

HTMLDocumentParser 中的HTMLTokenizer在解析到<script>开始标签时,创建HTMLScriptElement对象,在解析</script>时,开始解析JS代码啊,如果<script src=”">中含有src,那么发出一个异步请求(在异步请求过程中,parser会中断,等待JS的解析结果,期间Webkit会来做一些DNS预取,资源预解析等工作,总之WebKit是不会浪费这些宝贵时间的),等src资源返回后开始解析。

用户事件驱动

比如鼠标点击一个按钮

解析状态

onload等函数

WebKit中的JS执行的代码所在的位置

WebKit中所有的JS执行都是通过Frame中的ScriptController m_script;来完成,也就是说,所有的每个Frame只有一个JS入口。

ScriptController中含有一个V8Proxy的V8代理,所有执行过程都是通过V8Proxy来完成的。

如何把DOM接口的相关接口暴露给V8的?

要把DOM传递给V8调用就要解决两个问题,DOM对象怎么传递给V8?

DOM对象的中的方法怎么传递给V8?

还有诸如其他的Screen等对象是如何传递给V8的?

一个Frame中的V8运行环境,也就是上面文章所提到的Context,

W3C—WEB IDL
由该工作草案定义的接口定义语言(interface definition language)叫作Web IDL,它可被用来描述要在Web浏览器里实现的接口。Web IDL是一种IDL的变体,它所具有的很多特性使之能够更容易地对Web平台里的常用脚本对象的行为进行规定。为了支持过去只能以文字描述的常用功能,该IDL在很多方面得到了扩展。另外,它还为ECMAScript第3版和Java给出了精确的语言绑定。

回归WebKit核心代码WebCore中的源代码,可以发现有许多xxx.idl文件,这些文件就是需要暴露给JS解析引擎的接口。
以WebKit/WebCore/page/DOMWindow.h 为列,改文件主要在C++层次描述了一个Web页面的所有特性,包括 DOM,screen,History等等相关信息。这些信息都是通过WebKit/WebCore/page/DOMWindow.idl描述文件来描述的,DOMWindow.idl主要分为两个部分,属性和方法,DOMWindow.idl的代码太多了,就不在这里列举IDL文件内容了。其实xxx.idl文件在C++运行时并不起任何作用,真正起作用的是编译器利用 xxx.idl文件来生成的对应的C++源文件,由于通过xxx.idl接口描述的属性和功能规则比较简单,所以通过编译器通过perl语言,然后按照一定规则来生成对应的供JS引擎调用的C++源文件。
Chromium生成的V8接口对应的目录在src/chrome/Debug/obj/global_intermediate/webkit/bindings或者
src/chrome/Release/obj/global_intermediate/webkit/bindings.

通过分析这些动态生成的文件可以发现,他们的组成结构非常简单,
namespace WebCore {

class V8DOMWindow {

public:
static bool HasInstance(v8::Handle value);
static v8::Persistent GetRawTemplate();
static v8::Persistent GetTemplate();
static DOMWindow* toNative(v8::Handle);
static v8::Handle wrap(DOMWindow*);
static void derefObject(void*);
static WrapperTypeInfo info;
…忽略了下面的部分代码
};
v8::Handle toV8(DOMWindow*);
v8::Handle toV8(PassRefPtr);
}

然后CPP文件中是这样实现的
static const BatchedAttribute shadowAttrs[] = {
// Attribute ‘location’ (Type: ‘attribute’ ExtAttr: ‘V8DisallowShadowing DoNotCheckDomainSecurity CPPCustom V8CustomSetter JSCCustom’)
{“location”, DOMWindowInternal::locationAttrGetter, V8DOMWindow::locationAccessorSetter, 0 /* no data */, static_cast(v8::ALL_CAN_READ | v8::ALL_CAN_WRITE | v8::PROHIBITS_OVERWRITING), static_cast(v8::None | v8::DontDelete), 0 /* on instance */},
// Attribute ‘window’ (Type: ‘readonly attribute’ ExtAttr: ‘V8DisallowShadowing DoNotCheckDomainSecurity’)
{“window”, DOMWindowInternal::windowAttrGetter, 0, 0 /* no data */, static_cast(v8::ALL_CAN_READ | v8::PROHIBITS_OVERWRITING), static_cast(v8::None | v8::DontDelete), 0 /* on instance */},
// Attribute ‘top’ (Type: ‘attribute’ ExtAttr: ‘V8DisallowShadowing DoNotCheckDomainSecurityOnGet Replaceable V8ReadOnly’)
{“top”, DOMWindowInternal::topAttrGetter, 0, 0 /* no data */, static_cast(v8::ALL_CAN_READ | v8::PROHIBITS_OVERWRITING), static_cast(v8::None | v8::DontDelete), 0 /* on instance */},
};
static const BatchedAttribute DOMWindowAttrs[] = {
// Attribute ‘screen’ (Type: ‘readonly attribute’ ExtAttr: ”)
{“screen”, DOMWindowInternal::screenAttrGetter, 0, 0 /* no data */, static_cast(v8::DEFAULT), static_cast(v8::None), 0 /* on instance */},
// Attribute ‘history’ (Type: ‘readonly attribute’ ExtAttr: ‘JSCCustomGetter DoNotCheckDomainSecurity’)
{“history”, DOMWindowInternal::historyAttrGetter, 0, 0 /* no data */, static_cast(v8::ALL_CAN_READ), static_cast(v8::None), 0 /* on instance */}
……下面的代码忽略,
}

static const BatchedCallback DOMWindowCallbacks[] = {
{“getSelection”, DOMWindowInternal::getSelectionCallback},
{“print”, DOMWindowInternal::printCallback},
{“stop”, DOMWindowInternal::stopCallback},
{“open”, V8DOMWindow::openCallback},
{“showModalDialog”, V8DOMWindow::showModalDialogCallback},
{“alert”, DOMWindowInternal::alertCallback},
{“confirm”, DOMWindowInternal::confirmCallback},
{“prompt”, DOMWindowInternal::promptCallback},
{“find”, DOMWindowInternal::findCallback},
{“scrollBy”, DOMWindowInternal::scrollByCallback},
{“scrollTo”, DOMWindowInternal::scrollToCallback},
{“scroll”, DOMWindowInternal::scrollCallback},
{“moveBy”, DOMWindowInternal::moveByCallback},
{“moveTo”, DOMWindowInternal::moveToCallback},
{“resizeBy”, DOMWindowInternal::resizeByCallback},
{“resizeTo”, DOMWindowInternal::resizeToCallback},
{“getMatchedCSSRules”, DOMWindowInternal::getMatchedCSSRulesCallback},
{“setTimeout”, V8DOMWindow::setTimeoutCallback},
{“clearTimeout”, DOMWindowInternal::clearTimeoutCallback},
{“setInterval”, V8DOMWindow::setIntervalCallback},
{“clearInterval”, DOMWindowInternal::clearIntervalCallback},
{“atob”, DOMWindowInternal::atobCallback},
{“btoa”, DOMWindowInternal::btoaCallback},
{“addEventListener”, V8DOMWindow::addEventListenerCallback},
{“removeEventListener”, V8DOMWindow::removeEventListenerCallback},
{“captureEvents”, V8DOMWindow::captureEventsCallback},
{“releaseEvents”, V8DOMWindow::releaseEventsCallback},
};

注意到这两部分分别定义了JS所能调用的 属性和所使用的方法。
然后再把这些属性和方法注册到V8执行时所需要的Context中,其流程大致是这样的。
ScriptController::executeScript
ScriptController::evaluate
v8::Handle v8Context = V8Proxy::mainWorldContext(m_proxy->frame());
proxy->mainWorldContext();
V8DOMWindowShell::initContextIfNeeded
V8DOMWindowShell::createNewContext
V8DOMWindow::GetShadowObjectTemplate
static v8::Persistent ConfigureShadowObjectTemplate
void batchConfigureAttributes
void configureAttribute
(attribute.onProto ? proto : instance)->SetAccessor(v8::String::New(attribute.name),
attribute.getter,
attribute.setter,
v8::External::Wrap(attribute.data),
attribute.settings,
attribute.attribute);

注册函数的执行流程和上面这个流程类似。
这样V8就可以在指定的Context中调用所有WEB IDL中所规则的属性和方法了。

webkit如何实现JS DOM binding—基于V8分析相关推荐

  1. # 代码约架?Vue.js和Binding.scala两大框架作者的PK

    作为一个知乎小透明,最近看了一场炸鱼大片.两天前,民工叔因为 Teambition 是 React 技术栈而离职 一文,引发了激烈的讨论.其中民工叔偏向的技术选型Vue.js的作者出没现场黑了一把An ...

  2. Node.js 入门教程 6 V8 JavaScript 引擎

    Node.js 入门教程 Node.js官方入门教程 Node.js中文网 本文仅用于学习记录,不存在任何商业用途,如侵删 文章目录 Node.js 入门教程 6 V8 JavaScript 引擎 6 ...

  3. html js 选择器,h.js - dom元素选择器

    dom元素选择器 使用h(selector)可以快速的选择dom元素,支持下面几种选择方式: 1.id选择器 2.类选择器 3.标签选择器 4.原生对象选择器 选择器语法及返回语法: h('选择器') ...

  4. 前端笔记(Html+CSS+JS+DOM+网页特效+jQuery+HTML5+CSS3+canvas 标签+web开发重难点+面向对象+AJAX)

    第1章Html Html:超级文本标记语言(HyperText Markup Language),在浏览器上运行的一种标记语言. 就是给文本加上含有语义的标签. 接下来应该学习更多具体语义标签: 一. ...

  5. Node.js 内存管理和 V8 垃圾回收机制

    作者:五月君 链接:https://www.imooc.com/article/288799 来源:首发慕课网 本文已获作者 "五月君" 授权转载,原文首发于 "慕课网& ...

  6. java创建node类型数据类型_[Java教程]js DOM Node类型

    [Java教程]js DOM Node类型 0 2015-12-18 16:00:08 DOM(文档对象模型)是针对HTML和 DOM可以将任何HTML或 以下面为例: My article Hell ...

  7. js DOM Element属性和方法整理

    js DOM Element属性和方法整理 节点操作,属性 1. childNodes.children 这两个属性获取到的子节点会根据浏览器的不同而不同的,所以一定要判断下nodeType是否为1. ...

  8. js DOM——JS学习笔记2015-7-2(第73天)

    这个是w3cschool上面的简易版教程,虽然简易,但是对整个JS DOM,有个大致的概念,同时引入思维导图这种图表法学习方式,期待更加便于记忆和管理 转载于:https://www.cnblogs. ...

  9. js弹幕脚本(基于油猴)

    js弹幕脚本(基于油猴) 该脚本包含往视频上插入弹幕,发射弹幕,弹幕查询,弹幕暂停,脏话过滤等基础功能.话不多说 ,直接上代码. 仅供参考 ,该代码是我给别人写的定制化的,复制后不可用. // ==U ...

最新文章

  1. Morph 3D拥有近千名艺术家,欲打造全球最大的VR虚拟化身服装库
  2. 技术雷达峰会2020:从技术趋势看行业挑战
  3. Android开发效率—Eclipse快捷键
  4. Access restriction: The type Unsafe is not accessible due to restriction on required library
  5. java 打包成服务_maven javaProject打包发布成服务
  6. Python爬虫常用模块
  7. AGS Server 10.1 切图工具
  8. 通用mapper 如何处理多表条件查询通过list封装(一对多)
  9. IE9下透明度设置无效
  10. 如何使用DOSBox软件编写运行汇编语言程序
  11. 双盘转子动力学仿真c语言程序,[转载]基于ANSYS经典界面的双转子电机的转子动力学仿真...
  12. 程序员,不甘平凡又害怕努力…
  13. 计算机模拟超光速,超光速十代笔记本电脑怎么样-电脑测评
  14. Windows编程 Windows程序的生与死(上)
  15. 专利检索及分析模拟登陆(python)
  16. 郑州73中学计算机老师,关于“郑州市中学信息技术优质课评比”的通知
  17. 如何自己制作简历模板?简历在线制作的方法介绍
  18. 图片融合 c++ cuda加速
  19. ARCGIS中如何实现点集之间的两两连线
  20. 百度网盘BaiduYunCacheFileV0.db数据库研究

热门文章

  1. 范数的深刻解读(转自知乎)
  2. 如何选择开源许可证?(转)
  3. sysbench压力测试工具简介和使用(一)
  4. book: Effective Java
  5. 水晶报表自定义函数(替换并截取特殊字符后内容)
  6. docker添加阿里云专属镜像
  7. 守卫者的挑战(guard)
  8. java程序员面试经历(不忘初心,永不放弃,放得始终)。
  9. IE8下submit表单没反应
  10. 网易云信,发送验证码短信C#版代码