| /* |
| * 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. |
| */ |
| |
| // |
| // Emit a JavaScript wrapper to run a wasm module with some test |
| // values, useful for fuzzing. |
| // |
| |
| namespace wasm { |
| |
| static std::string generateJSWrapper(Module& wasm) { |
| std::string ret; |
| ret += "if (typeof console === 'undefined') {\n" |
| " console = { log: print };\n" |
| "}\n" |
| "var binary;\n" |
| "if (typeof process === 'object' && typeof require === 'function' /* node.js detection */) {\n" |
| " var args = process.argv.slice(2);\n" |
| " binary = require('fs').readFileSync(args[0]);\n" |
| " if (!binary.buffer) binary = new Uint8Array(binary);\n" |
| "} else {\n" |
| " var args;\n" |
| " if (typeof scriptArgs != 'undefined') {\n" |
| " args = scriptArgs;\n" |
| " } else if (typeof arguments != 'undefined') {\n" |
| " args = arguments;\n" |
| " }\n" |
| " if (typeof readbuffer === 'function') {\n" |
| " binary = new Uint8Array(readbuffer(args[0]));\n" |
| " } else {\n" |
| " binary = read(args[0], 'binary');\n" |
| " }\n" |
| "}\n" |
| "var instance = new WebAssembly.Instance(new WebAssembly.Module(binary), {});\n"; |
| for (auto& exp : wasm.exports) { |
| auto* func = wasm.getFunctionOrNull(exp->value); |
| if (!func) continue; // something exported other than a function |
| auto bad = false; // check for things we can't support |
| for (Type param : func->params) { |
| if (param == i64) bad = true; |
| } |
| if (func->result == i64) bad = true; |
| if (bad) continue; |
| ret += "if (instance.exports.hangLimitInitializer) instance.exports.hangLimitInitializer();\n"; |
| ret += "try {\n"; |
| ret += std::string(" console.log('calling: ") + exp->name.str + "');\n"; |
| if (func->result != none) { |
| ret += " console.log(' result: ' + "; |
| } |
| ret += std::string("instance.exports.") + exp->name.str + "("; |
| bool first = true; |
| for (Type param : func->params) { |
| WASM_UNUSED(param); |
| // zeros in arguments TODO more? |
| if (first) { |
| first = false; |
| } else { |
| ret += ", "; |
| } |
| ret += "0"; |
| } |
| ret += ")"; |
| if (func->result != none) { |
| ret += ")"; // for console.log |
| } |
| ret += ";\n"; |
| ret += "} catch (e) {\n"; |
| ret += " console.log(' exception: ' + e);\n"; |
| ret += "}\n"; |
| } |
| ret += "console.log('done.')\n"; |
| return ret; |
| } |
| |
| } // namespace wasm |
| |