Add __init__ function to all modules created in asm-to-wasm

TEST=asm-wasm.js
R=titzer@chromium.org,bradnelson@google.com
BUG=

Review URL: https://codereview.chromium.org/1583603002

Cr-Commit-Position: refs/heads/master@{#33256}
This commit is contained in:
aseemgarg 2016-01-12 17:23:43 -08:00 committed by Commit bot
parent 042760d233
commit 9933b03de8
4 changed files with 74 additions and 42 deletions

View File

@ -47,12 +47,24 @@ class AsmWasmBuilderImpl : public AstVisitor {
cache_(TypeCache::Get()), cache_(TypeCache::Get()),
breakable_blocks_(zone), breakable_blocks_(zone),
block_size_(0), block_size_(0),
init_function_initialized(false),
init_function_index(0) { init_function_index(0) {
InitializeAstVisitor(isolate); InitializeAstVisitor(isolate);
} }
void Compile() { RECURSE(VisitFunctionLiteral(literal_)); } void InitializeInitFunction() {
unsigned char init[] = "__init__";
init_function_index = builder_->AddFunction();
current_function_builder_ = builder_->FunctionAt(init_function_index);
current_function_builder_->SetName(init, 8);
current_function_builder_->ReturnType(kAstStmt);
current_function_builder_->Exported(1);
current_function_builder_ = nullptr;
}
void Compile() {
InitializeInitFunction();
RECURSE(VisitFunctionLiteral(literal_));
}
void VisitVariableDeclaration(VariableDeclaration* decl) {} void VisitVariableDeclaration(VariableDeclaration* decl) {}
@ -380,12 +392,6 @@ class AsmWasmBuilderImpl : public AstVisitor {
AddLeb128(LookupOrInsertLocal(var, var_type), true); AddLeb128(LookupOrInsertLocal(var, var_type), true);
} }
} }
} else if (marking_exported) {
Variable* var = expr->var();
if (var->is_function()) {
uint16_t index = LookupOrInsertFunction(var);
builder_->FunctionAt(index)->Exported(1);
}
} }
} }
@ -425,25 +431,28 @@ class AsmWasmBuilderImpl : public AstVisitor {
ZoneList<ObjectLiteralProperty*>* props = expr->properties(); ZoneList<ObjectLiteralProperty*>* props = expr->properties();
for (int i = 0; i < props->length(); ++i) { for (int i = 0; i < props->length(); ++i) {
ObjectLiteralProperty* prop = props->at(i); ObjectLiteralProperty* prop = props->at(i);
RECURSE(Visit(prop->value())); DCHECK(marking_exported);
VariableProxy* expr = prop->value()->AsVariableProxy();
DCHECK(expr != nullptr);
Variable* var = expr->var();
Literal* name = prop->key()->AsLiteral();
DCHECK(name != nullptr);
DCHECK(name->IsPropertyName());
const AstRawString* raw_name = name->AsRawPropertyName();
if (var->is_function()) {
uint16_t index = LookupOrInsertFunction(var);
builder_->FunctionAt(index)->Exported(1);
builder_->FunctionAt(index)
->SetName(raw_name->raw_data(), raw_name->length());
}
} }
} }
void VisitArrayLiteral(ArrayLiteral* expr) { UNREACHABLE(); } void VisitArrayLiteral(ArrayLiteral* expr) { UNREACHABLE(); }
void LoadInitFunction() { void LoadInitFunction() {
if (!init_function_initialized) { current_function_builder_ = builder_->FunctionAt(init_function_index);
init_function_initialized = true; in_function_ = true;
unsigned char init[] = "__init__";
init_function_index = builder_->AddFunction(init, 8);
current_function_builder_ = builder_->FunctionAt(init_function_index);
current_function_builder_->ReturnType(kAstStmt);
current_function_builder_->Exported(1);
in_function_ = true;
} else {
current_function_builder_ = builder_->FunctionAt(init_function_index);
in_function_ = true;
}
} }
void UnLoadInitFunction() { void UnLoadInitFunction() {
@ -465,7 +474,6 @@ class AsmWasmBuilderImpl : public AstVisitor {
if (value_op != nullptr && MatchBinaryOperation(value_op) == kAsIs) { if (value_op != nullptr && MatchBinaryOperation(value_op) == kAsIs) {
VariableProxy* target_var = expr->target()->AsVariableProxy(); VariableProxy* target_var = expr->target()->AsVariableProxy();
VariableProxy* effective_value_var = GetLeft(value_op)->AsVariableProxy(); VariableProxy* effective_value_var = GetLeft(value_op)->AsVariableProxy();
// TODO(aseemgarg): simplify block_size_ or replace with a kNop
if (target_var != nullptr && effective_value_var != nullptr && if (target_var != nullptr && effective_value_var != nullptr &&
target_var->var() == effective_value_var->var()) { target_var->var() == effective_value_var->var()) {
block_size_--; block_size_--;
@ -969,8 +977,7 @@ class AsmWasmBuilderImpl : public AstVisitor {
DCHECK(builder_ != nullptr); DCHECK(builder_ != nullptr);
ZoneHashMap::Entry* entry = functions_.Lookup(v, ComputePointerHash(v)); ZoneHashMap::Entry* entry = functions_.Lookup(v, ComputePointerHash(v));
if (entry == nullptr) { if (entry == nullptr) {
uint16_t index = builder_->AddFunction(v->raw_name()->raw_data(), uint16_t index = builder_->AddFunction();
v->raw_name()->length());
IndexContainer* container = new (zone()) IndexContainer(); IndexContainer* container = new (zone()) IndexContainer();
container->index = index; container->index = index;
entry = functions_.LookupOrInsert(v, ComputePointerHash(v), entry = functions_.LookupOrInsert(v, ComputePointerHash(v),
@ -1013,7 +1020,6 @@ class AsmWasmBuilderImpl : public AstVisitor {
TypeCache const& cache_; TypeCache const& cache_;
ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_; ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_;
int block_size_; int block_size_;
bool init_function_initialized;
uint16_t init_function_index; uint16_t init_function_index;
DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();

View File

@ -63,22 +63,14 @@ struct WasmFunctionBuilder::Type {
}; };
WasmFunctionBuilder::WasmFunctionBuilder(Zone* zone, const unsigned char* name, WasmFunctionBuilder::WasmFunctionBuilder(Zone* zone)
int name_length)
: return_type_(kAstI32), : return_type_(kAstI32),
locals_(zone), locals_(zone),
exported_(0), exported_(0),
external_(0), external_(0),
body_(zone), body_(zone),
local_indices_(zone), local_indices_(zone),
name_(zone) { name_(zone) {}
if (name_length > 0) {
for (int i = 0; i < name_length; i++) {
name_.push_back(*(name + i));
}
name_.push_back('\0');
}
}
uint16_t WasmFunctionBuilder::AddParam(LocalType type) { uint16_t WasmFunctionBuilder::AddParam(LocalType type) {
@ -152,6 +144,16 @@ void WasmFunctionBuilder::Exported(uint8_t flag) { exported_ = flag; }
void WasmFunctionBuilder::External(uint8_t flag) { external_ = flag; } void WasmFunctionBuilder::External(uint8_t flag) { external_ = flag; }
void WasmFunctionBuilder::SetName(const unsigned char* name, int name_length) {
name_.clear();
if (name_length > 0) {
for (int i = 0; i < name_length; i++) {
name_.push_back(*(name + i));
}
name_.push_back('\0');
}
}
WasmFunctionEncoder* WasmFunctionBuilder::Build(Zone* zone, WasmFunctionEncoder* WasmFunctionBuilder::Build(Zone* zone,
WasmModuleBuilder* mb) const { WasmModuleBuilder* mb) const {
@ -348,10 +350,8 @@ WasmModuleBuilder::WasmModuleBuilder(Zone* zone)
signature_map_(zone) {} signature_map_(zone) {}
uint16_t WasmModuleBuilder::AddFunction(const unsigned char* name, uint16_t WasmModuleBuilder::AddFunction() {
int name_length) { functions_.push_back(new (zone_) WasmFunctionBuilder(zone_));
functions_.push_back(new (zone_)
WasmFunctionBuilder(zone_, name, name_length));
return static_cast<uint16_t>(functions_.size() - 1); return static_cast<uint16_t>(functions_.size() - 1);
} }

View File

@ -65,10 +65,11 @@ class WasmFunctionBuilder : public ZoneObject {
void EditImmediate(uint32_t offset, const byte immediate); void EditImmediate(uint32_t offset, const byte immediate);
void Exported(uint8_t flag); void Exported(uint8_t flag);
void External(uint8_t flag); void External(uint8_t flag);
void SetName(const unsigned char* name, int name_length);
WasmFunctionEncoder* Build(Zone* zone, WasmModuleBuilder* mb) const; WasmFunctionEncoder* Build(Zone* zone, WasmModuleBuilder* mb) const;
private: private:
WasmFunctionBuilder(Zone* zone, const unsigned char* name, int name_length); explicit WasmFunctionBuilder(Zone* zone);
friend class WasmModuleBuilder; friend class WasmModuleBuilder;
LocalType return_type_; LocalType return_type_;
struct Type; struct Type;
@ -125,8 +126,7 @@ class WasmModuleWriter : public ZoneObject {
class WasmModuleBuilder : public ZoneObject { class WasmModuleBuilder : public ZoneObject {
public: public:
explicit WasmModuleBuilder(Zone* zone); explicit WasmModuleBuilder(Zone* zone);
uint16_t AddFunction(const unsigned char* name = nullptr, uint16_t AddFunction();
int name_length = 0);
uint32_t AddGlobal(MachineType type, bool exported); uint32_t AddGlobal(MachineType type, bool exported);
WasmFunctionBuilder* FunctionAt(size_t index); WasmFunctionBuilder* FunctionAt(size_t index);
void AddDataSegment(WasmDataSegmentEncoder* data); void AddDataSegment(WasmDataSegmentEncoder* data);

View File

@ -757,3 +757,29 @@ function TestNestedSwitch() {
} }
assertEquals(43, _WASMEXP_.asmCompileRun(TestNestedSwitch.toString())); assertEquals(43, _WASMEXP_.asmCompileRun(TestNestedSwitch.toString()));
function TestInitFunctionWithNoGlobals() {
"use asm";
function caller() {
return 51;
}
return {caller};
}
var module = _WASMEXP_.instantiateModuleFromAsm(
TestInitFunctionWithNoGlobals.toString());
module.__init__();
assertEquals(51, module.caller());
function TestExportNameDifferentFromFunctionName() {
"use asm";
function caller() {
return 55;
}
return {alt_caller:caller};
}
var module = _WASMEXP_.instantiateModuleFromAsm(
TestExportNameDifferentFromFunctionName.toString());
module.__init__();
assertEquals(55, module.alt_caller());