Bug 1486577 - Move compilation and evaluation APIs into a new public js/CompilationAndEvaluation.h header. r=jandem
authorJeff Walden <jwalden@mit.edu>
Fri, 24 Aug 2018 14:55:28 -0500
changeset 488840 9fb317294f45476f0a2d2aa6dde4ec4848bac91d
parent 488839 8896f3fdaf990d7d18ba07b08132fa12e18f8284
child 488841 2dc7007e3924444f55345606b6785f2d2ba89ce1
push id9734
push usershindli@mozilla.com
push dateThu, 30 Aug 2018 12:18:07 +0000
treeherdermozilla-beta@71c71ab3afae [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1486577
milestone63.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 1486577 - Move compilation and evaluation APIs into a new public js/CompilationAndEvaluation.h header. r=jandem
js/public/CompilationAndEvaluation.h
js/rust/etc/wrapper.hpp
js/src/jsapi.h
js/src/moz.build
new file mode 100644
--- /dev/null
+++ b/js/public/CompilationAndEvaluation.h
@@ -0,0 +1,223 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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/. */
+
+/* Functions for compiling and evaluating scripts. */
+
+#ifndef js_CompilationAndEvaluation_h
+#define js_CompilationAndEvaluation_h
+
+#include <stddef.h> // size_t
+#include <stdio.h> // FILE
+
+#include "jstypes.h" // JS_PUBLIC_API
+
+#include "js/CompileOptions.h" // JS::CompileOptions, JS::ReadOnlyCompileOptions
+#include "js/RootingAPI.h" // JS::Handle, JS::MutableHandle
+
+struct JSContext;
+class JSFunction;
+class JSObject;
+class JSScript;
+
+namespace JS {
+
+template<typename T> class AutoVector;
+
+class SourceBufferHolder;
+union Value;
+
+} // namespace JS
+
+/**
+ * Given a buffer, return false if the buffer might become a valid JavaScript
+ * script with the addition of more lines, or true if the validity of such a
+ * script is conclusively known (because it's the prefix of a valid script --
+ * and possibly the entirety of such a script).
+ *
+ * The intent of this function is to enable interactive compilation: accumulate
+ * lines in a buffer until JS_BufferIsCompilableUnit is true, then pass it to
+ * the compiler.
+ */
+extern JS_PUBLIC_API(bool)
+JS_BufferIsCompilableUnit(JSContext* cx, JS::Handle<JSObject*> obj, const char* utf8,
+                          size_t length);
+
+/*
+ * NB: JS_ExecuteScript and the JS::Evaluate APIs come in two flavors: either
+ * they use the global as the scope, or they take an AutoObjectVector of objects
+ * to use as the scope chain.  In the former case, the global is also used as
+ * the "this" keyword value and the variables object (ECMA parlance for where
+ * 'var' and 'function' bind names) of the execution context for script.  In the
+ * latter case, the first object in the provided list is used, unless the list
+ * is empty, in which case the global is used.
+ *
+ * Why a runtime option?  The alternative is to add APIs duplicating those
+ * for the other value of flags, and that doesn't seem worth the code bloat
+ * cost.  Such new entry points would probably have less obvious names, too, so
+ * would not tend to be used.  The ContextOptionsRef adjustment, OTOH, can be
+ * more easily hacked into existing code that does not depend on the bug; such
+ * code can continue to use the familiar JS::Evaluate, etc., entry points.
+ */
+
+/**
+ * Evaluate a script in the scope of the current global of cx.
+ */
+extern JS_PUBLIC_API(bool)
+JS_ExecuteScript(JSContext* cx, JS::Handle<JSScript*> script, JS::MutableHandle<JS::Value> rval);
+
+extern JS_PUBLIC_API(bool)
+JS_ExecuteScript(JSContext* cx, JS::Handle<JSScript*> script);
+
+/**
+ * As above, but providing an explicit scope chain.  envChain must not include
+ * the global object on it; that's implicit.  It needs to contain the other
+ * objects that should end up on the script's scope chain.
+ */
+extern JS_PUBLIC_API(bool)
+JS_ExecuteScript(JSContext* cx, JS::AutoVector<JSObject*>& envChain,
+                 JS::Handle<JSScript*> script, JS::MutableHandle<JS::Value> rval);
+
+extern JS_PUBLIC_API(bool)
+JS_ExecuteScript(JSContext* cx, JS::AutoVector<JSObject*>& envChain, JS::Handle<JSScript*> script);
+
+/**
+ * |script| will always be set. On failure, it will be set to nullptr.
+ */
+extern JS_PUBLIC_API(bool)
+JS_CompileScript(JSContext* cx, const char* ascii, size_t length,
+                 const JS::CompileOptions& options,
+                 JS::MutableHandle<JSScript*> script);
+
+/**
+ * |script| will always be set. On failure, it will be set to nullptr.
+ */
+extern JS_PUBLIC_API(bool)
+JS_CompileUCScript(JSContext* cx, JS::SourceBufferHolder& srcBuf,
+                   const JS::CompileOptions& options,
+                   JS::MutableHandle<JSScript*> script);
+
+namespace JS {
+
+/**
+ * Like the above, but handles a cross-compartment script. If the script is
+ * cross-compartment, it is cloned into the current compartment before executing.
+ */
+extern JS_PUBLIC_API(bool)
+CloneAndExecuteScript(JSContext* cx, Handle<JSScript*> script, MutableHandle<Value> rval);
+
+/**
+ * Like CloneAndExecuteScript above, but allows executing under a non-syntactic
+ * environment chain.
+ */
+extern JS_PUBLIC_API(bool)
+CloneAndExecuteScript(JSContext* cx, AutoVector<JSObject*>& envChain, Handle<JSScript*> script,
+                      MutableHandle<Value> rval);
+
+/**
+ * Evaluate the given source buffer in the scope of the current global of cx.
+ */
+extern JS_PUBLIC_API(bool)
+Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
+         SourceBufferHolder& srcBuf, MutableHandle<Value> rval);
+
+/**
+ * As above, but providing an explicit scope chain.  envChain must not include
+ * the global object on it; that's implicit.  It needs to contain the other
+ * objects that should end up on the script's scope chain.
+ */
+extern JS_PUBLIC_API(bool)
+Evaluate(JSContext* cx, AutoVector<JSObject*>& envChain, const ReadOnlyCompileOptions& options,
+         SourceBufferHolder& srcBuf, MutableHandle<Value> rval);
+
+/**
+ * Evaluate the given byte buffer in the scope of the current global of cx.
+ */
+extern JS_PUBLIC_API(bool)
+Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
+         const char* bytes, size_t length, MutableHandle<Value> rval);
+
+/**
+ * Evaluate the given file in the scope of the current global of cx.
+ */
+extern JS_PUBLIC_API(bool)
+Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
+         const char* filename, MutableHandle<Value> rval);
+
+/**
+ * |script| will always be set. On failure, it will be set to nullptr.
+ */
+extern JS_PUBLIC_API(bool)
+Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
+        SourceBufferHolder& srcBuf, MutableHandle<JSScript*> script);
+
+extern JS_PUBLIC_API(bool)
+Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
+        const char* bytes, size_t length, MutableHandle<JSScript*> script);
+
+extern JS_PUBLIC_API(bool)
+Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
+        FILE* file, MutableHandle<JSScript*> script);
+
+extern JS_PUBLIC_API(bool)
+Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
+        const char* filename, MutableHandle<JSScript*> script);
+
+extern JS_PUBLIC_API(bool)
+CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
+                            SourceBufferHolder& srcBuf, MutableHandle<JSScript*> script);
+
+extern JS_PUBLIC_API(bool)
+CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
+                            const char* bytes, size_t length, MutableHandle<JSScript*> script);
+
+extern JS_PUBLIC_API(bool)
+CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
+                            FILE* file, MutableHandle<JSScript*> script);
+
+extern JS_PUBLIC_API(bool)
+CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
+                            const char* filename, MutableHandle<JSScript*> script);
+
+/**
+ * Compile a function with envChain plus the global as its scope chain.
+ * envChain must contain objects in the current compartment of cx.  The actual
+ * scope chain used for the function will consist of With wrappers for those
+ * objects, followed by the current global of the compartment cx is in.  This
+ * global must not be explicitly included in the scope chain.
+ */
+extern JS_PUBLIC_API(bool)
+CompileFunction(JSContext* cx, AutoVector<JSObject*>& envChain,
+                const ReadOnlyCompileOptions& options,
+                const char* name, unsigned nargs, const char* const* argnames,
+                SourceBufferHolder& srcBuf, MutableHandle<JSFunction*> fun);
+
+/**
+ * Same as above, but taking a const char * for the function body.
+ */
+extern JS_PUBLIC_API(bool)
+CompileFunction(JSContext* cx, AutoVector<JSObject*>& envChain,
+                const ReadOnlyCompileOptions& options,
+                const char* name, unsigned nargs, const char* const* argnames,
+                const char* bytes, size_t length, MutableHandle<JSFunction*> fun);
+
+/*
+ * Associate an element wrapper and attribute name with a previously compiled
+ * script, for debugging purposes. Calling this function is optional, but should
+ * be done before script execution if it is required.
+ */
+extern JS_PUBLIC_API(bool)
+InitScriptSourceElement(JSContext* cx, Handle<JSScript*> script,
+                        Handle<JSObject*> element, Handle<JSString*> elementAttrName = nullptr);
+
+/*
+ * For a script compiled with the hideScriptFromDebugger option, expose the
+ * script to the debugger by calling the debugger's onNewScript hook.
+ */
+extern JS_PUBLIC_API(void)
+ExposeScriptToDebugger(JSContext* cx, Handle<JSScript*> script);
+
+} /* namespace JS */
+
+#endif /* js_CompilationAndEvaluation_h */
--- a/js/rust/etc/wrapper.hpp
+++ b/js/rust/etc/wrapper.hpp
@@ -8,16 +8,17 @@
 #ifndef _MSC_VER
 #include <unistd.h>
 #endif
 
 typedef uint32_t HashNumber;
 
 #include "jsapi.h"
 #include "jsfriendapi.h"
