| /* |
| * Copyright 2017 WebAssembly Community Group participants |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| // |
| // Abstracts reading and writing, supporting both text and binary |
| // depending on the suffix. |
| // |
| // When the suffix is unclear, writing defaults to text (this |
| // allows odd suffixes, which we use in the test suite), while |
| // reading will check the magic number and default to text if not |
| // binary. |
| // |
| |
| #include "wasm-io.h" |
| #include "wasm-s-parser.h" |
| #include "wasm-binary.h" |
| #include "support/file.h" |
| |
| namespace wasm { |
| |
| void ModuleReader::readText(std::string filename, Module& wasm) { |
| if (debug) std::cerr << "reading text from " << filename << "\n"; |
| auto input(read_file<std::string>(filename, Flags::Text, debug ? Flags::Debug : Flags::Release)); |
| SExpressionParser parser(const_cast<char*>(input.c_str())); |
| Element& root = *parser.root; |
| SExpressionWasmBuilder builder(wasm, *root[0]); |
| } |
| |
| void ModuleReader::readBinary(std::string filename, Module& wasm) { |
| if (debug) std::cerr << "reading binary from " << filename << "\n"; |
| auto input(read_file<std::vector<char>>(filename, Flags::Binary, debug ? Flags::Debug : Flags::Release)); |
| WasmBinaryBuilder parser(wasm, input, debug); |
| parser.read(); |
| } |
| |
| void ModuleReader::read(std::string filename, Module& wasm) { |
| // see if this is a wasm binary |
| std::ifstream infile; |
| std::ios_base::openmode flags = std::ifstream::in | std::ifstream::binary; |
| infile.open(filename, flags); |
| char buffer[4] = { 1, 2, 3, 4 }; |
| infile.read(buffer, 4); |
| infile.close(); |
| if (buffer[0] == '\0' && buffer[1] == 'a' && buffer[2] == 's' && buffer[3] == 'm') { |
| readBinary(filename, wasm); |
| } else { |
| // default to text |
| readText(filename, wasm); |
| } |
| } |
| |
| void ModuleWriter::writeText(Module& wasm, std::string filename) { |
| if (debug) std::cerr << "writing text to " << filename << "\n"; |
| Output output(filename, Flags::Text, debug ? Flags::Debug : Flags::Release); |
| WasmPrinter::printModule(&wasm, output.getStream()); |
| } |
| |
| void ModuleWriter::writeBinary(Module& wasm, std::string filename, |
| std::string binaryMapFilename, |
| std::string binaryMapUrl) { |
| if (debug) std::cerr << "writing binary to " << filename << "\n"; |
| BufferWithRandomAccess buffer(debug); |
| WasmBinaryWriter writer(&wasm, buffer, debug); |
| writer.setNamesSection(debugInfo); |
| std::ofstream* binaryMapStream = nullptr; |
| if (binaryMapFilename.size()) { |
| binaryMapStream = new std::ofstream; |
| binaryMapStream->open(binaryMapFilename); |
| writer.setBinaryMap(binaryMapStream, binaryMapUrl); |
| } |
| if (symbolMap.size() > 0) writer.setSymbolMap(symbolMap); |
| writer.write(); |
| Output output(filename, Flags::Binary, debug ? Flags::Debug : Flags::Release); |
| buffer.writeTo(output); |
| if (binaryMapStream) { |
| binaryMapStream->close(); |
| delete binaryMapStream; |
| } |
| } |
| |
| void ModuleWriter::write(Module& wasm, std::string filename) { |
| if (binary && filename.size() > 0) { |
| writeBinary(wasm, filename, std::string(), std::string()); |
| } else { |
| writeText(wasm, filename); |
| } |
| } |
| |
| } |