From b4aed63f5758b955e84840c5871b1301ccb6968f Mon Sep 17 00:00:00 2001 From: trav90 Date: Sun, 2 Sep 2018 18:45:56 -0500 Subject: Convert the trailing array of BindingNames at the end of the various kinds of scope data into raw unsigned chars into which those BindingNames are placement-new'd, rather than memcpy-ing non-trivial classes around and failing to comply with the C++ object model --- js/src/frontend/Parser.cpp | 76 ++++++++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 33 deletions(-) (limited to 'js/src/frontend/Parser.cpp') diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 623379f61..343621194 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -19,6 +19,8 @@ #include "frontend/Parser.h" +#include + #include "jsapi.h" #include "jsatom.h" #include "jscntxt.h" @@ -1452,7 +1454,7 @@ static typename Scope::Data* NewEmptyBindingData(ExclusiveContext* cx, LifoAlloc& alloc, uint32_t numBindings) { size_t allocSize = Scope::sizeOfData(numBindings); - typename Scope::Data* bindings = static_cast(alloc.alloc(allocSize)); + auto* bindings = static_cast(alloc.alloc(allocSize)); if (!bindings) { ReportOutOfMemory(cx); return nullptr; @@ -1461,6 +1463,18 @@ NewEmptyBindingData(ExclusiveContext* cx, LifoAlloc& alloc, uint32_t numBindings return bindings; } +/** + * Copy-construct |BindingName|s from |bindings| into |cursor|, then return + * the location one past the newly-constructed |BindingName|s. + */ +static MOZ_MUST_USE BindingName* +FreshlyInitializeBindings(BindingName* cursor, const Vector& bindings) +{ + for (const BindingName& binding : bindings) + new (cursor++) BindingName(binding); + return cursor; +} + template <> Maybe Parser::newGlobalScopeData(ParseContext::Scope& scope) @@ -1505,22 +1519,20 @@ Parser::newGlobalScopeData(ParseContext::Scope& scope) return Nothing(); // The ordering here is important. See comments in GlobalScope. - BindingName* start = bindings->names; + BindingName* start = bindings->trailingNames.start(); BindingName* cursor = start; - PodCopy(cursor, funs.begin(), funs.length()); - cursor += funs.length(); + cursor = FreshlyInitializeBindings(cursor, funs); bindings->varStart = cursor - start; - PodCopy(cursor, vars.begin(), vars.length()); - cursor += vars.length(); + cursor = FreshlyInitializeBindings(cursor, vars); bindings->letStart = cursor - start; - PodCopy(cursor, lets.begin(), lets.length()); - cursor += lets.length(); + cursor = FreshlyInitializeBindings(cursor, lets); bindings->constStart = cursor - start; - PodCopy(cursor, consts.begin(), consts.length()); + cursor = FreshlyInitializeBindings(cursor, consts); + bindings->length = numBindings; } @@ -1572,22 +1584,20 @@ Parser::newModuleScopeData(ParseContext::Scope& scope) return Nothing(); // The ordering here is important. See comments in ModuleScope. - BindingName* start = bindings->names; + BindingName* start = bindings->trailingNames.start(); BindingName* cursor = start; - PodCopy(cursor, imports.begin(), imports.length()); - cursor += imports.length(); + cursor = FreshlyInitializeBindings(cursor, imports); bindings->varStart = cursor - start; - PodCopy(cursor, vars.begin(), vars.length()); - cursor += vars.length(); + cursor = FreshlyInitializeBindings(cursor, vars); bindings->letStart = cursor - start; - PodCopy(cursor, lets.begin(), lets.length()); - cursor += lets.length(); + cursor = FreshlyInitializeBindings(cursor, lets); bindings->constStart = cursor - start; - PodCopy(cursor, consts.begin(), consts.length()); + cursor = FreshlyInitializeBindings(cursor, consts); + bindings->length = numBindings; } @@ -1623,16 +1633,16 @@ Parser::newEvalScopeData(ParseContext::Scope& scope) if (!bindings) return Nothing(); - BindingName* start = bindings->names; + BindingName* start = bindings->trailingNames.start(); BindingName* cursor = start; // Keep track of what vars are functions. This is only used in BCE to omit // superfluous DEFVARs. - PodCopy(cursor, funs.begin(), funs.length()); - cursor += funs.length(); + cursor = FreshlyInitializeBindings(cursor, funs); bindings->varStart = cursor - start; - PodCopy(cursor, vars.begin(), vars.length()); + cursor = FreshlyInitializeBindings(cursor, vars); + bindings->length = numBindings; } @@ -1719,18 +1729,17 @@ Parser::newFunctionScopeData(ParseContext::Scope& scope, bool return Nothing(); // The ordering here is important. See comments in FunctionScope. - BindingName* start = bindings->names; + BindingName* start = bindings->trailingNames.start(); BindingName* cursor = start; - PodCopy(cursor, positionalFormals.begin(), positionalFormals.length()); - cursor += positionalFormals.length(); + cursor = FreshlyInitializeBindings(cursor, positionalFormals); bindings->nonPositionalFormalStart = cursor - start; - PodCopy(cursor, formals.begin(), formals.length()); - cursor += formals.length(); + cursor = FreshlyInitializeBindings(cursor, formals); bindings->varStart = cursor - start; - PodCopy(cursor, vars.begin(), vars.length()); + cursor = FreshlyInitializeBindings(cursor, vars); + bindings->length = numBindings; } @@ -1760,10 +1769,11 @@ Parser::newVarScopeData(ParseContext::Scope& scope) return Nothing(); // The ordering here is important. See comments in FunctionScope. - BindingName* start = bindings->names; + BindingName* start = bindings->trailingNames.start(); BindingName* cursor = start; - PodCopy(cursor, vars.begin(), vars.length()); + cursor = FreshlyInitializeBindings(cursor, vars); + bindings->length = numBindings; } @@ -1808,14 +1818,14 @@ Parser::newLexicalScopeData(ParseContext::Scope& scope) return Nothing(); // The ordering here is important. See comments in LexicalScope. - BindingName* cursor = bindings->names; + BindingName* cursor = bindings->trailingNames.start(); BindingName* start = cursor; - PodCopy(cursor, lets.begin(), lets.length()); - cursor += lets.length(); + cursor = FreshlyInitializeBindings(cursor, lets); bindings->constStart = cursor - start; - PodCopy(cursor, consts.begin(), consts.length()); + cursor = FreshlyInitializeBindings(cursor, consts); + bindings->length = numBindings; } -- cgit v1.2.3 From 36cb80d1cac66a1511bec4ad97947a2deeab2e08 Mon Sep 17 00:00:00 2001 From: trav90 Date: Sun, 2 Sep 2018 18:59:51 -0500 Subject: Call the relevant scope-data constructor when allocating it, and poison/mark as undefined the memory for the trailing array of BindingNames, ratther than impermissibly PodZero-ing non-trivial classes. --- js/src/frontend/Parser.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'js/src/frontend/Parser.cpp') diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 343621194..7bfab87a3 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -1453,13 +1453,11 @@ template static typename Scope::Data* NewEmptyBindingData(ExclusiveContext* cx, LifoAlloc& alloc, uint32_t numBindings) { + using Data = typename Scope::Data; size_t allocSize = Scope::sizeOfData(numBindings); - auto* bindings = static_cast(alloc.alloc(allocSize)); - if (!bindings) { + auto* bindings = alloc.allocInSize(allocSize, numBindings); + if (!bindings) ReportOutOfMemory(cx); - return nullptr; - } - PodZero(bindings); return bindings; } -- cgit v1.2.3