1fd4e5da5Sopenharmony_ci// Copyright (c) 2015-2016 The Khronos Group Inc. 2fd4e5da5Sopenharmony_ci// 3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License. 5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at 6fd4e5da5Sopenharmony_ci// 7fd4e5da5Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 8fd4e5da5Sopenharmony_ci// 9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and 13fd4e5da5Sopenharmony_ci// limitations under the License. 14fd4e5da5Sopenharmony_ci 15fd4e5da5Sopenharmony_ci// Assembler tests for literal numbers and literal strings. 16fd4e5da5Sopenharmony_ci 17fd4e5da5Sopenharmony_ci#include <string> 18fd4e5da5Sopenharmony_ci 19fd4e5da5Sopenharmony_ci#include "test/test_fixture.h" 20fd4e5da5Sopenharmony_ci 21fd4e5da5Sopenharmony_cinamespace spvtools { 22fd4e5da5Sopenharmony_cinamespace { 23fd4e5da5Sopenharmony_ci 24fd4e5da5Sopenharmony_ciusing spvtest::TextToBinaryTest; 25fd4e5da5Sopenharmony_ci 26fd4e5da5Sopenharmony_ciTEST_F(TextToBinaryTest, LiteralStringInPlaceOfLiteralNumber) { 27fd4e5da5Sopenharmony_ci EXPECT_EQ( 28fd4e5da5Sopenharmony_ci R"(Invalid unsigned integer literal: "I shouldn't be a string")", 29fd4e5da5Sopenharmony_ci CompileFailure(R"(OpSource GLSL "I shouldn't be a string")")); 30fd4e5da5Sopenharmony_ci} 31fd4e5da5Sopenharmony_ci 32fd4e5da5Sopenharmony_ciTEST_F(TextToBinaryTest, GarbageInPlaceOfLiteralString) { 33fd4e5da5Sopenharmony_ci EXPECT_EQ("Invalid literal string 'nice-source-code'.", 34fd4e5da5Sopenharmony_ci CompileFailure("OpSourceExtension nice-source-code")); 35fd4e5da5Sopenharmony_ci} 36fd4e5da5Sopenharmony_ci 37fd4e5da5Sopenharmony_ciTEST_F(TextToBinaryTest, LiteralNumberInPlaceOfLiteralString) { 38fd4e5da5Sopenharmony_ci EXPECT_EQ("Expected literal string, found literal number '1000'.", 39fd4e5da5Sopenharmony_ci CompileFailure("OpSourceExtension 1000")); 40fd4e5da5Sopenharmony_ci} 41fd4e5da5Sopenharmony_ci 42fd4e5da5Sopenharmony_ciTEST_F(TextToBinaryTest, LiteralFloatInPlaceOfLiteralInteger) { 43fd4e5da5Sopenharmony_ci EXPECT_EQ("Invalid unsigned integer literal: 10.5", 44fd4e5da5Sopenharmony_ci CompileFailure("OpSource GLSL 10.5")); 45fd4e5da5Sopenharmony_ci 46fd4e5da5Sopenharmony_ci EXPECT_EQ("Invalid unsigned integer literal: 0.2", 47fd4e5da5Sopenharmony_ci CompileFailure(R"(OpMemberName %type 0.2 "member0.2")")); 48fd4e5da5Sopenharmony_ci 49fd4e5da5Sopenharmony_ci EXPECT_EQ("Invalid unsigned integer literal: 32.42", 50fd4e5da5Sopenharmony_ci CompileFailure("%int = OpTypeInt 32.42 0")); 51fd4e5da5Sopenharmony_ci 52fd4e5da5Sopenharmony_ci EXPECT_EQ("Invalid unsigned integer literal: 4.5", 53fd4e5da5Sopenharmony_ci CompileFailure("%mat = OpTypeMatrix %vec 4.5")); 54fd4e5da5Sopenharmony_ci 55fd4e5da5Sopenharmony_ci EXPECT_EQ("Invalid unsigned integer literal: 1.5", 56fd4e5da5Sopenharmony_ci CompileFailure("OpExecutionMode %main LocalSize 1.5 1.6 1.7")); 57fd4e5da5Sopenharmony_ci 58fd4e5da5Sopenharmony_ci EXPECT_EQ("Invalid unsigned integer literal: 0.123", 59fd4e5da5Sopenharmony_ci CompileFailure("%i32 = OpTypeInt 32 1\n" 60fd4e5da5Sopenharmony_ci "%c = OpConstant %i32 0.123")); 61fd4e5da5Sopenharmony_ci} 62fd4e5da5Sopenharmony_ci 63fd4e5da5Sopenharmony_ciTEST_F(TextToBinaryTest, LiteralInt64) { 64fd4e5da5Sopenharmony_ci const std::string code = 65fd4e5da5Sopenharmony_ci "%1 = OpTypeInt 64 0\n%2 = OpConstant %1 123456789021\n"; 66fd4e5da5Sopenharmony_ci EXPECT_EQ(code, EncodeAndDecodeSuccessfully(code)); 67fd4e5da5Sopenharmony_ci} 68fd4e5da5Sopenharmony_ci 69fd4e5da5Sopenharmony_ciTEST_F(TextToBinaryTest, LiteralDouble) { 70fd4e5da5Sopenharmony_ci const std::string code = 71fd4e5da5Sopenharmony_ci "%1 = OpTypeFloat 64\n%2 = OpSpecConstant %1 3.14159265358979\n"; 72fd4e5da5Sopenharmony_ci EXPECT_EQ(code, EncodeAndDecodeSuccessfully(code)); 73fd4e5da5Sopenharmony_ci} 74fd4e5da5Sopenharmony_ci 75fd4e5da5Sopenharmony_ciTEST_F(TextToBinaryTest, LiteralStringASCIILong) { 76fd4e5da5Sopenharmony_ci // SPIR-V allows strings up to 65535 characters. 77fd4e5da5Sopenharmony_ci // Test the simple case of UTF-8 code points corresponding 78fd4e5da5Sopenharmony_ci // to ASCII characters. 79fd4e5da5Sopenharmony_ci EXPECT_EQ(65535, SPV_LIMIT_LITERAL_STRING_UTF8_CHARS_MAX); 80fd4e5da5Sopenharmony_ci const std::string code = 81fd4e5da5Sopenharmony_ci "OpSourceExtension \"" + 82fd4e5da5Sopenharmony_ci std::string(SPV_LIMIT_LITERAL_STRING_UTF8_CHARS_MAX, 'o') + "\"\n"; 83fd4e5da5Sopenharmony_ci EXPECT_EQ(code, EncodeAndDecodeSuccessfully(code)); 84fd4e5da5Sopenharmony_ci} 85fd4e5da5Sopenharmony_ci 86fd4e5da5Sopenharmony_ciTEST_F(TextToBinaryTest, LiteralStringUTF8LongEncodings) { 87fd4e5da5Sopenharmony_ci // SPIR-V allows strings up to 65535 characters. 88fd4e5da5Sopenharmony_ci // Test the case of many Unicode characters, each of which has 89fd4e5da5Sopenharmony_ci // a 4-byte UTF-8 encoding. 90fd4e5da5Sopenharmony_ci 91fd4e5da5Sopenharmony_ci // An instruction is at most 65535 words long. The first one 92fd4e5da5Sopenharmony_ci // contains the wordcount and opcode. So the worst case number of 93fd4e5da5Sopenharmony_ci // 4-byte UTF-8 characters is 65533, since we also need to 94fd4e5da5Sopenharmony_ci // store a terminating null character. 95fd4e5da5Sopenharmony_ci 96fd4e5da5Sopenharmony_ci // This string fits exactly into 65534 words. 97fd4e5da5Sopenharmony_ci const std::string good_string = 98fd4e5da5Sopenharmony_ci spvtest::MakeLongUTF8String(65533) 99fd4e5da5Sopenharmony_ci // The following single character has a 3 byte encoding, 100fd4e5da5Sopenharmony_ci // which fits snugly against the terminating null. 101fd4e5da5Sopenharmony_ci + "\xe8\x80\x80"; 102fd4e5da5Sopenharmony_ci 103fd4e5da5Sopenharmony_ci // These strings will overflow any instruction with 0 or 1 other 104fd4e5da5Sopenharmony_ci // arguments, respectively. 105fd4e5da5Sopenharmony_ci const std::string bad_0_arg_string = spvtest::MakeLongUTF8String(65534); 106fd4e5da5Sopenharmony_ci const std::string bad_1_arg_string = spvtest::MakeLongUTF8String(65533); 107fd4e5da5Sopenharmony_ci 108fd4e5da5Sopenharmony_ci const std::string good_code = "OpSourceExtension \"" + good_string + "\"\n"; 109fd4e5da5Sopenharmony_ci EXPECT_EQ(good_code, EncodeAndDecodeSuccessfully(good_code)); 110fd4e5da5Sopenharmony_ci 111fd4e5da5Sopenharmony_ci // Prove that it works on more than one instruction. 112fd4e5da5Sopenharmony_ci const std::string good_code_2 = "OpSourceContinued \"" + good_string + "\"\n"; 113fd4e5da5Sopenharmony_ci EXPECT_EQ(good_code, EncodeAndDecodeSuccessfully(good_code)); 114fd4e5da5Sopenharmony_ci 115fd4e5da5Sopenharmony_ci // Failure cases. 116fd4e5da5Sopenharmony_ci EXPECT_EQ("Instruction too long: more than 65535 words.", 117fd4e5da5Sopenharmony_ci CompileFailure("OpSourceExtension \"" + bad_0_arg_string + "\"\n")); 118fd4e5da5Sopenharmony_ci EXPECT_EQ("Instruction too long: more than 65535 words.", 119fd4e5da5Sopenharmony_ci CompileFailure("OpSourceContinued \"" + bad_0_arg_string + "\"\n")); 120fd4e5da5Sopenharmony_ci EXPECT_EQ("Instruction too long: more than 65535 words.", 121fd4e5da5Sopenharmony_ci CompileFailure("OpName %target \"" + bad_1_arg_string + "\"\n")); 122fd4e5da5Sopenharmony_ci} 123fd4e5da5Sopenharmony_ci 124fd4e5da5Sopenharmony_ci} // namespace 125fd4e5da5Sopenharmony_ci} // namespace spvtools 126