Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/unsupported-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Exit code `0` when the entry (and best-effort `include`/`require` targets with s

Operands that are not foldable (variables, function calls, non-literal concatenation) emit a **stderr warning** (`dynamic include/require (not followed)`) and are not traversed. Runtime include for VM/JIT/AOT is tracked separately ([#54](https://github.com/PurHur/php-compiler/issues/54), [#85](https://github.com/PurHur/php-compiler/issues/85)).

Some constructs (for example `break`/`continue`, `list()` / short-list destructuring, and prefix/postfix `++`/`--`) are lowered by php-cfg before the compiler sees them; they compile in VM/JIT/AOT like ordinary assign and arithmetic.
Some constructs (for example `break`/`continue`, `list()` / short-list / keyed-list destructuring (`["a" => $x]`), and prefix/postfix `++`/`--`) are lowered by php-cfg before the compiler sees them; they compile in VM/JIT/AOT like ordinary assign and array fetches.

## Known gaps (tracking issues)

Expand Down
6 changes: 6 additions & 0 deletions lib/Block.php
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,12 @@ public function getFrame(Context $context, ?Frame $frame = null): Frame {
throw new \LogicException("Could not resolve argument");
}
} else {
if (null !== $frame && isset($frame->scope[$pos])) {
// Preserve predecessor slot values across CFG splits (e.g. string-key
// array literal before keyed list destructuring, issue #1234).
$scope[$pos] = $frame->scope[$pos];
continue;
}
if (null !== $frame) {
$inherited = self::findVariableInParentFrames($op, $frame);
if (null !== $inherited) {
Expand Down
14 changes: 3 additions & 11 deletions lib/Compiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -226,21 +226,13 @@ private function needsCfgSplitBeforeStringDimFetch(Op $op, Block $block): bool

private function splitCfgBlockAfterStringKeyedArray(Block $block): Block
{
$hub = new Block($block->orig);
$hub->inheritScopeFrom($block);
$this->inheritFuncFromParent($hub, $block);
$jumpToHub = new OpCode(OpCode::TYPE_JUMP);
$jumpToHub->block1 = $hub;
$block->addOpCode($jumpToHub);

$cont = new Block($block->orig);
$cont->inheritScopeFrom($block);
$this->inheritFuncFromParent($cont, $hub);
$this->inheritFuncFromParent($cont, $block);
$jumpToCont = new OpCode(OpCode::TYPE_JUMP);
$jumpToCont->block1 = $cont;
$hub->addOpCode($jumpToCont);
$hub->parents[] = $block;
$cont->parents[] = $hub;
$block->addOpCode($jumpToCont);
$cont->parents[] = $block;

return $cont;
}
Expand Down
11 changes: 11 additions & 0 deletions test/compliance/cases/language/keyed_list_destruct.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
--TEST--
keyed list destructuring with string keys (issue #1234)
--FILE--
<?php
["a" => $x, "b" => $y] = array("a" => 1, "b" => 2);
echo $x, $y, "\n";
["name" => $name] = array("name" => "Ada");
echo $name, "\n";
--EXPECT--
12
Ada
Loading