| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/signature.h" | 5 #include "src/signature.h" |
| 6 | 6 |
| 7 #include "src/bit-vector.h" | 7 #include "src/bit-vector.h" |
| 8 #include "src/flags.h" | 8 #include "src/flags.h" |
| 9 #include "src/handles.h" | 9 #include "src/handles.h" |
| 10 #include "src/zone/zone-containers.h" | 10 #include "src/zone/zone-containers.h" |
| 11 | 11 |
| 12 #include "src/wasm/ast-decoder.h" | |
| 13 #include "src/wasm/decoder.h" | 12 #include "src/wasm/decoder.h" |
| 13 #include "src/wasm/function-body-decoder.h" |
| 14 #include "src/wasm/wasm-module.h" | 14 #include "src/wasm/wasm-module.h" |
| 15 #include "src/wasm/wasm-opcodes.h" | 15 #include "src/wasm/wasm-opcodes.h" |
| 16 | 16 |
| 17 #include "src/ostreams.h" | 17 #include "src/ostreams.h" |
| 18 | 18 |
| 19 #include "src/compiler/wasm-compiler.h" | 19 #include "src/compiler/wasm-compiler.h" |
| 20 | 20 |
| 21 namespace v8 { | 21 namespace v8 { |
| 22 namespace internal { | 22 namespace internal { |
| 23 namespace wasm { | 23 namespace wasm { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 }; | 94 }; |
| 95 | 95 |
| 96 static Value* NO_VALUE = nullptr; | 96 static Value* NO_VALUE = nullptr; |
| 97 | 97 |
| 98 enum ControlKind { kControlIf, kControlBlock, kControlLoop, kControlTry }; | 98 enum ControlKind { kControlIf, kControlBlock, kControlLoop, kControlTry }; |
| 99 | 99 |
| 100 // An entry on the control stack (i.e. if, block, loop). | 100 // An entry on the control stack (i.e. if, block, loop). |
| 101 struct Control { | 101 struct Control { |
| 102 const byte* pc; | 102 const byte* pc; |
| 103 ControlKind kind; | 103 ControlKind kind; |
| 104 int stack_depth; // stack height at the beginning of the construct. | 104 int stack_depth; // stack height at the beginning of the construct. |
| 105 SsaEnv* end_env; // end environment for the construct. | 105 SsaEnv* end_env; // end environment for the construct. |
| 106 SsaEnv* false_env; // false environment (only for if). | 106 SsaEnv* false_env; // false environment (only for if). |
| 107 TryInfo* try_info; // Information used for compiling try statements. | 107 TryInfo* try_info; // Information used for compiling try statements. |
| 108 int32_t previous_catch; // The previous Control (on the stack) with a catch. | 108 int32_t previous_catch; // The previous Control (on the stack) with a catch. |
| 109 | 109 |
| 110 // Values merged into the end of this control construct. | 110 // Values merged into the end of this control construct. |
| 111 MergeValues merge; | 111 MergeValues merge; |
| 112 | 112 |
| 113 inline bool is_if() const { return kind == kControlIf; } | 113 inline bool is_if() const { return kind == kControlIf; } |
| 114 inline bool is_block() const { return kind == kControlBlock; } | 114 inline bool is_block() const { return kind == kControlBlock; } |
| 115 inline bool is_loop() const { return kind == kControlLoop; } | 115 inline bool is_loop() const { return kind == kControlLoop; } |
| 116 inline bool is_try() const { return kind == kControlTry; } | 116 inline bool is_try() const { return kind == kControlTry; } |
| 117 | 117 |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 local_type_vec_(zone), | 375 local_type_vec_(zone), |
| 376 stack_(zone), | 376 stack_(zone), |
| 377 control_(zone), | 377 control_(zone), |
| 378 last_end_found_(false), | 378 last_end_found_(false), |
| 379 current_catch_(kNullCatch) { | 379 current_catch_(kNullCatch) { |
| 380 local_types_ = &local_type_vec_; | 380 local_types_ = &local_type_vec_; |
| 381 } | 381 } |
| 382 | 382 |
| 383 bool Decode() { | 383 bool Decode() { |
| 384 if (FLAG_wasm_code_fuzzer_gen_test) { | 384 if (FLAG_wasm_code_fuzzer_gen_test) { |
| 385 PrintAstForDebugging(start_, end_); | 385 PrintWasmCodeForDebugging(start_, end_); |
| 386 } | 386 } |
| 387 base::ElapsedTimer decode_timer; | 387 base::ElapsedTimer decode_timer; |
| 388 if (FLAG_trace_wasm_decode_time) { | 388 if (FLAG_trace_wasm_decode_time) { |
| 389 decode_timer.Start(); | 389 decode_timer.Start(); |
| 390 } | 390 } |
| 391 stack_.clear(); | 391 stack_.clear(); |
| 392 control_.clear(); | 392 control_.clear(); |
| 393 | 393 |
| 394 if (end_ < pc_) { | 394 if (end_ < pc_) { |
| 395 error("function body end < start"); | 395 error("function body end < start"); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 | 455 |
| 456 return true; | 456 return true; |
| 457 } | 457 } |
| 458 | 458 |
| 459 bool TraceFailed() { | 459 bool TraceFailed() { |
| 460 TRACE("wasm-error module+%-6d func+%d: %s\n\n", baserel(error_pc_), | 460 TRACE("wasm-error module+%-6d func+%d: %s\n\n", baserel(error_pc_), |
| 461 startrel(error_pc_), error_msg_.get()); | 461 startrel(error_pc_), error_msg_.get()); |
| 462 return false; | 462 return false; |
| 463 } | 463 } |
| 464 | 464 |
| 465 bool DecodeLocalDecls(AstLocalDecls& decls) { | 465 bool DecodeLocalDecls(BodyLocalDecls& decls) { |
| 466 DecodeLocalDecls(); | 466 DecodeLocalDecls(); |
| 467 if (failed()) return false; | 467 if (failed()) return false; |
| 468 decls.decls_encoded_size = pc_offset(); | 468 decls.decls_encoded_size = pc_offset(); |
| 469 decls.local_types.reserve(local_type_vec_.size()); | 469 decls.local_types.reserve(local_type_vec_.size()); |
| 470 for (size_t pos = 0; pos < local_type_vec_.size();) { | 470 for (size_t pos = 0; pos < local_type_vec_.size();) { |
| 471 uint32_t count = 0; | 471 uint32_t count = 0; |
| 472 LocalType type = local_type_vec_[pos]; | 472 LocalType type = local_type_vec_[pos]; |
| 473 while (pos < local_type_vec_.size() && local_type_vec_[pos] == type) { | 473 while (pos < local_type_vec_.size() && local_type_vec_[pos] == type) { |
| 474 pos++; | 474 pos++; |
| 475 count++; | 475 count++; |
| (...skipping 1406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1882 } | 1882 } |
| 1883 default: | 1883 default: |
| 1884 UNREACHABLE(); | 1884 UNREACHABLE(); |
| 1885 node = nullptr; | 1885 node = nullptr; |
| 1886 break; | 1886 break; |
| 1887 } | 1887 } |
| 1888 Push(GetReturnType(sig), node); | 1888 Push(GetReturnType(sig), node); |
| 1889 } | 1889 } |
| 1890 }; | 1890 }; |
| 1891 | 1891 |
| 1892 bool DecodeLocalDecls(AstLocalDecls& decls, const byte* start, | 1892 bool DecodeLocalDecls(BodyLocalDecls& decls, const byte* start, |
| 1893 const byte* end) { | 1893 const byte* end) { |
| 1894 AccountingAllocator allocator; | 1894 AccountingAllocator allocator; |
| 1895 Zone tmp(&allocator, ZONE_NAME); | 1895 Zone tmp(&allocator, ZONE_NAME); |
| 1896 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; | 1896 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; |
| 1897 WasmFullDecoder decoder(&tmp, nullptr, body); | 1897 WasmFullDecoder decoder(&tmp, nullptr, body); |
| 1898 return decoder.DecodeLocalDecls(decls); | 1898 return decoder.DecodeLocalDecls(decls); |
| 1899 } | 1899 } |
| 1900 | 1900 |
| 1901 BytecodeIterator::BytecodeIterator(const byte* start, const byte* end, | 1901 BytecodeIterator::BytecodeIterator(const byte* start, const byte* end, |
| 1902 AstLocalDecls* decls) | 1902 BodyLocalDecls* decls) |
| 1903 : Decoder(start, end) { | 1903 : Decoder(start, end) { |
| 1904 if (decls != nullptr) { | 1904 if (decls != nullptr) { |
| 1905 if (DecodeLocalDecls(*decls, start, end)) { | 1905 if (DecodeLocalDecls(*decls, start, end)) { |
| 1906 pc_ += decls->decls_encoded_size; | 1906 pc_ += decls->decls_encoded_size; |
| 1907 if (pc_ > end_) pc_ = end_; | 1907 if (pc_ > end_) pc_ = end_; |
| 1908 } | 1908 } |
| 1909 } | 1909 } |
| 1910 } | 1910 } |
| 1911 | 1911 |
| 1912 DecodeResult VerifyWasmCode(AccountingAllocator* allocator, | 1912 DecodeResult VerifyWasmCode(AccountingAllocator* allocator, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1923 WasmFullDecoder decoder(&zone, builder, body); | 1923 WasmFullDecoder decoder(&zone, builder, body); |
| 1924 decoder.Decode(); | 1924 decoder.Decode(); |
| 1925 return decoder.toResult<DecodeStruct*>(nullptr); | 1925 return decoder.toResult<DecodeStruct*>(nullptr); |
| 1926 } | 1926 } |
| 1927 | 1927 |
| 1928 unsigned OpcodeLength(const byte* pc, const byte* end) { | 1928 unsigned OpcodeLength(const byte* pc, const byte* end) { |
| 1929 WasmDecoder decoder(nullptr, nullptr, pc, end); | 1929 WasmDecoder decoder(nullptr, nullptr, pc, end); |
| 1930 return decoder.OpcodeLength(pc); | 1930 return decoder.OpcodeLength(pc); |
| 1931 } | 1931 } |
| 1932 | 1932 |
| 1933 void PrintAstForDebugging(const byte* start, const byte* end) { | 1933 void PrintWasmCodeForDebugging(const byte* start, const byte* end) { |
| 1934 AccountingAllocator allocator; | 1934 AccountingAllocator allocator; |
| 1935 OFStream os(stdout); | 1935 OFStream os(stdout); |
| 1936 PrintAst(&allocator, FunctionBodyForTesting(start, end), os, nullptr); | 1936 PrintWasmCode(&allocator, FunctionBodyForTesting(start, end), os, nullptr); |
| 1937 } | 1937 } |
| 1938 | 1938 |
| 1939 bool PrintAst(AccountingAllocator* allocator, const FunctionBody& body, | 1939 bool PrintWasmCode(AccountingAllocator* allocator, const FunctionBody& body, |
| 1940 std::ostream& os, | 1940 std::ostream& os, |
| 1941 std::vector<std::tuple<uint32_t, int, int>>* offset_table) { | 1941 std::vector<std::tuple<uint32_t, int, int>>* offset_table) { |
| 1942 Zone zone(allocator, ZONE_NAME); | 1942 Zone zone(allocator, ZONE_NAME); |
| 1943 WasmFullDecoder decoder(&zone, nullptr, body); | 1943 WasmFullDecoder decoder(&zone, nullptr, body); |
| 1944 int line_nr = 0; | 1944 int line_nr = 0; |
| 1945 | 1945 |
| 1946 // Print the function signature. | 1946 // Print the function signature. |
| 1947 if (body.sig) { | 1947 if (body.sig) { |
| 1948 os << "// signature: " << *body.sig << std::endl; | 1948 os << "// signature: " << *body.sig << std::endl; |
| 1949 ++line_nr; | 1949 ++line_nr; |
| 1950 } | 1950 } |
| 1951 | 1951 |
| 1952 // Print the local declarations. | 1952 // Print the local declarations. |
| 1953 AstLocalDecls decls(&zone); | 1953 BodyLocalDecls decls(&zone); |
| 1954 BytecodeIterator i(body.start, body.end, &decls); | 1954 BytecodeIterator i(body.start, body.end, &decls); |
| 1955 if (body.start != i.pc() && !FLAG_wasm_code_fuzzer_gen_test) { | 1955 if (body.start != i.pc() && !FLAG_wasm_code_fuzzer_gen_test) { |
| 1956 os << "// locals: "; | 1956 os << "// locals: "; |
| 1957 for (auto p : decls.local_types) { | 1957 for (auto p : decls.local_types) { |
| 1958 LocalType type = p.first; | 1958 LocalType type = p.first; |
| 1959 uint32_t count = p.second; | 1959 uint32_t count = p.second; |
| 1960 os << " " << count << " " << WasmOpcodes::TypeName(type); | 1960 os << " " << count << " " << WasmOpcodes::TypeName(type); |
| 1961 } | 1961 } |
| 1962 os << std::endl; | 1962 os << std::endl; |
| 1963 ++line_nr; | 1963 ++line_nr; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2041 case kExprCallFunction: { | 2041 case kExprCallFunction: { |
| 2042 CallFunctionOperand operand(&i, i.pc()); | 2042 CallFunctionOperand operand(&i, i.pc()); |
| 2043 os << " // function #" << operand.index; | 2043 os << " // function #" << operand.index; |
| 2044 if (decoder.Complete(i.pc(), operand)) { | 2044 if (decoder.Complete(i.pc(), operand)) { |
| 2045 os << ": " << *operand.sig; | 2045 os << ": " << *operand.sig; |
| 2046 } | 2046 } |
| 2047 break; | 2047 break; |
| 2048 } | 2048 } |
| 2049 default: | 2049 default: |
| 2050 break; | 2050 break; |
| 2051 } | 2051 } |
| 2052 os << std::endl; | 2052 os << std::endl; |
| 2053 ++line_nr; | 2053 ++line_nr; |
| 2054 } | 2054 } |
| 2055 | 2055 |
| 2056 return decoder.ok(); | 2056 return decoder.ok(); |
| 2057 } | 2057 } |
| 2058 | 2058 |
| 2059 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, | 2059 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, |
| 2060 const byte* start, const byte* end) { | 2060 const byte* start, const byte* end) { |
| 2061 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; | 2061 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; |
| 2062 WasmFullDecoder decoder(zone, nullptr, body); | 2062 WasmFullDecoder decoder(zone, nullptr, body); |
| 2063 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); | 2063 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); |
| 2064 } | 2064 } |
| 2065 | 2065 |
| 2066 } // namespace wasm | 2066 } // namespace wasm |
| 2067 } // namespace internal | 2067 } // namespace internal |
| 2068 } // namespace v8 | 2068 } // namespace v8 |
| OLD | NEW |