Bug 1554362 - Implement nsJSUtils::CompileModule for UTF-8 as well as UTF-16. r=bzbarsky
authorJeff Walden <jwalden@mit.edu>
Sat, 15 Jun 2019 20:47:51 +0000
changeset 479055 c26e7cea7730652a2112039c79d63fb1657f0443
parent 479054 a3e4205698b8711791e4bc97ceaceabaa137c553
child 479056 0fc25c40772cd3af794af00711493db05ee43ef7
push id88045
push userjwalden@mit.edu
push dateSat, 15 Jun 2019 20:50:08 +0000
treeherderautoland@613d59f386c7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs1554362
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1554362 - Implement nsJSUtils::CompileModule for UTF-8 as well as UTF-16. r=bzbarsky Differential Revision: https://phabricator.services.mozilla.com/D34821
dom/base/nsJSUtils.cpp
dom/base/nsJSUtils.h
js/public/Modules.h
js/src/vm/Modules.cpp
--- a/dom/base/nsJSUtils.cpp
+++ b/dom/base/nsJSUtils.cpp
@@ -10,17 +10,17 @@
  * The goal of the utility functions is to cut down on the size of
  * the generated code itself.
  */
 
 #include "nsJSUtils.h"
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "js/CompilationAndEvaluation.h"
-#include "js/Modules.h"  // JS::CompileModule, JS::GetModuleScript, JS::Module{Instantiate,Evaluate}
+#include "js/Modules.h"  // JS::CompileModule{,DontInflate}, JS::GetModuleScript, JS::Module{Instantiate,Evaluate}
 #include "js/OffThreadScriptCompilation.h"
 #include "js/SourceText.h"
 #include "nsIScriptContext.h"
 #include "nsIScriptElement.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIXPConnect.h"
 #include "nsCOMPtr.h"
 #include "nsIScriptSecurityManager.h"
@@ -32,16 +32,17 @@
 #include "nsGlobalWindow.h"
 #include "nsXBLPrototypeBinding.h"
 #include "mozilla/CycleCollectedJSContext.h"
 #include "mozilla/StaticPrefs.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/Date.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/ScriptSettings.h"
+#include "mozilla/Utf8.h"  // mozilla::Utf8Unit
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 bool nsJSUtils::GetCallingLocation(JSContext* aContext, nsACString& aFilename,
                                    uint32_t* aLineno, uint32_t* aColumn) {
   JS::AutoFilename filename;
   if (!JS::DescribeScriptedCaller(aContext, &filename, aLineno, aColumn)) {
@@ -445,41 +446,74 @@ nsresult nsJSUtils::ExecutionContext::Ex
       return EvaluationExceptionToNSResult(mCx);
     }
     aRetValue.set(JS::StringValue(str));
   }
 
   return NS_OK;
 }
 
-nsresult nsJSUtils::CompileModule(JSContext* aCx,
-                                  JS::SourceText<char16_t>& aSrcBuf,
-                                  JS::Handle<JSObject*> aEvaluationGlobal,
-                                  JS::CompileOptions& aCompileOptions,
-                                  JS::MutableHandle<JSObject*> aModule) {
+static JSObject* CompileModule(JSContext* aCx,
+                               JS::CompileOptions& aCompileOptions,
+                               JS::SourceText<char16_t>& aSrcBuf) {
+  return JS::CompileModule(aCx, aCompileOptions, aSrcBuf);
+}
+
+static JSObject* CompileModule(JSContext* aCx,
+                               JS::CompileOptions& aCompileOptions,
+                               JS::SourceText<Utf8Unit>& aSrcBuf) {
+  // Once compile-UTF-8-without-inflating is stable, it'll be renamed to remove
+  // the "DontInflate" suffix, these two overloads can be removed, and
+  // |JS::CompileModule| can be used in the sole caller below.
+  return JS::CompileModuleDontInflate(aCx, aCompileOptions, aSrcBuf);
+}
+
+template <typename Unit>
+static nsresult CompileJSModule(JSContext* aCx, JS::SourceText<Unit>& aSrcBuf,
+                                JS::Handle<JSObject*> aEvaluationGlobal,
+                                JS::CompileOptions& aCompileOptions,
+                                JS::MutableHandle<JSObject*> aModule) {
   AUTO_PROFILER_LABEL("nsJSUtils::CompileModule", JS);
   MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
   MOZ_ASSERT(aSrcBuf.get());
   MOZ_ASSERT(JS_IsGlobalObject(aEvaluationGlobal));
   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx) == aEvaluationGlobal);
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(CycleCollectedJSContext::Get() &&
              CycleCollectedJSContext::Get()->MicroTaskLevel());
 
   NS_ENSURE_TRUE(xpc::Scriptability::Get(aEvaluationGlobal).Allowed(), NS_OK);
 
-  JSObject* module = JS::CompileModule(aCx, aCompileOptions, aSrcBuf);
+  JSObject* module = CompileModule(aCx, aCompileOptions, aSrcBuf);
   if (!module) {
     return NS_ERROR_FAILURE;
   }
 
   aModule.set(module);
   return NS_OK;
 }
 
