Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Unified Diff: src/asmjs/asm-typer.cc

Issue 2398023002: [wasm] asm.js - Parse and convert asm.js to wasm a function at a time. (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/asmjs/asm-typer.cc
diff --git a/src/asmjs/asm-typer.cc b/src/asmjs/asm-typer.cc
index 91bec8c09012fa05b0d68b536e5df10b0cbaddb3..56247916693d914274ae9a0f90fd231444102a6b 100644
--- a/src/asmjs/asm-typer.cc
+++ b/src/asmjs/asm-typer.cc
@@ -91,6 +91,51 @@ Statement* AsmTyper::FlattenedStatements::Next() {
}
// ----------------------------------------------------------------------------
+// Implementation of AsmTyper::SourceLayoutTracker
+
+bool AsmTyper::SourceLayoutTracker::IsValid() const {
+ const Section* kAllSections[] = {&use_asm_, &globals_, &functions_, &tables_,
+ &exports_};
+ for (size_t ii = 0; ii < arraysize(kAllSections); ++ii) {
+ const auto& curr_section = *kAllSections[ii];
+ for (size_t jj = ii + 1; jj < arraysize(kAllSections); ++jj) {
+ if (curr_section.OverlapsWith(*kAllSections[jj])) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+void AsmTyper::SourceLayoutTracker::Section::AddNewElement(
+ const AstNode& node) {
+ const int node_pos = node.position();
+ if (start_ == kNoSourcePosition) {
+ start_ = node_pos;
+ } else {
+ start_ = std::max(start_, node_pos);
+ }
+ if (end_ == kNoSourcePosition) {
+ end_ = node_pos;
+ } else {
+ end_ = std::max(end_, node_pos);
+ }
+}
+
+bool AsmTyper::SourceLayoutTracker::Section::OverlapsWith(
+ const Section& other) const {
+ if (start_ == kNoSourcePosition) {
+ DCHECK_EQ(end_, kNoSourcePosition);
+ return false;
+ }
+ if (other.start_ == kNoSourcePosition) {
+ DCHECK_EQ(other.end_, kNoSourcePosition);
+ return false;
+ }
+ return other.start_ < end_ || other.end_ < start_;
+}
+
+// ----------------------------------------------------------------------------
// Implementation of AsmTyper::VariableInfo
AsmTyper::VariableInfo* AsmTyper::VariableInfo::ForSpecialSymbol(
@@ -139,7 +184,8 @@ AsmTyper::AsmTyper(Isolate* isolate, Zone* zone, Script* script,
stack_limit_(isolate->stack_guard()->real_climit()),
node_types_(zone_),
fround_type_(AsmType::FroundType(zone_)),
- ffi_type_(AsmType::FFIType(zone_)) {
+ ffi_type_(AsmType::FFIType(zone_)),
+ function_pointer_tables_(zone_) {
InitializeStdlib();
}
@@ -434,7 +480,27 @@ AsmTyper::StandardMember AsmTyper::VariableAsStandardMember(Variable* var) {
}
bool AsmTyper::Validate() {
- if (!AsmType::None()->IsExactly(ValidateModule(root_))) {
+ return ValidatePhase1of2() &&
+ !AsmType::None()->IsExactly(ValidateModuleFunctions(root_)) &&
+ ValidatePhase2of2();
+}
+
+bool AsmTyper::ValidatePhase1of2() {
+ if (!AsmType::None()->IsExactly(ValidateModulePhase1of2(root_))) {
+ return true;
+ }
+ return false;
+}
+
+bool AsmTyper::ValidateInnerFunction(FunctionDeclaration* fun_decl) {
+ if (!AsmType::None()->IsExactly(ValidateModuleFunction(fun_decl))) {
+ return true;
+ }
+ return false;
+}
+
+bool AsmTyper::ValidatePhase2of2() {
+ if (!AsmType::None()->IsExactly(ValidateModulePhase2of2(root_))) {
return true;
}
return false;
@@ -477,89 +543,7 @@ Assignment* ExtractInitializerExpression(Statement* statement) {
} // namespace
// 6.1 ValidateModule
-namespace {
-// SourceLayoutTracker keeps track of the start and end positions of each
-// section in the asm.js source. The sections should not overlap, otherwise the
-// asm.js source is invalid.
-class SourceLayoutTracker {
- public:
- SourceLayoutTracker() = default;
-
- bool IsValid() const {
- const Section* kAllSections[] = {&use_asm_, &globals_, &functions_,
- &tables_, &exports_};
- for (size_t ii = 0; ii < arraysize(kAllSections); ++ii) {
- const auto& curr_section = *kAllSections[ii];
- for (size_t jj = ii + 1; jj < arraysize(kAllSections); ++jj) {
- if (curr_section.OverlapsWith(*kAllSections[jj])) {
- return false;
- }
- }
- }
- return true;
- }
-
- void AddUseAsm(const AstNode& node) { use_asm_.AddNewElement(node); }
-
- void AddGlobal(const AstNode& node) { globals_.AddNewElement(node); }
-
- void AddFunction(const AstNode& node) { functions_.AddNewElement(node); }
-
- void AddTable(const AstNode& node) { tables_.AddNewElement(node); }
-
- void AddExport(const AstNode& node) { exports_.AddNewElement(node); }
-
- private:
- class Section {
- public:
- Section() = default;
- Section(const Section&) = default;
- Section& operator=(const Section&) = default;
-
- void AddNewElement(const AstNode& node) {
- const int node_pos = node.position();
- if (start_ == kNoSourcePosition) {
- start_ = node_pos;
- } else {
- start_ = std::max(start_, node_pos);
- }
- if (end_ == kNoSourcePosition) {
- end_ = node_pos;
- } else {
- end_ = std::max(end_, node_pos);
- }
- }
-
- bool OverlapsWith(const Section& other) const {
- if (start_ == kNoSourcePosition) {
- DCHECK_EQ(end_, kNoSourcePosition);
- return false;
- }
- if (other.start_ == kNoSourcePosition) {
- DCHECK_EQ(other.end_, kNoSourcePosition);
- return false;
- }
- return other.start_ < end_ || other.end_ < start_;
- }
-
- private:
- int start_ = kNoSourcePosition;
- int end_ = kNoSourcePosition;
- };
-
- Section use_asm_;
- Section globals_;
- Section functions_;
- Section tables_;
- Section exports_;
-
- DISALLOW_COPY_AND_ASSIGN(SourceLayoutTracker);
-};
-} // namespace
-
-AsmType* AsmTyper::ValidateModule(FunctionLiteral* fun) {
- SourceLayoutTracker source_layout;
-
+AsmType* AsmTyper::ValidateModulePhase1of2(FunctionLiteral* fun) {
DeclarationScope* scope = fun->scope();
if (!scope->is_function_scope()) FAIL(fun, "Not at function scope.");
if (!ValidAsmIdentifier(fun->name()))
@@ -594,7 +578,6 @@ AsmType* AsmTyper::ValidateModule(FunctionLiteral* fun) {
}
}
- ZoneVector<Assignment*> function_pointer_tables(zone_);
FlattenedStatements iter(zone_, fun->body());
auto* use_asm_directive = iter.Next();
if (use_asm_directive == nullptr) {
@@ -616,8 +599,8 @@ AsmType* AsmTyper::ValidateModule(FunctionLiteral* fun) {
if (!IsUseAsmDirective(use_asm_directive)) {
FAIL(fun, "Missing \"use asm\".");
}
- source_layout.AddUseAsm(*use_asm_directive);
- ReturnStatement* module_return = nullptr;
+ source_layout_.AddUseAsm(*use_asm_directive);
+ module_return_ = nullptr;
// *VIOLATION* The spec states that globals should be followed by function
// declarations, which should be followed by function pointer tables, followed
@@ -627,43 +610,60 @@ AsmType* AsmTyper::ValidateModule(FunctionLiteral* fun) {
if (auto* assign = ExtractInitializerExpression(current)) {
if (assign->value()->IsArrayLiteral()) {
// Save function tables for later validation.
- function_pointer_tables.push_back(assign);
+ function_pointer_tables_.push_back(assign);
} else {
RECURSE(ValidateGlobalDeclaration(assign));
- source_layout.AddGlobal(*assign);
+ source_layout_.AddGlobal(*assign);
}
continue;
}
if (auto* current_as_return = current->AsReturnStatement()) {
- if (module_return != nullptr) {
+ if (module_return_ != nullptr) {
FAIL(fun, "Multiple export statements.");
}
- module_return = current_as_return;
- source_layout.AddExport(*module_return);
+ module_return_ = current_as_return;
+ source_layout_.AddExport(*module_return_);
continue;
}
FAIL(current, "Invalid top-level statement in asm.js module.");
}
+ return AsmType::Int(); // Any type that is not AsmType::None();
+}
+
+AsmType* AsmTyper::ValidateModuleFunction(FunctionDeclaration* fun_decl) {
+ RECURSE(ValidateFunction(fun_decl));
+ source_layout_.AddFunction(*fun_decl);
+
+ return AsmType::Int(); // Any type that is not AsmType::None();
+}
+
+AsmType* AsmTyper::ValidateModuleFunctions(FunctionLiteral* fun) {
+ DeclarationScope* scope = fun->scope();
ZoneList<Declaration*>* decls = scope->declarations();
for (int ii = 0; ii < decls->length(); ++ii) {
Declaration* decl = decls->at(ii);
if (FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration()) {
- RECURSE(ValidateFunction(fun_decl));
- source_layout.AddFunction(*fun_decl);
+ RECURSE(ValidateModuleFunction(fun_decl));
continue;
}
}
- for (auto* function_table : function_pointer_tables) {
+ return AsmType::Int(); // Any type that is not AsmType::None();
+}
+
+AsmType* AsmTyper::ValidateModulePhase2of2(FunctionLiteral* fun) {
+ for (auto* function_table : function_pointer_tables_) {
RECURSE(ValidateFunctionTable(function_table));
- source_layout.AddTable(*function_table);
+ source_layout_.AddTable(*function_table);
}
+ DeclarationScope* scope = fun->scope();
+ ZoneList<Declaration*>* decls = scope->declarations();
for (int ii = 0; ii < decls->length(); ++ii) {
Declaration* decl = decls->at(ii);
@@ -687,7 +687,7 @@ AsmType* AsmTyper::ValidateModule(FunctionLiteral* fun) {
}
// 6.2 ValidateExport
- if (module_return == nullptr) {
+ if (module_return_ == nullptr) {
FAIL(fun, "Missing asm.js module export.");
}
@@ -698,9 +698,9 @@ AsmType* AsmTyper::ValidateModule(FunctionLiteral* fun) {
}
}
- RECURSE(ValidateExport(module_return));
+ RECURSE(ValidateExport(module_return_));
- if (!source_layout.IsValid()) {
+ if (!source_layout_.IsValid()) {
FAIL(fun, "Invalid asm.js source code layout.");
}
@@ -856,6 +856,7 @@ AsmType* AsmTyper::ValidateGlobalDeclaration(Assignment* assign) {
AsmType* AsmTyper::ExportType(VariableProxy* fun_export) {
auto* fun_info = Lookup(fun_export->var());
if (fun_info == nullptr) {
+ UNREACHABLE();
FAIL(fun_export, "Undefined identifier in asm.js module export.");
}

Powered by Google App Engine
This is Rietveld 408576698