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