Merge pull request #48793 from vnen/gdscript-fix-temp-type-adjust
GDScript: Fix crash caused by uninitialized temp stack slots
This commit is contained in:
commit
2fcfc83da9
3 changed files with 49 additions and 7 deletions
|
@ -129,12 +129,6 @@ uint32_t GDScriptByteCodeGenerator::add_temporary(const GDScriptDataType &p_type
|
|||
int idx = temporaries.size();
|
||||
pool.push_back(idx);
|
||||
temporaries.push_back(new_temp);
|
||||
|
||||
// First time using this, so adjust to the proper type.
|
||||
if (temp_type != Variant::NIL) {
|
||||
Address addr(Address::TEMPORARY, idx, p_type);
|
||||
write_type_adjust(addr, temp_type);
|
||||
}
|
||||
}
|
||||
int slot = pool.front()->get();
|
||||
pool.pop_front();
|
||||
|
@ -189,8 +183,12 @@ GDScriptFunction *GDScriptByteCodeGenerator::write_end() {
|
|||
append(GDScriptFunction::OPCODE_END, 0);
|
||||
|
||||
for (int i = 0; i < temporaries.size(); i++) {
|
||||
int stack_index = i + max_locals + RESERVED_STACK;
|
||||
for (int j = 0; j < temporaries[i].bytecode_indices.size(); j++) {
|
||||
opcodes.write[temporaries[i].bytecode_indices[j]] = (i + max_locals + RESERVED_STACK) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
|
||||
opcodes.write[temporaries[i].bytecode_indices[j]] = stack_index | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
|
||||
}
|
||||
if (temporaries[i].type != Variant::NIL) {
|
||||
function->temporary_slots[stack_index] = temporaries[i].type;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -497,6 +497,8 @@ private:
|
|||
Vector<GDScriptDataType> argument_types;
|
||||
GDScriptDataType return_type;
|
||||
|
||||
Map<int, Variant::Type> temporary_slots;
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
Vector<StringName> arg_names;
|
||||
Vector<Variant> default_arg_values;
|
||||
|
|
|
@ -152,6 +152,44 @@ String GDScriptFunction::_get_call_error(const Callable::CallError &p_err, const
|
|||
return err_text;
|
||||
}
|
||||
|
||||
void (*type_init_function_table[])(Variant *) = {
|
||||
nullptr, // NIL (shouldn't be called).
|
||||
&VariantInitializer<bool>::init, // BOOL.
|
||||
&VariantInitializer<int64_t>::init, // INT.
|
||||
&VariantInitializer<double>::init, // FLOAT.
|
||||
&VariantInitializer<String>::init, // STRING.
|
||||
&VariantInitializer<Vector2>::init, // VECTOR2.
|
||||
&VariantInitializer<Vector2i>::init, // VECTOR2I.
|
||||
&VariantInitializer<Rect2>::init, // RECT2.
|
||||
&VariantInitializer<Rect2i>::init, // RECT2I.
|
||||
&VariantInitializer<Vector3>::init, // VECTOR3.
|
||||
&VariantInitializer<Vector3i>::init, // VECTOR3I.
|
||||
&VariantInitializer<Transform2D>::init, // TRANSFORM2D.
|
||||
&VariantInitializer<Plane>::init, // PLANE.
|
||||
&VariantInitializer<Quat>::init, // QUAT.
|
||||
&VariantInitializer<AABB>::init, // AABB.
|
||||
&VariantInitializer<Basis>::init, // BASIS.
|
||||
&VariantInitializer<Transform>::init, // TRANSFORM.
|
||||
&VariantInitializer<Color>::init, // COLOR.
|
||||
&VariantInitializer<StringName>::init, // STRING_NAME.
|
||||
&VariantInitializer<NodePath>::init, // NODE_PATH.
|
||||
&VariantInitializer<RID>::init, // RID.
|
||||
&VariantTypeAdjust<Object *>::adjust, // OBJECT.
|
||||
&VariantInitializer<Callable>::init, // CALLABLE.
|
||||
&VariantInitializer<Signal>::init, // SIGNAL.
|
||||
&VariantInitializer<Dictionary>::init, // DICTIONARY.
|
||||
&VariantInitializer<Array>::init, // ARRAY.
|
||||
&VariantInitializer<PackedByteArray>::init, // PACKED_BYTE_ARRAY.
|
||||
&VariantInitializer<PackedInt32Array>::init, // PACKED_INT32_ARRAY.
|
||||
&VariantInitializer<PackedInt64Array>::init, // PACKED_INT64_ARRAY.
|
||||
&VariantInitializer<PackedFloat32Array>::init, // PACKED_FLOAT32_ARRAY.
|
||||
&VariantInitializer<PackedFloat64Array>::init, // PACKED_FLOAT64_ARRAY.
|
||||
&VariantInitializer<PackedStringArray>::init, // PACKED_STRING_ARRAY.
|
||||
&VariantInitializer<PackedVector2Array>::init, // PACKED_VECTOR2_ARRAY.
|
||||
&VariantInitializer<PackedVector3Array>::init, // PACKED_VECTOR3_ARRAY.
|
||||
&VariantInitializer<PackedColorArray>::init, // PACKED_COLOR_ARRAY.
|
||||
};
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define OPCODES_TABLE \
|
||||
static const void *switch_table_ops[] = { \
|
||||
|
@ -492,6 +530,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||
|
||||
memnew_placement(&stack[ADDR_STACK_CLASS], Variant(script));
|
||||
|
||||
for (const Map<int, Variant::Type>::Element *E = temporary_slots.front(); E; E = E->next()) {
|
||||
type_init_function_table[E->get()](&stack[E->key()]);
|
||||
}
|
||||
|
||||
String err_text;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
|
Loading…
Reference in a new issue