分享

学习SpiderMonkey60的心得笔记(二)Hello World

 Dark_f 2022-02-10
这里直接使用网上的资源
https://github.com/mozilla-spidermonkey/spidermonkey-embedding-examples
这个网页里提供了SpiderMonkey ESR60和68的例子,他们将例子做成类似于一种模板,这里的演示,对他们的模板稍作修改。
用VS建立一个新的控制台应用项目,名称就取为test。其中test.h文件如下:

 //Test.h
 #pragma once
 #include <jsapi.h>
 extern const JSClassOps DefaultGlobalClassOps;
 JSObject* CreateGlobal(JSContext* cx);
 bool RunExample(bool(*task)(JSContext*), bool initSelfHosting = true);

而test.cpp文件如下:

 //test.cpp
 #include "stdafx.h"
 #include <jsapi.h>
 #include <js/Initialization.h>
 #include "Test.h"
 // A standard set of ClassOps for globals. This includes hooks to resolve
 // standard JavaScript builtin types to give a more full-featured shell.
 const JSClassOps DefaultGlobalClassOps = {

  nullptr,                         // addProperty
  nullptr,                         // deleteProperty
  nullptr,                         // enumerate
  JS_NewEnumerateStandardClasses,  // newEnumerate
  JS_ResolveStandardClass,         // resolve
  JS_MayResolveStandardClass,      // mayResolve
  nullptr,                         // finalize
  nullptr,                         // call
  nullptr,                         // hasInstance
  nullptr,                         // construct
  JS_GlobalObjectTraceHook         // trace

 };

 // Create a simple Global object. A global object is the top-level 'this' value
 // in a script and is required in order to compile or execute JavaScript.
 JSObject* CreateGlobal(JSContext* cx) {

  JS::CompartmentOptions ops;
  static JSClass GlobalClass = { "global", JSCLASS_GLOBAL_FLAGS, &DefaultGlobalClassOps };
  return JS_NewGlobalObject(cx, &GlobalClass, nullptr, JS::FireOnNewGlobalHook, ops);

 }

 // Initialize the JS environment, create a JSContext and run the example
 // function in that context. By default the self-hosting environment is
 // initialized as it is needed to run any JavaScript). If the 'initSelfHosting'
 // argument is false, we will not initialize self-hosting and instead leave
 // that to the caller.
 bool RunExample(bool(*task)(JSContext*), bool initSelfHosting) {

  if (!JS_Init()) {
         return false;
  }
  JSContext* cx = JS_NewContext(JS::DefaultHeapMaxBytes);
  if (!cx) {
         return false;
  }
  if (initSelfHosting && !JS::InitSelfHostedCode(cx)) {
        return false;
  }

  if (!task(cx)) {
        return false;
  }

  JS_DestroyContext(cx);
  JS_ShutDown();

  return true;

 }
 //This example illustrates the bare minimum you need to do to execute a
 //JavaScript program using embedded SpiderMonkey. It does no error handling and
 //simply exits if something goes wrong.
 //
 //The above parts of this example that are reused in many simple embedding examples.
 //
 //To use the interpreter you need to create a context and a global object, and
 //do some setup on both of these. You also need to enter a "request" (lock on
 //the interpreter) and a "compartment" (environment within one global object)
 //before you can execute code.

 static bool ExecuteCodePrintResult(JSContext* cx, const char* code) {
         JS::CompileOptions options(cx);
         options.setFileAndLine("noname", 1);
         JS::RootedValue rval(cx);

         if (!JS::Evaluate(cx, options, code, strlen(code), &rval)) {
                 return false;
         }
  /*
  * There are many ways to display an arbitrary value as a result. In this
  * case, we know that the value is a string because of the expression that we
  * executed, so we can just print the string directly.
  */
          printf("%s\n", JS_EncodeString(cx, rval.toString()));
          return true;
 }

 static bool HelloExample(JSContext* cx) {
           JSAutoRequest ar(cx);
           JS::RootedObject global(cx, CreateGlobal(cx));
           if (!global) {
                   return false;
           }

           JSAutoCompartment ac(cx, global);

  /*
  * The 'js' delimiter is meaningless, but it's useful for marking C++ raw
  * strings semantically.
  */
            return ExecuteCodePrintResult(cx, R"js(`hello world, it is ${new Date()}`)js");
 }

 int main()
 {
           if (!RunExample(HelloExample)) {
                   return 1;
           }
           return 0;
 }

将之编译后,运行将会得到:
Hello World + local time on your computer。

这个模板,我们以后的练习都在此上做修改完成,因此,对我们的学习很重要。想学习的朋友,也一定要理解它。

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多