Servo: The Embeddable Browser Engine
Embedding, in the context of this article, is the process of hosting a web rendering engine inside another application. This engine displays content exactly as a regular web browser would, but allows the application author to customize the user’s experience further than what is possible in the typical display of a normal website. Development time can be reduced by keeping part of the content of an application in web-related languages due to the relative ease of writing web content and the widespread knowledge of HTML5.
The technique of embedding web content is used in many places by many companies, including:
- Popular Linux applications such as Rhythmbox, Kate, Eclipse, and Evolution have support for embedding web content.
- Microsoft Entourage and Apple Mail for Mac OS both utilize embedding for displaying web content and parts of the UI.
- Adobe products, including their constantly-running updater, embed full web runtimes.
- Valve’s Steam client also depends heavily on embedding web content, as they reuse the content from their online store to display in their native application.
- Many applications in mobile app stores are simply a native wrapper around a web browser control and HTML5 resources.
HTML5 has been gaining significant traction in the mobile and embedded world. According to a recent survey HTML5 is a leading platform for application development in all markets, and this figure is likely to increase as the number of mobile platforms grows in the future. Finally, HTML5 is a widely known cross-platform solution which guarantees portability.
The Need for A Common, Embeddable API
There are very few common APIs for embedding content into applications, and until a couple years ago, the most prevalent API was WebKit. This was problematic because WebKit’s API is not considered stable, forcing developers to rewrite parts of their application in order to keep up with changes in the underlying browser engine. In recent years, Blink was forked from WebKit, creating yet another embeddable API. Unfortunately, in addition to being confined to C++, Blink’s embedding API is also not stable, perpetuating the increased workload for application developers.
One solution for these problems is to use the Chromium Embedded Framework. Launched in 2008, the project is based on the Blink browser engine but aims to completely insulate its users from underlying engine changes. It provides a base C API with C++ extensions; allowing support at the lowest levels of software development. Currently, this API is used extensively by Valve for their Steam client, and by Adobe, for various products.
The Servo Solution
The Servo browser engine aims to be embeddable in order to provide maximum flexibility to developers. To this end, it must provide a stable API and ABI for developers to rely on. It is written in Rust because it provides an API usable from C. Designing yet another embeddable web API is an extremely complex task which requires a tremendous amount of consideration and review. It also requires extensive documentation to be written, frameworks to be tested, and the resulting product to be promoted and accepted into general usage. Based on this, we decided to take a different approach.
Servo implements the Chromium Embedded Framework API: if it’s good enough for Valve, it’s good enough for us. This means developers who currently use CEF will not need to make any application changes to compare performance between the Blink and Servo engines, and prospective developers will not have yet another browser API to review and consider. Hopefully, this also means Servo will reach an embeddable state much more quickly.
The methodology for this implementation is twofold: ensure full symbol coverage, and attempt to mimic the exact functionality of each method call as closely as possible. Since this is not a common practice, let’s break it down a little further. Symbol coverage refers to the externally visible symbols provided by a library. Rust, using the extern “C” keywords, allows any function written in Rust to be directly accessible from C with no extra work needed. So in this regard, full symbol coverage would mean that every CEF function call is able to be hooked by Servo’s embedding library. It also requires that any time an externally-used struct is allocated, it must match the size and member positioning as a similar struct allocated by the real CEF.
pub struct cef_string_utf8 {
pub str: *mut u8,
pub length: size_t,
pub dtor: extern "C" fn(str: *mut u8),
}
Mimicking functionality is a bit trickier. This requires full understanding of each CEF function and how it ties into the browser engine. Then, the same order of operations must be replicated using the underlying Servo browser engine. This can be quite a complex process, as CEF makes internal function calls back and forth between itself and Blink, sometimes requiring functions to operate recursively.
The method for implementing and testing the success of this endeavor has been a bit complex. First, a symbol list was needed. Using standard utilities, specifically the nm tool on Linux, we copied the undefined symbols from some of the example CEF applications. This provided an easy starting point to begin implementing functions and functionality. With the list of target symbols, it became much easier to track the execution of the application through the CEF library and determine what was happening in each function call. From here it became a case of using Rust/Servo to replicate the expected and observed behavior.
A Few Hitches Along The Way
The process of writing this implementation for embedding has not come very far because it was only recently begun; at present, there is only a very small team focusing on it. However, there have been some difficulties that may be interesting to other developers. One such difficulty that was immediately apparent was tracking the C API’s execution through the C++ extensions provided by CEF. The example applications all use the C++ extensions which required a bit of legwork to understand how they utilize and wrap the C API and what was going on internally. The solution here was extremely rudimentary, just read a whole bunch of source code. Eventually, even the most high-level wrapper would come down to one or two function calls which could then be written and tested more thoroughly.
Another difficulty that took quite a while to track down is a byproduct of the testing environment. In order to run the CEF examples with the Servo backend, we needed to use some library preloading hacks (LD_PRELOAD and friends on Linux) so the running environment would inject the Servo embedding symbols for use in the application, effectively overriding the CEF-provided functions. However, as long as the CEF library is used in any function call it will invoke the underlying Blink runtime, which uses the tcmalloc allocator. The reason this is problematic is because tcmalloc uses different function calls for allocating memory between C and C++ than what is expected, and it complains quite loudly when it detects any deviation from this behavior. As a result, the Servo embedding library needed to provide wrappers to allow calling these functions directly for memory allocation, but only when using the preload hack:
pub fn new(size: size_t) -> *mut c_void {
unsafe {
tc_new(size)
}
}
The embedding support is now sufficient to run Servo within the cefsimple application, and a number of tasks are currently open to improve support in other directions. For more information check out the GitHub page.
Guest Author: Lars Bergstrom
Lars Bergstrom is a researcher at Mozilla, currently working on the servo parallel web browser project.He received his Ph.D. from the University of Chicago‘s Computer Science department, studying under Dr. John Reppy. His Master’s paper was on the implementation of analysis and optimization passes in our parallel compiler, Manticore. His Ph.D. research was on how to add mutation safely and efficiently into a functional parallel programming language. He has also been doing work on a runtime, garbage collector, and most recently some extensions to control-flow analysis. Before that, he was a manager and a developer at Microsoft in the Visual Studio organization, working on next-generation software development tools technology out at the Redmond, WA offices.
Servo: The Embeddable Browser Engine的更多相关文章
- Vedis - An Embeddable Datastore Engine
Vedis - An Embeddable Datastore Engine An Embeddable Datastore Engine Tweet Follo ...
- 关于Servo项目中Rust代码行数的数据来源
我两个月之前的一篇博客<为什么我说Rust是靠谱的编程语言>(下面简称原文),在当中"6. 两个半大型成功案例"一节.我以前写道: Servo: 下一代浏览器渲染引擎( ...
- Browser Page Parsing Details
Browser Work: 1.输入网址. 2.浏览器查找域名的IP地址. 3. 浏览器给web服务器发送一个HTTP请求 4. 网站服务的永久重定向响应 5. 浏览器跟踪重定向地址 现在,浏 ...
- Architecture options to run a workflow engine
This week a customer called and asked (translated into my own words and shortened): “We do composite ...
- Rendering Engine 主流的浏览器内核(排版引擎、渲染引擎、解释引擎)有哪几种,分别的特点
一.A web browser engine A rendering engine is software that draws text and images on the screen. The ...
- 实现ECMAScript的引擎
list of ECMAScript engines From Wikipedia, the free encyclopedia An ECMAScript engine is a progr ...
- SharpBrowser
SharpBrowser is the fastest open source C# web browser there is! Slightly faster than Google Chrome ...
- OSCP Learning Notes - Privilege Escalation
Privilege Escalation Download the Basic-pentesting vitualmation from the following website: https:// ...
- Web自动化测试工具调研
背景 Web自动化测试越来越被重视, 因为现在Web已经是工程化的状态. 如何通过工具测试, 保证Web开发的质量,提升开发效率,是Web工具的诞生的来由. Web测试分为以下几个方面: 1. 界面测 ...
随机推荐
- ubuntu权限管理常用命令 分类: linux ubuntu 学习笔记 2015-07-05 14:15 77人阅读 评论(0) 收藏
1.chmod 第一种方式 chomd [{ugoa}{+-=}{rwx}] [文件或者目录] u 代表该文件所属用户 g 代表该文件所属用户组 o 代表访客 a 代表所有用户 +-=分别表示增加权限 ...
- git提交时的冲突处理
转自http://www.cnblogs.com/mengdd/p/3585038.html 当两条分支对同一个文件的同一个文本块进行了不同的修改,并试图合并时,Git不能自动合并的,称之为冲突(co ...
- android打包签名介绍
Keytool 是一个有效的安全钥匙和证书的管理工具. Java 中的 keytool.exe (位于 JDK\Bin 目录下)可以用来创建数字证书,所有的数字证书是以一条一条(采用别名区别)的形式存 ...
- C#基础入门--关于C#背景介绍以及变量相关
在正式探索C#的奥秘之前,我们先谈一谈关于学习方法的问题吧.你会不会有这样的感悟,自己努力奋斗得到的东西倍加珍惜,飘到眼前的,却不屑一顾.我认为,学习的整个历程亦是如此.在学习过程中,只有我们遇到了问 ...
- ionic 项目分享No.2——简化版【转】
写在文章前:由于最近研究ionic框架,深感这块的Demo寥寥可数,而大家又都藏私,堂堂天朝,何时才有百家争鸣之象,开源精神吾辈当仁不让! ...
- 在C#中使用正则表达式自动匹配并获取所需要的数据
转自:http://my.oschina.net/bv10000/blog/111736 正则表达式能根据设置匹配各种数据(比如:e-mail地址,电话号码,身份中号码等等).正则表达式功能强大,使用 ...
- [弹出消息] C#ShowMessageBox帮助类
点击下载 ShowMessage.rar 看下面代码吧 /// <summary> /// 类说明:Assistant /// 编 码 人:苏飞 /// 联系方式:361983679 // ...
- 【Windows】Windows中的数据类型以及命名
一.大写标示符 Windows中的很多标识符都是以两个或者三个大写字母作为前缀的,且其后紧跟一个下划线.这些标识符都是常量数值,前缀表明该常量的一般类别.如下 前缀 常量 CS(Class Style ...
- Jquery全选与反选checkbox(代码示例)
今天在公司要实现操作权限的功能,需要根据左边的树,选择一项,判断右边的操作权限,例如,增加,修改,删除,查看等按钮的显示与隐藏: 这个功能实现思路如下: 1.操作权限:增加.修改等按钮的ID和Text ...
- SQL使用存儲過程訪問不同服務器
用openrowset连接远程SQL或插入数据 --如果只是临时访问,可以直接用openrowset --查询示例 select * from openrowset('SQLOLEDB', 'sql服 ...