+#include "js/CompilationAndEvaluation.h"
 #include "js/CompileOptions.h"
 #include "js/Conversions.h"
 #include "js/Initialization.h"
 #include "js/MemoryMetrics.h"
 #include "js/SourceBufferHolder.h"
 #include "js/StructuredClone.h"
 
 // Replacements for types that are too difficult for rust-bindgen.
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -23,16 +23,17 @@
 #include <stdio.h>
 
 #include "jspubtd.h"
 
 #include "js/AllocPolicy.h"
 #include "js/CallArgs.h"
 #include "js/CharacterEncoding.h"
 #include "js/Class.h"
+#include "js/CompilationAndEvaluation.h"
 #include "js/CompileOptions.h"
 #include "js/ErrorReport.h"
 #include "js/GCVector.h"
 #include "js/HashTable.h"
 #include "js/Id.h"
 #include "js/MemoryFunctions.h"
 #include "js/OffThreadScriptCompilation.h"
 #include "js/Principals.h"
@@ -3010,230 +3011,37 @@ CloneFunctionObject(JSContext* cx, Handl
  * the global object on it; that's implicit.  It needs to contain the other
  * objects that should end up on the clone's scope chain.
  */
 extern JS_PUBLIC_API(JSObject*)
 CloneFunctionObject(JSContext* cx, HandleObject funobj, AutoObjectVector& scopeChain);
 
 } // namespace JS
 
