Skip to content

Commit d309623

Browse files
committed
VirtualMachine: Add procedures
1 parent 4b6572c commit d309623

File tree

2 files changed

+31
-5
lines changed

2 files changed

+31
-5
lines changed

src/engine/virtualmachine.cpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ VirtualMachine::VirtualMachine(Target *target, Engine *engine) :
3737
for (int i = 0; i < MAX_REG_COUNT; i++)
3838
m_regs[i] = new Value();
3939
m_loops.reserve(256);
40+
m_callTree.reserve(1024);
4041
}
4142

4243
/*! Destroys the VirtualMachine object. */
@@ -47,6 +48,13 @@ VirtualMachine::~VirtualMachine()
4748
delete m_regs;
4849
}
4950

51+
/*! Sets the list of procedures (custom blocks). */
52+
void VirtualMachine::setProcedures(const std::vector<unsigned int *> &procedures)
53+
{
54+
m_proceduresVector = procedures;
55+
m_procedures = m_proceduresVector.data();
56+
}
57+
5058
/*! Sets the list of functions. */
5159
void VirtualMachine::setFunctions(const std::vector<BlockFunc> &functions)
5260
{
@@ -145,7 +153,8 @@ unsigned int *VirtualMachine::run(unsigned int *pos)
145153
&&do_str_at,
146154
&&do_str_length,
147155
&&do_str_contains,
148-
&&do_exec
156+
&&do_exec,
157+
&&do_call_procedure
149158
};
150159
unsigned int *loopStart;
151160
unsigned int *loopEnd;
@@ -156,8 +165,14 @@ unsigned int *VirtualMachine::run(unsigned int *pos)
156165
if (m_regCount > 0) {
157166
std::cout << "warning: VM: " << m_regCount << " registers were leaked by the script; this is most likely a bug in the VM or in the compiler" << std::endl;
158167
}
159-
m_atEnd = true;
160-
return pos;
168+
if (m_callTree.empty()) {
169+
m_atEnd = true;
170+
return pos;
171+
} else {
172+
pos = m_callTree.back();
173+
m_callTree.pop_back();
174+
DISPATCH();
175+
}
161176

162177
do_const:
163178
ADD_RET_VALUE(GET_NEXT_ARG());
@@ -576,4 +591,9 @@ do_list_get_item : {
576591
do_exec:
577592
FREE_REGS(m_functions[*++pos](this));
578593
DISPATCH();
594+
595+
do_call_procedure:
596+
m_callTree.push_back(++pos);
597+
pos = m_procedures[*pos];
598+
DISPATCH();
579599
}

src/engine/virtualmachine.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ enum Opcode
6868
OP_STR_AT, /*! Stores the character at index in the last register of the string in the second last register, in the last register. */
6969
OP_STR_LENGTH, /*! Stores the length of the string in the last register, in the last register. */
7070
OP_STR_CONTAINS, /*! Stores true in the last register if the string stored in the second last register contains the substring in the last register. */
71-
OP_EXEC /*!< Calls the function with the index in the argument. */
71+
OP_EXEC, /*!< Calls the function with the index in the argument. */
72+
OP_CALL_PROCEDURE /*! Calls the procedure (custom block) with the index in the argument. */
7273
};
7374

7475
}
@@ -84,6 +85,7 @@ class LIBSCRATCHCPP_EXPORT VirtualMachine
8485
VirtualMachine(const VirtualMachine &) = delete;
8586
~VirtualMachine();
8687

88+
void setProcedures(const std::vector<unsigned int *> &procedures);
8789
void setFunctions(const std::vector<BlockFunc> &functions);
8890
void setConstValues(const std::vector<Value> &values);
8991
void setVariables(const std::vector<Value *> &variables);
@@ -111,7 +113,7 @@ class LIBSCRATCHCPP_EXPORT VirtualMachine
111113
unsigned int *run(unsigned int *pos);
112114

113115
static inline const unsigned int instruction_arg_count[] = {
114-
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1
116+
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1
115117
};
116118

117119
typedef struct
@@ -128,6 +130,10 @@ class LIBSCRATCHCPP_EXPORT VirtualMachine
128130
Engine *m_engine = nullptr;
129131
bool m_atEnd = false;
130132
std::vector<Loop> m_loops;
133+
std::vector<unsigned int *> m_callTree;
134+
135+
unsigned int **m_procedures = nullptr;
136+
std::vector<unsigned int *> m_proceduresVector;
131137

132138
BlockFunc *m_functions;
133139
std::vector<BlockFunc> m_functionsVector;

0 commit comments

Comments
 (0)