/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 | 328k | { |
7 | 328k | std::string tmp(x); |
8 | 328k | if (!tmp.empty()) |
9 | 15.9k | tmp.erase(std::remove_if(tmp.begin(), tmp.end(), |
10 | 6.35M | [](char c) { return !(std::isalpha(c) || std::isdigit(c)); } ), tmp.end()); |
11 | 328k | return tmp; |
12 | 328k | } |
13 | | |
14 | | void protoConverter::visit(ArrType const& x) |
15 | 46.7k | { |
16 | 46.7k | if (x.elements_size() > 0) { |
17 | 7.26k | int i = x.elements_size(); |
18 | 7.26k | m_output << "["; |
19 | 305k | for (auto &e : x.elements()) { |
20 | 305k | i--; |
21 | 305k | if (i == 0) { |
22 | 7.26k | visit(e); |
23 | 298k | } else { |
24 | 298k | visit(e); |
25 | 298k | m_output << ", "; |
26 | 298k | } |
27 | 305k | } |
28 | 7.26k | m_output << "]"; |
29 | 39.5k | } else { |
30 | 39.5k | m_output << "[1]"; |
31 | 39.5k | } |
32 | 46.7k | } |
33 | | |
34 | | void protoConverter::visit(Array const& x) |
35 | 46.7k | { |
36 | 46.7k | switch (x.arr_func()) { |
37 | 8.28k | case Array::FLATTEN: |
38 | 8.28k | visit(x.arr_arg()); |
39 | 8.28k | m_output << ".flatten"; |
40 | 8.28k | break; |
41 | 139 | case Array::COMPACT: |
42 | 139 | visit(x.arr_arg()); |
43 | 139 | m_output << ".compact"; |
44 | 139 | break; |
45 | 1.59k | case Array::FETCH: |
46 | 1.59k | visit(x.arr_arg()); |
47 | 1.59k | m_output << ".fetch"; |
48 | 1.59k | break; |
49 | 785 | case Array::FILL: |
50 | 785 | visit(x.arr_arg()); |
51 | 785 | m_output << ".fill"; |
52 | 785 | break; |
53 | 784 | case Array::ROTATE: |
54 | 784 | visit(x.arr_arg()); |
55 | 784 | m_output << ".rotate"; |
56 | 784 | break; |
57 | 1.22k | case Array::ROTATE_E: |
58 | 1.22k | visit(x.arr_arg()); |
59 | 1.22k | m_output << ".rotate!"; |
60 | 1.22k | break; |
61 | 12 | case Array::DELETEIF: |
62 | 12 | visit(x.arr_arg()); |
63 | 12 | m_output << ".delete_if"; |
64 | 12 | break; |
65 | 1.20k | case Array::INSERT: |
66 | 1.20k | visit(x.arr_arg()); |
67 | 1.20k | m_output << ".insert"; |
68 | 1.20k | break; |
69 | 12 | case Array::BSEARCH: |
70 | 12 | visit(x.arr_arg()); |
71 | 12 | m_output << ".bsearch"; |
72 | 12 | break; |
73 | 147 | case Array::KEEPIF: |
74 | 147 | visit(x.arr_arg()); |
75 | 147 | m_output << ".keep_if"; |
76 | 147 | break; |
77 | 132 | case Array::SELECT: |
78 | 132 | visit(x.arr_arg()); |
79 | 132 | m_output << ".select"; |
80 | 132 | break; |
81 | 673 | case Array::VALUES_AT: |
82 | 673 | visit(x.arr_arg()); |
83 | 673 | m_output << ".values_at"; |
84 | 673 | break; |
85 | 1.63k | case Array::BLOCK: |
86 | 1.63k | visit(x.arr_arg()); |
87 | 1.63k | m_output << ".index"; |
88 | 1.63k | break; |
89 | 1.00k | case Array::DIG: |
90 | 1.00k | visit(x.arr_arg()); |
91 | 1.00k | m_output << ".dig"; |
92 | 1.00k | break; |
93 | 1.09k | case Array::SLICE: |
94 | 1.09k | visit(x.arr_arg()); |
95 | 1.09k | m_output << ".slice"; |
96 | 1.09k | break; |
97 | 2.02k | case Array::PERM: |
98 | 2.02k | visit(x.arr_arg()); |
99 | 2.02k | m_output << ".permutation"; |
100 | 2.02k | break; |
101 | 25.3k | case Array::COMB: |
102 | 25.3k | visit(x.arr_arg()); |
103 | 25.3k | m_output << ".combination"; |
104 | 25.3k | break; |
105 | 498 | case Array::ASSOC: |
106 | 498 | visit(x.arr_arg()); |
107 | 498 | m_output << ".assoc"; |
108 | 498 | break; |
109 | 186 | case Array::RASSOC: |
110 | 186 | visit(x.arr_arg()); |
111 | 186 | m_output << ".rassoc"; |
112 | 186 | break; |
113 | 46.7k | } |
114 | 46.7k | m_output << "("; |
115 | 46.7k | visit(x.val_arg()); |
116 | 46.7k | m_output << ")"; |
117 | 46.7k | } |
118 | | |
119 | | void protoConverter::visit(AssignmentStatement const& x) |
120 | 120k | { |
121 | 120k | m_output << "var_" << m_numLiveVars << " = "; |
122 | 120k | visit(x.rvalue()); |
123 | 120k | m_numVarsPerScope.top()++; |
124 | 120k | m_numLiveVars++; |
125 | 120k | m_output << "\n"; |
126 | 120k | } |
127 | | |
128 | | void protoConverter::visit(BinaryOp const& x) |
129 | 95.7k | { |
130 | 95.7k | m_output << "("; |
131 | 95.7k | visit(x.left()); |
132 | 95.7k | switch (x.op()) { |
133 | 12.2k | case BinaryOp::ADD: m_output << " + "; break; |
134 | 20.9k | case BinaryOp::SUB: m_output << " - "; break; |
135 | 8.28k | case BinaryOp::MUL: m_output << " * "; break; |
136 | 12.4k | case BinaryOp::DIV: m_output << " / "; break; |
137 | 5.71k | case BinaryOp::MOD: m_output << " % "; break; |
138 | 5.74k | case BinaryOp::XOR: m_output << " ^ "; break; |
139 | 4.33k | case BinaryOp::AND: m_output << " and "; break; |
140 | 1.88k | case BinaryOp::OR: m_output << " or "; break; |
141 | 1.94k | case BinaryOp::EQ: m_output << " == "; break; |
142 | 3.32k | case BinaryOp::NE: m_output << " != "; break; |
143 | 3.72k | case BinaryOp::LE: m_output << " <= "; break; |
144 | 1.64k | case BinaryOp::GE: m_output << " >= "; break; |
145 | 1.37k | case BinaryOp::LT: m_output << " < "; break; |
146 | 2.28k | case BinaryOp::GT: m_output << " > "; break; |
147 | 9.88k | case BinaryOp::RS: m_output << " >> "; break; |
148 | 95.7k | } |
149 | 95.7k | visit(x.right()); |
150 | 95.7k | m_output << ")"; |
151 | 95.7k | } |
152 | | |
153 | | void protoConverter::visit(BuiltinFuncs const& x) |
154 | 84.6k | { |
155 | 84.6k | switch (x.bifunc_oneof_case()) { |
156 | 8.00k | case BuiltinFuncs::kOs: |
157 | 8.00k | visit(x.os()); |
158 | 8.00k | break; |
159 | 6.52k | case BuiltinFuncs::kTime: |
160 | 6.52k | visit(x.time()); |
161 | 6.52k | break; |
162 | 46.7k | case BuiltinFuncs::kArr: |
163 | 46.7k | visit(x.arr()); |
164 | 46.7k | break; |
165 | 4.82k | case BuiltinFuncs::kMops: |
166 | 4.82k | visit(x.mops()); |
167 | 4.82k | break; |
168 | 18.4k | case BuiltinFuncs::BIFUNC_ONEOF_NOT_SET: |
169 | 18.4k | m_output << "1"; |
170 | 18.4k | break; |
171 | 84.6k | } |
172 | 84.6k | m_output << "\n"; |
173 | 84.6k | } |
174 | | |
175 | | void protoConverter::visit(Const const& x) |
176 | 337k | { |
177 | 337k | switch (x.const_oneof_case()) { |
178 | 24.4k | case Const::kIntLit: |
179 | 24.4k | m_output << "(" << (x.int_lit() % 13) << ")"; |
180 | 24.4k | break; |
181 | 12.5k | case Const::kBoolVal: |
182 | 12.5k | m_output << "(" << x.bool_val() << ")"; |
183 | 12.5k | break; |
184 | 301k | case Const::CONST_ONEOF_NOT_SET: |
185 | 301k | m_output << "1"; |
186 | 301k | break; |
187 | 337k | } |
188 | 337k | } |
189 | | |
190 | | void protoConverter::visit(Function const& x) |
191 | 476 | { |
192 | 476 | m_output << "def foo()\nvar_0 = 1\n"; |
193 | 476 | visit(x.statements()); |
194 | 476 | m_output << "end\n"; |
195 | 476 | m_output << "foo\n"; |
196 | 476 | } |
197 | | |
198 | | void protoConverter::visit(HashType const& x) |
199 | 8.00k | { |
200 | 8.00k | if (x.keyval_size() > 0) { |
201 | 2.08k | int i = x.keyval_size(); |
202 | 2.08k | m_output << "{"; |
203 | 164k | for (auto &e : x.keyval()) { |
204 | 164k | i--; |
205 | 164k | if (i == 0) { |
206 | 2.08k | visit(e); |
207 | 2.08k | } |
208 | 162k | else { |
209 | 162k | visit(e); |
210 | 162k | m_output << ", "; |
211 | 162k | } |
212 | 164k | } |
213 | 2.08k | m_output << "}"; |
214 | 2.08k | } |
215 | 8.00k | } |
216 | | |
217 | | void protoConverter::visit(IfElse const& x) |
218 | 18.7k | { |
219 | 18.7k | m_output << "if "; |
220 | 18.7k | visit(x.cond()); |
221 | 18.7k | m_output << "\n"; |
222 | 18.7k | visit(x.if_body()); |
223 | 18.7k | m_output << "\nelse\n"; |
224 | 18.7k | visit(x.else_body()); |
225 | 18.7k | m_output << "\nend\n"; |
226 | 18.7k | } |
227 | | |
228 | | void protoConverter::visit(KVPair const& x) |
229 | 164k | { |
230 | 164k | m_output << "\"" << removeSpecial(x.key()) << "\""; |
231 | 164k | m_output << " => "; |
232 | 164k | m_output << "\"" << removeSpecial(x.val()) << "\""; |
233 | 164k | } |
234 | | |
235 | | void protoConverter::visit(MathConst const& x) |
236 | 785 | { |
237 | 785 | switch (x.math_const()) { |
238 | 135 | case MathConst::PI: |
239 | 135 | m_output << "Math::PI"; |
240 | 135 | break; |
241 | 650 | case MathConst::E: |
242 | 650 | m_output << "Math::E"; |
243 | 650 | break; |
244 | 785 | } |
245 | 785 | } |
246 | | |
247 | | void protoConverter::visit(MathOps const& x) |
248 | 4.82k | { |
249 | 4.82k | switch (x.math_op()) { |
250 | 1.79k | case MathOps::CBRT: |
251 | 1.79k | m_output << "Math.cbrt("; |
252 | 1.79k | visit(x.math_arg()); |
253 | 1.79k | m_output << ")"; |
254 | 1.79k | break; |
255 | 412 | case MathOps::COS: |
256 | 412 | m_output << "Math.cos("; |
257 | 412 | visit(x.math_arg()); |
258 | 412 | m_output << ")"; |
259 | 412 | break; |
260 | 374 | case MathOps::ERF: |
261 | 374 | m_output << "Math.erf("; |
262 | 374 | visit(x.math_arg()); |
263 | 374 | m_output << ")"; |
264 | 374 | break; |
265 | 335 | case MathOps::ERFC: |
266 | 335 | m_output << "Math.erfc("; |
267 | 335 | visit(x.math_arg()); |
268 | 335 | m_output << ")"; |
269 | 335 | break; |
270 | 566 | case MathOps::LOG: |
271 | 566 | m_output << "Math.log("; |
272 | 566 | visit(x.math_arg()); |
273 | 566 | m_output << ")"; |
274 | 566 | break; |
275 | 82 | case MathOps::LOG10: |
276 | 82 | m_output << "Math.log10("; |
277 | 82 | visit(x.math_arg()); |
278 | 82 | m_output << ")"; |
279 | 82 | break; |
280 | 150 | case MathOps::LOG2: |
281 | 150 | m_output << "Math.log2("; |
282 | 150 | visit(x.math_arg()); |
283 | 150 | m_output << ")"; |
284 | 150 | break; |
285 | 233 | case MathOps::SIN: |
286 | 233 | m_output << "Math.sin("; |
287 | 233 | visit(x.math_arg()); |
288 | 233 | m_output << ")"; |
289 | 233 | break; |
290 | 649 | case MathOps::SQRT: |
291 | 649 | m_output << "Math.sqrt("; |
292 | 649 | visit(x.math_arg()); |
293 | 649 | m_output << ")"; |
294 | 649 | break; |
295 | 232 | case MathOps::TAN: |
296 | 232 | m_output << "Math.tan("; |
297 | 232 | visit(x.math_arg()); |
298 | 232 | m_output << ")"; |
299 | 232 | break; |
300 | 4.82k | } |
301 | 4.82k | } |
302 | | |
303 | | void protoConverter::visit(MathType const& x) |
304 | 4.82k | { |
305 | 4.82k | switch (x.math_arg_oneof_case()) { |
306 | 979 | case MathType::kMathRval: |
307 | 979 | visit(x.math_rval()); |
308 | 979 | break; |
309 | 785 | case MathType::kMathConst: |
310 | 785 | visit(x.math_const()); |
311 | 785 | break; |
312 | 3.06k | case MathType::MATH_ARG_ONEOF_NOT_SET: |
313 | 3.06k | m_output << "1"; |
314 | 3.06k | break; |
315 | 4.82k | } |
316 | 4.82k | } |
317 | | |
318 | | void protoConverter::visit(ObjectSpace const& x) |
319 | 8.00k | { |
320 | 8.00k | switch (x.os_func()) { |
321 | 8.00k | case ObjectSpace::COUNT: |
322 | 8.00k | m_output << "ObjectSpace.count_objects"; |
323 | 8.00k | break; |
324 | 8.00k | } |
325 | 8.00k | m_output << "("; |
326 | 8.00k | visit(x.os_arg()); |
327 | 8.00k | m_output << ")" << "\n"; |
328 | 8.00k | } |
329 | | |
330 | | void protoConverter::visit(Rvalue const& x) |
331 | 398k | { |
332 | 398k | switch (x.rvalue_oneof_case()) { |
333 | 58.4k | case Rvalue::kVarref: |
334 | 58.4k | visit(x.varref()); |
335 | 58.4k | break; |
336 | 32.3k | case Rvalue::kCons: |
337 | 32.3k | visit(x.cons()); |
338 | 32.3k | break; |
339 | 95.7k | case Rvalue::kBinop: |
340 | 95.7k | visit(x.binop()); |
341 | 95.7k | break; |
342 | 211k | case Rvalue::RVALUE_ONEOF_NOT_SET: |
343 | 211k | m_output << "1"; |
344 | 211k | break; |
345 | 398k | } |
346 | 398k | } |
347 | | |
348 | | void protoConverter::visit(Statement const& x) |
349 | 343k | { |
350 | 343k | switch (x.stmt_oneof_case()) { |
351 | 120k | case Statement::kAssignment: |
352 | 120k | visit(x.assignment()); |
353 | 120k | break; |
354 | 18.7k | case Statement::kIfelse: |
355 | 18.7k | visit(x.ifelse()); |
356 | 18.7k | break; |
357 | 6.62k | case Statement::kTernaryStmt: |
358 | 6.62k | visit(x.ternary_stmt()); |
359 | 6.62k | break; |
360 | 84.6k | case Statement::kBuiltins: |
361 | 84.6k | visit(x.builtins()); |
362 | 84.6k | break; |
363 | 19.5k | case Statement::kBlockstmt: |
364 | 19.5k | visit(x.blockstmt()); |
365 | 19.5k | break; |
366 | 93.6k | case Statement::STMT_ONEOF_NOT_SET: |
367 | 93.6k | break; |
368 | 343k | } |
369 | 343k | m_output << "\n"; |
370 | 343k | } |
371 | | |
372 | | void protoConverter::visit(StatementSeq const& x) |
373 | 57.5k | { |
374 | 57.5k | if (x.statements_size() > 0) { |
375 | 20.9k | m_numVarsPerScope.push(0); |
376 | 20.9k | m_output << "@scope ||= begin\n"; |
377 | 20.9k | for (auto &st : x.statements()) |
378 | 343k | visit(st); |
379 | 20.9k | m_output << "end\n"; |
380 | 20.9k | m_numLiveVars -= m_numVarsPerScope.top(); |
381 | 20.9k | m_numVarsPerScope.pop(); |
382 | 20.9k | } |
383 | 57.5k | } |
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 | 6.62k | { |
424 | 6.62k | m_output << "("; |
425 | 6.62k | visit(x.tern_cond()); |
426 | 6.62k | m_output << " ? "; |
427 | 6.62k | visit(x.t_branch()); |
428 | 6.62k | m_output << " : "; |
429 | 6.62k | visit(x.f_branch()); |
430 | 6.62k | m_output << ")\n"; |
431 | 6.62k | } |
432 | | |
433 | | void protoConverter::visit(Time const& x) |
434 | 6.52k | { |
435 | 6.52k | switch (x.t_func()) { |
436 | 3.66k | case Time::AT: |
437 | 3.66k | m_output << "Time.at"; |
438 | 3.66k | break; |
439 | 2.86k | case Time::GM: |
440 | 2.86k | m_output << "Time.gm"; |
441 | 2.86k | break; |
442 | 6.52k | } |
443 | 6.52k | m_output << "(" << (x.t_arg()% 13) << ")" << "\n"; |
444 | 6.52k | } |
445 | | |
446 | | void protoConverter::visit(VarRef const& x) |
447 | 58.4k | { |
448 | 58.4k | m_output << "var_" << (static_cast<uint32_t>(x.varnum()) % m_numLiveVars); |
449 | 58.4k | } |
450 | | |
451 | | std::string protoConverter::FunctionToString(Function const& input) |
452 | 476 | { |
453 | 476 | visit(input); |
454 | 476 | return m_output.str(); |
455 | 476 | } |