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

Unified Diff: src/asmjs/asm-wasm-builder.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-wasm-builder.cc
diff --git a/src/asmjs/asm-wasm-builder.cc b/src/asmjs/asm-wasm-builder.cc
index 60bdd9a5a8473311ae54c694fd1ec53783f33e63..c4e64352b914e5e927bb35696a53768abbac5d9d 100644
--- a/src/asmjs/asm-wasm-builder.cc
+++ b/src/asmjs/asm-wasm-builder.cc
@@ -19,6 +19,9 @@
#include "src/ast/ast.h"
#include "src/ast/scopes.h"
#include "src/codegen.h"
+#include "src/compiler.h"
+#include "src/isolate.h"
+#include "src/parsing/parse-info.h"
namespace v8 {
namespace internal {
@@ -42,8 +45,8 @@ struct ForeignVariable {
class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
public:
- AsmWasmBuilderImpl(Isolate* isolate, Zone* zone, FunctionLiteral* literal,
- AsmTyper* typer)
+ AsmWasmBuilderImpl(Isolate* isolate, Zone* zone, Script* script,
+ FunctionLiteral* literal, AsmTyper* typer)
: local_variables_(ZoneHashMap::kDefaultHashMapCapacity,
ZoneAllocationPolicy(zone)),
functions_(ZoneHashMap::kDefaultHashMapCapacity,
@@ -56,12 +59,13 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
literal_(literal),
isolate_(isolate),
zone_(zone),
+ script_(script),
typer_(typer),
+ typer_failed_(false),
breakable_blocks_(zone),
foreign_variables_(zone),
init_function_(nullptr),
foreign_init_function_(nullptr),
- next_table_index_(0),
function_tables_(ZoneHashMap::kDefaultHashMapCapacity,
ZoneAllocationPolicy(zone)),
imported_function_table_(this) {
@@ -108,10 +112,21 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
return ret;
}
- void Build() {
+ bool Build() {
InitializeInitFunction();
- RECURSE(VisitFunctionLiteral(literal_));
+ if (!typer_->ValidatePhase1of2()) {
+ return false;
+ }
+ DCHECK(!HasStackOverflow());
+ VisitFunctionLiteral(literal_);
+ if (HasStackOverflow()) {
+ return false;
+ }
+ if (typer_failed_) {
+ return false;
+ }
BuildForeignInitFunction();
+ return true;
}
void VisitVariableDeclaration(VariableDeclaration* decl) {}
@@ -119,9 +134,40 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
void VisitFunctionDeclaration(FunctionDeclaration* decl) {
DCHECK_EQ(kModuleScope, scope_);
DCHECK_NULL(current_function_builder_);
+ bool had_body;
+ i::Zone zone(isolate_->allocator());
+ if (decl->fun()->body() == nullptr) {
+ Handle<SharedFunctionInfo> shared =
titzer 2016/10/07 12:56:59 Do we really need a shared function info here? See
bradn 2016/11/25 09:19:36 A large number of places in the parser assume a Sh
+ i::Compiler::NewSharedFunctionInfoFromLiteral(
+ isolate_, decl->fun(), handle(script_, isolate_));
+ shared->set_is_toplevel(false);
+ i::ParseInfo info(&zone, handle(script_, isolate_));
+ info.set_shared_info(shared);
+ info.set_language_mode(decl->fun()->scope()->language_mode());
+ info.set_lazy(true);
+ info.set_allow_lazy_parsing(false);
+ info.set_script_scope(decl->fun()->scope());
+ if (!i::Compiler::ParseAndAnalyze(&info)) {
+ typer_failed_ = true;
+ return;
+ }
+ FunctionLiteral* func = info.literal();
+ DCHECK_NOT_NULL(func);
+ decl->fun()->set_body(func->body());
+ had_body = false;
+ } else {
+ had_body = true;
+ }
+ if (!typer_->ValidateInnerFunction(decl)) {
+ typer_failed_ = true;
+ return;
+ }
current_function_builder_ = LookupOrInsertFunction(decl->proxy()->var());
scope_ = kFuncScope;
RECURSE(Visit(decl->fun()));
+ if (!had_body) {
+ decl->fun()->set_body(nullptr);
+ }
scope_ = kModuleScope;
current_function_builder_ = nullptr;
local_variables_.Clear();
@@ -135,6 +181,7 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
continue;
}
RECURSE(Visit(stmt));
+ if (typer_failed_) break;
if (stmt->IsJump()) break;
}
}
@@ -454,8 +501,13 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
UNREACHABLE();
}
}
- RECURSE(VisitStatements(expr->body()));
- RECURSE(VisitDeclarations(scope->declarations()));
+ if (scope_ == kFuncScope) {
titzer 2016/10/07 12:56:59 Why do we need to do the declarations after for a
bradn 2016/11/25 09:19:36 No good reason. Both should be declarations then s
+ RECURSE(VisitStatements(expr->body()));
+ RECURSE(VisitDeclarations(scope->declarations()));
+ } else {
+ RECURSE(VisitDeclarations(scope->declarations()));
+ RECURSE(VisitStatements(expr->body()));
+ }
}
void VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
@@ -637,6 +689,11 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
void VisitRegExpLiteral(RegExpLiteral* expr) { UNREACHABLE(); }
void VisitObjectLiteral(ObjectLiteral* expr) {
+ if (!typer_->ValidatePhase2of2()) {
+ typer_failed_ = true;
+ return;
+ }
+
ZoneList<ObjectLiteralProperty*>* props = expr->properties();
for (int i = 0; i < props->length(); ++i) {
ObjectLiteralProperty* prop = props->at(i);
@@ -669,10 +726,22 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
current_function_builder_ = nullptr;
}
- void AddFunctionTable(VariableProxy* table, ArrayLiteral* funcs) {
- auto* func_tbl_type = typer_->TypeOf(funcs)->AsFunctionTableType();
- DCHECK_NOT_NULL(func_tbl_type);
- auto* func_type = func_tbl_type->signature()->AsFunctionType();
+ struct FunctionTableIndices : public ZoneObject {
+ uint32_t start_index;
+ uint32_t signature_index;
+ };
+
+ FunctionTableIndices* LookupOrAddFunctionTable(VariableProxy* table,
+ Property* p) {
+ FunctionTableIndices* indices = LookupFunctionTable(table->var());
+ if (indices != nullptr) {
+ // Already setup.
+ return indices;
+ }
+ indices = new (zone()) FunctionTableIndices();
+ auto* func_type = typer_->TypeOf(p)->AsFunctionType();
+ auto* func_table_type = typer_->TypeOf(p->obj()->AsVariableProxy()->var())
+ ->AsFunctionTableType();
const auto& arguments = func_type->Arguments();
LocalType return_type = TypeFrom(func_type->ReturnType());
FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1,
@@ -684,38 +753,37 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
sig.AddParam(TypeFrom(arg));
}
uint32_t signature_index = builder_->AddSignature(sig.Build());
- InsertFunctionTable(table->var(), next_table_index_, signature_index);
- next_table_index_ += funcs->values()->length();
- for (int i = 0; i < funcs->values()->length(); ++i) {
- VariableProxy* func = funcs->values()->at(i)->AsVariableProxy();
- DCHECK_NOT_NULL(func);
- builder_->AddIndirectFunction(
- LookupOrInsertFunction(func->var())->func_index());
- }
- }
-
- struct FunctionTableIndices : public ZoneObject {
- uint32_t start_index;
- uint32_t signature_index;
- };
-
- void InsertFunctionTable(Variable* v, uint32_t start_index,
- uint32_t signature_index) {
- FunctionTableIndices* container = new (zone()) FunctionTableIndices();
- container->start_index = start_index;
- container->signature_index = signature_index;
+ indices->start_index =
+ builder_->AllocateIndirectFunctions(func_table_type->length());
+ indices->signature_index = signature_index;
ZoneHashMap::Entry* entry = function_tables_.LookupOrInsert(
- v, ComputePointerHash(v), ZoneAllocationPolicy(zone()));
- entry->value = container;
+ table->var(), ComputePointerHash(table->var()),
+ ZoneAllocationPolicy(zone()));
+ entry->value = indices;
+ return indices;
}
FunctionTableIndices* LookupFunctionTable(Variable* v) {
ZoneHashMap::Entry* entry =
function_tables_.Lookup(v, ComputePointerHash(v));
- DCHECK_NOT_NULL(entry);
+ if (entry == nullptr) {
+ return nullptr;
+ }
return reinterpret_cast<FunctionTableIndices*>(entry->value);
}
+ void PopulateFunctionTable(VariableProxy* table, ArrayLiteral* funcs) {
+ FunctionTableIndices* indices = LookupFunctionTable(table->var());
+ DCHECK_NOT_NULL(indices);
+ for (int i = 0; i < funcs->values()->length(); ++i) {
+ VariableProxy* func = funcs->values()->at(i)->AsVariableProxy();
+ DCHECK_NOT_NULL(func);
+ builder_->SetIndirectFunction(
+ indices->start_index + i,
+ LookupOrInsertFunction(func->var())->func_index());
+ }
+ }
+
class ImportedFunctionTable {
private:
class ImportedFunctionIndices : public ZoneObject {
@@ -736,20 +804,33 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
ZoneAllocationPolicy(builder->zone())),
builder_(builder) {}
- void AddImport(Variable* v, const char* name, int name_length) {
- ImportedFunctionIndices* indices = new (builder_->zone())
- ImportedFunctionIndices(name, name_length, builder_->zone());
+ ImportedFunctionIndices* LookupOrInsertImport(Variable* v) {
auto* entry = table_.LookupOrInsert(
v, ComputePointerHash(v), ZoneAllocationPolicy(builder_->zone()));
- entry->value = indices;
+ ImportedFunctionIndices* indices;
+ if (entry->value == nullptr) {
+ indices = new (builder_->zone())
+ ImportedFunctionIndices(nullptr, 0, builder_->zone());
+ entry->value = indices;
+ } else {
+ indices = reinterpret_cast<ImportedFunctionIndices*>(entry->value);
+ }
+ return indices;
+ }
+
+ void SetImportName(Variable* v, const char* name, int name_length) {
+ auto* indices = LookupOrInsertImport(v);
+ indices->name_ = name;
+ indices->name_length_ = name_length;
+ for (auto i : indices->signature_to_index_) {
+ builder_->builder_->SetImportName(i.second, indices->name_,
+ indices->name_length_);
+ }
}
// Get a function's index (or allocate if new).
- uint32_t LookupOrInsertImport(Variable* v, FunctionSig* sig) {
- ZoneHashMap::Entry* entry = table_.Lookup(v, ComputePointerHash(v));
- DCHECK_NOT_NULL(entry);
- ImportedFunctionIndices* indices =
- reinterpret_cast<ImportedFunctionIndices*>(entry->value);
+ uint32_t LookupOrInsertImportUse(Variable* v, FunctionSig* sig) {
+ auto* indices = LookupOrInsertImport(v);
WasmModuleBuilder::SignatureMap::iterator pos =
indices->signature_to_index_.find(sig);
if (pos != indices->signature_to_index_.end()) {
@@ -910,7 +991,7 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
if (typer_->TypeOf(target)->AsFFIType() != nullptr) {
const AstRawString* name =
prop->key()->AsLiteral()->AsRawPropertyName();
- imported_function_table_.AddImport(
+ imported_function_table_.SetImportName(
target->var(), reinterpret_cast<const char*>(name->raw_data()),
name->length());
}
@@ -919,14 +1000,10 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
return;
}
ArrayLiteral* funcs = expr->value()->AsArrayLiteral();
- if (funcs != nullptr &&
- typer_->TypeOf(funcs)
- ->AsFunctionTableType()
- ->signature()
- ->AsFunctionType()) {
+ if (funcs != nullptr) {
VariableProxy* target = expr->target()->AsVariableProxy();
DCHECK_NOT_NULL(target);
- AddFunctionTable(target, funcs);
+ PopulateFunctionTable(target, funcs);
// Only add to the function table. No init needed.
return;
}
@@ -1361,7 +1438,7 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
for (int i = 0; i < args->length(); ++i) {
sig.AddParam(TypeOf(args->at(i)));
}
- uint32_t index = imported_function_table_.LookupOrInsertImport(
+ uint32_t index = imported_function_table_.LookupOrInsertImportUse(
vp->var(), sig.Build());
VisitCallArgs(expr);
current_function_builder_->Emit(kExprCallFunction);
@@ -1382,7 +1459,7 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
DCHECK_NOT_NULL(p);
VariableProxy* var = p->obj()->AsVariableProxy();
DCHECK_NOT_NULL(var);
- FunctionTableIndices* indices = LookupFunctionTable(var->var());
+ FunctionTableIndices* indices = LookupOrAddFunctionTable(var, p);
Visit(p->key()); // TODO(titzer): should use RECURSE()
// We have to use a temporary for the correct order of evaluation.
@@ -1727,6 +1804,9 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
for (int i = 0; i < decls->length(); ++i) {
Declaration* decl = decls->at(i);
RECURSE(Visit(decl));
+ if (typer_failed_) {
+ return;
+ }
}
}
@@ -1854,7 +1934,9 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
FunctionLiteral* literal_;
Isolate* isolate_;
Zone* zone_;
+ Script* script_;
AsmTyper* typer_;
+ bool typer_failed_;
ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_;
ZoneVector<ForeignVariable> foreign_variables_;
WasmFunctionBuilder* init_function_;
@@ -1869,15 +1951,21 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl);
};
-AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone,
- FunctionLiteral* literal, AsmTyper* typer)
- : isolate_(isolate), zone_(zone), literal_(literal), typer_(typer) {}
+AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone, Script* script,
+ FunctionLiteral* literal)
+ : isolate_(isolate),
+ zone_(zone),
+ script_(script),
+ literal_(literal),
+ typer_(isolate, zone, script, literal) {}
// TODO(aseemgarg): probably should take zone (to write wasm to) as input so
// that zone in constructor may be thrown away once wasm module is written.
ZoneBuffer* AsmWasmBuilder::Run(i::Handle<i::FixedArray>* foreign_args) {
- AsmWasmBuilderImpl impl(isolate_, zone_, literal_, typer_);
- impl.Build();
+ AsmWasmBuilderImpl impl(isolate_, zone_, script_, literal_, &typer_);
+ if (!impl.Build()) {
+ return nullptr;
+ }
*foreign_args = impl.GetForeignArgs();
ZoneBuffer* buffer = new (zone_) ZoneBuffer(zone_);
impl.builder_->WriteTo(*buffer);
« src/asmjs/asm-typer.h ('K') | « src/asmjs/asm-wasm-builder.h ('k') | src/ast/ast.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698