/src/mruby/oss-fuzz/proto_to_ruby.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | #include "proto_to_ruby.h" |
2 | | |
3 | | using namespace ruby_fuzzer; |
4 | | |
5 | | std::string protoConverter::removeSpecial(const std::string &x) |
6 | 637k | { |
7 | 637k | std::string tmp(x); |
8 | 637k | if (!tmp.empty()) |
9 | 83.2k | tmp.erase(std::remove_if(tmp.begin(), tmp.end(), |
10 | 9.06M | [](char c) { return !(std::isalpha(c) || std::isdigit(c)); } ), tmp.end()); |
11 | 637k | return tmp; |
12 | 637k | } |
13 | | |
14 | | void protoConverter::visit(ArrType const& x) |
15 | 73.5k | { |
16 | 73.5k | if (x.elements_size() > 0) { |
17 | 13.0k | int i = x.elements_size(); |
18 | 13.0k | m_output << "["; |
19 | 492k | for (auto &e : x.elements()) { |
20 | 492k | i--; |
21 | 492k | if (i == 0) { |
22 | 13.0k | visit(e); |
23 | 479k | } else { |
24 | 479k | visit(e); |
25 | 479k | m_output << ", "; |
26 | 479k | } |
27 | 492k | } |
28 | 13.0k | m_output << "]"; |
29 | 60.4k | } else { |
30 | 60.4k | m_output << "[1]"; |
31 | 60.4k | } |
32 | 73.5k | } |
33 | | |
34 | | void protoConverter::visit(Array const& x) |
35 | 73.5k | { |
36 | 73.5k | switch (x.arr_func()) { |
37 | 11.8k | case Array::FLATTEN: |
38 | 11.8k | visit(x.arr_arg()); |
39 | 11.8k | m_output << ".flatten"; |
40 | 11.8k | break; |
41 | 80 | case Array::COMPACT: |
42 | 80 | visit(x.arr_arg()); |
43 | 80 | m_output << ".compact"; |
44 | 80 | break; |
45 | 901 | case Array::FETCH: |
46 | 901 | visit(x.arr_arg()); |
47 | 901 | m_output << ".fetch"; |
48 | 901 | break; |
49 | 1.40k | case Array::FILL: |
50 | 1.40k | visit(x.arr_arg()); |
51 | 1.40k | m_output << ".fill"; |
52 | 1.40k | break; |
53 | 1.58k | case Array::ROTATE: |
54 | 1.58k | visit(x.arr_arg()); |
55 | 1.58k | m_output << ".rotate"; |
56 | 1.58k | break; |
57 | 1.38k | case Array::ROTATE_E: |
58 | 1.38k | visit(x.arr_arg()); |
59 | 1.38k | m_output << ".rotate!"; |
60 | 1.38k | break; |
61 | 77 | case Array::DELETEIF: |
62 | 77 | visit(x.arr_arg()); |
63 | 77 | m_output << ".delete_if"; |
64 | 77 | break; |
65 | 2.42k | case Array::INSERT: |
66 | 2.42k | visit(x.arr_arg()); |
67 | 2.42k | m_output << ".insert"; |
68 | 2.42k | break; |
69 | 163 | case Array::BSEARCH: |
70 | 163 | visit(x.arr_arg()); |
71 | 163 | m_output << ".bsearch"; |
72 | 163 | break; |
73 | 148 | case Array::KEEPIF: |
74 | 148 | visit(x.arr_arg()); |
75 | 148 | m_output << ".keep_if"; |
76 | 148 | break; |
77 | 217 | case Array::SELECT: |
78 | 217 | visit(x.arr_arg()); |
79 | 217 | m_output << ".select"; |
80 | 217 | break; |
81 | 1.79k | case Array::VALUES_AT: |
82 | 1.79k | visit(x.arr_arg()); |
83 | 1.79k | m_output << ".values_at"; |
84 | 1.79k | break; |
85 | 3.91k | case Array::BLOCK: |
86 | 3.91k | visit(x.arr_arg()); |
87 | 3.91k | m_output << ".index"; |
88 | 3.91k | break; |
89 | 1.95k | case Array::DIG: |
90 | 1.95k | visit(x.arr_arg()); |
91 | 1.95k | m_output << ".dig"; |
92 | 1.95k | break; |
93 | 1.06k | case Array::SLICE: |
94 | 1.06k | visit(x.arr_arg()); |
95 | 1.06k | m_output << ".slice"; |
96 | 1.06k | break; |
97 | 4.87k | case Array::PERM: |
98 | 4.87k | visit(x.arr_arg()); |
99 | 4.87k | m_output << ".permutation"; |
100 | 4.87k | break; |
101 | 37.9k | case Array::COMB: |
102 | 37.9k | visit(x.arr_arg()); |
103 | 37.9k | m_output << ".combination"; |
104 | 37.9k | break; |
105 | 759 | case Array::ASSOC: |
106 | 759 | visit(x.arr_arg()); |
107 | 759 | m_output << ".assoc"; |
108 | 759 | break; |
109 | 1.01k | case Array::RASSOC: |
110 | 1.01k | visit(x.arr_arg()); |
111 | 1.01k | m_output << ".rassoc"; |
112 | 1.01k | break; |
113 | 73.5k | } |
114 | 73.5k | m_output << "("; |
115 | 73.5k | visit(x.val_arg()); |
116 | 73.5k | m_output << ")"; |
117 | 73.5k | } |
118 | | |
119 | | void protoConverter::visit(AssignmentStatement const& x) |
120 | 306k | { |
121 | 306k | m_output << "var_" << m_numLiveVars << " = "; |
122 | 306k | visit(x.rvalue()); |
123 | 306k | m_numVarsPerScope.top()++; |
124 | 306k | m_numLiveVars++; |
125 | 306k | m_output << "\n"; |
126 | 306k | } |
127 | | |
128 | | void protoConverter::visit(BinaryOp const& x) |
129 | 260k | { |
130 | 260k | m_output << "("; |
131 | 260k | visit(x.left()); |
132 | 260k | switch (x.op()) { |
133 | 42.5k | case BinaryOp::ADD: m_output << " + "; break; |
134 | 62.2k | case BinaryOp::SUB: m_output << " - "; break; |
135 | 37.3k | case BinaryOp::MUL: m_output << " * "; break; |
136 | 18.8k | case BinaryOp::DIV: m_output << " / "; break; |
137 | 12.1k | case BinaryOp::MOD: m_output << " % "; break; |
138 | 20.3k | case BinaryOp::XOR: m_output << " ^ "; break; |
139 | 9.00k | case BinaryOp::AND: m_output << " and "; break; |
140 | 5.32k | case BinaryOp::OR: m_output << " or "; break; |
141 | 3.18k | case BinaryOp::EQ: m_output << " == "; break; |
142 | 9.18k | case BinaryOp::NE: m_output << " != "; break; |
143 | 4.24k | case BinaryOp::LE: m_output << " <= "; break; |
144 | 4.87k | case BinaryOp::GE: m_output << " >= "; break; |
145 | 2.23k | case BinaryOp::LT: m_output << " < "; break; |
146 | 3.26k | case BinaryOp::GT: m_output << " > "; break; |
147 | 25.9k | case BinaryOp::RS: m_output << " >> "; break; |
148 | 260k | } |
149 | 260k | visit(x.right()); |
150 | 260k | m_output << ")"; |
151 | 260k | } |
152 | | |
153 | | void protoConverter::visit(BuiltinFuncs const& x) |
154 | 184k | { |
155 | 184k | switch (x.bifunc_oneof_case()) { |
156 | 20.2k | case BuiltinFuncs::kOs: |
157 | 20.2k | visit(x.os()); |
158 | 20.2k | break; |
159 | 15.0k | case BuiltinFuncs::kTime: |
160 | 15.0k | visit(x.time()); |
161 | 15.0k | break; |
162 | 73.5k | case BuiltinFuncs::kArr: |
163 | 73.5k | visit(x.arr()); |
164 | 73.5k | break; |
165 | 44.4k | case BuiltinFuncs::kMops: |
166 | 44.4k | visit(x.mops()); |
167 | 44.4k | break; |
168 | 30.8k | case BuiltinFuncs::BIFUNC_ONEOF_NOT_SET: |
169 | 30.8k | m_output << "1"; |
170 | 30.8k | break; |
171 | 184k | } |
172 | 184k | m_output << "\n"; |
173 | 184k | } |
174 | | |
175 | | void protoConverter::visit(Const const& x) |
176 | 579k | { |
177 | 579k | switch (x.const_oneof_case()) { |
178 | 79.2k | case Const::kIntLit: |
179 | 79.2k | m_output << "(" << (x.int_lit() % 13) << ")"; |
180 | 79.2k | break; |
181 | 30.1k | case Const::kBoolVal: |
182 | 30.1k | m_output << "(" << x.bool_val() << ")"; |
183 | 30.1k | break; |
184 | 469k | case Const::CONST_ONEOF_NOT_SET: |
185 | 469k | m_output << "1"; |
186 | 469k | break; |
187 | 579k | } |
188 | 579k | } |
189 | | |
190 | | void protoConverter::visit(Function const& x) |
191 | 2.10k | { |
192 | 2.10k | m_output << "def foo()\nvar_0 = 1\n"; |
193 | 2.10k | visit(x.statements()); |
194 | 2.10k | m_output << "end\n"; |
195 | 2.10k | m_output << "foo\n"; |
196 | 2.10k | } |
197 | | |
198 | | void protoConverter::visit(HashType const& x) |
199 | 20.2k | { |
200 | 20.2k | if (x.keyval_size() > 0) { |
201 | 6.67k | int i = x.keyval_size(); |
202 | 6.67k | m_output << "{"; |
203 | 318k | for (auto &e : x.keyval()) { |
204 | 318k | i--; |
205 | 318k | if (i == 0) { |
206 | 6.67k | visit(e); |
207 | 6.67k | } |
208 | 311k | else { |
209 | 311k | visit(e); |
210 | 311k | m_output << ", "; |
211 | 311k | } |
212 | 318k | } |
213 | 6.67k | m_output << "}"; |
214 | 6.67k | } |
215 | 20.2k | } |
216 | | |
217 | | void protoConverter::visit(IfElse const& x) |
218 | 34.9k | { |
219 | 34.9k | m_output << "if "; |
220 | 34.9k | visit(x.cond()); |
221 | 34.9k | m_output << "\n"; |
222 | 34.9k | visit(x.if_body()); |
223 | 34.9k | m_output << "\nelse\n"; |
224 | 34.9k | visit(x.else_body()); |
225 | 34.9k | m_output << "\nend\n"; |
226 | 34.9k | } |
227 | | |
228 | | void protoConverter::visit(KVPair const& x) |
229 | 318k | { |
230 | 318k | m_output << "\"" << removeSpecial(x.key()) << "\""; |
231 | 318k | m_output << " => "; |
232 | 318k | m_output << "\"" << removeSpecial(x.val()) << "\""; |
233 | 318k | } |
234 | | |
235 | | void protoConverter::visit(MathConst const& x) |
236 | 29.0k | { |
237 | 29.0k | switch (x.math_const()) { |
238 | 8.51k | case MathConst::PI: |
239 | 8.51k | m_output << "Math::PI"; |
240 | 8.51k | break; |
241 | 20.5k | case MathConst::E: |
242 | 20.5k | m_output << "Math::E"; |
243 | 20.5k | break; |
244 | 29.0k | } |
245 | 29.0k | } |
246 | | |
247 | | void protoConverter::visit(MathOps const& x) |
248 | 44.4k | { |
249 | 44.4k | switch (x.math_op()) { |
250 | 6.98k | case MathOps::CBRT: |
251 | 6.98k | m_output << "Math.cbrt("; |
252 | 6.98k | visit(x.math_arg()); |
253 | 6.98k | m_output << ")"; |
254 | 6.98k | break; |
255 | 1.28k | case MathOps::COS: |
256 | 1.28k | m_output << "Math.cos("; |
257 | 1.28k | visit(x.math_arg()); |
258 | 1.28k | m_output << ")"; |
259 | 1.28k | break; |
260 | 3.29k | case MathOps::ERF: |
261 | 3.29k | m_output << "Math.erf("; |
262 | 3.29k | visit(x.math_arg()); |
263 | 3.29k | m_output << ")"; |
264 | 3.29k | break; |
265 | 611 | case MathOps::ERFC: |
266 | 611 | m_output << "Math.erfc("; |
267 | 611 | visit(x.math_arg()); |
268 | 611 | m_output << ")"; |
269 | 611 | break; |
270 | 5.92k | case MathOps::LOG: |
271 | 5.92k | m_output << "Math.log("; |
272 | 5.92k | visit(x.math_arg()); |
273 | 5.92k | m_output << ")"; |
274 | 5.92k | break; |
275 | 898 | case MathOps::LOG10: |
276 | 898 | m_output << "Math.log10("; |
277 | 898 | visit(x.math_arg()); |
278 | 898 | m_output << ")"; |
279 | 898 | break; |
280 | 6.99k | case MathOps::LOG2: |
281 | 6.99k | m_output << "Math.log2("; |
282 | 6.99k | visit(x.math_arg()); |
283 | 6.99k | m_output << ")"; |
284 | 6.99k | break; |
285 | 1.99k | case MathOps::SIN: |
286 | 1.99k | m_output << "Math.sin("; |
287 | 1.99k | visit(x.math_arg()); |
288 | 1.99k | m_output << ")"; |
289 | 1.99k | break; |
290 | 7.14k | case MathOps::SQRT: |
291 | 7.14k | m_output << "Math.sqrt("; |
292 | 7.14k | visit(x.math_arg()); |
293 | 7.14k | m_output << ")"; |
294 | 7.14k | break; |
295 | 9.27k | case MathOps::TAN: |
296 | 9.27k | m_output << "Math.tan("; |
297 | 9.27k | visit(x.math_arg()); |
298 | 9.27k | m_output << ")"; |
299 | 9.27k | break; |
300 | 44.4k | } |
301 | 44.4k | } |
302 | | |
303 | | void protoConverter::visit(MathType const& x) |
304 | 44.4k | { |
305 | 44.4k | switch (x.math_arg_oneof_case()) { |
306 | 2.66k | case MathType::kMathRval: |
307 | 2.66k | visit(x.math_rval()); |
308 | 2.66k | break; |
309 | 29.0k | case MathType::kMathConst: |
310 | 29.0k | visit(x.math_const()); |
311 | 29.0k | break; |
312 | 12.7k | case MathType::MATH_ARG_ONEOF_NOT_SET: |
313 | 12.7k | m_output << "1"; |
314 | 12.7k | break; |
315 | 44.4k | } |
316 | 44.4k | } |
317 | | |
318 | | void protoConverter::visit(ObjectSpace const& x) |
319 | 20.2k | { |
320 | 20.2k | switch (x.os_func()) { |
321 | 20.2k | case ObjectSpace::COUNT: |
322 | 20.2k | m_output << "ObjectSpace.count_objects"; |
323 | 20.2k | break; |
324 | 20.2k | } |
325 | 20.2k | m_output << "("; |
326 | 20.2k | visit(x.os_arg()); |
327 | 20.2k | m_output << ")" << "\n"; |
328 | 20.2k | } |
329 | | |
330 | | void protoConverter::visit(Rvalue const& x) |
331 | 984k | { |
332 | 984k | switch (x.rvalue_oneof_case()) { |
333 | 144k | case Rvalue::kVarref: |
334 | 144k | visit(x.varref()); |
335 | 144k | break; |
336 | 86.8k | case Rvalue::kCons: |
337 | 86.8k | visit(x.cons()); |
338 | 86.8k | break; |
339 | 260k | case Rvalue::kBinop: |
340 | 260k | visit(x.binop()); |
341 | 260k | break; |
342 | 492k | case Rvalue::RVALUE_ONEOF_NOT_SET: |
343 | 492k | m_output << "1"; |
344 | 492k | break; |
345 | 984k | } |
346 | 984k | } |
347 | | |
348 | | void protoConverter::visit(Statement const& x) |
349 | 783k | { |
350 | 783k | switch (x.stmt_oneof_case()) { |
351 | 306k | case Statement::kAssignment: |
352 | 306k | visit(x.assignment()); |
353 | 306k | break; |
354 | 34.9k | case Statement::kIfelse: |
355 | 34.9k | visit(x.ifelse()); |
356 | 34.9k | break; |
357 | 15.1k | case Statement::kTernaryStmt: |
358 | 15.1k | visit(x.ternary_stmt()); |
359 | 15.1k | break; |
360 | 184k | case Statement::kBuiltins: |
361 | 184k | visit(x.builtins()); |
362 | 184k | break; |
363 | 43.5k | case Statement::kBlockstmt: |
364 | 43.5k | visit(x.blockstmt()); |
365 | 43.5k | break; |
366 | 198k | case Statement::STMT_ONEOF_NOT_SET: |
367 | 198k | break; |
368 | 783k | } |
369 | 783k | m_output << "\n"; |
370 | 783k | } |
371 | | |
372 | | void protoConverter::visit(StatementSeq const& x) |
373 | 115k | { |
374 | 115k | if (x.statements_size() > 0) { |
375 | 51.3k | m_numVarsPerScope.push(0); |
376 | 51.3k | m_output << "@scope ||= begin\n"; |
377 | 51.3k | for (auto &st : x.statements()) |
378 | 783k | visit(st); |
379 | 51.3k | m_output << "end\n"; |
380 | 51.3k | m_numLiveVars -= m_numVarsPerScope.top(); |
381 | 51.3k | m_numVarsPerScope.pop(); |
382 | 51.3k | } |
383 | 115k | } |
384 | | |
385 | | void protoConverter::visit(StringExtNoArg const& x) |
386 | 0 | { |
387 | 0 | m_output << "\"" << removeSpecial(x.str_arg()) << "\""; |
388 | 0 | switch (x.str_op()) { |
389 | 0 | case StringExtNoArg::DUMP: |
390 | 0 | m_output << ".dump"; |
391 | 0 | break; |
392 | 0 | case StringExtNoArg::STRIP: |
393 | 0 | m_output << ".strip"; |
394 | 0 | break; |
395 | 0 | case StringExtNoArg::LSTRIP: |
396 | 0 | m_output << ".lstrip"; |
397 | 0 | break; |
398 | 0 | case StringExtNoArg::RSTRIP: |
399 | 0 | m_output << ".rstrip"; |
400 | 0 | break; |
401 | 0 | case StringExtNoArg::STRIPE: |
402 | 0 | m_output << ".strip!"; |
403 | 0 | break; |
404 | 0 | case StringExtNoArg::LSTRIPE: |
405 | 0 | m_output << ".lstrip!"; |
406 | 0 | break; |
407 | 0 | case StringExtNoArg::RSTRIPE: |
408 | 0 | m_output << ".rstrip!"; |
409 | 0 | break; |
410 | 0 | case StringExtNoArg::SWAPCASE: |
411 | 0 | m_output << ".swapcase"; |
412 | 0 | break; |
413 | 0 | case StringExtNoArg::SWAPCASEE: |
414 | 0 | m_output << ".swapcase!"; |
415 | 0 | break; |
416 | 0 | case StringExtNoArg::SQUEEZE: |
417 | 0 | m_output << ".squeeze"; |
418 | 0 | break; |
419 | 0 | } |
420 | 0 | } |
421 | | |
422 | | void protoConverter::visit(Ternary const& x) |
423 | 15.1k | { |
424 | 15.1k | m_output << "("; |
425 | 15.1k | visit(x.tern_cond()); |
426 | 15.1k | m_output << " ? "; |
427 | 15.1k | visit(x.t_branch()); |
428 | 15.1k | m_output << " : "; |
429 | 15.1k | visit(x.f_branch()); |
430 | 15.1k | m_output << ")\n"; |
431 | 15.1k | } |
432 | | |
433 | | void protoConverter::visit(Time const& x) |
434 | 15.0k | { |
435 | 15.0k | switch (x.t_func()) { |
436 | 4.82k | case Time::AT: |
437 | 4.82k | m_output << "Time.at"; |
438 | 4.82k | break; |
439 | 10.2k | case Time::GM: |
440 | 10.2k | m_output << "Time.gm"; |
441 | 10.2k | break; |
442 | 15.0k | } |
443 | 15.0k | m_output << "(" << (x.t_arg()% 13) << ")" << "\n"; |
444 | 15.0k | } |
445 | | |
446 | | void protoConverter::visit(VarRef const& x) |
447 | 144k | { |
448 | 144k | m_output << "var_" << (static_cast<uint32_t>(x.varnum()) % m_numLiveVars); |
449 | 144k | } |
450 | | |
451 | | std::string protoConverter::FunctionToString(Function const& input) |
452 | 2.10k | { |
453 | 2.10k | visit(input); |
454 | 2.10k | return m_output.str(); |
455 | 2.10k | } |