Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/js/src/jsapi-tests/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 10 kB image not shown  

Quelle  testStencil.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: set ts=8 sts=2 et sw=2 tw=80:
 */

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#include <string.h>

#include "jsapi.h"

#include "frontend/CompilationStencil.h"
#include "js/CompilationAndEvaluation.h"
#include "js/EnvironmentChain.h"  // JS::EnvironmentChain
#include "js/experimental/CompileScript.h"
#include "js/experimental/JSStencil.h"
#include "js/Modules.h"
#include "js/PropertyAndElement.h"  // JS_GetProperty, JS_HasOwnProperty, JS_SetProperty
#include "js/Transcoding.h"
#include "jsapi-tests/tests.h"
#include "vm/HelperThreads.h"  // js::RunPendingSourceCompressions
#include "vm/Monitor.h"        // js::Monitor, js::AutoLockMonitor

BEGIN_TEST(testStencil_Basic) {
  const char* chars =
      "function f() { return 42; }"
      "f();";
  auto result = basic_test<char, mozilla::Utf8Unit>(chars);
  CHECK(result);

  const char16_t* chars16 =
      u"function f() { return 42; }"
      u"f();";
  auto result16 = basic_test<char16_t, char16_t>(chars16);
  CHECK(result16);

  return true;
}

template <typename CharT, typename SourceT>
bool basic_test(const CharT* chars) {
  size_t length = std::char_traits<CharT>::length(chars);

  JS::SourceText<SourceT> srcBuf;
  CHECK(srcBuf.init(cx, chars, length, JS::SourceOwnership::Borrowed));

  JS::CompileOptions options(cx);
  RefPtr<JS::Stencil> stencil =
      JS::CompileGlobalScriptToStencil(cx, options, srcBuf);
  CHECK(stencil);

  JS::InstantiateOptions instantiateOptions(options);
  JS::RootedScript script(
      cx, JS::InstantiateGlobalStencil(cx, instantiateOptions, stencil));
  CHECK(script);

  JS::RootedValue rval(cx);
  CHECK(JS_ExecuteScript(cx, script, &rval));
  CHECK(rval.isNumber() && rval.toNumber() == 42);

  return true;
}
END_TEST(testStencil_Basic)

BEGIN_TEST(testStencil_Module) {
  const char* chars =
      "export function f() { return 42; }"
      "globalThis.x = f();";
  auto result = basic_test<char, mozilla::Utf8Unit>(chars);
  CHECK(result);

  const char16_t* chars16 =
      u"export function f() { return 42; }"
      u"globalThis.x = f();";
  auto result16 = basic_test<char16_t, char16_t>(chars16);
  CHECK(result16);

  return true;
}

template <typename CharT, typename SourceT>
bool basic_test(const CharT* chars) {
  size_t length = std::char_traits<CharT>::length(chars);

  JS::SourceText<SourceT> srcBuf;
  CHECK(srcBuf.init(cx, chars, length, JS::SourceOwnership::Borrowed));

  JS::CompileOptions options(cx);
  options.setFile("testStencil_Module");

  RefPtr<JS::Stencil> stencil =
      JS::CompileModuleScriptToStencil(cx, options, srcBuf);
  CHECK(stencil);

  JS::InstantiateOptions instantiateOptions(options);
  JS::RootedObject moduleObject(
      cx, JS::InstantiateModuleStencil(cx, instantiateOptions, stencil));
  CHECK(moduleObject);

  // Link and evaluate the module graph. The link step used to be call
  // "instantiate" but is unrelated to the concept in Stencil with same name.
  JS::RootedValue rval(cx);
  CHECK(JS::ModuleLink(cx, moduleObject));
  CHECK(JS::ModuleEvaluate(cx, moduleObject, &rval));
  CHECK(!rval.isUndefined());

  js::RunJobs(cx);
  CHECK(JS_GetProperty(cx, global, "x", &rval));
  CHECK(rval.isNumber() && rval.toNumber() == 42);

  return true;
}
END_TEST(testStencil_Module)