-/**
- * Given a buffer, return false if the buffer might become a valid
- * javascript statement with the addition of more lines.  Otherwise return
- * true.  The intent is to support interactive compilation - accumulate
- * lines in a buffer until JS_BufferIsCompilableUnit is true, then pass it to
- * the compiler.
- */
-extern JS_PUBLIC_API(bool)
-JS_BufferIsCompilableUnit(JSContext* cx, JS::Handle<JSObject*> obj, const char* utf8,
-                          size_t length);
-
-/**
- * |script| will always be set. On failure, it will be set to nullptr.
- */
-extern JS_PUBLIC_API(bool)
-JS_CompileScript(JSContext* cx, const char* ascii, size_t length,
-                 const JS::CompileOptions& options,
-                 JS::MutableHandleScript script);
-
-/**
- * |script| will always be set. On failure, it will be set to nullptr.
- */
-extern JS_PUBLIC_API(bool)
-JS_CompileUCScript(JSContext* cx, JS::SourceBufferHolder& srcBuf,
-                   const JS::CompileOptions& options,
-                   JS::MutableHandleScript script);
-
 extern JS_PUBLIC_API(JSObject*)
 JS_GetGlobalFromScript(JSScript* script);
 
 extern JS_PUBLIC_API(const char*)
 JS_GetScriptFilename(JSScript* script);
 
 extern JS_PUBLIC_API(unsigned)
 JS_GetScriptBaseLineNumber(JSContext* cx, JSScript* script);
 
 extern JS_PUBLIC_API(JSScript*)
 JS_GetFunctionScript(JSContext* cx, JS::HandleFunction fun);
 
