1/*
2 * Copyright 2017 WebAssembly Community Group participants
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//
18// Emit a JavaScript wrapper to run a wasm module with some test
19// values, useful for fuzzing.
20//
21
22#include "wasm-type.h"
23#include "wasm.h"
24#include <string>
25
26namespace wasm {
27
28inline std::string generateJSWrapper(Module& wasm) {
29 std::string ret;
30 ret += "if (typeof console === 'undefined') {\n"
31 " console = { log: print };\n"
32 "}\n"
33 "var tempRet0;\n"
34 "var binary;\n"
35 "if (typeof process === 'object' && typeof require === 'function' /* "
36 "node.js detection */) {\n"
37 " var args = process.argv.slice(2);\n"
38 " binary = require('fs').readFileSync(args[0]);\n"
39 " if (!binary.buffer) binary = new Uint8Array(binary);\n"
40 "} else {\n"
41 " var args;\n"
42 " if (typeof scriptArgs != 'undefined') {\n"
43 " args = scriptArgs;\n"
44 " } else if (typeof arguments != 'undefined') {\n"
45 " args = arguments;\n"
46 " }\n"
47 " if (typeof readbuffer === 'function') {\n"
48 " binary = new Uint8Array(readbuffer(args[0]));\n"
49 " } else {\n"
50 " binary = read(args[0], 'binary');\n"
51 " }\n"
52 "}\n"
53 "function literal(x, type) {\n"
54 " var ret = '';\n"
55 " switch (type) {\n"
56 " case 'i32': ret += (x | 0); break;\n"
57 " case 'f32':\n"
58 " case 'f64': {\n"
59 " if (x == 0 && (1 / x) < 0) ret += '-';\n"
60 " ret += Number(x).toString();\n"
61 " break;\n"
62 " }\n"
63 " // For anything else, just print the type.\n"
64 " default: ret += type; break;\n"
65 " }\n"
66 " return ret;\n"
67 "}\n"
68 "var instance = new WebAssembly.Instance(new "
69 "WebAssembly.Module(binary), {\n"
70 " 'fuzzing-support': {\n"
71 " 'log-i32': function(x) { "
72 "console.log('[LoggingExternalInterface logging ' + literal(x, 'i32') "
73 "+ ']') },\n"
74 " 'log-i64': function(x, y) { "
75 "console.log('[LoggingExternalInterface logging ' + literal(x, 'i32') "
76 "+ ' ' + literal(y, 'i32') + ']') },\n" // legalization: two i32s
77 " 'log-f32': function(x) { "
78 "console.log('[LoggingExternalInterface logging ' + literal(x, 'f64') "
79 "+ ']') },\n" // legalization: an f64
80 " 'log-f64': function(x) { "
81 "console.log('[LoggingExternalInterface logging ' + literal(x, 'f64') "
82 "+ ']') },\n"
83 " },\n"
84 " 'env': {\n"
85 " 'setTempRet0': function(x) { tempRet0 = x },\n"
86 " 'getTempRet0': function() { return tempRet0 },\n"
87 " },\n"
88 "});\n";
89 for (auto& exp : wasm.exports) {
90 if (exp->kind != ExternalKind::Function) {
91 continue; // something exported other than a function
92 }
93 auto* func = wasm.getFunction(exp->value);
94 ret += "try {\n";
95 ret += std::string(" console.log('[fuzz-exec] calling ") +
96 exp->name.toString() + "');\n";
97 if (func->getResults() != Type::none) {
98 ret += std::string(" console.log('[fuzz-exec] note result: ") +
99 exp->name.toString() + " => ' + literal(";
100 } else {
101 ret += " ";
102 }
103 ret += std::string("instance.exports.") + exp->name.toString() + "(";
104 bool first = true;
105 for (auto param : func->getParams()) {
106 // zeros in arguments TODO more?
107 if (first) {
108 first = false;
109 } else {
110 ret += ", ";
111 }
112 if (param.isRef()) {
113 ret += "null";
114 } else {
115 ret += "0";
116 if (param == Type::i64) {
117 ret += ", 0";
118 }
119 }
120 }
121 ret += ")";
122 if (func->getResults() != Type::none) {
123 ret += ", '" + func->getResults().toString() + "'))";
124 // TODO: getTempRet
125 }
126 ret += ";\n";
127 ret += "} catch (e) {\n";
128 ret += " console.log('exception!' /* + e */);\n";
129 ret += "}\n";
130 }
131 return ret;
132}
133
134} // namespace wasm
135

source code of dart_sdk/third_party/binaryen/src/src/tools/js-wrapper.h