SpiderMonkey 24:如何调用Reflect.parse()?

时间:2015-12-27 12:47:38

标签: javascript c++ parsing spidermonkey

根据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 Scripts并在C ++中获取AST,我不喜欢绕道而行,并在JS本身进行分析。你有什么建议吗?文档不是很好imho。

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

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

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

任何提示/建议以最佳方式(在您看来)都会受到高度赞赏。谢谢:))

1 个答案:

答案 0 :(得分:3)

  

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

如果修补猴子是你的选择,我有一个可能的方法。我正在使用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

Value* vp期望作为第二个参数的reflect_parseJS::AutoValueArray<3>,其构造如下:

  • 索引0稍后会将JSValue保存到返回的对象。 CallArgs::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函数一样。