Skip to content

Commit ea7ec4e

Browse files
committed
fix #548: Do not use OP_READ_VAR in sensing_of block
1 parent 5c36bff commit ea7ec4e

File tree

3 files changed

+48
-11
lines changed

3 files changed

+48
-11
lines changed

src/blocks/sensingblocks.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,13 +276,16 @@ void SensingBlocks::compileOf(Compiler *compiler)
276276

277277
default: {
278278
// Variable
279+
f = &variableOfTargetByIndex;
279280
Target *target = engine->targetAt(index);
280281
auto varIndex = target->findVariable(property->value().toString());
281282

282283
if (varIndex == -1)
283284
compiler->addInstruction(vm::OP_NULL);
284-
else
285-
compiler->addInstruction(vm::OP_READ_VAR, { compiler->variableIndex(target->variableAt(varIndex)) });
285+
else {
286+
// NOTE: The OP_READ_VAR instruction can't be used for this (see #548)
287+
compiler->addConstValue(varIndex);
288+
}
286289

287290
break;
288291
}
@@ -869,6 +872,19 @@ unsigned int SensingBlocks::variableOfTarget(VirtualMachine *vm)
869872
return 1;
870873
}
871874

875+
unsigned int SensingBlocks::variableOfTargetByIndex(VirtualMachine *vm)
876+
{
877+
Target *target = vm->engine()->targetAt(vm->getInput(0, 1)->toInt());
878+
879+
if (target) {
880+
const int varIndex = vm->getInput(0, 2)->toInt();
881+
vm->replaceReturnValue(target->variableAt(varIndex)->value(), 2);
882+
} else
883+
vm->replaceReturnValue(0, 2);
884+
885+
return 1;
886+
}
887+
872888
unsigned int SensingBlocks::backdropNumberOfStage(VirtualMachine *vm)
873889
{
874890
Target *target = vm->engine()->targetAt(vm->engine()->findTarget(vm->getInput(0, 1)->toString()));

src/blocks/sensingblocks.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ class SensingBlocks : public IBlockSection
131131
static unsigned int volumeOfTarget(VirtualMachine *vm);
132132
static unsigned int volumeOfTargetByIndex(VirtualMachine *vm);
133133
static unsigned int variableOfTarget(VirtualMachine *vm);
134+
static unsigned int variableOfTargetByIndex(VirtualMachine *vm);
134135
static unsigned int backdropNumberOfStage(VirtualMachine *vm);
135136
static unsigned int backdropNumberOfStageByIndex(VirtualMachine *vm);
136137
static unsigned int backdropNameOfStage(VirtualMachine *vm);

test/blocks/sensing_blocks_test.cpp

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,8 +1356,8 @@ TEST_F(SensingBlocksTest, Of)
13561356

13571357
compiler.init();
13581358

1359-
EXPECT_CALL(m_engineMock, findTarget("Sprite2")).Times(9).WillRepeatedly(Return(6));
1360-
EXPECT_CALL(m_engineMock, findTarget("_stage_")).Times(5).WillRepeatedly(Return(0));
1359+
EXPECT_CALL(m_engineMock, findTarget("Sprite2")).WillRepeatedly(Return(6));
1360+
EXPECT_CALL(m_engineMock, findTarget("_stage_")).WillRepeatedly(Return(0));
13611361

13621362
EXPECT_CALL(m_engineMock, functionIndex(&SensingBlocks::xPositionOfSpriteByIndex)).WillOnce(Return(0));
13631363
compiler.setBlock(block1);
@@ -1444,21 +1444,25 @@ TEST_F(SensingBlocksTest, Of)
14441444
auto v2 = std::make_shared<Variable>("var2", "some variable");
14451445
stage.addVariable(v1);
14461446
stage.addVariable(v2);
1447+
EXPECT_CALL(m_engineMock, functionIndex(&SensingBlocks::variableOfTargetByIndex)).WillOnce(Return(19));
14471448
EXPECT_CALL(m_engineMock, targetAt(0)).WillOnce(Return(&stage));
14481449
compiler.setBlock(block21);
14491450
SensingBlocks::compileOf(&compiler);
14501451

1452+
EXPECT_CALL(m_engineMock, functionIndex(&SensingBlocks::variableOfTargetByIndex)).WillOnce(Return(19));
14511453
EXPECT_CALL(m_engineMock, targetAt(0)).WillOnce(Return(&stage));
14521454
compiler.setBlock(block22);
14531455
SensingBlocks::compileOf(&compiler);
14541456

14551457
Sprite sprite;
14561458
auto v3 = std::make_shared<Variable>("var3", "some variable");
14571459
sprite.addVariable(v3);
1460+
EXPECT_CALL(m_engineMock, functionIndex(&SensingBlocks::variableOfTargetByIndex)).WillOnce(Return(19));
14581461
EXPECT_CALL(m_engineMock, targetAt(6)).WillOnce(Return(&sprite));
14591462
compiler.setBlock(block23);
14601463
SensingBlocks::compileOf(&compiler);
14611464

1465+
EXPECT_CALL(m_engineMock, functionIndex(&SensingBlocks::variableOfTargetByIndex)).WillOnce(Return(19));
14621466
EXPECT_CALL(m_engineMock, targetAt(6)).WillOnce(Return(&sprite));
14631467
compiler.setBlock(block24);
14641468
SensingBlocks::compileOf(&compiler);
@@ -1547,21 +1551,37 @@ TEST_F(SensingBlocksTest, Of)
15471551
vm::OP_NULL,
15481552
vm::OP_EXEC,
15491553
17,
1550-
vm::OP_READ_VAR,
1551-
0,
1554+
vm::OP_CONST,
1555+
10,
1556+
vm::OP_CONST,
1557+
11,
1558+
vm::OP_EXEC,
1559+
19,
15521560
vm::OP_NULL,
1553-
vm::OP_READ_VAR,
1554-
1,
1561+
vm::OP_CONST,
1562+
12,
1563+
vm::OP_EXEC,
1564+
19,
1565+
vm::OP_CONST,
1566+
13,
1567+
vm::OP_CONST,
1568+
14,
1569+
vm::OP_EXEC,
1570+
19,
15551571
vm::OP_NULL,
15561572
vm::OP_CONST,
1557-
10,
1573+
15,
1574+
vm::OP_EXEC,
1575+
19,
1576+
vm::OP_CONST,
1577+
16,
15581578
vm::OP_NULL,
15591579
vm::OP_EXEC,
15601580
18,
15611581
vm::OP_NULL,
15621582
vm::OP_HALT }));
1563-
ASSERT_EQ(compiler.constValues(), std::vector<Value>({ 6, 6, 6, 6, 6, 6, 6, 0, 0, 0, "some variable" }));
1564-
ASSERT_EQ(compiler.variables(), std::vector<Variable *>({ v2.get(), v3.get() }));
1583+
ASSERT_EQ(compiler.constValues(), std::vector<Value>({ 6, 6, 6, 6, 6, 6, 6, 0, 0, 0, 1, 0, 0, 0, 6, 6, "some variable" }));
1584+
ASSERT_TRUE(compiler.variables().empty());
15651585
}
15661586

15671587
TEST_F(SensingBlocksTest, XPositionOfSprite)

0 commit comments

Comments
 (0)