-namespace JS {
-
-/**
- * |script| will always be set. On failure, it will be set to nullptr.
- */
-extern JS_PUBLIC_API(bool)
-Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
-        SourceBufferHolder& srcBuf, JS::MutableHandleScript script);
-
-extern JS_PUBLIC_API(bool)
-Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
-        const char* bytes, size_t length, JS::MutableHandleScript script);
-
-extern JS_PUBLIC_API(bool)
-Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
-        FILE* file, JS::MutableHandleScript script);
-
-extern JS_PUBLIC_API(bool)
-Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
-        const char* filename, JS::MutableHandleScript script);
-
-extern JS_PUBLIC_API(bool)
-CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
-                            SourceBufferHolder& srcBuf, JS::MutableHandleScript script);
-
-extern JS_PUBLIC_API(bool)
-CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
-                            const char* bytes, size_t length, JS::MutableHandleScript script);
-
-extern JS_PUBLIC_API(bool)
-CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
-                            FILE* file, JS::MutableHandleScript script);
-
-extern JS_PUBLIC_API(bool)
-CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
-                            const char* filename, JS::MutableHandleScript script);
-
-/**
- * Compile a function with envChain plus the global as its scope chain.
- * envChain must contain objects in the current compartment of cx.  The actual
- * scope chain used for the function will consist of With wrappers for those
- * objects, followed by the current global of the compartment cx is in.  This
- * global must not be explicitly included in the scope chain.
- */
-extern JS_PUBLIC_API(bool)
-CompileFunction(JSContext* cx, AutoObjectVector& envChain,
-                const ReadOnlyCompileOptions& options,
-                const char* name, unsigned nargs, const char* const* argnames,
-                SourceBufferHolder& srcBuf, JS::MutableHandleFunction fun);
-
-/**
- * Same as above, but taking a const char * for the function body.
- */
-extern JS_PUBLIC_API(bool)
-CompileFunction(JSContext* cx, AutoObjectVector& envChain,
-                const ReadOnlyCompileOptions& options,
-                const char* name, unsigned nargs, const char* const* argnames,
-                const char* bytes, size_t length, JS::MutableHandleFunction fun);
-
-/*
- * Associate an element wrapper and attribute name with a previously compiled
- * script, for debugging purposes. Calling this function is optional, but should
- * be done before script execution if it is required.
- */
-extern JS_PUBLIC_API(bool)
-InitScriptSourceElement(JSContext* cx, HandleScript script,
-                        HandleObject element, HandleString elementAttrName = nullptr);
-
-/*
- * For a script compiled with the hideScriptFromDebugger option, expose the
- * script to the debugger by calling the debugger's onNewScript hook.
- */
-extern JS_PUBLIC_API(void)
-ExposeScriptToDebugger(JSContext* cx, HandleScript script);
-
-} /* namespace JS */
-
 extern JS_PUBLIC_API(JSString*)
 JS_DecompileScript(JSContext* cx, JS::Handle<JSScript*> script);
 
 extern JS_PUBLIC_API(JSString*)
 JS_DecompileFunction(JSContext* cx, JS::Handle<JSFunction*> fun);
 
 
