【问题标题】:SpiderMonkey 24: How to call Reflect.parse()?SpiderMonkey 24:如何调用 Reflect.parse()?
【发布时间】:2016-04-01 12:51:51
【问题描述】:

根据Parser API,您可以致电Reflect.parse() 获取AST。不幸的是,当尝试在 C++ 中评估一个脚本时,它给了我一个错误,说 ReferenceError: Reflect is not defined:

const char *script = "var r = Reflect.parse(\"obj.foo + 42\");";
bool ok = JS_EvaluateScript(cx, global, script, strlen(script), filename, lineno, rval.address());

实际上,我想解析一些简单的 JS 脚本并在 C++ 中获取 AST,我不喜欢绕道而行并在 JS 本身中对其进行分析的方式。你有什么建议吗?文档不是很好恕我直言。

我尝试使用 JS_CompileScript(),但似乎 1) JSScript 类的成员在使用编译后的库时不可见 2) 不再有关于树的信息 (?)。

我很想使用非常旧的 1.6 版本,因为那里有一个非常好的parsing tutorial。您对此有何看法?

另一种方法是不编译 SpiderMonkey 并直接使用 Parser 类。

任何提示/建议(在您看来)是最佳方式,我们将不胜感激。谢谢你:)

【问题讨论】:

    标签: javascript c++ parsing spidermonkey


    【解决方案1】:

    实际上,我想解析一些简单的 JS 脚本并在 C++ 中获取 AST,我不喜欢绕道而行并在 JS 本身中对其进行分析的方式。你有什么建议吗?

    如果修补 Monkey 是(曾经)适合您的选项,我有一个可能的方法。我正在使用 SpiderMonkey 45 执行此操作,但 Reflect API 已经存在于 24 中。

    ReflectParse.cpp:3593,有函数

    static bool reflect_parse(JSContext* cx, uint32_t argc, Value* vp)
    

    将其设为非静态并在jsapi.h 中声明,如下所示:

    extern JS_PUBLIC_API(bool) reflect_parse(JSContext* cx, uint32_t argc, JS::Value* vp);
    

    实际上,这是从所述文件中的JS_InitReflectParse 声明复制/粘贴。现在您可以从外部调用Reflect.parse() 的C 实现。

    您还需要一堆私有标头,我目前包括这些:builtin/ModuleObject.hjscntxt.hjscompartment.hjsobj.hfrontend/ParseNode.h

    reflect_parse 期望作为第二个参数的Value* vp 是一个构造如下的JS::AutoValueArray<3>

    • 索引 0 稍后会为返回的对象保存一个 JSValueCallArgs::rval() 从那里检索它。
    • 索引 1 包含某种幻数。不要碰。 (将其设置为某事对我来说是一个断言。)
    • 索引 2 包含另一个 JS::AutoValueArray<n>,其中包含 Reflect.parse 的参数。

    所以对于像Reflect.parse(code) 这样的简单调用,参数可以如下所示:

    JS::RootedString codeJsStr(context); // Empty string for now
    JS::AutoValueArray<1> parseParams(context);
    parseParams[0].setString(codeJsStr);
    JS::AutoValueArray<3> vp(m_context);
    vp[2].set(*parseParams.begin());
    reflect_parse(m_context, parseParams.length(), vp.begin());
    

    然后可以在CallArgs 的帮助下处理返回值,就像记录从 C 调用 js 函数一样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-03
      • 1970-01-01
      • 2016-01-29
      • 2014-05-07
      • 1970-01-01
      • 2019-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多