summaryrefslogtreecommitdiffstats
path: root/modules/gdscript/gdscript_vm.cpp
diff options
context:
space:
mode:
authorGeorge Marques <george@gmarqu.es>2022-04-20 14:22:22 -0300
committerGeorge Marques <george@gmarqu.es>2022-04-24 21:49:02 -0300
commit01d13ab2c16aa69a6f81c10dfe4845a50c3e0c63 (patch)
treea469ac2f5102117868a37b43a5ad167a3cb62e99 /modules/gdscript/gdscript_vm.cpp
parent690fefe43ee74c0ae3ed5642f3aefbeb711f9d1c (diff)
downloadredot-engine-01d13ab2c16aa69a6f81c10dfe4845a50c3e0c63.tar.gz
GDScript: Allow using self in lambdas
Diffstat (limited to 'modules/gdscript/gdscript_vm.cpp')
-rw-r--r--modules/gdscript/gdscript_vm.cpp36
1 files changed, 36 insertions, 0 deletions
diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp
index 2afb850c32..e28dd26c28 100644
--- a/modules/gdscript/gdscript_vm.cpp
+++ b/modules/gdscript/gdscript_vm.cpp
@@ -306,6 +306,7 @@ void (*type_init_function_table[])(Variant *) = {
&&OPCODE_AWAIT, \
&&OPCODE_AWAIT_RESUME, \
&&OPCODE_CREATE_LAMBDA, \
+ &&OPCODE_CREATE_SELF_LAMBDA, \
&&OPCODE_JUMP, \
&&OPCODE_JUMP_IF, \
&&OPCODE_JUMP_IF_NOT, \
@@ -2277,6 +2278,41 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
DISPATCH_OPCODE;
+ OPCODE(OPCODE_CREATE_SELF_LAMBDA) {
+ CHECK_SPACE(2 + instr_arg_count);
+
+ GD_ERR_BREAK(p_instance == nullptr);
+
+ ip += instr_arg_count;
+
+ int captures_count = _code_ptr[ip + 1];
+ GD_ERR_BREAK(captures_count < 0);
+
+ int lambda_index = _code_ptr[ip + 2];
+ GD_ERR_BREAK(lambda_index < 0 || lambda_index >= _lambdas_count);
+ GDScriptFunction *lambda = _lambdas_ptr[lambda_index];
+
+ Vector<Variant> captures;
+ captures.resize(captures_count);
+ for (int i = 0; i < captures_count; i++) {
+ GET_INSTRUCTION_ARG(arg, i);
+ captures.write[i] = *arg;
+ }
+
+ GDScriptLambdaSelfCallable *callable;
+ if (Object::cast_to<RefCounted>(p_instance->owner)) {
+ callable = memnew(GDScriptLambdaSelfCallable(Ref<RefCounted>(Object::cast_to<RefCounted>(p_instance->owner)), lambda, captures));
+ } else {
+ callable = memnew(GDScriptLambdaSelfCallable(p_instance->owner, lambda, captures));
+ }
+
+ GET_INSTRUCTION_ARG(result, captures_count);
+ *result = Callable(callable);
+
+ ip += 3;
+ }
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_JUMP) {
CHECK_SPACE(2);
int to = _code_ptr[ip + 1];