Bug 1491137 - Split the JS::Compile that takes const char*/size_t into JS::CompileUtf8 and JS::CompileLatin1 that assert |options.utf8| has consistent value, and a JS::Compile that delegates to one of those as appropriate -- a step toward having entirely separate compilation functions that do direct parsing of UTF-8 without inflating first. r=jandem

--HG--
extra : rebase_source : 4fbc10a7e5e221da4c68c02dc155d925e7a7367d
This commit is contained in:
Jeff Walden 2018-09-12 20:48:44 -07:00
Родитель 1b48d2350b
Коммит 8f587a8aa5
6 изменённых файлов: 126 добавлений и 29 удалений

Просмотреть файл

@ -86,7 +86,7 @@ JS_ExecuteScript(JSContext* cx, JS::AutoVector<JSObject*>& envChain, JS::Handle<
* |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,
JS_CompileScript(JSContext* cx, const char* bytes, size_t length,
const JS::CompileOptions& options,
JS::MutableHandle<JSScript*> script);
@ -152,9 +152,63 @@ extern JS_PUBLIC_API(bool)
Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
SourceBufferHolder& srcBuf, MutableHandle<JSScript*> script);
/**
* Compile the provided UTF-8 data into a script. If the data contains invalid
* UTF-8, an error is reported.
*
* The |options.utf8| flag is asserted to be true. At a future time this flag
* will be removed and UTF-8-ness of source bytes will be entirely determined
* by which compilation function is called.
*
* |script| is always set to the compiled script or to null in case of error.
*/
extern JS_PUBLIC_API(bool)
CompileUtf8(JSContext* cx, const ReadOnlyCompileOptions& options,
const char* bytes, size_t length, MutableHandle<JSScript*> script);
/**
* Compile the provided Latin-1 data (i.e. each byte directly corresponds to
* the same Unicode code point) into a script.
*
* The |options.utf8| flag is asserted to be false. At a future time this flag
* will be removed and UTF-8-ness of source bytes will be entirely determined
* by which compilation function is called.
*
* This function may eventually be removed, such that *only* bytes containing
* UTF-8 source text may be directly compiled. Avoid using it if you can.
*
* |script| is always set to the compiled script or to null in case of error.
*/
extern JS_PUBLIC_API(bool)
CompileLatin1(JSContext* cx, const ReadOnlyCompileOptions& options,
const char* bytes, size_t length, MutableHandle<JSScript*> script);
/**
* DEPRECATED
*
* Compile the provided bytes into a script.
*
* If |options.utf8|, the bytes are interpreted as UTF-8 data. If the data
* contains any malformed UTF-8, an error is reported.
*
* Otherwise they are interpreted as Latin-1, i.e. each byte directly
* corresponds to the same Unicode code point.
*
* |script| is always set to the compiled script or to null in case of error.
*
* Do not use this API. The JS::CompileOptions::utf8 flag that indicates how
* to interpret |bytes| is currently being replaced by functions indicating an
* exact expected encoding. If you have byte data to compile, you should use
* either JS::CompileUtf8 or JS::CompileLatin1, as appropriate.
*/
inline bool
Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
const char* bytes, size_t length, MutableHandle<JSScript*> script);
const char* bytes, size_t length, MutableHandle<JSScript*> script)
{
return options.utf8
? CompileUtf8(cx, options, bytes, length, script)
: CompileLatin1(cx, options, bytes, length, script);
}
extern JS_PUBLIC_API(bool)
Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
@ -168,9 +222,17 @@ extern JS_PUBLIC_API(bool)
CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
SourceBufferHolder& srcBuf, MutableHandle<JSScript*> script);
/**
* Compile the given Latin-1 data for non-syntactic scope.
*
* There is no way to compile UTF-8 data for non-syntactic scope because no
* user currently needs it. Such way could be added in the future if it's ever
* needed.
*/
extern JS_PUBLIC_API(bool)
CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
const char* bytes, size_t length, MutableHandle<JSScript*> script);
CompileLatin1ForNonSyntacticScope(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,

Просмотреть файл

@ -85,7 +85,7 @@ testCompile(bool nonSyntactic)
CHECK(CompileForNonSyntacticScope(cx, options, buf, &script));
CHECK_EQUAL(script->hasNonSyntacticScope(), true);
CHECK(CompileForNonSyntacticScope(cx, options, src, length, &script));
CHECK(CompileLatin1ForNonSyntacticScope(cx, options, src, length, &script));
CHECK_EQUAL(script->hasNonSyntacticScope(), true);
{

Просмотреть файл

@ -28,7 +28,7 @@ BEGIN_TEST(testExecuteInJSMEnvironment_Basic)
options.setNoScriptRval(true);
JS::RootedScript script(cx);
CHECK(JS::CompileForNonSyntacticScope(cx, options, src, sizeof(src)-1, &script));
CHECK(JS::CompileLatin1ForNonSyntacticScope(cx, options, src, sizeof(src) - 1, &script));
JS::RootedObject varEnv(cx, js::NewJSMEnvironment(cx));
JS::RootedObject lexEnv(cx, JS_ExtensibleLexicalEnvironment(varEnv));
@ -88,7 +88,7 @@ BEGIN_TEST(testExecuteInJSMEnvironment_Callback)
options.setNoScriptRval(true);
JS::RootedScript script(cx);
CHECK(JS::CompileForNonSyntacticScope(cx, options, src, sizeof(src)-1, &script));
CHECK(JS::CompileLatin1ForNonSyntacticScope(cx, options, src, sizeof(src) - 1, &script));
JS::RootedObject nsvo(cx, js::NewJSMEnvironment(cx));
CHECK(nsvo);

Просмотреть файл

@ -9,6 +9,9 @@
#include "js/CompilationAndEvaluation.h"
#include "mozilla/Maybe.h" // mozilla::None, mozilla::Some
#include "mozilla/TextUtils.h" // mozilla::IsAscii
#include <algorithm> // std::all_of
#include "jstypes.h" // JS_PUBLIC_API
@ -50,15 +53,27 @@ Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
}
static bool
Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
const char* bytes, size_t length, JS::MutableHandleScript script)
CompileLatin1(JSContext* cx, const ReadOnlyCompileOptions& options,
const char* bytes, size_t length, JS::MutableHandleScript script)
{
char16_t* chars;
if (options.utf8) {
chars = JS::UTF8CharsToNewTwoByteCharsZ(cx, UTF8Chars(bytes, length), &length).get();
} else {
chars = InflateString(cx, bytes, length);
MOZ_ASSERT(!options.utf8);
char16_t* chars = InflateString(cx, bytes, length);
if (!chars) {
return false;
}
SourceBufferHolder source(chars, length, SourceBufferHolder::GiveOwnership);
return ::Compile(cx, options, source, script);
}
static bool
CompileUtf8(JSContext* cx, const ReadOnlyCompileOptions& options,
const char* bytes, size_t length, JS::MutableHandleScript script)
{
MOZ_ASSERT(options.utf8);
char16_t* chars = JS::UTF8CharsToNewTwoByteCharsZ(cx, UTF8Chars(bytes, length), &length).get();
if (!chars) {
return false;
}
@ -76,7 +91,12 @@ Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
return false;
}
return ::Compile(cx, options, reinterpret_cast<const char*>(buffer.begin()), buffer.length(), script);
return options.utf8
? ::CompileUtf8(cx, options,
reinterpret_cast<const char*>(buffer.begin()), buffer.length(), script)
: ::CompileLatin1(cx, options,
reinterpret_cast<const char*>(buffer.begin()), buffer.length(),
script);
}
static bool
@ -100,10 +120,19 @@ JS::Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
}
bool
JS::Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
const char* bytes, size_t length, JS::MutableHandleScript script)
JS::CompileLatin1(JSContext* cx, const ReadOnlyCompileOptions& options,
const char* bytes, size_t length, JS::MutableHandleScript script)
{
return ::Compile(cx, options, bytes, length, script);
MOZ_ASSERT(!options.utf8);
return ::CompileLatin1(cx, options, bytes, length, script);
}
bool
JS::CompileUtf8(JSContext* cx, const ReadOnlyCompileOptions& options,
const char* bytes, size_t length, JS::MutableHandleScript script)
{
MOZ_ASSERT(options.utf8);
return ::CompileUtf8(cx, options, bytes, length, script);
}
bool
@ -130,12 +159,16 @@ JS::CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& opt
}
bool
JS::CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& optionsArg,
const char* bytes, size_t length, JS::MutableHandleScript script)
JS::CompileLatin1ForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& optionsArg,
const char* bytes, size_t length,
JS::MutableHandleScript script)
{
MOZ_ASSERT(!optionsArg.utf8,
"this function only compiles Latin-1 source text");
CompileOptions options(cx, optionsArg);
options.setNonSyntacticScope(true);
return ::Compile(cx, options, bytes, length, script);
return ::CompileLatin1(cx, options, bytes, length, script);
}
bool
@ -157,10 +190,12 @@ JS::CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& opt
}
JS_PUBLIC_API(bool)
JS_CompileScript(JSContext* cx, const char* ascii, size_t length,
JS_CompileScript(JSContext* cx, const char* bytes, size_t length,
const JS::CompileOptions& options, MutableHandleScript script)
{
return ::Compile(cx, options, ascii, length, script);
return options.utf8
? ::CompileUtf8(cx, options, bytes, length, script)
: ::CompileLatin1(cx, options, bytes, length, script);
}
JS_PUBLIC_API(bool)

Просмотреть файл

@ -879,18 +879,18 @@ mozJSComponentLoader::ObjectForLocation(ComponentLoaderInfo& aInfo,
// don't early return for them here.
auto buf = map.get<char>();
if (reuseGlobal) {
CompileForNonSyntacticScope(cx, options, buf.get(), map.size(), &script);
CompileLatin1ForNonSyntacticScope(cx, options, buf.get(), map.size(), &script);
} else {
Compile(cx, options, buf.get(), map.size(), &script);
CompileLatin1(cx, options, buf.get(), map.size(), &script);
}
} else {
nsCString str;
MOZ_TRY_VAR(str, ReadScript(aInfo));
if (reuseGlobal) {
CompileForNonSyntacticScope(cx, options, str.get(), str.Length(), &script);
CompileLatin1ForNonSyntacticScope(cx, options, str.get(), str.Length(), &script);
} else {
Compile(cx, options, str.get(), str.Length(), &script);
CompileLatin1(cx, options, str.get(), str.Length(), &script);
}
}
// Propagate the exception, if one exists. Also, don't leave the stale

Просмотреть файл

@ -178,9 +178,9 @@ PrepareScript(nsIURI* uri,
// the lazy source loader doesn't know the encoding.
options.setSourceIsLazy(true);
if (wantGlobalScript) {
return JS::Compile(cx, options, buf, len, script);
return JS::CompileLatin1(cx, options, buf, len, script);
}
return JS::CompileForNonSyntacticScope(cx, options, buf, len, script);
return JS::CompileLatin1ForNonSyntacticScope(cx, options, buf, len, script);
}
static bool