… | |
… | |
155 | eq ne gt lt ge le |
155 | eq ne gt lt ge le |
156 | regcomp regcreset regcmaybe |
156 | regcomp regcreset regcmaybe |
157 | ); |
157 | ); |
158 | |
158 | |
159 | my %callop = ( |
159 | my %callop = ( |
160 | entersub => "(PL_ppaddr [OP_ENTERSUB]) (aTHX)", |
160 | entersub => "(PL_op->op_ppaddr) (aTHX)", |
161 | mapstart => "Perl_pp_grepstart (aTHX)", |
161 | mapstart => "Perl_pp_grepstart (aTHX)", |
162 | ); |
162 | ); |
163 | |
163 | |
164 | sub callop { |
164 | sub callop { |
165 | $callop{$op_name} || "Perl_pp_$op_name (aTHX)" |
165 | $callop{$op_name} || "Perl_pp_$op_name (aTHX)" |
… | |
… | |
223 | if ($Config{useithreads} ne "define") { |
223 | if ($Config{useithreads} ne "define") { |
224 | # disable optimisations on ithreads |
224 | # disable optimisations on ithreads |
225 | |
225 | |
226 | *op_const = sub { |
226 | *op_const = sub { |
227 | $source .= " { dSP; PUSHs ((SV *)${$op->sv}L); PUTBACK; }\n"; |
227 | $source .= " { dSP; PUSHs ((SV *)${$op->sv}L); PUTBACK; }\n"; |
|
|
228 | |
|
|
229 | $ops[0]{follows_const}++ if @ops;#d# |
228 | |
230 | |
229 | out_next; |
231 | out_next; |
230 | }; |
232 | }; |
231 | |
233 | |
232 | *op_gv = \&op_const; |
234 | *op_gv = \&op_const; |
… | |
… | |
333 | |
335 | |
334 | sub op_padsv { |
336 | sub op_padsv { |
335 | my $flags = $op->flags; |
337 | my $flags = $op->flags; |
336 | my $padofs = "(PADOFFSET)" . $op->targ; |
338 | my $padofs = "(PADOFFSET)" . $op->targ; |
337 | |
339 | |
338 | #d#TODO: why does our version break |
|
|
339 | # breaks gce with can't coerce array.... |
|
|
340 | if (($flags & B::OPf_MOD) && ($op->private & B::OPpDEREF)) {#d# |
|
|
341 | return out_linear;#d# |
|
|
342 | }#d# |
|
|
343 | |
|
|
344 | $source .= <<EOF; |
340 | $source .= <<EOF; |
345 | { |
341 | { |
346 | dSP; |
342 | dSP; |
347 | SV *sv = PAD_SVl ($padofs); |
343 | SV *sv = PAD_SVl ($padofs); |
348 | EOF |
344 | EOF |
349 | |
345 | |
350 | if (($flags & B::OPf_MOD) && ($op->private & B::OPpLVAL_INTRO)) { |
346 | if (($flags & B::OPf_MOD) && ($op->private & B::OPpLVAL_INTRO)) { |
351 | $source .= " SAVECLEARSV (PAD_SVl ($padofs));\n"; |
347 | $source .= " SAVECLEARSV (PAD_SVl ($padofs));\n"; |
352 | $ops[0]{pre_padsv_lval_intro}++ if @ops;#d# |
348 | $ops[0]{follows_padsv_lval_intro}++ if @ops;#d# |
353 | } |
349 | } |
354 | |
350 | |
355 | $source .= <<EOF; |
351 | $source .= <<EOF; |
356 | PUSHs (sv); |
352 | PUSHs (sv); |
357 | PUTBACK; |
353 | PUTBACK; |
358 | EOF |
354 | EOF |
359 | |
355 | |
360 | if (($flags & B::OPf_MOD) && ($op->private & B::OPpDEREF)) { |
356 | if (($flags & B::OPf_MOD) && ($op->private & B::OPpDEREF)) { |
361 | $source .= " vivify_ref (sv, $flags & OPpDEREF);\n"; |
357 | $source .= " vivify_ref (sv, " . $op->private . " & OPpDEREF);\n"; |
362 | } |
358 | } |
363 | $source .= " }\n"; |
359 | $source .= " }\n"; |
364 | |
360 | |
365 | out_next; |
361 | out_next; |
366 | } |
362 | } |
… | |
… | |
372 | dPOPTOPssrl; |
368 | dPOPTOPssrl; |
373 | EOF |
369 | EOF |
374 | $source .= " SV *temp = left; left = right; right = temp;\n" |
370 | $source .= " SV *temp = left; left = right; right = temp;\n" |
375 | if $op->private & B::OPpASSIGN_BACKWARDS; |
371 | if $op->private & B::OPpASSIGN_BACKWARDS; |
376 | |
372 | |
377 | if ($insn->{pre_padsv_lval_intro} && !($op->private & B::OPpASSIGN_BACKWARDS)) { |
373 | if ($insn->{follows_padsv_lval_intro} && !($op->private & B::OPpASSIGN_BACKWARDS)) { |
378 | # simple assignment - the target exists, but is basically undef |
374 | # simple assignment - the target exists, but is basically undef |
379 | $source .= " SvSetSV (right, left);\n"; |
375 | $source .= " SvSetSV (right, left);\n"; |
380 | } else { |
376 | } else { |
381 | $source .= " SvSetMagicSV (right, left);\n"; |
377 | $source .= " SvSetMagicSV (right, left);\n"; |
382 | } |
378 | } |
… | |
… | |
389 | |
385 | |
390 | out_next; |
386 | out_next; |
391 | } |
387 | } |
392 | |
388 | |
393 | # pattern const+ (or general push1) |
389 | # pattern const+ (or general push1) |
394 | # pattern pushmark return(?) |
|
|
395 | # pattern pushmark gv rv2av pushmark padsv+o.ä. aassign |
390 | # pattern pushmark gv rv2av pushmark padsv+o.ä. aassign |
396 | |
391 | |
397 | # pattern const method_named |
|
|
398 | sub op_method_named { |
392 | sub op_method_named { |
|
|
393 | if ($insn->{follows_const}) { |
399 | $source .= <<EOF; |
394 | $source .= <<EOF; |
|
|
395 | { |
|
|
396 | dSP; |
|
|
397 | static SV *last_cv; |
|
|
398 | static U32 last_sub_generation; |
|
|
399 | |
|
|
400 | /* simple "polymorphic" inline cache */ |
|
|
401 | if (PL_sub_generation == last_sub_generation) |
|
|
402 | { |
|
|
403 | PUSHs (last_cv); |
|
|
404 | PUTBACK; |
|
|
405 | } |
|
|
406 | else |
|
|
407 | { |
|
|
408 | PL_op = nextop; nextop = Perl_pp_method_named (aTHX); |
|
|
409 | |
|
|
410 | SPAGAIN; |
|
|
411 | last_sub_generation = PL_sub_generation; |
|
|
412 | last_cv = TOPs; |
|
|
413 | } |
|
|
414 | } |
|
|
415 | EOF |
|
|
416 | } else { |
|
|
417 | $source .= <<EOF; |
400 | { |
418 | { |
401 | static HV *last_stash; |
419 | static HV *last_stash; |
402 | static SV *last_cv; |
420 | static SV *last_cv; |
403 | static U32 last_sub_generation; |
421 | static U32 last_sub_generation; |
404 | |
422 | |
… | |
… | |
431 | /* error case usually */ |
449 | /* error case usually */ |
432 | PL_op = nextop; nextop = Perl_pp_method_named (aTHX); |
450 | PL_op = nextop; nextop = Perl_pp_method_named (aTHX); |
433 | } |
451 | } |
434 | } |
452 | } |
435 | EOF |
453 | EOF |
|
|
454 | } |
436 | |
455 | |
437 | out_next; |
456 | out_next; |
438 | } |
457 | } |
439 | |
458 | |
440 | sub op_grepstart { |
459 | sub op_grepstart { |