打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
spidermonkey学习II
spiderMonkey实际上是一个类似JVM之类的虚拟机,它把js源代码解析成为中间码bytecode,然后执行这些中间码。首先我们会看看spiderMonkey是如何工作的,下一篇我们会看看js代码是如何与C函数互相调用的。
spiderMonkey解析器是单个,路径非常深的一个函数,这个函数每次会执行一个bytecode指令,使用switch语句,或者依靠编译器来跳转到当前指令指向的下一个代码段。JS-to-JS函数调用会进行javascript压栈,而不会增加C的栈。因为现在JS-C-JS的调用模式越来越普遍,解析器会不断地重入。
一些spidermonkey bytecode有很多特别的case,因为他们的参数不同。
编译器由以下组件组成:一个随机的逻辑扫描器,一个递归下降的parser,生成一个AST,还有一个进行树遍历的code generator
spidermonkey代码阅读笔记:
先忽略一些初始化过程。在通过js 的public API获得js global object和context后,外部只需要调用一下JS_EvaluateUCScriptForPrincipals或者类似的evaluate接口就可以运行js的源代码了。
而evaluate系列的函数流程为:
js_CompileScript -> js_Execute  -> JS_DestroyScript,
首先来分析编译过程:
js_CompileScript(cx, obj, principals, TCF_COMPILE_N_GO,
                              chars, length, NULL, filename, lineno);
在编译的时候,首先初始化parser的context:
js_InitParseContext.
    js_InitParseContext,首先第一步是初始化JSParseContext中的JSTokenStream这个数据结构。如:
        ts->userbuf.base = (jschar *)base;
        ts->userbuf.limit = (jschar *)base + length;
        ts->userbuf.ptr = (jschar *)base;
     userbuf中存储的数据为js源代码,length为源代码长度,所以userbuf.limit为数据的末尾。
    另外,初始化了tokenbuf这个数据结构,
      ts->tokenbuf.grow = GrowTokenBuf;
      ts->tokenbuf.data = cx;
     tokenbuf.grow为函数指针,指向分配内存空间的具体函数。data为JSContext
      //还有各种listener
     ts->listener = cx->debugHooks->sourceHandler;
     ts->listenerData = cx->debugHooks->sourceHandlerData;
    
然后调用
MaybeSetupFrame(cx, obj, fp, &frame);
这个函数的作用是初始化一下JSStackFrame frame这个数据结构,并且复制给cx->fp
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
js_PeekToken(JSContext *cx, JSTokenStream *ts)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

js_InitCodeGenerator


  for (;;) {
        pc.tokenStream.flags |= TSF_OPERAND;
        tt = js_PeekToken(cx, &pc.tokenStream);
        pc.tokenStream.flags &= ~TSF_OPERAND;
        if (tt <= TOK_EOF) {
            if (tt == TOK_EOF)
                break;
            JS_ASSERT(tt == TOK_ERROR);
            script = NULL;
            goto out;
        }

        pn = Statement(cx, &pc.tokenStream, &cg.treeContext);
        if (!pn) {
            script = NULL;
            goto out;
        }

        /*
         * FIXME bug 346749: let declarations at the top level in a script are
         * turned into var declarations and do not introduce block nodes.
         */
        JS_ASSERT(!cg.treeContext.blockNode);

        if (!js_FoldConstants(cx, pn, &cg.treeContext) ||
            !js_EmitTree(cx, &cg, pn)) {
            script = NULL;
            goto out;
        }
        RecycleTree(pn, &cg.treeContext);
    }
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
SpiderMonkey-让你的C++程序支持JavaScript脚本
脚本引擎小PK: SpiderMonkey vs V8(二)
学习SpiderMonkey60的心得笔记(五)调用JS中的函数
【风宇冲】Unity3D教程宝典之Shader篇:特别讲CG函数
让C代码在浏览器中运行
在Python中执行javascript
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服