summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <rverschelde@gmail.com>2017-11-09 19:23:28 +0100
committerGitHub <noreply@github.com>2017-11-09 19:23:28 +0100
commit881defa209435816f52b08edfd876159592e830a (patch)
treefa52df4738dfc0d4d79d7111475776493eebfb45
parentc179db29d972cfe31187011756e637f4f5bc451c (diff)
parent38ae49e5740eb213b892e59d0d66d71bc59eb316 (diff)
Merge pull request #12784 from hpvb/fix-12401
Make sure we don't leak when an opcode is followed by itself
-rw-r--r--modules/gdscript/gd_function.cpp130
1 files changed, 80 insertions, 50 deletions
diff --git a/modules/gdscript/gd_function.cpp b/modules/gdscript/gd_function.cpp
index ce503b62f2..1a46ad324a 100644
--- a/modules/gdscript/gd_function.cpp
+++ b/modules/gdscript/gd_function.cpp
@@ -170,7 +170,7 @@ static String _get_var_type(const Variant *p_type) {
return basestr;
}
-#if defined(__GNUC__) && !defined(__clang__)
+#if defined(__GNUC__)
#define OPCODES_TABLE \
static const void *switch_table_ops[] = { \
&&OPCODE_OPERATOR, \
@@ -427,8 +427,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
*dst = ret;
#endif
ip += 5;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_EXTENDS_TEST) {
CHECK_SPACE(4);
@@ -492,8 +493,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
*dst = extends_ok;
ip += 4;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_SET) {
CHECK_SPACE(3);
@@ -518,8 +520,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
}
#endif
ip += 4;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_GET) {
CHECK_SPACE(3);
@@ -550,8 +553,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
*dst = ret;
#endif
ip += 4;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_SET_NAMED) {
CHECK_SPACE(3);
@@ -575,8 +579,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
}
#endif
ip += 4;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_GET_NAMED) {
CHECK_SPACE(4);
@@ -609,8 +614,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
*dst = ret;
#endif
ip += 4;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_SET_MEMBER) {
CHECK_SPACE(3);
@@ -631,8 +637,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
}
#endif
ip += 3;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_GET_MEMBER) {
CHECK_SPACE(3);
@@ -649,8 +656,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
}
#endif
ip += 3;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_ASSIGN) {
CHECK_SPACE(3);
@@ -660,8 +668,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
*dst = *src;
ip += 3;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_ASSIGN_TRUE) {
CHECK_SPACE(2);
@@ -670,8 +679,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
*dst = true;
ip += 2;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_ASSIGN_FALSE) {
CHECK_SPACE(2);
@@ -680,8 +690,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
*dst = false;
ip += 2;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_CONSTRUCT) {
CHECK_SPACE(2);
@@ -708,8 +719,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
ip += 4 + argc;
//construct a basic type
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_CONSTRUCT_ARRAY) {
CHECK_SPACE(1);
@@ -728,8 +740,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
*dst = array;
ip += 3 + argc;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_CONSTRUCT_DICTIONARY) {
CHECK_SPACE(1);
@@ -750,8 +763,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
*dst = dict;
ip += 3 + argc * 2;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_CALL_RETURN)
OPCODE(OPCODE_CALL) {
@@ -830,8 +844,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
//_call_func(NULL,base,*methodname,ip,argc,p_instance,stack);
ip += argc + 1;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_CALL_BUILT_IN) {
CHECK_SPACE(4);
@@ -869,12 +884,14 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
}
#endif
ip += argc + 1;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_CALL_SELF) {
OPCODE_BREAK;
}
+
OPCODE(OPCODE_CALL_SELF_BASE) {
CHECK_SPACE(2);
@@ -948,8 +965,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
}
ip += 4 + argc;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_YIELD)
OPCODE(OPCODE_YIELD_SIGNAL) {
@@ -1032,6 +1050,7 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
exit_ok = true;
OPCODE_BREAK;
}
+
OPCODE(OPCODE_YIELD_RESUME) {
CHECK_SPACE(2);
@@ -1044,8 +1063,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
GET_VARIANT_PTR(result, 1);
*result = p_state->result;
ip += 2;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_JUMP) {
CHECK_SPACE(2);
@@ -1053,8 +1073,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
GD_ERR_BREAK(to < 0 || to > _code_size);
ip = to;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_JUMP_IF) {
CHECK_SPACE(3);
@@ -1067,11 +1088,12 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
int to = _code_ptr[ip + 2];
GD_ERR_BREAK(to < 0 || to > _code_size);
ip = to;
- DISPATCH_OPCODE;
+ } else {
+ ip += 3;
}
- ip += 3;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_JUMP_IF_NOT) {
CHECK_SPACE(3);
@@ -1084,17 +1106,19 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
int to = _code_ptr[ip + 2];
GD_ERR_BREAK(to < 0 || to > _code_size);
ip = to;
- DISPATCH_OPCODE;
+ } else {
+ ip += 3;
}
- ip += 3;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_JUMP_TO_DEF_ARGUMENT) {
CHECK_SPACE(2);
ip = _default_arg_ptr[defarg];
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_RETURN) {
CHECK_SPACE(2);
@@ -1103,6 +1127,7 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
exit_ok = true;
OPCODE_BREAK;
}
+
OPCODE(OPCODE_ITERATE_BEGIN) {
CHECK_SPACE(8); //space for this a regular iterate
@@ -1121,20 +1146,21 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
int jumpto = _code_ptr[ip + 3];
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
ip = jumpto;
- DISPATCH_OPCODE;
- }
- GET_VARIANT_PTR(iterator, 4);
+ } else {
+ GET_VARIANT_PTR(iterator, 4);
- *iterator = container->iter_get(*counter, valid);
+ *iterator = container->iter_get(*counter, valid);
#ifdef DEBUG_ENABLED
- if (!valid) {
- err_text = "Unable to obtain iterator object of type " + Variant::get_type_name(container->get_type()) + "'.";
- OPCODE_BREAK;
- }
+ if (!valid) {
+ err_text = "Unable to obtain iterator object of type " + Variant::get_type_name(container->get_type()) + "'.";
+ OPCODE_BREAK;
+ }
#endif
- ip += 5; //skip regular iterate which is always next
- DISPATCH_OPCODE;
+ ip += 5; //skip regular iterate which is always next
+ }
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_ITERATE) {
CHECK_SPACE(4);
@@ -1153,20 +1179,21 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
int jumpto = _code_ptr[ip + 3];
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
ip = jumpto;
- DISPATCH_OPCODE;
- }
- GET_VARIANT_PTR(iterator, 4);
+ } else {
+ GET_VARIANT_PTR(iterator, 4);
- *iterator = container->iter_get(*counter, valid);
+ *iterator = container->iter_get(*counter, valid);
#ifdef DEBUG_ENABLED
- if (!valid) {
- err_text = "Unable to obtain iterator object of type " + Variant::get_type_name(container->get_type()) + "' (but was obtained on first iteration?).";
- OPCODE_BREAK;
- }
+ if (!valid) {
+ err_text = "Unable to obtain iterator object of type " + Variant::get_type_name(container->get_type()) + "' (but was obtained on first iteration?).";
+ OPCODE_BREAK;
+ }
#endif
- ip += 5; //loop again
- DISPATCH_OPCODE;
+ ip += 5; //loop again
+ }
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_ASSERT) {
CHECK_SPACE(2);
GET_VARIANT_PTR(test, 1);
@@ -1182,8 +1209,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
#endif
ip += 2;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_BREAKPOINT) {
#ifdef DEBUG_ENABLED
if (ScriptDebugger::get_singleton()) {
@@ -1191,8 +1219,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
}
#endif
ip += 1;
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_LINE) {
CHECK_SPACE(2);
@@ -1220,8 +1249,9 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
ScriptDebugger::get_singleton()->line_poll();
}
- DISPATCH_OPCODE;
}
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_END) {
exit_ok = true;