Index: src/wasm/asm-wasm-builder.cc |
diff --git a/src/wasm/asm-wasm-builder.cc b/src/wasm/asm-wasm-builder.cc |
index abb69d5678565b5ebe91efa18f98c1dc1365e672..4e7549327128f92591662bdd6dddd980528f4e59 100644 |
--- a/src/wasm/asm-wasm-builder.cc |
+++ b/src/wasm/asm-wasm-builder.cc |
@@ -75,8 +75,88 @@ class AsmWasmBuilderImpl : public AstVisitor { |
current_function_builder_ = nullptr; |
} |
+ void AddStdlibImport(const char* name, int kind, int args) { |
+ uint16_t index = builder_->AddFunction(); |
+ std_function_index_[kind] = index; |
+ WasmFunctionBuilder* b = builder_->FunctionAt(index); |
+ b->External(1); |
+ b->SetName(reinterpret_cast<const unsigned char*>(name), |
+ static_cast<int>(strlen(name))); |
+ b->ReturnType(kAstF64); |
+ for (int i = 0; i < args; ++i) { |
+ b->AddParam(kAstF64); |
+ } |
+ } |
+ |
+ void InitializeStdlibFunctions() { |
+ for (int i = 0; i < AsmTyper::kStdlibMax; ++i) { |
+ std_function_index_[i] = -1; |
+ } |
+ } |
+ |
+ void AddStdlibFunction(int kind) { |
+ const char* name = nullptr; |
+ int args = 0; |
+ switch (kind) { |
+ case AsmTyper::kMathAcos: |
+ name = "_acos"; |
+ args = 1; |
+ break; |
+ case AsmTyper::kMathAsin: |
+ name = "_asin"; |
+ args = 1; |
+ break; |
+ case AsmTyper::kMathAtan: |
+ name = "_atan"; |
+ args = 1; |
+ break; |
+ case AsmTyper::kMathCos: |
+ name = "_cos"; |
+ args = 1; |
+ break; |
+ case AsmTyper::kMathSin: |
+ name = "_sin"; |
+ args = 1; |
+ break; |
+ case AsmTyper::kMathTan: |
+ name = "_tan"; |
+ args = 1; |
+ break; |
+ case AsmTyper::kMathExp: |
+ name = "_exp"; |
+ args = 1; |
+ break; |
+ case AsmTyper::kMathLog: |
+ name = "_log"; |
+ args = 1; |
+ break; |
+ case AsmTyper::kMathAtan2: |
+ name = "_atan2"; |
+ args = 2; |
+ break; |
+ case AsmTyper::kMathPow: |
+ name = "_pow"; |
+ args = 2; |
+ break; |
+ } |
+ DCHECK(name != nullptr); |
+ AddStdlibImport(name, kind, args); |
+ } |
+ |
+ void EmitStdlibCall(int kind) { |
+ if (std_function_index_[kind] < 0) { |
+ AddStdlibFunction(kind); |
+ } |
+ current_function_builder_->Emit(kExprCallFunction); |
+ std::vector<uint8_t> index_arr = |
+ UnsignedLEB128From(std_function_index_[kind]); |
+ current_function_builder_->EmitCode( |
+ &index_arr[0], static_cast<uint32_t>(index_arr.size())); |
+ } |
+ |
void Compile() { |
InitializeInitFunction(); |
+ InitializeStdlibFunctions(); |
RECURSE(VisitFunctionLiteral(literal_)); |
} |
@@ -842,36 +922,36 @@ class AsmWasmBuilderImpl : public AstVisitor { |
return false; |
} |
case AsmTyper::kMathAcos: { |
- UNREACHABLE(); |
- break; // TODO(bradnelson): Implement as external. |
+ EmitStdlibCall(AsmTyper::kMathAcos); |
+ break; |
} |
case AsmTyper::kMathAsin: { |
- UNREACHABLE(); |
- break; // TODO(bradnelson): Implement as external. |
+ EmitStdlibCall(AsmTyper::kMathAsin); |
+ break; |
} |
case AsmTyper::kMathAtan: { |
- UNREACHABLE(); |
- break; // TODO(bradnelson): Implement as external. |
+ EmitStdlibCall(AsmTyper::kMathAtan); |
+ break; |
} |
case AsmTyper::kMathCos: { |
- UNREACHABLE(); |
- break; // TODO(bradnelson): Implement as external. |
+ EmitStdlibCall(AsmTyper::kMathCos); |
+ break; |
} |
case AsmTyper::kMathSin: { |
- UNREACHABLE(); |
- break; // TODO(bradnelson): Implement as external. |
+ EmitStdlibCall(AsmTyper::kMathSin); |
+ break; |
} |
case AsmTyper::kMathTan: { |
- UNREACHABLE(); |
- break; // TODO(bradnelson): Implement as external. |
+ EmitStdlibCall(AsmTyper::kMathTan); |
+ break; |
} |
case AsmTyper::kMathExp: { |
- UNREACHABLE(); |
- break; // TODO(bradnelson): Implement as external. |
+ EmitStdlibCall(AsmTyper::kMathExp); |
+ break; |
} |
case AsmTyper::kMathLog: { |
- UNREACHABLE(); |
- break; // TODO(bradnelson): Implement as external. |
+ EmitStdlibCall(AsmTyper::kMathLog); |
+ break; |
} |
case AsmTyper::kMathCeil: { |
if (call_type == kAstF32) { |
@@ -904,8 +984,17 @@ class AsmWasmBuilderImpl : public AstVisitor { |
break; |
} |
case AsmTyper::kMathAbs: { |
titzer
2016/02/24 17:54:11
We're going to need some more extensive tests for
bradn
2016/02/24 18:07:29
Yeah this one is goofy, Math.abs is supposed to ha
|
- // TODO(bradnelson): Handle signed. |
- if (call_type == kAstF32) { |
+ // TODO(bradnelson): Should this be cast to float? |
+ if (call_type == kAstI32) { |
+ current_function_builder_->Emit(kExprIfElse); |
+ current_function_builder_->Emit(kExprI32LtS); |
+ Visit(args->at(0)); |
+ byte code[] = {WASM_I32(0)}; |
titzer
2016/02/24 17:54:11
WASM_I8
bradn
2016/02/24 18:07:29
Done.
|
+ current_function_builder_->EmitCode(code, sizeof(code)); |
+ current_function_builder_->Emit(kExprI32Sub); |
+ current_function_builder_->EmitCode(code, sizeof(code)); |
+ Visit(args->at(0)); |
+ } else if (call_type == kAstF32) { |
current_function_builder_->Emit(kExprF32Abs); |
} else if (call_type == kAstF64) { |
current_function_builder_->Emit(kExprF64Abs); |
@@ -915,9 +1004,13 @@ class AsmWasmBuilderImpl : public AstVisitor { |
break; |
} |
case AsmTyper::kMathMin: { |
- // TODO(bradnelson): Handle signed. |
// TODO(bradnelson): Change wasm to match Math.min in asm.js mode. |
- if (call_type == kAstF32) { |
+ if (call_type == kAstI32) { |
+ current_function_builder_->Emit(kExprIfElse); |
bradn
2016/02/24 18:07:29
Min and max have the same -(1<<31) issue it seems
|
+ current_function_builder_->Emit(kExprI32LeS); |
+ Visit(args->at(0)); |
+ Visit(args->at(1)); |
+ } else if (call_type == kAstF32) { |
current_function_builder_->Emit(kExprF32Min); |
} else if (call_type == kAstF64) { |
current_function_builder_->Emit(kExprF64Min); |
@@ -927,9 +1020,13 @@ class AsmWasmBuilderImpl : public AstVisitor { |
break; |
} |
case AsmTyper::kMathMax: { |
- // TODO(bradnelson): Handle signed. |
// TODO(bradnelson): Change wasm to match Math.max in asm.js mode. |
- if (call_type == kAstF32) { |
+ if (call_type == kAstI32) { |
+ current_function_builder_->Emit(kExprIfElse); |
+ current_function_builder_->Emit(kExprI32GtS); |
+ Visit(args->at(0)); |
+ Visit(args->at(1)); |
+ } else if (call_type == kAstF32) { |
current_function_builder_->Emit(kExprF32Max); |
} else if (call_type == kAstF64) { |
current_function_builder_->Emit(kExprF64Max); |
@@ -939,12 +1036,12 @@ class AsmWasmBuilderImpl : public AstVisitor { |
break; |
} |
case AsmTyper::kMathAtan2: { |
- UNREACHABLE(); |
- break; // TODO(bradnelson): Implement as external. |
+ EmitStdlibCall(AsmTyper::kMathAtan2); |
+ break; |
} |
case AsmTyper::kMathPow: { |
- UNREACHABLE(); |
- break; // TODO(bradnelson): Implement as external. |
+ EmitStdlibCall(AsmTyper::kMathPow); |
+ break; |
} |
case AsmTyper::kMathImul: { |
current_function_builder_->Emit(kExprI32Mul); |
@@ -1487,6 +1584,7 @@ class AsmWasmBuilderImpl : public AstVisitor { |
uint32_t next_table_index_; |
ZoneHashMap function_tables_; |
ImportedFunctionTable imported_function_table_; |
+ int std_function_index_[AsmTyper::kStdlibMax]; |
DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); |