BEGIN_TEST(testStencil_NonSyntactic) {
  const char* chars =
      "function f() { return x; }"
      "f();";

  JS::SourceText<mozilla::Utf8Unit> srcBuf;
  CHECK(srcBuf.init(cx, chars, strlen(chars), JS::SourceOwnership::Borrowed));

  JS::CompileOptions options(cx);
  options.setNonSyntacticScope(true);

  RefPtr<JS::Stencil> stencil =
      JS::CompileGlobalScriptToStencil(cx, options, srcBuf);
  CHECK(stencil);

  JS::InstantiateOptions instantiateOptions(options);
  JS::RootedScript script(
      cx, JS::InstantiateGlobalStencil(cx, instantiateOptions, stencil));
  CHECK(script);

  JS::RootedObject obj(cx, JS_NewPlainObject(cx));
  JS::RootedValue val(cx, JS::Int32Value(42));
  CHECK(obj);
  CHECK(JS_SetProperty(cx, obj, "x", val));

  JS::EnvironmentChain envChain(cx, JS::SupportUnscopables::No);
  CHECK(envChain.append(obj));

  JS::RootedValue rval(cx);
  CHECK(JS_ExecuteScript(cx, envChain, script, &rval));
  CHECK(rval.isNumber() && rval.toNumber() == 42);

  return true;
}
END_TEST(testStencil_NonSyntactic)

BEGIN_TEST(testStencil_MultiGlobal) {
  const char* chars =
      "/**************************************/"
      "/**************************************/"
      "/**************************************/"
      "/**************************************/"
      "/**************************************/"
      "/**************************************/"
      "function f() { return 42; }"
      "f();";

  JS::SourceText<mozilla::Utf8Unit> srcBuf;
  CHECK(srcBuf.init(cx, chars, strlen(chars), JS::SourceOwnership::Borrowed));

  JS::CompileOptions options(cx);
  RefPtr<JS::Stencil> stencil =
      JS::CompileGlobalScriptToStencil(cx, options, srcBuf);
  CHECK(stencil);

  CHECK(RunInNewGlobal(cx, stencil));
  CHECK(RunInNewGlobal(cx, stencil));
  CHECK(RunInNewGlobal(cx, stencil));

  // Start any pending SourceCompressionTasks now to confirm nothing fell apart
  // when using a JS::Stencil multiple times.
  CHECK(strlen(chars) > js::ScriptSource::MinimumCompressibleLength);
  js::RunPendingSourceCompressions(cx->runtime());

  return true;
}
bool RunInNewGlobal(JSContext* cx, RefPtr<JS::Stencil> stencil) {
  JS::RootedObject otherGlobal(cx, createGlobal());
  CHECK(otherGlobal);

  JSAutoRealm ar(cx, otherGlobal);

  JS::InstantiateOptions instantiateOptions;
  JS::RootedScript script(
      cx, JS::InstantiateGlobalStencil(cx, instantiateOptions, stencil));
  CHECK(script);

  JS::RootedValue rval(cx);
  CHECK(JS_ExecuteScript(cx, script, &rval));
  CHECK(rval.isNumber() && rval.toNumber() == 42);

  return true;
}
END_TEST(testStencil_MultiGlobal)

