diff options
author | Ben Smith <binjimin@gmail.com> | 2017-08-16 10:12:03 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-16 10:12:03 -0700 |
commit | bc3deb3288252866d9b571cd28c4104b9ffffd56 (patch) | |
tree | d39d5056d954240f541b11f7c3a2d80b7c31d256 /src/binary-reader.cc | |
parent | 3d3920f6d9388c46af6725dabb34d98752958d8d (diff) | |
download | wabt-bc3deb3288252866d9b571cd28c4104b9ffffd56.tar.gz wabt-bc3deb3288252866d9b571cd28c4104b9ffffd56.tar.bz2 wabt-bc3deb3288252866d9b571cd28c4104b9ffffd56.zip |
Add saturating float truncation operators (#573)
Add saturating truncation operators as described here:
https://github.com/webassembly/nontrapping-float-to-int-conversions.
This change also codifies the mechanism for enabling new WebAssembly features
by passing the `Features` object. Opcode now has a `IsEnabled(const Features&)`
member function to query if the opcode is enabled. This means that the
`--future-exceptions` flag has been renamed to `--enable-exceptions` for
consistency. Checking whether the feature is enabled always happens at input;
either WastParser or BinaryReader.
Diffstat (limited to 'src/binary-reader.cc')
-rw-r--r-- | src/binary-reader.cc | 62 |
1 files changed, 43 insertions, 19 deletions
diff --git a/src/binary-reader.cc b/src/binary-reader.cc index 9bdbf153..07feafae 100644 --- a/src/binary-reader.cc +++ b/src/binary-reader.cc @@ -48,10 +48,10 @@ } \ } while (0) -#define ERROR_UNLESS_FUTURE_EXCEPTIONS_OPCODE(opcode) \ - do { \ - if (!options_->allow_future_exceptions) \ - return ReportUnexpectedOpcode(opcode); \ +#define ERROR_UNLESS_OPCODE_ENABLED(opcode) \ + do { \ + if (!opcode.IsEnabled(options_->features)) \ + return ReportUnexpectedOpcode(opcode); \ } while (0) #define CALLBACK0(member) \ @@ -269,17 +269,28 @@ Result BinaryReader::ReportUnexpectedOpcode(Opcode opcode, const char* maybe_space = " "; if (!message) message = maybe_space = ""; - PrintError("unexpected opcode%s%s: %d (0x%x)", - maybe_space, message, opcode.GetCode(), opcode.GetCode()); + if (opcode.HasPrefix()) { + PrintError("unexpected opcode%s%s: %d %d (0x%x 0x%x)", maybe_space, message, + opcode.GetPrefix(), opcode.GetCode(), opcode.GetPrefix(), + opcode.GetCode()); + } else { + PrintError("unexpected opcode%s%s: %d (0x%x)", + maybe_space, message, opcode.GetCode(), opcode.GetCode()); + } return Result::Error; } Result BinaryReader::ReadOpcode(Opcode* out_value, const char* desc) { uint8_t value = 0; - if (Failed(ReadU8(&value, desc))) { - return Result::Error; + CHECK_RESULT(ReadU8(&value, desc)); + + if (Opcode::IsPrefixByte(value)) { + uint32_t code; + CHECK_RESULT(ReadU32Leb128(&code, desc)); + *out_value = Opcode::FromCode(value, code); + } else { + *out_value = Opcode::FromCode(value); } - *out_value = Opcode::FromCode(value); return Result::Ok; } @@ -1009,7 +1020,7 @@ Result BinaryReader::ReadFunctionBody(Offset end_offset) { break; case Opcode::Try: { - ERROR_UNLESS_FUTURE_EXCEPTIONS_OPCODE(opcode); + ERROR_UNLESS_OPCODE_ENABLED(opcode); Type sig_type; CHECK_RESULT(ReadType(&sig_type, "try signature type")); ERROR_UNLESS(is_inline_sig_type(sig_type), @@ -1021,7 +1032,7 @@ Result BinaryReader::ReadFunctionBody(Offset end_offset) { } case Opcode::Catch: { - ERROR_UNLESS_FUTURE_EXCEPTIONS_OPCODE(opcode); + ERROR_UNLESS_OPCODE_ENABLED(opcode); Index index; CHECK_RESULT(ReadIndex(&index, "exception index")); CALLBACK(OnCatchExpr, index); @@ -1030,14 +1041,14 @@ Result BinaryReader::ReadFunctionBody(Offset end_offset) { } case Opcode::CatchAll: { - ERROR_UNLESS_FUTURE_EXCEPTIONS_OPCODE(opcode); + ERROR_UNLESS_OPCODE_ENABLED(opcode); CALLBACK(OnCatchAllExpr); CALLBACK0(OnOpcodeBare); break; } case Opcode::Rethrow: { - ERROR_UNLESS_FUTURE_EXCEPTIONS_OPCODE(opcode); + ERROR_UNLESS_OPCODE_ENABLED(opcode); Index depth; CHECK_RESULT(ReadIndex(&depth, "catch depth")); CALLBACK(OnRethrowExpr, depth); @@ -1046,7 +1057,7 @@ Result BinaryReader::ReadFunctionBody(Offset end_offset) { } case Opcode::Throw: { - ERROR_UNLESS_FUTURE_EXCEPTIONS_OPCODE(opcode); + ERROR_UNLESS_OPCODE_ENABLED(opcode); Index index; CHECK_RESULT(ReadIndex(&index, "exception index")); CALLBACK(OnThrowExpr, index); @@ -1054,6 +1065,19 @@ Result BinaryReader::ReadFunctionBody(Offset end_offset) { break; } + case Opcode::I32TruncSSatF32: + case Opcode::I32TruncUSatF32: + case Opcode::I32TruncSSatF64: + case Opcode::I32TruncUSatF64: + case Opcode::I64TruncSSatF32: + case Opcode::I64TruncUSatF32: + case Opcode::I64TruncSSatF64: + case Opcode::I64TruncUSatF64: + ERROR_UNLESS_OPCODE_ENABLED(opcode); + CALLBACK(OnConvertExpr, opcode); + CALLBACK0(OnOpcodeBare); + break; + default: return ReportUnexpectedOpcode(opcode); } @@ -1291,7 +1315,7 @@ Result BinaryReader::ReadCustomSection(Offset section_size) { CHECK_RESULT(ReadRelocSection(section_size)); } else if (section_name == WABT_BINARY_SECTION_LINKING) { CHECK_RESULT(ReadLinkingSection(section_size)); - } else if (options_->allow_future_exceptions && + } else if (options_->features.exceptions_enabled() && section_name == WABT_BINARY_SECTION_EXCEPTION) { CHECK_RESULT(ReadExceptionSection(section_size)); } else { @@ -1405,8 +1429,8 @@ Result BinaryReader::ReadImportSection(Offset section_size) { } case ExternalKind::Except: { - if (!options_->allow_future_exceptions) - PrintError("invalid import exception kind: exceptions not allowed"); + ERROR_UNLESS(options_->features.exceptions_enabled(), + "invalid import exception kind: exceptions not allowed"); TypeVector sig; CHECK_RESULT(ReadExceptionType(sig)); CALLBACK(OnImport, i, module_name, field_name); @@ -1527,8 +1551,8 @@ Result BinaryReader::ReadExportSection(Offset section_size) { break; case ExternalKind::Except: // Note: Can't check if index valid, exceptions section comes later. - if (!options_->allow_future_exceptions) - PrintError("invalid export exception kind: exceptions not allowed"); + ERROR_UNLESS(options_->features.exceptions_enabled(), + "invalid export exception kind: exceptions not allowed"); break; } |