Translates a given assembly language module into binary form. If a diagnostic is generated, it is not yet marked as being for a text-based input.
| 896 | // If a diagnostic is generated, it is not yet marked as being |
| 897 | // for a text-based input. |
| 898 | spv_result_t spvTextToBinaryInternal(const spvtools::AssemblyGrammar& grammar, |
| 899 | const spvtools::MessageConsumer& consumer, |
| 900 | const spv_text text, |
| 901 | const uint32_t options, |
| 902 | spv_binary* pBinary) { |
| 903 | // The ids in this set will have the same values both in source and binary. |
| 904 | // All other ids will be generated by filling in the gaps. |
| 905 | std::set<uint32_t> ids_to_preserve; |
| 906 | |
| 907 | if (options & SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS) { |
| 908 | // Collect all numeric ids from the source into ids_to_preserve. |
| 909 | const spv_result_t result = |
| 910 | GetNumericIds(grammar, consumer, text, &ids_to_preserve); |
| 911 | if (result != SPV_SUCCESS) return result; |
| 912 | } |
| 913 | |
| 914 | spvtools::AssemblyContext context(text, consumer, std::move(ids_to_preserve)); |
| 915 | |
| 916 | if (!text->str) return context.diagnostic() << "Missing assembly text."; |
| 917 | if (!pBinary) return SPV_ERROR_INVALID_POINTER; |
| 918 | |
| 919 | std::vector<spv_instruction_t> instructions; |
| 920 | |
| 921 | // Skip past whitespace and comments. |
| 922 | context.advance(); |
| 923 | |
| 924 | while (context.hasText()) { |
| 925 | instructions.push_back({}); |
| 926 | spv_instruction_t& inst = instructions.back(); |
| 927 | |
| 928 | if (auto error = spvTextEncodeOpcode(grammar, &context, &inst)) { |
| 929 | return error; |
| 930 | } |
| 931 | |
| 932 | if (context.advance()) break; |
| 933 | } |
| 934 | |
| 935 | size_t totalSize = SPV_INDEX_INSTRUCTION; |
| 936 | for (auto& inst : instructions) { |
| 937 | totalSize += inst.words.size(); |
| 938 | } |
| 939 | |
| 940 | uint32_t* data = new uint32_t[totalSize]; |
| 941 | if (!data) return SPV_ERROR_OUT_OF_MEMORY; |
| 942 | uint64_t currentIndex = SPV_INDEX_INSTRUCTION; |
| 943 | for (auto& inst : instructions) { |
| 944 | memcpy(data + currentIndex, inst.words.data(), |
| 945 | sizeof(uint32_t) * inst.words.size()); |
| 946 | currentIndex += inst.words.size(); |
| 947 | } |
| 948 | |
| 949 | if (auto error = SetHeader(grammar.target_env(), context.getBound(), data)) |
| 950 | return error; |
| 951 | |
| 952 | spv_binary binary = new spv_binary_t(); |
| 953 | if (!binary) { |
| 954 | delete[] data; |
| 955 | return SPV_ERROR_OUT_OF_MEMORY; |
no test coverage detected