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

Unified Diff: src/wasm/asm-wasm-builder.cc

Issue 1729833002: Add wasm internal opcodes for asm.js stdlib functions we're missing. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: merge Created 4 years, 10 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
« no previous file with comments | « src/typing-asm.h ('k') | test/mjsunit/wasm/asm-wasm.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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();
« no previous file with comments | « src/typing-asm.h ('k') | test/mjsunit/wasm/asm-wasm.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698