+nsresult nsJSUtils::CompileModule(JSContext* aCx,
+                                  JS::SourceText<char16_t>& aSrcBuf,
+                                  JS::Handle<JSObject*> aEvaluationGlobal,
+                                  JS::CompileOptions& aCompileOptions,
+                                  JS::MutableHandle<JSObject*> aModule) {
+  return CompileJSModule(aCx, aSrcBuf, aEvaluationGlobal, aCompileOptions,
+                         aModule);
+}
+
+nsresult nsJSUtils::CompileModule(JSContext* aCx,
+                                  JS::SourceText<Utf8Unit>& aSrcBuf,
+                                  JS::Handle<JSObject*> aEvaluationGlobal,
+                                  JS::CompileOptions& aCompileOptions,
+                                  JS::MutableHandle<JSObject*> aModule) {
+  return CompileJSModule(aCx, aSrcBuf, aEvaluationGlobal, aCompileOptions,
+                         aModule);
+}
+
 nsresult nsJSUtils::InitModuleSourceElement(JSContext* aCx,
                                             JS::Handle<JSObject*> aModule,
                                             nsIScriptElement* aElement) {
   JS::Rooted<JS::Value> value(aCx);
   nsresult rv = nsContentUtils::WrapNative(aCx, aElement, &value,
                                            /* aAllowWrapping = */ true);
   if (NS_FAILED(rv)) {
     return rv;
--- a/dom/base/nsJSUtils.h
+++ b/dom/base/nsJSUtils.h
@@ -11,16 +11,17 @@
  * This is not a generated file. It contains common utility functions
  * invoked from the JavaScript code generated from IDL interfaces.
  * The goal of the utility functions is to cut down on the size of
  * the generated code itself.
  */
 
 #include "mozilla/Assertions.h"
 #include "mozilla/StaticPrefs.h"
+#include "mozilla/Utf8.h"  // mozilla::Utf8Unit
 
 #include "GeckoProfiler.h"
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "js/Conversions.h"
 #include "js/SourceText.h"
 #include "js/StableStringChars.h"
 #include "nsString.h"
@@ -205,16 +206,22 @@ class nsJSUtils {
   }
 
   static nsresult CompileModule(JSContext* aCx,
                                 JS::SourceText<char16_t>& aSrcBuf,
                                 JS::Handle<JSObject*> aEvaluationGlobal,
                                 JS::CompileOptions& aCompileOptions,
                                 JS::MutableHandle<JSObject*> aModule);
 
+  static nsresult CompileModule(JSContext* aCx,
+                                JS::SourceText<mozilla::Utf8Unit>& aSrcBuf,
+                                JS::Handle<JSObject*> aEvaluationGlobal,
+                                JS::CompileOptions& aCompileOptions,
+                                JS::MutableHandle<JSObject*> aModule);
+
   static nsresult InitModuleSourceElement(JSContext* aCx,
                                           JS::Handle<JSObject*> aModule,
                                           nsIScriptElement* aElement);
 
   static nsresult ModuleInstantiate(JSContext* aCx,
                                     JS::Handle<JSObject*> aModule);
 
   static nsresult ModuleEvaluate(JSContext* aCx, JS::Handle<JSObject*> aModule);
--- a/js/public/Modules.h
+++ b/js/public/Modules.h
@@ -91,18 +91,27 @@ extern JS_PUBLIC_API bool FinishDynamicM
  */
 extern JS_PUBLIC_API JSObject* CompileModule(
     JSContext* cx, const ReadOnlyCompileOptions& options,
     SourceText<char16_t>& srcBuf);
 
 /**
  * Parse the given source buffer as a module in the scope of the current global
  * of cx and return a source text module record.
+ *
+ * The "DontInflate" suffix and (semantically unobservable) don't-inflate
+ * characteristic are temporary while bugs in UTF-8 compilation are ironed out.
+ * In the long term this function will be renamed |JS::CompileModule| and will
+ * just never inflate.
+ *
+ * NOTE: UTF-8 compilation is currently experimental, and it's possible it has
+ *       as-yet-undiscovered bugs that the UTF-16 compilation functions do not
+ *       have.  Use only if you're willing to take a risk!
  */
-extern JS_PUBLIC_API JSObject* CompileModule(
+extern JS_PUBLIC_API JSObject* CompileModuleDontInflate(
     JSContext* cx, const ReadOnlyCompileOptions& options,
     SourceText<mozilla::Utf8Unit>& srcBuf);
 
 /**
  * Set a private value associated with a source text module record.
  */
 extern JS_PUBLIC_API void SetModulePrivate(JSObject* module,
                                            const Value& value);
--- a/js/src/vm/Modules.cpp
+++ b/js/src/vm/Modules.cpp
@@ -95,19 +95,19 @@ static JSObject* CompileModuleHelper(JSC
 }
 
 JS_PUBLIC_API JSObject* JS::CompileModule(JSContext* cx,
                                           const ReadOnlyCompileOptions& options,
                                           SourceText<char16_t>& srcBuf) {
   return CompileModuleHelper(cx, options, srcBuf);
 }
 
-JS_PUBLIC_API JSObject* JS::CompileModule(JSContext* cx,
-                                          const ReadOnlyCompileOptions& options,
-                                          SourceText<Utf8Unit>& srcBuf) {
+JS_PUBLIC_API JSObject* JS::CompileModuleDontInflate(
+    JSContext* cx, const ReadOnlyCompileOptions& options,
+    SourceText<Utf8Unit>& srcBuf) {
   return CompileModuleHelper(cx, options, srcBuf);
 }
 
 JS_PUBLIC_API void JS::SetModulePrivate(JSObject* module, const Value& value) {
   JSRuntime* rt = module->zone()->runtimeFromMainThread();
   module->as<ModuleObject>().scriptSourceObject()->setPrivate(rt, value);
 }