BEGIN_TEST(testStencil_Transcode) {
  JS::SetProcessBuildIdOp(TestGetBuildId);

  JS::TranscodeBuffer buffer;

  {
    const char* chars =
        "function f() { return 42; }"
        "f();";

    JS::SourceText<mozilla::Utf8Unit> srcBuf;
    CHECK(srcBuf.init(cx, chars, strlen(chars), JS::SourceOwnership::Borrowed));

    JS::CompileOptions options(cx);
    RefPtr<JS::Stencil> stencil =
        JS::CompileGlobalScriptToStencil(cx, options, srcBuf);
    CHECK(stencil);

    // Encode Stencil to XDR
    JS::TranscodeResult res = JS::EncodeStencil(cx, stencil, buffer);
    CHECK(res == JS::TranscodeResult::Ok);
    CHECK(!buffer.empty());

    // Instantiate and Run
    JS::InstantiateOptions instantiateOptions(options);
    JS::RootedScript script(
        cx, JS::InstantiateGlobalStencil(cx, instantiateOptions, stencil));
    JS::RootedValue rval(cx);
    CHECK(script);
    CHECK(JS_ExecuteScript(cx, script, &rval));
    CHECK(rval.isNumber() && rval.toNumber() == 42);
  }

  // Create a new global
  CHECK(createGlobal());
  JSAutoRealm ar(cx, global);

  // Confirm it doesn't have the old code
  bool found = false;
  CHECK(JS_HasOwnProperty(cx, global, "f", &found));
  CHECK(!found);

  {
    // Decode the stencil into new range
    RefPtr<JS::Stencil> stencil;

    {
      JS::DecodeOptions decodeOptions;
      JS::TranscodeRange range(buffer.begin(), buffer.length());
      JS::TranscodeResult res =
          JS::DecodeStencil(cx, decodeOptions, range, getter_AddRefs(stencil));
      CHECK(res == JS::TranscodeResult::Ok);
    }

    {
      JS::FrontendContext* fc = JS::NewFrontendContext();
      JS::DecodeOptions decodeOptions;
      JS::TranscodeRange range(buffer.begin(), buffer.length());
      JS::TranscodeResult res =
          JS::DecodeStencil(fc, decodeOptions, range, getter_AddRefs(stencil));
      CHECK(res == JS::TranscodeResult::Ok);
      JS::DestroyFrontendContext(fc);
    }

    // Delete the buffer to verify that the decoded stencil has no dependency
    // to the buffer.
    memset(buffer.begin(), 0, buffer.length());
    buffer.clear();

    // Instantiate and Run
    JS::InstantiateOptions instantiateOptions;
    JS::RootedScript script(
        cx, JS::InstantiateGlobalStencil(cx, instantiateOptions, stencil));
    stencil = nullptr;
    JS::RootedValue rval(cx);
    CHECK(script);
    CHECK(JS_ExecuteScript(cx, script, &rval));
    CHECK(rval.isNumber() && rval.toNumber() == 42);
  }

  return true;
}
static bool TestGetBuildId(JS::BuildIdCharVector* buildId) {
  const char buildid[] = "testXDR";
  return buildId->append(buildid, sizeof(buildid));
}
END_TEST(testStencil_Transcode)

BEGIN_TEST(testStencil_TranscodeBorrowing) {
  JS::SetProcessBuildIdOp(TestGetBuildId);

  JS::TranscodeBuffer buffer;

  {
    const char* chars =
        "function f() { return 42; }"
        "f();";

    JS::SourceText<mozilla::Utf8Unit> srcBuf;
    CHECK(srcBuf.init(cx, chars, strlen(chars), JS::SourceOwnership::Borrowed));

    JS::CompileOptions options(cx);
    RefPtr<JS::Stencil> stencil =
        JS::CompileGlobalScriptToStencil(cx, options, srcBuf);
    CHECK(stencil);

    // Encode Stencil to XDR
    JS::TranscodeResult res = JS::EncodeStencil(cx, stencil, buffer);
    CHECK(res == JS::TranscodeResult::Ok);
    CHECK(!buffer.empty());
  }

  JS::RootedScript script(cx);
  {
    JS::TranscodeRange range(buffer.begin(), buffer.length());
    JS::DecodeOptions decodeOptions;
    decodeOptions.borrowBuffer = true;
    RefPtr<JS::Stencil> stencil;
    JS::TranscodeResult res =
        JS::DecodeStencil(cx, decodeOptions, range, getter_AddRefs(stencil));
    CHECK(res == JS::TranscodeResult::Ok);

    JS::InstantiateOptions instantiateOptions;
    script = JS::InstantiateGlobalStencil(cx, instantiateOptions, stencil);
    CHECK(script);
  }

  // Delete the buffer to verify that the instantiated script has no dependency
  // to the buffer.
  memset(buffer.begin(), 0, buffer.length());
  buffer.clear();

  JS::RootedValue rval(cx);
  CHECK(JS_ExecuteScript(cx, script, &rval));
  CHECK(rval.isNumber() && rval.toNumber() == 42);

  return true;
}
static bool TestGetBuildId(JS::BuildIdCharVector* buildId) {
  const char buildid[] = "testXDR";
  return buildId->append(buildid, sizeof(buildid));
}
END_TEST(testStencil_TranscodeBorrowing)

100%


¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.