2 # Copyright (C) 2001-2009, Parrot Foundation.
7 use lib qw( . lib ../lib ../../lib );
10 use Parrot::Test::Util 'create_tempfile';
12 use Parrot::Test tests => 17;
16 t/pmc/eval.t - Dynamic Code Evaluation
24 Tests on-the-fly PASM, PIR and PAST compilation and invocation.
28 pasm_output_is( <<'CODE', <<'OUTPUT', "eval_sc" );
29 compreg P1, "PASM" # get compiler
30 set_args "0", "print \"in eval\\n\"\nset_returns \"()\"\nreturncc\n"
33 invokecc P0 # eval code P0
41 pasm_output_is( <<'CODE', <<'OUTPUT', "call subs in evaled code " );
42 set S5, ".pcc_sub _foo:\n"
43 concat S5, "print \"foo\\n\"\n"
44 concat S5, "set_returns \"()\"\n"
45 concat S5, "returncc\n"
62 pasm_output_is( <<'CODE', <<'OUTPUT', "call 2 subs in evaled code " );
63 set S5, ".pcc_sub _foo:\n"
64 concat S5, "print \"foo\\n\"\n"
65 concat S5, "set_returns \"()\"\n"
66 concat S5, "returncc\n"
67 concat S5, ".pcc_sub _bar:\n"
68 concat S5, "print \"bar\\n\"\n"
69 concat S5, "set_returns \"()\"\n"
70 concat S5, "returncc\n"
89 pir_output_is( <<'CODE', <<'OUTPUT', "PIR compiler sub" );
93 get_global compiler, "xcompile"
94 compreg "XPASM", compiler
95 .local pmc my_compiler
96 my_compiler = compreg "XPASM"
99 code = "print \"ok\\n\"\n"
100 code .= "set_returns \"()\"\n"
102 the_sub = my_compiler("_foo", code)
104 the_sub = get_global "_foo"
109 .param string sub_name
115 .local pmc pasm_compiler
116 pasm_compiler = compreg "PASM"
118 $P0 = pasm_compiler($S0)
126 pir_output_is( <<'CODE', <<'OUTPUT', "bug #31467" );
130 $P0 = find_name "_builtin"
134 $S0 = ".sub main\nprint \"dynamic\\n\"\n.end\n"
138 set_global "funcs", $P1
140 $S0 = ".sub main\n$P1 = get_global\"funcs\"\n"
141 $S0 .= "$P0 = $P1['dynamic']\n$P0()\n"
142 $S0 .= "$P0 = $P1['builtin']\n$P0()\n"
159 pir_output_is( <<'CODE', <<'OUTPUT', "PIR compiler sub PASM" );
163 .local pmc compiler, invokable
164 compiler = compreg "PUTS"
166 invokable = compiler("ok 1")
171 .sub register_compiler
172 $P0 = get_global "puts"
177 .param string printme
179 .local pmc pasm_compiler, retval
180 pasm_compiler = compreg "PASM"
187 code .= "set_returns \"()\"\n"
190 retval = pasm_compiler( code )
198 pir_output_is( <<'CODE', <<'OUTPUT', "PIR compiler sub PIR" );
202 .local pmc compiler, invokable
203 compiler = compreg "PUTS"
205 invokable = compiler( "ok 1" )
210 .sub register_compiler
212 counter = new ['Integer']
214 set_global "counter", counter
216 $P0 = get_global "_puts"
221 .param string printme
223 .local pmc pir_compiler, retval
224 pir_compiler = compreg "PIR"
227 counter = get_global "counter"
231 code = ".sub anonymous"
240 retval = pir_compiler( code )
248 my (undef, $temp_pbc) = create_tempfile( SUFFIX => '.pbc', UNLINK => 1 );
249 my (undef, $temp2_pbc) = create_tempfile( SUFFIX => '.pbc', UNLINK => 1 );
251 pir_output_is( <<"CODE", <<'OUTPUT', "eval.get_string" );
256 f1 = compi("foo_1", "hello from foo_1")
258 io = new ['FileHandle']
259 io.'open'("$temp_pbc", 'w')
262 load_bytecode "$temp_pbc"
263 f2 = compi("foo_2", "hello from foo_2")
264 io.'open'("$temp2_pbc", 'w')
267 load_bytecode "$temp2_pbc"
272 .param string printme
274 .local pmc pir_compiler, retval
275 pir_compiler = compreg "PIR"
281 code .= "\\\\n\\"\\n"
284 retval = pir_compiler(code)
292 (my $temp_name = $temp_pbc) =~ s/\.pbc$//;
293 (my $temp2_name = $temp2_pbc) =~ s/\.pbc$//;
295 pir_output_is( <<"CODE", <<'OUTPUT', "check loaded lib hash" );
297 load_bytecode "$temp_pbc"
298 load_bytecode "$temp2_pbc"
299 .local pmc pbc_hash, interp
300 .include 'iglobals.pasm'
302 pbc_hash = interp[.IGLOBALS_PBC_LIBS]
303 \$I0 = elements pbc_hash
306 \$I1 = exists pbc_hash['$temp_name']
309 \$I2 = exists pbc_hash['$temp2_name']
312 \$S0 = pbc_hash['$temp2_name']
313 # print \$S0 not portable
314 \$I3 = index \$S0, '$temp2_name'
324 (my $fh, $temp_pbc) = create_tempfile( SUFFIX => '.pbc', UNLINK => 1 );
327 pir_output_is( <<"CODE", <<'OUTPUT', "eval.get_string - same file" );
331 f1 = compi("foo_1", "hello from foo_1")
333 io = new ['FileHandle']
334 io.'open'("$temp_pbc", 'w')
337 load_bytecode "$temp_pbc"
338 f2 = compi("foo_2", "hello from foo_2")
339 io.'open'("$temp_pbc", 'w')
342 load_bytecode "$temp_pbc"
347 .param string printme
349 .local pmc pir_compiler, retval
350 pir_compiler = compreg "PIR"
356 code .= "\\\\n\\"\\n"
359 retval = pir_compiler(code)
366 my (undef, $temp_file) = create_tempfile( UNLINK => 1 );
368 pir_output_is( <<"CODE", <<'OUTPUT', "eval.freeze" );
372 f = compi("foo_1", "hello from foo_1")
374 io = new ['FileHandle']
375 io.'open'("$temp_file", 'w')
383 .param string printme
385 .local pmc pir_compiler, retval
386 pir_compiler = compreg "PIR"
392 code .= "\\\\n\\"\\n"
395 retval = pir_compiler(code)
402 pir_output_is( <<"CODE", <<'OUTPUT', "eval.thaw", todo => 'TT #1142' );
408 io = new ['FileHandle']
409 io.'open'(file, 'rb')
410 \$S0 = io.'readall'()
413 sweep 1 # ensure all of the object survives GC
415 e = get_global "foo_1"
423 pir_output_is( <<"CODE", <<'OUTPUT', "eval.freeze+thaw" );
427 f = compi("foo_1", "hello from foo_1")
429 io = new ['FileHandle']
430 io.'open'("$temp_file", 'wb')
439 .param string printme
441 .local pmc pir_compiler, retval
442 pir_compiler = compreg "PIR"
454 code .= "\\\\n\\"\\n"
457 retval = pir_compiler(code)
466 io = new ['FileHandle']
467 io.'open'(file, 'rb')
468 \$S0 = io.'readall'()
472 e = get_global "foo_1"
481 pir_output_is( <<'CODE', <<'OUTPUT', "get_pmc_keyed_int" );
484 .local pmc e, s, compi
493 compi = compreg "PIR"
507 pir_output_is( <<'CODE', <<'OUTPUT', "catch compile err" );
526 my ($TEMP, $filename) = create_tempfile( SUFFIX => '.pir', UNLINK => 1 );
535 pir_error_output_like( <<"CODE", <<'OUTPUT', "compile err in load_bytecode" );
537 load_bytecode "$filename"
542 /undefined identifier/
545 pir_output_is( <<'CODE', <<'OUTPUT', "catch compile err in load_bytecode" );
548 load_bytecode "$filename"
560 # cperl-indent-level: 4
563 # vim: expandtab shiftwidth=4: