Make continuations cloneable
Continuations would throw before if you tried to clone them. This restriction has been lifted.
Esse commit está contido em:
@@ -149,10 +149,84 @@ String c_Continuation::t_getcalledclass() {
|
||||
return called_class;
|
||||
}
|
||||
|
||||
void c_Continuation::dupContVar(const StringData* name, TypedValue* src) {
|
||||
ActRec *fp = actRec();
|
||||
Id destId = fp->m_func->lookupVarId(name);
|
||||
if (destId != kInvalidId) {
|
||||
// Copy the value of the local to the cont object.
|
||||
tvDupFlattenVars(src, frame_local(fp, destId), nullptr);
|
||||
} else {
|
||||
ActRec *contFP = fp;
|
||||
if (!fp->hasVarEnv()) {
|
||||
// This VarEnv may potentially outlive the most recently stack-allocated
|
||||
// VarEnv, so we need to heap allocate it.
|
||||
fp->setVarEnv(VarEnv::createLocalOnHeap(fp));
|
||||
}
|
||||
fp->getVarEnv()->setWithRef(name, src);
|
||||
}
|
||||
}
|
||||
|
||||
static const StaticString s_this("this");
|
||||
|
||||
void c_Continuation::copyContinuationVars(ActRec* fp) {
|
||||
// For functions that contain only named locals, we can copy TVs
|
||||
// right to the local space.
|
||||
static const StringData* thisStr = s_this.get();
|
||||
bool skipThis;
|
||||
if (fp->hasVarEnv()) {
|
||||
Stats::inc(Stats::Cont_CreateVerySlow);
|
||||
Array definedVariables = fp->getVarEnv()->getDefinedVariables();
|
||||
skipThis = definedVariables.exists(s_this, true);
|
||||
|
||||
for (ArrayIter iter(definedVariables); !iter.end(); iter.next()) {
|
||||
if (iter.first().getStringData()->same(s___cont__.get())) {
|
||||
continue;
|
||||
}
|
||||
dupContVar(iter.first().getStringData(),
|
||||
const_cast<TypedValue *>(iter.secondRef().asTypedValue()));
|
||||
}
|
||||
} else {
|
||||
const Func *genFunc = actRec()->m_func;
|
||||
skipThis = genFunc->lookupVarId(thisStr) != kInvalidId;
|
||||
// skip local 0 because that's the old continuation
|
||||
for (Id i = 1; i < genFunc->numNamedLocals(); ++i) {
|
||||
dupContVar(genFunc->localVarName(i), frame_local(fp, i));
|
||||
}
|
||||
}
|
||||
|
||||
// If $this is used as a local inside the body and is not provided
|
||||
// by our containing environment, just prefill it here instead of
|
||||
// using InitThisLoc inside the body
|
||||
if (!skipThis && fp->hasThis()) {
|
||||
Id id = actRec()->m_func->lookupVarId(thisStr);
|
||||
if (id != kInvalidId) {
|
||||
tvAsVariant(frame_local(actRec(), id)) = fp->getThis();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unused
|
||||
Variant c_Continuation::t___clone() {
|
||||
throw_fatal(
|
||||
"Trying to clone an uncloneable object of class Continuation");
|
||||
return uninit_null();
|
||||
not_reached();
|
||||
}
|
||||
|
||||
c_Continuation *c_Continuation::clone() {
|
||||
const Func *origFunc = m_origFunc;
|
||||
const Func *genFunc = actRec()->m_func;
|
||||
|
||||
ActRec *fp = g_vmContext->getFP();
|
||||
c_Continuation* cont = origFunc->isMethod()
|
||||
? g_vmContext->createContMeth(origFunc, genFunc, fp->getThisOrClass())
|
||||
: g_vmContext->createContFunc(origFunc, genFunc);
|
||||
|
||||
cont->copyContinuationVars(actRec());
|
||||
|
||||
cont->o_subclassData.u16 = o_subclassData.u16;
|
||||
cont->m_label = m_label;
|
||||
cont->m_index = m_index;
|
||||
cont->m_value = m_value;
|
||||
|
||||
return cont;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -71,6 +71,8 @@ public:
|
||||
String t_getcalledclass();
|
||||
Variant t___clone();
|
||||
|
||||
c_Continuation* clone();
|
||||
|
||||
static c_Continuation* alloc(const Func* origFunc, const Func* genFunc) {
|
||||
assert(origFunc);
|
||||
assert(genFunc);
|
||||
@@ -128,6 +130,9 @@ private:
|
||||
return (char*)(m_arPtr + 1) - (char*)this;
|
||||
}
|
||||
|
||||
void dupContVar(const StringData *name, TypedValue *src);
|
||||
void copyContinuationVars(ActRec *fp);
|
||||
|
||||
public:
|
||||
/* 32-bit o_id from ObjectData */
|
||||
int32_t m_label;
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
function foo($a1, &$a2) {
|
||||
$a1 += 10;
|
||||
$a2 += 100;
|
||||
yield $a1 * 10000 + $a2;
|
||||
$a1 += 20;
|
||||
$a2 += 200;
|
||||
yield $a1 * 10000 + $a2;
|
||||
$a1 += 30;
|
||||
$a2 += 300;
|
||||
yield $a1 * 10000 + $a2;
|
||||
}
|
||||
$a1 = 1;
|
||||
$a2 = -999999999;
|
||||
$x = foo($a1, $a2);
|
||||
$y1 = clone $x;
|
||||
$y2 = clone $x;
|
||||
$a2 = 2;
|
||||
foreach ($y1 as $v) {
|
||||
$v1 = (int)($v / 10000);
|
||||
$v2 = $v % 10000;
|
||||
echo $v1 . " " . $v2 . "\n";
|
||||
++$a2;
|
||||
}
|
||||
echo "--------\n";
|
||||
var_dump($a1, $a2);
|
||||
echo "========\n";
|
||||
foreach ($y2 as $v) {
|
||||
$v1 = (int)($v / 10000);
|
||||
$v2 = $v % 10000;
|
||||
echo $v1 . " " . $v2 . "\n";
|
||||
++$a2;
|
||||
}
|
||||
echo "--------\n";
|
||||
var_dump($a1, $a2);
|
||||
echo "========\n";
|
||||
foreach ($x as $v) {
|
||||
$v1 = (int)($v / 10000);
|
||||
$v2 = $v % 10000;
|
||||
echo $v1 . " " . $v2 . "\n";
|
||||
++$a2;
|
||||
}
|
||||
echo "--------\n";
|
||||
var_dump($a1, $a2);
|
||||
@@ -0,0 +1,20 @@
|
||||
11 102
|
||||
31 303
|
||||
61 604
|
||||
--------
|
||||
int(1)
|
||||
int(605)
|
||||
========
|
||||
11 705
|
||||
31 906
|
||||
61 1207
|
||||
--------
|
||||
int(1)
|
||||
int(1208)
|
||||
========
|
||||
11 1308
|
||||
31 1509
|
||||
61 1810
|
||||
--------
|
||||
int(1)
|
||||
int(1811)
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
$foo = function() {
|
||||
static $x = 1;
|
||||
$x += 10;
|
||||
yield $x;
|
||||
$x += 100;
|
||||
yield $x;
|
||||
$x += 1000;
|
||||
yield $x;
|
||||
};
|
||||
$x = $foo();
|
||||
$x->next();
|
||||
$y1 = clone $x;
|
||||
$y2 = clone $x;
|
||||
foreach ($x as $v) {
|
||||
echo $v . "\n";
|
||||
}
|
||||
echo "========\n";
|
||||
foreach ($y1 as $v) {
|
||||
echo $v . "\n";
|
||||
}
|
||||
echo "========\n";
|
||||
foreach ($y2 as $v) {
|
||||
echo $v . "\n";
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
111
|
||||
1111
|
||||
========
|
||||
1211
|
||||
2211
|
||||
========
|
||||
2311
|
||||
3311
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
function f(&$a) {
|
||||
++$a;
|
||||
yield $a;
|
||||
++$a;
|
||||
yield $a;
|
||||
}
|
||||
$a = 3;
|
||||
$x = f($a);
|
||||
unset($a);
|
||||
$y1 = clone $x;
|
||||
$y2 = clone $x;
|
||||
foreach ($y1 as $v) {
|
||||
echo $v . "\n";
|
||||
}
|
||||
echo "========\n";
|
||||
foreach ($y2 as $v) {
|
||||
echo $v . "\n";
|
||||
}
|
||||
echo "========\n";
|
||||
foreach ($x as $v) {
|
||||
echo $v . "\n";
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
4
|
||||
5
|
||||
========
|
||||
4
|
||||
5
|
||||
========
|
||||
4
|
||||
5
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
function foo($a, &$b) {
|
||||
$var1 = 'x';
|
||||
$var2 = 'y';
|
||||
$$var1 = $a;
|
||||
$$var2 =& $b;
|
||||
unset($a);
|
||||
unset($b);
|
||||
$$var1 += 10;
|
||||
$$var2 += 100;
|
||||
yield $$var1 * 10000 + $$var2;
|
||||
$$var1 += 20;
|
||||
$$var2 += 200;
|
||||
yield $$var1 * 10000 + $$var2;
|
||||
$$var1 += 30;
|
||||
$$var2 += 300;
|
||||
yield $$var1 * 10000 + $$var2;
|
||||
}
|
||||
$a1 = 1;
|
||||
$a2 = -999999999;
|
||||
$x = foo($a1, $a2);
|
||||
$a2 = 2;
|
||||
$x->next();
|
||||
$y1 = clone $x;
|
||||
$y2 = clone $x;
|
||||
foreach ($y1 as $v) {
|
||||
$v1 = (int)($v / 10000);
|
||||
$v2 = $v % 10000;
|
||||
echo $v1 . " " . $v2 . "\n";
|
||||
++$a2;
|
||||
}
|
||||
echo "--------\n";
|
||||
var_dump($a1, $a2);
|
||||
echo "========\n";
|
||||
foreach ($y2 as $v) {
|
||||
$v1 = (int)($v / 10000);
|
||||
$v2 = $v % 10000;
|
||||
echo $v1 . " " . $v2 . "\n";
|
||||
++$a2;
|
||||
}
|
||||
echo "--------\n";
|
||||
var_dump($a1, $a2);
|
||||
echo "========\n";
|
||||
foreach ($x as $v) {
|
||||
$v1 = (int)($v / 10000);
|
||||
$v2 = $v % 10000;
|
||||
echo $v1 . " " . $v2 . "\n";
|
||||
++$a2;
|
||||
}
|
||||
echo "--------\n";
|
||||
var_dump($a1, $a2);
|
||||
@@ -0,0 +1,17 @@
|
||||
31 302
|
||||
61 603
|
||||
--------
|
||||
int(1)
|
||||
int(604)
|
||||
========
|
||||
31 804
|
||||
61 1105
|
||||
--------
|
||||
int(1)
|
||||
int(1106)
|
||||
========
|
||||
31 1306
|
||||
61 1607
|
||||
--------
|
||||
int(1)
|
||||
int(1608)
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
function foo($a1, &$a2) {
|
||||
$a1 += 10;
|
||||
$a2 += 100;
|
||||
yield $a1 * 10000 + $a2;
|
||||
$a1 += 20;
|
||||
$a2 += 200;
|
||||
yield $a1 * 10000 + $a2;
|
||||
$a1 += 30;
|
||||
$a2 += 300;
|
||||
yield $a1 * 10000 + $a2;
|
||||
}
|
||||
$a1 = 1;
|
||||
$a2 = -999999999;
|
||||
$x = foo($a1, $a2);
|
||||
$a2 = 2;
|
||||
$x->next();
|
||||
$y1 = clone $x;
|
||||
$y2 = clone $x;
|
||||
foreach ($y1 as $v) {
|
||||
$v1 = (int)($v / 10000);
|
||||
$v2 = $v % 10000;
|
||||
echo $v1 . " " . $v2 . "\n";
|
||||
++$a2;
|
||||
}
|
||||
echo "--------\n";
|
||||
var_dump($a1, $a2);
|
||||
echo "========\n";
|
||||
foreach ($y2 as $v) {
|
||||
$v1 = (int)($v / 10000);
|
||||
$v2 = $v % 10000;
|
||||
echo $v1 . " " . $v2 . "\n";
|
||||
++$a2;
|
||||
}
|
||||
echo "--------\n";
|
||||
var_dump($a1, $a2);
|
||||
echo "========\n";
|
||||
foreach ($x as $v) {
|
||||
$v1 = (int)($v / 10000);
|
||||
$v2 = $v % 10000;
|
||||
echo $v1 . " " . $v2 . "\n";
|
||||
++$a2;
|
||||
}
|
||||
echo "--------\n";
|
||||
var_dump($a1, $a2);
|
||||
@@ -0,0 +1,17 @@
|
||||
31 302
|
||||
61 603
|
||||
--------
|
||||
int(1)
|
||||
int(604)
|
||||
========
|
||||
31 804
|
||||
61 1105
|
||||
--------
|
||||
int(1)
|
||||
int(1106)
|
||||
========
|
||||
31 1306
|
||||
61 1607
|
||||
--------
|
||||
int(1)
|
||||
int(1608)
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
$foo = function ($a1, &$a2) {
|
||||
$a1 += 10;
|
||||
$a2 += 100;
|
||||
yield $a1 * 10000 + $a2;
|
||||
$a1 += 20;
|
||||
$a2 += 200;
|
||||
yield $a1 * 10000 + $a2;
|
||||
$a1 += 30;
|
||||
$a2 += 300;
|
||||
yield $a1 * 10000 + $a2;
|
||||
};
|
||||
$a1 = 1;
|
||||
$a2 = -999999999;
|
||||
$x = $foo($a1, $a2);
|
||||
$y1 = clone $x;
|
||||
$y2 = clone $x;
|
||||
$a2 = 2;
|
||||
foreach ($y1 as $v) {
|
||||
$v1 = (int)($v / 10000);
|
||||
$v2 = $v % 10000;
|
||||
echo $v1 . " " . $v2 . "\n";
|
||||
++$a2;
|
||||
}
|
||||
echo "--------\n";
|
||||
var_dump($a1, $a2);
|
||||
echo "========\n";
|
||||
foreach ($y2 as $v) {
|
||||
$v1 = (int)($v / 10000);
|
||||
$v2 = $v % 10000;
|
||||
echo $v1 . " " . $v2 . "\n";
|
||||
++$a2;
|
||||
}
|
||||
echo "--------\n";
|
||||
var_dump($a1, $a2);
|
||||
echo "========\n";
|
||||
foreach ($x as $v) {
|
||||
$v1 = (int)($v / 10000);
|
||||
$v2 = $v % 10000;
|
||||
echo $v1 . " " . $v2 . "\n";
|
||||
++$a2;
|
||||
}
|
||||
echo "--------\n";
|
||||
var_dump($a1, $a2);
|
||||
@@ -0,0 +1,20 @@
|
||||
11 102
|
||||
31 303
|
||||
61 604
|
||||
--------
|
||||
int(1)
|
||||
int(605)
|
||||
========
|
||||
11 705
|
||||
31 906
|
||||
61 1207
|
||||
--------
|
||||
int(1)
|
||||
int(1208)
|
||||
========
|
||||
11 1308
|
||||
31 1509
|
||||
61 1810
|
||||
--------
|
||||
int(1)
|
||||
int(1811)
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
$foo = function ($a1, &$a2) {
|
||||
$a1 += 10;
|
||||
$a2 += 100;
|
||||
yield $a1 * 10000 + $a2;
|
||||
$a1 += 20;
|
||||
$a2 += 200;
|
||||
yield $a1 * 10000 + $a2;
|
||||
$a1 += 30;
|
||||
$a2 += 300;
|
||||
yield $a1 * 10000 + $a2;
|
||||
};
|
||||
$a1 = 1;
|
||||
$a2 = -999999999;
|
||||
$x = $foo($a1, $a2);
|
||||
$a2 = 2;
|
||||
$x->next();
|
||||
$y1 = clone $x;
|
||||
$y2 = clone $x;
|
||||
foreach ($y1 as $v) {
|
||||
$v1 = (int)($v / 10000);
|
||||
$v2 = $v % 10000;
|
||||
echo $v1 . " " . $v2 . "\n";
|
||||
++$a2;
|
||||
}
|
||||
echo "--------\n";
|
||||
var_dump($a1, $a2);
|
||||
echo "========\n";
|
||||
foreach ($y2 as $v) {
|
||||
$v1 = (int)($v / 10000);
|
||||
$v2 = $v % 10000;
|
||||
echo $v1 . " " . $v2 . "\n";
|
||||
++$a2;
|
||||
}
|
||||
echo "--------\n";
|
||||
var_dump($a1, $a2);
|
||||
echo "========\n";
|
||||
foreach ($x as $v) {
|
||||
$v1 = (int)($v / 10000);
|
||||
$v2 = $v % 10000;
|
||||
echo $v1 . " " . $v2 . "\n";
|
||||
++$a2;
|
||||
}
|
||||
echo "--------\n";
|
||||
var_dump($a1, $a2);
|
||||
@@ -0,0 +1,17 @@
|
||||
31 302
|
||||
61 603
|
||||
--------
|
||||
int(1)
|
||||
int(604)
|
||||
========
|
||||
31 804
|
||||
61 1105
|
||||
--------
|
||||
int(1)
|
||||
int(1106)
|
||||
========
|
||||
31 1306
|
||||
61 1607
|
||||
--------
|
||||
int(1)
|
||||
int(1608)
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
$a1 = 1;
|
||||
$a2 = -999999999;
|
||||
$foo = function () use ($a1, &$a2) {
|
||||
$a1 += 10;
|
||||
$a2 += 100;
|
||||
yield $a1 * 10000 + $a2;
|
||||
$a1 += 20;
|
||||
$a2 += 200;
|
||||
yield $a1 * 10000 + $a2;
|
||||
$a1 += 30;
|
||||
$a2 += 300;
|
||||
yield $a1 * 10000 + $a2;
|
||||
};
|
||||
$x = $foo();
|
||||
$y1 = clone $x;
|
||||
$y2 = clone $x;
|
||||
$a2 = 2;
|
||||
foreach ($y1 as $v) {
|
||||
$v1 = (int)($v / 10000);
|
||||
$v2 = $v % 10000;
|
||||
echo $v1 . " " . $v2 . "\n";
|
||||
++$a2;
|
||||
}
|
||||
echo "--------\n";
|
||||
var_dump($a1, $a2);
|
||||
echo "========\n";
|
||||
foreach ($y2 as $v) {
|
||||
$v1 = (int)($v / 10000);
|
||||
$v2 = $v % 10000;
|
||||
echo $v1 . " " . $v2 . "\n";
|
||||
++$a2;
|
||||
}
|
||||
echo "--------\n";
|
||||
var_dump($a1, $a2);
|
||||
echo "========\n";
|
||||
foreach ($x as $v) {
|
||||
$v1 = (int)($v / 10000);
|
||||
$v2 = $v % 10000;
|
||||
echo $v1 . " " . $v2 . "\n";
|
||||
++$a2;
|
||||
}
|
||||
echo "--------\n";
|
||||
var_dump($a1, $a2);
|
||||
@@ -0,0 +1,20 @@
|
||||
11 102
|
||||
31 303
|
||||
61 604
|
||||
--------
|
||||
int(1)
|
||||
int(605)
|
||||
========
|
||||
11 705
|
||||
31 906
|
||||
61 1207
|
||||
--------
|
||||
int(1)
|
||||
int(1208)
|
||||
========
|
||||
11 1308
|
||||
31 1509
|
||||
61 1810
|
||||
--------
|
||||
int(1)
|
||||
int(1811)
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
$a1 = 1;
|
||||
$a2 = -999999999;
|
||||
$foo = function () use ($a1, &$a2) {
|
||||
$a1 += 10;
|
||||
$a2 += 100;
|
||||
yield $a1 * 10000 + $a2;
|
||||
$a1 += 20;
|
||||
$a2 += 200;
|
||||
yield $a1 * 10000 + $a2;
|
||||
$a1 += 30;
|
||||
$a2 += 300;
|
||||
yield $a1 * 10000 + $a2;
|
||||
};
|
||||
$x = $foo();
|
||||
$a2 = 2;
|
||||
$x->next();
|
||||
$y1 = clone $x;
|
||||
$y2 = clone $x;
|
||||
foreach ($y1 as $v) {
|
||||
$v1 = (int)($v / 10000);
|
||||
$v2 = $v % 10000;
|
||||
echo $v1 . " " . $v2 . "\n";
|
||||
++$a2;
|
||||
}
|
||||
echo "--------\n";
|
||||
var_dump($a1, $a2);
|
||||
echo "========\n";
|
||||
foreach ($y2 as $v) {
|
||||
$v1 = (int)($v / 10000);
|
||||
$v2 = $v % 10000;
|
||||
echo $v1 . " " . $v2 . "\n";
|
||||
++$a2;
|
||||
}
|
||||
echo "--------\n";
|
||||
var_dump($a1, $a2);
|
||||
echo "========\n";
|
||||
foreach ($x as $v) {
|
||||
$v1 = (int)($v / 10000);
|
||||
$v2 = $v % 10000;
|
||||
echo $v1 . " " . $v2 . "\n";
|
||||
++$a2;
|
||||
}
|
||||
echo "--------\n";
|
||||
var_dump($a1, $a2);
|
||||
@@ -0,0 +1,17 @@
|
||||
31 302
|
||||
61 603
|
||||
--------
|
||||
int(1)
|
||||
int(604)
|
||||
========
|
||||
31 804
|
||||
61 1105
|
||||
--------
|
||||
int(1)
|
||||
int(1106)
|
||||
========
|
||||
31 1306
|
||||
61 1607
|
||||
--------
|
||||
int(1)
|
||||
int(1608)
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
function foo() {
|
||||
static $x = 1;
|
||||
$x += 10;
|
||||
yield $x;
|
||||
$x += 100;
|
||||
yield $x;
|
||||
$x += 1000;
|
||||
yield $x;
|
||||
}
|
||||
$x = foo();
|
||||
$y1 = clone $x;
|
||||
$y2 = clone $x;
|
||||
foreach ($x as $v) {
|
||||
echo $v . "\n";
|
||||
}
|
||||
echo "========\n";
|
||||
foreach ($y1 as $v) {
|
||||
echo $v . "\n";
|
||||
}
|
||||
echo "========\n";
|
||||
foreach ($y2 as $v) {
|
||||
echo $v . "\n";
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
11
|
||||
111
|
||||
1111
|
||||
========
|
||||
1121
|
||||
1221
|
||||
2221
|
||||
========
|
||||
2231
|
||||
2331
|
||||
3331
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
function foo() {
|
||||
static $x = 1;
|
||||
$x += 10;
|
||||
yield $x;
|
||||
$x += 100;
|
||||
yield $x;
|
||||
$x += 1000;
|
||||
yield $x;
|
||||
}
|
||||
$x = foo();
|
||||
$x->next();
|
||||
$y1 = clone $x;
|
||||
$y2 = clone $x;
|
||||
foreach ($x as $v) {
|
||||
echo $v . "\n";
|
||||
}
|
||||
echo "========\n";
|
||||
foreach ($y1 as $v) {
|
||||
echo $v . "\n";
|
||||
}
|
||||
echo "========\n";
|
||||
foreach ($y2 as $v) {
|
||||
echo $v . "\n";
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
111
|
||||
1111
|
||||
========
|
||||
1211
|
||||
2211
|
||||
========
|
||||
2311
|
||||
3311
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
$foo = function() {
|
||||
static $x = 1;
|
||||
$x += 10;
|
||||
yield $x;
|
||||
$x += 100;
|
||||
yield $x;
|
||||
$x += 1000;
|
||||
yield $x;
|
||||
};
|
||||
$x = $foo();
|
||||
$y1 = clone $x;
|
||||
$y2 = clone $x;
|
||||
foreach ($x as $v) {
|
||||
echo $v . "\n";
|
||||
}
|
||||
echo "========\n";
|
||||
foreach ($y1 as $v) {
|
||||
echo $v . "\n";
|
||||
}
|
||||
echo "========\n";
|
||||
foreach ($y2 as $v) {
|
||||
echo $v . "\n";
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
11
|
||||
111
|
||||
1111
|
||||
========
|
||||
1121
|
||||
1221
|
||||
2221
|
||||
========
|
||||
2231
|
||||
2331
|
||||
3331
|
||||
Referência em uma Nova Issue
Bloquear um usuário