-/*
- * NB: JS_ExecuteScript and the JS::Evaluate APIs come in two flavors: either
- * they use the global as the scope, or they take an AutoObjectVector of objects
- * to use as the scope chain.  In the former case, the global is also used as
- * the "this" keyword value and the variables object (ECMA parlance for where
- * 'var' and 'function' bind names) of the execution context for script.  In the
- * latter case, the first object in the provided list is used, unless the list
- * is empty, in which case the global is used.
- *
- * Why a runtime option?  The alternative is to add APIs duplicating those
- * for the other value of flags, and that doesn't seem worth the code bloat
- * cost.  Such new entry points would probably have less obvious names, too, so
- * would not tend to be used.  The ContextOptionsRef adjustment, OTOH, can be
- * more easily hacked into existing code that does not depend on the bug; such
- * code can continue to use the familiar JS::Evaluate, etc., entry points.
- */
-
-/**
- * Evaluate a script in the scope of the current global of cx.
- */
-extern JS_PUBLIC_API(bool)
-JS_ExecuteScript(JSContext* cx, JS::HandleScript script, JS::MutableHandleValue rval);
-
-extern JS_PUBLIC_API(bool)
-JS_ExecuteScript(JSContext* cx, JS::HandleScript script);
-
-/**
- * As above, but providing an explicit scope chain.  envChain must not include
- * the global object on it; that's implicit.  It needs to contain the other
- * objects that should end up on the script's scope chain.
- */
-extern JS_PUBLIC_API(bool)
-JS_ExecuteScript(JSContext* cx, JS::AutoObjectVector& envChain,
-                 JS::HandleScript script, JS::MutableHandleValue rval);
-
-extern JS_PUBLIC_API(bool)
-JS_ExecuteScript(JSContext* cx, JS::AutoObjectVector& envChain, JS::HandleScript script);
-
 namespace JS {
 
-/**
- * Like the above, but handles a cross-compartment script. If the script is
- * cross-compartment, it is cloned into the current compartment before executing.
- */
-extern JS_PUBLIC_API(bool)
-CloneAndExecuteScript(JSContext* cx, JS::Handle<JSScript*> script,
-                      JS::MutableHandleValue rval);
-
-/**
- * Like CloneAndExecuteScript above, but allows executing under a non-syntactic
- * environment chain.
- */
-extern JS_PUBLIC_API(bool)
-CloneAndExecuteScript(JSContext* cx, JS::AutoObjectVector& envChain,
-                      JS::Handle<JSScript*> script,
-                      JS::MutableHandleValue rval);
-
-} /* namespace JS */
-
-namespace JS {
-
-/**
- * Evaluate the given source buffer in the scope of the current global of cx.
- */
-extern JS_PUBLIC_API(bool)
-Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
-         SourceBufferHolder& srcBuf, JS::MutableHandleValue rval);
-
-/**
- * As above, but providing an explicit scope chain.  envChain must not include
- * the global object on it; that's implicit.  It needs to contain the other
- * objects that should end up on the script's scope chain.
- */
-extern JS_PUBLIC_API(bool)
-Evaluate(JSContext* cx, AutoObjectVector& envChain, const ReadOnlyCompileOptions& options,
-         SourceBufferHolder& srcBuf, JS::MutableHandleValue rval);
-
-/**
- * Evaluate the given byte buffer in the scope of the current global of cx.
- */
-extern JS_PUBLIC_API(bool)
-Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
-         const char* bytes, size_t length, JS::MutableHandleValue rval);
-
-/**
- * Evaluate the given file in the scope of the current global of cx.
- */
-extern JS_PUBLIC_API(bool)
-Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
-         const char* filename, JS::MutableHandleValue rval);
-
 using ModuleResolveHook = JSScript* (*)(JSContext*, HandleScript, HandleString);
 
 /**
  * Get the HostResolveImportedModule hook for the runtime.
  */
 extern JS_PUBLIC_API(ModuleResolveHook)
 GetModuleResolveHook(JSRuntime* rt);
 
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -124,16 +124,17 @@ EXPORTS += [
 
 EXPORTS.js += [
     '../public/AllocPolicy.h',
     '../public/AutoByteString.h',
     '../public/CallArgs.h',
     '../public/CallNonGenericMethod.h',
     '../public/CharacterEncoding.h',
     '../public/Class.h',
+    '../public/CompilationAndEvaluation.h',
     '../public/CompileOptions.h',
     '../public/Conversions.h',
     '../public/Date.h',
     '../public/Debug.h',
     '../public/ErrorReport.h',
     '../public/GCAnnotations.h',
     '../public/GCAPI.h',
     '../public/GCHashTable.h',