分享

学习SpiderMonkey60的心得笔记(四)寻找global object

 Dark_f 2022-02-10
在SpiderMonkey里,JS的变量、函数、类等,都被视作global object的特性,因此,如果你的JavaScript如下面这样:
          /*JavaScript*/
          var a = 12;
          var b = 25;
          var num = a + b;
那么,如果在C/C++应用程序中要找出num等于多少,该怎么寻找呢?
这时,我们应该知道,当SpiderMonkey解释了上面的JavaScript语句后,其中的变量a、b和num都是某个global object的特性。找到这个object,再利用JSAPI的
          bool
          JS_GetProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::MutableHandleValue vp);
 
这个函数,就可以提取特性值。这个JSAPI的返回值是bool,参数有:cx(上下文),obj(就是object,下面需要寻找的),name(特性的名称,这里就是我们要找的num),vp(就是特性的数值,也就是我们想要知道的num的值)。
因此,只要找到这个object,则要利用上面的JSAPI,就可得到num。要找到那个obj,就可以使用下面这个JSAPI。
           JSObject*
           CurrentGlobalOrNull(JSContext* cx);
 
从上面的代码可以看出,这个JSAPI返回一个JSObject*,而参数只有JSContext* cx。下面就是怎么得到num值的C++代码。(这些代码只要添加到前面笔记2中的ExecuteCodePrintResult方法内JS已经编译后的语句下面(也就是提取已经编译后的结果),同时修改 HelloExample中的ExecuteCodePrintResult(cx, R"js(`hello world, it is ${new Date()}`)js");中的内容为:ExecuteCodePrintResult(cx, R"js(
                                                              var a = 12;
                                                              var b = 25;
                                                              var num = a + b;
                                                              )js");
即可,日志中不好贴代码,就不贴全部的代码了)
         //找到obj
         JS::RootedObject obj(cx, JS::CurrentGlobalOrNull(cx));
         //定义一个“根化”的JS::Value,用来存放num的值,也就是上个JSAPI中的vp
         JS::RootedValue rval(cx);
         //取得特性num的数值
         JS_GetProperty(cx, obj, "num", &rval);
         //(上面一行JSAPI的返回值是bool,所以上面的代码可以这样来写)
         //定义一个bool变量ok
         bool ok;
         //用ok接收提取特性是否成功
         ok = JS_GetProperty(cx, obj, "num", &rval);
         //根据ok显示结果
         if(ok){
                  //这里的rval.toInt32()就是将JS::Value转换成int
                  printf("The num is %d\n", rval.toInt32());
         }
         else {
                 printf("The num isn't found!\n");
                 return false;
         }
 
程序运行结果会显示:
        The num is 37
 


另外,在前面提到的JSAPI手册中有说明:如果在JSNative内,寻找object的方法可以使用下面的JSAPI,原文如下:
But in a JSNative the correct way to do this is:
         /* JSAPI */
         bool myNative(JSContext *cx, unsigned argc, JS::Value *vp)
        {
                 JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
                 JSObject *global = JS_GetGlobalForObject(cx, &args.callee());
                 ...
         }
也就是说,在JSNative的内部寻找object,应该使用的JSAPI是:
         JSObject*
         JS_GetGlobalForObject(JSContext* cx, JSObject* obj);
上面的JSAPI,等我们学习到JSNative时,再讨论。

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多