Index: src/wasm/asm-wasm-builder.cc |
diff --git a/src/wasm/asm-wasm-builder.cc b/src/wasm/asm-wasm-builder.cc |
index 691cc374694e0773ac4791b7c0b145698c0d9fc7..24cdaa9f29547b75cac468942502d79b0743f40a 100644 |
--- a/src/wasm/asm-wasm-builder.cc |
+++ b/src/wasm/asm-wasm-builder.cc |
@@ -27,7 +27,8 @@ namespace wasm { |
class AsmWasmBuilderImpl : public AstVisitor { |
public: |
- AsmWasmBuilderImpl(Isolate* isolate, Zone* zone, FunctionLiteral* literal) |
+ AsmWasmBuilderImpl(Isolate* isolate, Zone* zone, FunctionLiteral* literal, |
+ Handle<Object> foreign) |
: local_variables_(HashMap::PointersMatch, |
ZoneHashMap::kDefaultHashMapCapacity, |
ZoneAllocationPolicy(zone)), |
@@ -44,6 +45,7 @@ class AsmWasmBuilderImpl : public AstVisitor { |
literal_(literal), |
isolate_(isolate), |
zone_(zone), |
+ foreign_(foreign), |
cache_(TypeCache::Get()), |
breakable_blocks_(zone), |
block_size_(0), |
@@ -559,6 +561,30 @@ class AsmWasmBuilderImpl : public AstVisitor { |
void VisitAssignment(Assignment* expr) { |
bool in_init = false; |
if (!in_function_) { |
+ BinaryOperation* binop = expr->value()->AsBinaryOperation(); |
+ if (binop != nullptr) { |
+ Property* prop = binop->left()->AsProperty(); |
+ DCHECK(prop != nullptr); |
+ LoadInitFunction(); |
+ is_set_op_ = true; |
+ RECURSE(Visit(expr->target())); |
+ DCHECK(!is_set_op_); |
+ if (binop->op() == Token::MUL) { |
+ DCHECK(binop->right()->IsLiteral()); |
+ DCHECK(binop->right()->AsLiteral()->raw_value()->AsNumber() == 1.0); |
+ DCHECK(binop->right()->AsLiteral()->raw_value()->ContainsDot()); |
+ VisitForeignVariable(true, prop); |
+ } else if (binop->op() == Token::BIT_OR) { |
+ DCHECK(binop->right()->IsLiteral()); |
+ DCHECK(binop->right()->AsLiteral()->raw_value()->AsNumber() == 0.0); |
+ DCHECK(!binop->right()->AsLiteral()->raw_value()->ContainsDot()); |
+ VisitForeignVariable(false, prop); |
+ } else { |
+ UNREACHABLE(); |
+ } |
+ UnLoadInitFunction(); |
+ return; |
+ } |
// TODO(bradnelson): Get rid of this. |
if (TypeOf(expr->value()) == kAstStmt) { |
Property* prop = expr->value()->AsProperty(); |
@@ -610,6 +636,55 @@ class AsmWasmBuilderImpl : public AstVisitor { |
void VisitThrow(Throw* expr) { UNREACHABLE(); } |
+ void VisitForeignVariable(bool is_float, Property* expr) { |
+ DCHECK(expr->obj()->AsVariableProxy()); |
+ DCHECK(expr->obj()->AsVariableProxy()->var()->location() == |
+ VariableLocation::PARAMETER); |
+ DCHECK(expr->obj()->AsVariableProxy()->var()->index() == 1); |
+ Literal* key_literal = expr->key()->AsLiteral(); |
+ DCHECK(key_literal != nullptr); |
+ if (!key_literal->value().is_null() && !foreign_.is_null() && |
+ foreign_->IsObject()) { |
+ Handle<Name> name = |
+ i::Object::ToName(isolate_, key_literal->value()).ToHandleChecked(); |
+ MaybeHandle<Object> maybe_value = i::Object::GetProperty(foreign_, name); |
+ if (!maybe_value.is_null()) { |
+ Handle<Object> value = maybe_value.ToHandleChecked(); |
+ if (is_float) { |
+ MaybeHandle<Object> maybe_nvalue = i::Object::ToNumber(value); |
+ if (!maybe_nvalue.is_null()) { |
+ Handle<Object> nvalue = maybe_nvalue.ToHandleChecked(); |
+ if (nvalue->IsNumber()) { |
+ double val = nvalue->Number(); |
+ byte code[] = {WASM_F64(val)}; |
+ current_function_builder_->EmitCode(code, sizeof(code)); |
+ return; |
+ } |
+ } |
+ } else { |
+ MaybeHandle<Object> maybe_nvalue = |
+ i::Object::ToInt32(isolate_, value); |
+ if (!maybe_nvalue.is_null()) { |
+ Handle<Object> nvalue = maybe_nvalue.ToHandleChecked(); |
+ if (nvalue->IsNumber()) { |
+ int32_t val = static_cast<int32_t>(nvalue->Number()); |
+ byte code[] = {WASM_I32(val)}; |
+ current_function_builder_->EmitCode(code, sizeof(code)); |
+ return; |
+ } |
+ } |
+ } |
+ } |
+ } |
+ if (is_float) { |
+ byte code[] = {WASM_F64(std::numeric_limits<double>::quiet_NaN())}; |
+ current_function_builder_->EmitCode(code, sizeof(code)); |
+ } else { |
+ byte code[] = {WASM_I32(0)}; |
+ current_function_builder_->EmitCode(code, sizeof(code)); |
+ } |
+ } |
+ |
void VisitProperty(Property* expr) { |
Expression* obj = expr->obj(); |
DCHECK(obj->bounds().lower == obj->bounds().upper); |
@@ -1173,6 +1248,7 @@ class AsmWasmBuilderImpl : public AstVisitor { |
FunctionLiteral* literal_; |
Isolate* isolate_; |
Zone* zone_; |
+ Handle<Object> foreign_; |
TypeCache const& cache_; |
ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_; |
int block_size_; |
@@ -1188,13 +1264,13 @@ class AsmWasmBuilderImpl : public AstVisitor { |
}; |
AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone, |
- FunctionLiteral* literal) |
- : isolate_(isolate), zone_(zone), literal_(literal) {} |
+ FunctionLiteral* literal, Handle<Object> foreign) |
+ : isolate_(isolate), zone_(zone), literal_(literal), foreign_(foreign) {} |
// 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. |
WasmModuleIndex* AsmWasmBuilder::Run() { |
- AsmWasmBuilderImpl impl(isolate_, zone_, literal_); |
+ AsmWasmBuilderImpl impl(isolate_, zone_, literal_, foreign_); |
impl.Compile(); |
WasmModuleWriter* writer = impl.builder_->Build(zone_); |
return writer->WriteTo(zone_); |