Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/modules/gdscript/gdscript_vm.cpp
10277 views
1
/**************************************************************************/
2
/* gdscript_vm.cpp */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#include "gdscript.h"
32
#include "gdscript_function.h"
33
#include "gdscript_lambda_callable.h"
34
35
#include "core/os/os.h"
36
37
#ifdef DEBUG_ENABLED
38
39
static bool _profile_count_as_native(const Object *p_base_obj, const StringName &p_methodname) {
40
if (!p_base_obj) {
41
return false;
42
}
43
StringName cname = p_base_obj->get_class_name();
44
if ((p_methodname == "new" && cname == "GDScript") || p_methodname == "call") {
45
return false;
46
}
47
return ClassDB::class_exists(cname) && ClassDB::has_method(cname, p_methodname, false);
48
}
49
50
static String _get_element_type(Variant::Type builtin_type, const StringName &native_type, const Ref<Script> &script_type) {
51
if (script_type.is_valid() && script_type->is_valid()) {
52
return GDScript::debug_get_script_name(script_type);
53
} else if (native_type != StringName()) {
54
return native_type.operator String();
55
} else {
56
return Variant::get_type_name(builtin_type);
57
}
58
}
59
60
static String _get_var_type(const Variant *p_var) {
61
String basestr;
62
63
if (p_var->get_type() == Variant::OBJECT) {
64
bool was_freed;
65
Object *bobj = p_var->get_validated_object_with_check(was_freed);
66
if (!bobj) {
67
if (was_freed) {
68
basestr = "previously freed";
69
} else {
70
basestr = "null instance";
71
}
72
} else {
73
if (bobj->is_class_ptr(GDScriptNativeClass::get_class_ptr_static())) {
74
basestr = Object::cast_to<GDScriptNativeClass>(bobj)->get_name();
75
} else {
76
basestr = bobj->get_class();
77
if (bobj->get_script_instance()) {
78
basestr += " (" + GDScript::debug_get_script_name(bobj->get_script_instance()->get_script()) + ")";
79
}
80
}
81
}
82
83
} else {
84
if (p_var->get_type() == Variant::ARRAY) {
85
basestr = "Array";
86
const Array *p_array = VariantInternal::get_array(p_var);
87
if (p_array->is_typed()) {
88
basestr += "[" + _get_element_type((Variant::Type)p_array->get_typed_builtin(), p_array->get_typed_class_name(), p_array->get_typed_script()) + "]";
89
}
90
} else if (p_var->get_type() == Variant::DICTIONARY) {
91
basestr = "Dictionary";
92
const Dictionary *p_dictionary = VariantInternal::get_dictionary(p_var);
93
if (p_dictionary->is_typed()) {
94
basestr += "[" + _get_element_type((Variant::Type)p_dictionary->get_typed_key_builtin(), p_dictionary->get_typed_key_class_name(), p_dictionary->get_typed_key_script()) +
95
", " + _get_element_type((Variant::Type)p_dictionary->get_typed_value_builtin(), p_dictionary->get_typed_value_class_name(), p_dictionary->get_typed_value_script()) + "]";
96
}
97
} else {
98
basestr = Variant::get_type_name(p_var->get_type());
99
}
100
}
101
102
return basestr;
103
}
104
105
void GDScriptFunction::_profile_native_call(uint64_t p_t_taken, const String &p_func_name, const String &p_instance_class_name) {
106
HashMap<String, Profile::NativeProfile>::Iterator inner_prof = profile.native_calls.find(p_func_name);
107
if (inner_prof) {
108
inner_prof->value.call_count += 1;
109
} else {
110
String sig = vformat("%s::0::%s%s%s", get_script()->get_script_path(), p_instance_class_name, p_instance_class_name.is_empty() ? "" : ".", p_func_name);
111
inner_prof = profile.native_calls.insert(p_func_name, Profile::NativeProfile{ 1, 0, sig });
112
}
113
inner_prof->value.total_time += p_t_taken;
114
}
115
116
#endif // DEBUG_ENABLED
117
118
Variant GDScriptFunction::_get_default_variant_for_data_type(const GDScriptDataType &p_data_type) {
119
if (p_data_type.kind == GDScriptDataType::BUILTIN) {
120
if (p_data_type.builtin_type == Variant::ARRAY) {
121
Array array;
122
// Typed array.
123
if (p_data_type.has_container_element_type(0)) {
124
const GDScriptDataType &element_type = p_data_type.get_container_element_type(0);
125
array.set_typed(element_type.builtin_type, element_type.native_type, element_type.script_type);
126
}
127
128
return array;
129
} else if (p_data_type.builtin_type == Variant::DICTIONARY) {
130
Dictionary dict;
131
// Typed dictionary.
132
if (p_data_type.has_container_element_types()) {
133
const GDScriptDataType &key_type = p_data_type.get_container_element_type_or_variant(0);
134
const GDScriptDataType &value_type = p_data_type.get_container_element_type_or_variant(1);
135
dict.set_typed(key_type.builtin_type, key_type.native_type, key_type.script_type, value_type.builtin_type, value_type.native_type, value_type.script_type);
136
}
137
138
return dict;
139
} else {
140
Callable::CallError ce;
141
Variant variant;
142
Variant::construct(p_data_type.builtin_type, variant, nullptr, 0, ce);
143
144
ERR_FAIL_COND_V(ce.error != Callable::CallError::CALL_OK, Variant());
145
146
return variant;
147
}
148
}
149
150
return Variant();
151
}
152
153
String GDScriptFunction::_get_call_error(const String &p_where, const Variant **p_argptrs, int p_argcount, const Variant &p_ret, const Callable::CallError &p_err) const {
154
switch (p_err.error) {
155
case Callable::CallError::CALL_OK:
156
return String();
157
case Callable::CallError::CALL_ERROR_INVALID_METHOD:
158
if (p_ret.get_type() == Variant::STRING && !p_ret.operator String().is_empty()) {
159
return "Invalid call " + p_where + ": " + p_ret.operator String();
160
}
161
return "Invalid call. Nonexistent " + p_where + ".";
162
case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT:
163
ERR_FAIL_INDEX_V_MSG(p_err.argument, p_argcount, "Bug: Invalid call error argument index.", "Bug: Invalid call error argument index.");
164
ERR_FAIL_NULL_V_MSG(p_argptrs[p_err.argument], "Bug: Argument is null pointer.", "Bug: Argument is null pointer.");
165
// Handle the Object to Object case separately as we don't have further class details.
166
#ifdef DEBUG_ENABLED
167
if (p_err.expected == Variant::OBJECT && p_argptrs[p_err.argument]->get_type() == p_err.expected) {
168
return "Invalid type in " + p_where + ". The Object-derived class of argument " + itos(p_err.argument + 1) + " (" + _get_var_type(p_argptrs[p_err.argument]) + ") is not a subclass of the expected argument class.";
169
}
170
if (p_err.expected == Variant::ARRAY && p_argptrs[p_err.argument]->get_type() == p_err.expected) {
171
return "Invalid type in " + p_where + ". The array of argument " + itos(p_err.argument + 1) + " (" + _get_var_type(p_argptrs[p_err.argument]) + ") does not have the same element type as the expected typed array argument.";
172
}
173
if (p_err.expected == Variant::DICTIONARY && p_argptrs[p_err.argument]->get_type() == p_err.expected) {
174
return "Invalid type in " + p_where + ". The dictionary of argument " + itos(p_err.argument + 1) + " (" + _get_var_type(p_argptrs[p_err.argument]) + ") does not have the same element type as the expected typed dictionary argument.";
175
}
176
#endif // DEBUG_ENABLED
177
return "Invalid type in " + p_where + ". Cannot convert argument " + itos(p_err.argument + 1) + " from " + Variant::get_type_name(p_argptrs[p_err.argument]->get_type()) + " to " + Variant::get_type_name(Variant::Type(p_err.expected)) + ".";
178
case Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS:
179
case Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS:
180
return "Invalid call to " + p_where + ". Expected " + itos(p_err.expected) + " argument(s).";
181
case Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL:
182
return "Attempt to call " + p_where + " on a null instance.";
183
case Callable::CallError::CALL_ERROR_METHOD_NOT_CONST:
184
return "Attempt to call " + p_where + " on a const instance.";
185
}
186
return "Bug: Invalid call error code " + itos(p_err.error) + ".";
187
}
188
189
String GDScriptFunction::_get_callable_call_error(const String &p_where, const Callable &p_callable, const Variant **p_argptrs, int p_argcount, const Variant &p_ret, const Callable::CallError &p_err) const {
190
Vector<Variant> binds;
191
p_callable.get_bound_arguments_ref(binds);
192
193
int args_unbound = p_callable.get_unbound_arguments_count();
194
195
if (p_argcount - args_unbound < 0) {
196
return "Callable unbinds " + itos(args_unbound) + " arguments, but called with " + itos(p_argcount);
197
} else {
198
Vector<const Variant *> argptrs;
199
argptrs.resize(p_argcount - args_unbound + binds.size());
200
for (int i = 0; i < p_argcount - args_unbound; i++) {
201
argptrs.write[i] = p_argptrs[i];
202
}
203
for (int i = 0; i < binds.size(); i++) {
204
argptrs.write[i + p_argcount - args_unbound] = &binds[i];
205
}
206
return _get_call_error(p_where, (const Variant **)argptrs.ptr(), argptrs.size(), p_ret, p_err);
207
}
208
}
209
210
void (*type_init_function_table[])(Variant *) = {
211
nullptr, // NIL (shouldn't be called).
212
&VariantInitializer<bool>::init, // BOOL.
213
&VariantInitializer<int64_t>::init, // INT.
214
&VariantInitializer<double>::init, // FLOAT.
215
&VariantInitializer<String>::init, // STRING.
216
&VariantInitializer<Vector2>::init, // VECTOR2.
217
&VariantInitializer<Vector2i>::init, // VECTOR2I.
218
&VariantInitializer<Rect2>::init, // RECT2.
219
&VariantInitializer<Rect2i>::init, // RECT2I.
220
&VariantInitializer<Vector3>::init, // VECTOR3.
221
&VariantInitializer<Vector3i>::init, // VECTOR3I.
222
&VariantInitializer<Transform2D>::init, // TRANSFORM2D.
223
&VariantInitializer<Vector4>::init, // VECTOR4.
224
&VariantInitializer<Vector4i>::init, // VECTOR4I.
225
&VariantInitializer<Plane>::init, // PLANE.
226
&VariantInitializer<Quaternion>::init, // QUATERNION.
227
&VariantInitializer<AABB>::init, // AABB.
228
&VariantInitializer<Basis>::init, // BASIS.
229
&VariantInitializer<Transform3D>::init, // TRANSFORM3D.
230
&VariantInitializer<Projection>::init, // PROJECTION.
231
&VariantInitializer<Color>::init, // COLOR.
232
&VariantInitializer<StringName>::init, // STRING_NAME.
233
&VariantInitializer<NodePath>::init, // NODE_PATH.
234
&VariantInitializer<RID>::init, // RID.
235
&VariantInitializer<Object *>::init, // OBJECT.
236
&VariantInitializer<Callable>::init, // CALLABLE.
237
&VariantInitializer<Signal>::init, // SIGNAL.
238
&VariantInitializer<Dictionary>::init, // DICTIONARY.
239
&VariantInitializer<Array>::init, // ARRAY.
240
&VariantInitializer<PackedByteArray>::init, // PACKED_BYTE_ARRAY.
241
&VariantInitializer<PackedInt32Array>::init, // PACKED_INT32_ARRAY.
242
&VariantInitializer<PackedInt64Array>::init, // PACKED_INT64_ARRAY.
243
&VariantInitializer<PackedFloat32Array>::init, // PACKED_FLOAT32_ARRAY.
244
&VariantInitializer<PackedFloat64Array>::init, // PACKED_FLOAT64_ARRAY.
245
&VariantInitializer<PackedStringArray>::init, // PACKED_STRING_ARRAY.
246
&VariantInitializer<PackedVector2Array>::init, // PACKED_VECTOR2_ARRAY.
247
&VariantInitializer<PackedVector3Array>::init, // PACKED_VECTOR3_ARRAY.
248
&VariantInitializer<PackedColorArray>::init, // PACKED_COLOR_ARRAY.
249
&VariantInitializer<PackedVector4Array>::init, // PACKED_VECTOR4_ARRAY.
250
};
251
252
#if defined(__GNUC__) || defined(__clang__)
253
#define OPCODES_TABLE \
254
static const void *switch_table_ops[] = { \
255
&&OPCODE_OPERATOR, \
256
&&OPCODE_OPERATOR_VALIDATED, \
257
&&OPCODE_TYPE_TEST_BUILTIN, \
258
&&OPCODE_TYPE_TEST_ARRAY, \
259
&&OPCODE_TYPE_TEST_DICTIONARY, \
260
&&OPCODE_TYPE_TEST_NATIVE, \
261
&&OPCODE_TYPE_TEST_SCRIPT, \
262
&&OPCODE_SET_KEYED, \
263
&&OPCODE_SET_KEYED_VALIDATED, \
264
&&OPCODE_SET_INDEXED_VALIDATED, \
265
&&OPCODE_GET_KEYED, \
266
&&OPCODE_GET_KEYED_VALIDATED, \
267
&&OPCODE_GET_INDEXED_VALIDATED, \
268
&&OPCODE_SET_NAMED, \
269
&&OPCODE_SET_NAMED_VALIDATED, \
270
&&OPCODE_GET_NAMED, \
271
&&OPCODE_GET_NAMED_VALIDATED, \
272
&&OPCODE_SET_MEMBER, \
273
&&OPCODE_GET_MEMBER, \
274
&&OPCODE_SET_STATIC_VARIABLE, \
275
&&OPCODE_GET_STATIC_VARIABLE, \
276
&&OPCODE_ASSIGN, \
277
&&OPCODE_ASSIGN_NULL, \
278
&&OPCODE_ASSIGN_TRUE, \
279
&&OPCODE_ASSIGN_FALSE, \
280
&&OPCODE_ASSIGN_TYPED_BUILTIN, \
281
&&OPCODE_ASSIGN_TYPED_ARRAY, \
282
&&OPCODE_ASSIGN_TYPED_DICTIONARY, \
283
&&OPCODE_ASSIGN_TYPED_NATIVE, \
284
&&OPCODE_ASSIGN_TYPED_SCRIPT, \
285
&&OPCODE_CAST_TO_BUILTIN, \
286
&&OPCODE_CAST_TO_NATIVE, \
287
&&OPCODE_CAST_TO_SCRIPT, \
288
&&OPCODE_CONSTRUCT, \
289
&&OPCODE_CONSTRUCT_VALIDATED, \
290
&&OPCODE_CONSTRUCT_ARRAY, \
291
&&OPCODE_CONSTRUCT_TYPED_ARRAY, \
292
&&OPCODE_CONSTRUCT_DICTIONARY, \
293
&&OPCODE_CONSTRUCT_TYPED_DICTIONARY, \
294
&&OPCODE_CALL, \
295
&&OPCODE_CALL_RETURN, \
296
&&OPCODE_CALL_ASYNC, \
297
&&OPCODE_CALL_UTILITY, \
298
&&OPCODE_CALL_UTILITY_VALIDATED, \
299
&&OPCODE_CALL_GDSCRIPT_UTILITY, \
300
&&OPCODE_CALL_BUILTIN_TYPE_VALIDATED, \
301
&&OPCODE_CALL_SELF_BASE, \
302
&&OPCODE_CALL_METHOD_BIND, \
303
&&OPCODE_CALL_METHOD_BIND_RET, \
304
&&OPCODE_CALL_BUILTIN_STATIC, \
305
&&OPCODE_CALL_NATIVE_STATIC, \
306
&&OPCODE_CALL_NATIVE_STATIC_VALIDATED_RETURN, \
307
&&OPCODE_CALL_NATIVE_STATIC_VALIDATED_NO_RETURN, \
308
&&OPCODE_CALL_METHOD_BIND_VALIDATED_RETURN, \
309
&&OPCODE_CALL_METHOD_BIND_VALIDATED_NO_RETURN, \
310
&&OPCODE_AWAIT, \
311
&&OPCODE_AWAIT_RESUME, \
312
&&OPCODE_CREATE_LAMBDA, \
313
&&OPCODE_CREATE_SELF_LAMBDA, \
314
&&OPCODE_JUMP, \
315
&&OPCODE_JUMP_IF, \
316
&&OPCODE_JUMP_IF_NOT, \
317
&&OPCODE_JUMP_TO_DEF_ARGUMENT, \
318
&&OPCODE_JUMP_IF_SHARED, \
319
&&OPCODE_RETURN, \
320
&&OPCODE_RETURN_TYPED_BUILTIN, \
321
&&OPCODE_RETURN_TYPED_ARRAY, \
322
&&OPCODE_RETURN_TYPED_DICTIONARY, \
323
&&OPCODE_RETURN_TYPED_NATIVE, \
324
&&OPCODE_RETURN_TYPED_SCRIPT, \
325
&&OPCODE_ITERATE_BEGIN, \
326
&&OPCODE_ITERATE_BEGIN_INT, \
327
&&OPCODE_ITERATE_BEGIN_FLOAT, \
328
&&OPCODE_ITERATE_BEGIN_VECTOR2, \
329
&&OPCODE_ITERATE_BEGIN_VECTOR2I, \
330
&&OPCODE_ITERATE_BEGIN_VECTOR3, \
331
&&OPCODE_ITERATE_BEGIN_VECTOR3I, \
332
&&OPCODE_ITERATE_BEGIN_STRING, \
333
&&OPCODE_ITERATE_BEGIN_DICTIONARY, \
334
&&OPCODE_ITERATE_BEGIN_ARRAY, \
335
&&OPCODE_ITERATE_BEGIN_PACKED_BYTE_ARRAY, \
336
&&OPCODE_ITERATE_BEGIN_PACKED_INT32_ARRAY, \
337
&&OPCODE_ITERATE_BEGIN_PACKED_INT64_ARRAY, \
338
&&OPCODE_ITERATE_BEGIN_PACKED_FLOAT32_ARRAY, \
339
&&OPCODE_ITERATE_BEGIN_PACKED_FLOAT64_ARRAY, \
340
&&OPCODE_ITERATE_BEGIN_PACKED_STRING_ARRAY, \
341
&&OPCODE_ITERATE_BEGIN_PACKED_VECTOR2_ARRAY, \
342
&&OPCODE_ITERATE_BEGIN_PACKED_VECTOR3_ARRAY, \
343
&&OPCODE_ITERATE_BEGIN_PACKED_COLOR_ARRAY, \
344
&&OPCODE_ITERATE_BEGIN_PACKED_VECTOR4_ARRAY, \
345
&&OPCODE_ITERATE_BEGIN_OBJECT, \
346
&&OPCODE_ITERATE_BEGIN_RANGE, \
347
&&OPCODE_ITERATE, \
348
&&OPCODE_ITERATE_INT, \
349
&&OPCODE_ITERATE_FLOAT, \
350
&&OPCODE_ITERATE_VECTOR2, \
351
&&OPCODE_ITERATE_VECTOR2I, \
352
&&OPCODE_ITERATE_VECTOR3, \
353
&&OPCODE_ITERATE_VECTOR3I, \
354
&&OPCODE_ITERATE_STRING, \
355
&&OPCODE_ITERATE_DICTIONARY, \
356
&&OPCODE_ITERATE_ARRAY, \
357
&&OPCODE_ITERATE_PACKED_BYTE_ARRAY, \
358
&&OPCODE_ITERATE_PACKED_INT32_ARRAY, \
359
&&OPCODE_ITERATE_PACKED_INT64_ARRAY, \
360
&&OPCODE_ITERATE_PACKED_FLOAT32_ARRAY, \
361
&&OPCODE_ITERATE_PACKED_FLOAT64_ARRAY, \
362
&&OPCODE_ITERATE_PACKED_STRING_ARRAY, \
363
&&OPCODE_ITERATE_PACKED_VECTOR2_ARRAY, \
364
&&OPCODE_ITERATE_PACKED_VECTOR3_ARRAY, \
365
&&OPCODE_ITERATE_PACKED_COLOR_ARRAY, \
366
&&OPCODE_ITERATE_PACKED_VECTOR4_ARRAY, \
367
&&OPCODE_ITERATE_OBJECT, \
368
&&OPCODE_ITERATE_RANGE, \
369
&&OPCODE_STORE_GLOBAL, \
370
&&OPCODE_STORE_NAMED_GLOBAL, \
371
&&OPCODE_TYPE_ADJUST_BOOL, \
372
&&OPCODE_TYPE_ADJUST_INT, \
373
&&OPCODE_TYPE_ADJUST_FLOAT, \
374
&&OPCODE_TYPE_ADJUST_STRING, \
375
&&OPCODE_TYPE_ADJUST_VECTOR2, \
376
&&OPCODE_TYPE_ADJUST_VECTOR2I, \
377
&&OPCODE_TYPE_ADJUST_RECT2, \
378
&&OPCODE_TYPE_ADJUST_RECT2I, \
379
&&OPCODE_TYPE_ADJUST_VECTOR3, \
380
&&OPCODE_TYPE_ADJUST_VECTOR3I, \
381
&&OPCODE_TYPE_ADJUST_TRANSFORM2D, \
382
&&OPCODE_TYPE_ADJUST_VECTOR4, \
383
&&OPCODE_TYPE_ADJUST_VECTOR4I, \
384
&&OPCODE_TYPE_ADJUST_PLANE, \
385
&&OPCODE_TYPE_ADJUST_QUATERNION, \
386
&&OPCODE_TYPE_ADJUST_AABB, \
387
&&OPCODE_TYPE_ADJUST_BASIS, \
388
&&OPCODE_TYPE_ADJUST_TRANSFORM3D, \
389
&&OPCODE_TYPE_ADJUST_PROJECTION, \
390
&&OPCODE_TYPE_ADJUST_COLOR, \
391
&&OPCODE_TYPE_ADJUST_STRING_NAME, \
392
&&OPCODE_TYPE_ADJUST_NODE_PATH, \
393
&&OPCODE_TYPE_ADJUST_RID, \
394
&&OPCODE_TYPE_ADJUST_OBJECT, \
395
&&OPCODE_TYPE_ADJUST_CALLABLE, \
396
&&OPCODE_TYPE_ADJUST_SIGNAL, \
397
&&OPCODE_TYPE_ADJUST_DICTIONARY, \
398
&&OPCODE_TYPE_ADJUST_ARRAY, \
399
&&OPCODE_TYPE_ADJUST_PACKED_BYTE_ARRAY, \
400
&&OPCODE_TYPE_ADJUST_PACKED_INT32_ARRAY, \
401
&&OPCODE_TYPE_ADJUST_PACKED_INT64_ARRAY, \
402
&&OPCODE_TYPE_ADJUST_PACKED_FLOAT32_ARRAY, \
403
&&OPCODE_TYPE_ADJUST_PACKED_FLOAT64_ARRAY, \
404
&&OPCODE_TYPE_ADJUST_PACKED_STRING_ARRAY, \
405
&&OPCODE_TYPE_ADJUST_PACKED_VECTOR2_ARRAY, \
406
&&OPCODE_TYPE_ADJUST_PACKED_VECTOR3_ARRAY, \
407
&&OPCODE_TYPE_ADJUST_PACKED_COLOR_ARRAY, \
408
&&OPCODE_TYPE_ADJUST_PACKED_VECTOR4_ARRAY, \
409
&&OPCODE_ASSERT, \
410
&&OPCODE_BREAKPOINT, \
411
&&OPCODE_LINE, \
412
&&OPCODE_END \
413
}; \
414
static_assert(std::size(switch_table_ops) == (OPCODE_END + 1), "Opcodes in jump table aren't the same as opcodes in enum.");
415
416
#define OPCODE(m_op) \
417
m_op:
418
#define OPCODE_WHILE(m_test)
419
#define OPCODES_END \
420
OPSEXIT:
421
#define OPCODES_OUT \
422
OPSOUT:
423
#define OPCODE_SWITCH(m_test) goto *switch_table_ops[m_test];
424
425
#ifdef DEBUG_ENABLED
426
#define DISPATCH_OPCODE \
427
last_opcode = _code_ptr[ip]; \
428
goto *switch_table_ops[last_opcode]
429
#else // !DEBUG_ENABLED
430
#define DISPATCH_OPCODE goto *switch_table_ops[_code_ptr[ip]]
431
#endif // DEBUG_ENABLED
432
433
#define OPCODE_BREAK goto OPSEXIT
434
#define OPCODE_OUT goto OPSOUT
435
#else // !(defined(__GNUC__) || defined(__clang__))
436
#define OPCODES_TABLE
437
#define OPCODE(m_op) case m_op:
438
#define OPCODE_WHILE(m_test) while (m_test)
439
#define OPCODES_END
440
#define OPCODES_OUT
441
#define DISPATCH_OPCODE continue
442
443
#ifdef _MSC_VER
444
#define OPCODE_SWITCH(m_test) \
445
__assume(m_test <= OPCODE_END); \
446
switch (m_test)
447
#else // !_MSC_VER
448
#define OPCODE_SWITCH(m_test) switch (m_test)
449
#endif // _MSC_VER
450
451
#define OPCODE_BREAK break
452
#define OPCODE_OUT break
453
#endif // defined(__GNUC__) || defined(__clang__)
454
455
// Helpers for VariantInternal methods in macros.
456
#define OP_GET_BOOL get_bool
457
#define OP_GET_INT get_int
458
#define OP_GET_FLOAT get_float
459
#define OP_GET_VECTOR2 get_vector2
460
#define OP_GET_VECTOR2I get_vector2i
461
#define OP_GET_VECTOR3 get_vector3
462
#define OP_GET_VECTOR3I get_vector3i
463
#define OP_GET_RECT2 get_rect2
464
#define OP_GET_VECTOR4 get_vector4
465
#define OP_GET_VECTOR4I get_vector4i
466
#define OP_GET_RECT2I get_rect2i
467
#define OP_GET_QUATERNION get_quaternion
468
#define OP_GET_COLOR get_color
469
#define OP_GET_STRING get_string
470
#define OP_GET_STRING_NAME get_string_name
471
#define OP_GET_NODE_PATH get_node_path
472
#define OP_GET_CALLABLE get_callable
473
#define OP_GET_SIGNAL get_signal
474
#define OP_GET_ARRAY get_array
475
#define OP_GET_DICTIONARY get_dictionary
476
#define OP_GET_PACKED_BYTE_ARRAY get_byte_array
477
#define OP_GET_PACKED_INT32_ARRAY get_int32_array
478
#define OP_GET_PACKED_INT64_ARRAY get_int64_array
479
#define OP_GET_PACKED_FLOAT32_ARRAY get_float32_array
480
#define OP_GET_PACKED_FLOAT64_ARRAY get_float64_array
481
#define OP_GET_PACKED_STRING_ARRAY get_string_array
482
#define OP_GET_PACKED_VECTOR2_ARRAY get_vector2_array
483
#define OP_GET_PACKED_VECTOR3_ARRAY get_vector3_array
484
#define OP_GET_PACKED_COLOR_ARRAY get_color_array
485
#define OP_GET_PACKED_VECTOR4_ARRAY get_vector4_array
486
#define OP_GET_TRANSFORM3D get_transform
487
#define OP_GET_TRANSFORM2D get_transform2d
488
#define OP_GET_PROJECTION get_projection
489
#define OP_GET_PLANE get_plane
490
#define OP_GET_AABB get_aabb
491
#define OP_GET_BASIS get_basis
492
#define OP_GET_RID get_rid
493
494
#define METHOD_CALL_ON_NULL_VALUE_ERROR(method_pointer) "Cannot call method '" + (method_pointer)->get_name() + "' on a null value."
495
#define METHOD_CALL_ON_FREED_INSTANCE_ERROR(method_pointer) "Cannot call method '" + (method_pointer)->get_name() + "' on a previously freed instance."
496
497
Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_args, int p_argcount, Callable::CallError &r_err, CallState *p_state) {
498
OPCODES_TABLE;
499
500
if (!_code_ptr) {
501
return _get_default_variant_for_data_type(return_type);
502
}
503
504
r_err.error = Callable::CallError::CALL_OK;
505
506
static thread_local int call_depth = 0;
507
if (unlikely(++call_depth > MAX_CALL_DEPTH)) {
508
call_depth--;
509
#ifdef DEBUG_ENABLED
510
String err_file;
511
if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && !p_instance->script->path.is_empty()) {
512
err_file = p_instance->script->path;
513
} else if (_script) {
514
err_file = _script->path;
515
}
516
if (err_file.is_empty()) {
517
err_file = "<built-in>";
518
}
519
String err_func = name;
520
if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && p_instance->script->local_name != StringName()) {
521
err_func = p_instance->script->local_name.operator String() + "." + err_func;
522
}
523
int err_line = _initial_line;
524
const char *err_text = "Stack overflow. Check for infinite recursion in your script.";
525
_err_print_error(err_func.utf8().get_data(), err_file.utf8().get_data(), err_line, err_text, false, ERR_HANDLER_SCRIPT);
526
GDScriptLanguage::get_singleton()->debug_break(err_text, false);
527
#endif
528
return _get_default_variant_for_data_type(return_type);
529
}
530
531
Variant retvalue;
532
Variant *stack = nullptr;
533
Variant **instruction_args = nullptr;
534
int defarg = 0;
535
536
uint32_t alloca_size = 0;
537
GDScript *script;
538
int ip = 0;
539
int line = _initial_line;
540
541
if (p_state) {
542
//use existing (supplied) state (awaited)
543
stack = (Variant *)p_state->stack.ptr();
544
instruction_args = (Variant **)&p_state->stack.ptr()[sizeof(Variant) * p_state->stack_size]; //ptr() to avoid bounds check
545
line = p_state->line;
546
ip = p_state->ip;
547
alloca_size = p_state->stack.size();
548
script = p_state->script;
549
p_instance = p_state->instance;
550
defarg = p_state->defarg;
551
552
} else {
553
if (p_argcount != _argument_count) {
554
if (p_argcount > _argument_count) {
555
if (!is_vararg()) {
556
r_err.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
557
r_err.expected = _argument_count;
558
call_depth--;
559
return _get_default_variant_for_data_type(return_type);
560
}
561
} else if (p_argcount < _argument_count - _default_arg_count) {
562
r_err.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
563
r_err.expected = _argument_count - _default_arg_count;
564
call_depth--;
565
return _get_default_variant_for_data_type(return_type);
566
} else {
567
defarg = _argument_count - p_argcount;
568
}
569
}
570
571
alloca_size = sizeof(Variant *) * FIXED_ADDRESSES_MAX + sizeof(Variant *) * _instruction_args_size + sizeof(Variant) * _stack_size;
572
573
uint8_t *aptr = (uint8_t *)alloca(alloca_size);
574
stack = (Variant *)aptr;
575
576
const int non_vararg_arg_count = MIN(p_argcount, _argument_count);
577
for (int i = 0; i < non_vararg_arg_count; i++) {
578
if (!argument_types[i].has_type) {
579
memnew_placement(&stack[i + FIXED_ADDRESSES_MAX], Variant(*p_args[i]));
580
continue;
581
}
582
// If types already match, don't call Variant::construct(). Constructors of some types
583
// (e.g. packed arrays) do copies, whereas they pass by reference when inside a Variant.
584
if (argument_types[i].is_type(*p_args[i], false)) {
585
memnew_placement(&stack[i + FIXED_ADDRESSES_MAX], Variant(*p_args[i]));
586
continue;
587
}
588
if (!argument_types[i].is_type(*p_args[i], true)) {
589
r_err.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
590
r_err.argument = i;
591
r_err.expected = argument_types[i].builtin_type;
592
call_depth--;
593
return _get_default_variant_for_data_type(return_type);
594
}
595
if (argument_types[i].kind == GDScriptDataType::BUILTIN) {
596
if (argument_types[i].builtin_type == Variant::DICTIONARY && argument_types[i].has_container_element_types()) {
597
const GDScriptDataType &arg_key_type = argument_types[i].get_container_element_type_or_variant(0);
598
const GDScriptDataType &arg_value_type = argument_types[i].get_container_element_type_or_variant(1);
599
Dictionary dict(p_args[i]->operator Dictionary(), arg_key_type.builtin_type, arg_key_type.native_type, arg_key_type.script_type, arg_value_type.builtin_type, arg_value_type.native_type, arg_value_type.script_type);
600
memnew_placement(&stack[i + FIXED_ADDRESSES_MAX], Variant(dict));
601
} else if (argument_types[i].builtin_type == Variant::ARRAY && argument_types[i].has_container_element_type(0)) {
602
const GDScriptDataType &arg_type = argument_types[i].container_element_types[0];
603
Array array(p_args[i]->operator Array(), arg_type.builtin_type, arg_type.native_type, arg_type.script_type);
604
memnew_placement(&stack[i + FIXED_ADDRESSES_MAX], Variant(array));
605
} else {
606
Variant variant;
607
Variant::construct(argument_types[i].builtin_type, variant, &p_args[i], 1, r_err);
608
if (unlikely(r_err.error)) {
609
r_err.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
610
r_err.argument = i;
611
r_err.expected = argument_types[i].builtin_type;
612
call_depth--;
613
return _get_default_variant_for_data_type(return_type);
614
}
615
memnew_placement(&stack[i + FIXED_ADDRESSES_MAX], Variant(variant));
616
}
617
} else {
618
memnew_placement(&stack[i + FIXED_ADDRESSES_MAX], Variant(*p_args[i]));
619
}
620
}
621
for (int i = non_vararg_arg_count + FIXED_ADDRESSES_MAX; i < _stack_size; i++) {
622
memnew_placement(&stack[i], Variant);
623
}
624
625
if (is_vararg()) {
626
Array vararg;
627
stack[_vararg_index] = vararg;
628
if (p_argcount > _argument_count) {
629
vararg.resize(p_argcount - _argument_count);
630
for (int i = 0; i < p_argcount - _argument_count; i++) {
631
vararg[i] = *p_args[i + _argument_count];
632
}
633
}
634
}
635
636
if (_instruction_args_size) {
637
instruction_args = (Variant **)&aptr[sizeof(Variant) * _stack_size];
638
} else {
639
instruction_args = nullptr;
640
}
641
642
for (const KeyValue<int, Variant::Type> &E : temporary_slots) {
643
type_init_function_table[E.value](&stack[E.key]);
644
}
645
}
646
647
if (p_instance) {
648
memnew_placement(&stack[ADDR_STACK_SELF], Variant(p_instance->owner));
649
script = p_instance->script.ptr();
650
} else {
651
memnew_placement(&stack[ADDR_STACK_SELF], Variant);
652
script = _script;
653
}
654
memnew_placement(&stack[ADDR_STACK_CLASS], Variant(script));
655
memnew_placement(&stack[ADDR_STACK_NIL], Variant);
656
657
String err_text;
658
659
GDScriptLanguage::CallLevel call_level;
660
GDScriptLanguage::get_singleton()->enter_function(&call_level, p_instance, this, stack, &ip, &line);
661
662
#ifdef DEBUG_ENABLED
663
#define GD_ERR_BREAK(m_cond) \
664
{ \
665
if (unlikely(m_cond)) { \
666
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true. Breaking..:"); \
667
OPCODE_BREAK; \
668
} \
669
}
670
671
#define CHECK_SPACE(m_space) \
672
GD_ERR_BREAK((ip + m_space) > _code_size)
673
674
#define GET_VARIANT_PTR(m_v, m_code_ofs) \
675
Variant *m_v; \
676
{ \
677
int address = _code_ptr[ip + 1 + (m_code_ofs)]; \
678
int address_type = (address & ADDR_TYPE_MASK) >> ADDR_BITS; \
679
if (unlikely(address_type < 0 || address_type >= ADDR_TYPE_MAX)) { \
680
err_text = "Bad address type."; \
681
OPCODE_BREAK; \
682
} \
683
int address_index = address & ADDR_MASK; \
684
if (unlikely(address_index < 0 || address_index >= variant_address_limits[address_type])) { \
685
if (address_type == ADDR_TYPE_MEMBER && !p_instance) { \
686
err_text = "Cannot access member without instance."; \
687
} else { \
688
err_text = "Bad address index."; \
689
} \
690
OPCODE_BREAK; \
691
} \
692
m_v = &variant_addresses[address_type][address_index]; \
693
if (unlikely(!m_v)) \
694
OPCODE_BREAK; \
695
}
696
697
#else // !DEBUG_ENABLED
698
#define GD_ERR_BREAK(m_cond)
699
#define CHECK_SPACE(m_space)
700
701
#define GET_VARIANT_PTR(m_v, m_code_ofs) \
702
Variant *m_v; \
703
{ \
704
int address = _code_ptr[ip + 1 + (m_code_ofs)]; \
705
m_v = &variant_addresses[(address & ADDR_TYPE_MASK) >> ADDR_BITS][address & ADDR_MASK]; \
706
if (unlikely(!m_v)) \
707
OPCODE_BREAK; \
708
}
709
710
#endif // DEBUG_ENABLED
711
712
#define LOAD_INSTRUCTION_ARGS \
713
int instr_arg_count = _code_ptr[ip + 1]; \
714
for (int i = 0; i < instr_arg_count; i++) { \
715
GET_VARIANT_PTR(v, i + 1); \
716
instruction_args[i] = v; \
717
} \
718
ip += 1; // Offset to skip instruction argcount.
719
720
#define GET_INSTRUCTION_ARG(m_v, m_idx) \
721
Variant *m_v = instruction_args[m_idx]
722
723
#ifdef DEBUG_ENABLED
724
uint64_t function_start_time = 0;
725
uint64_t function_call_time = 0;
726
727
if (GDScriptLanguage::get_singleton()->profiling) {
728
function_start_time = OS::get_singleton()->get_ticks_usec();
729
function_call_time = 0;
730
profile.call_count.increment();
731
profile.frame_call_count.increment();
732
}
733
bool exit_ok = false;
734
int variant_address_limits[ADDR_TYPE_MAX] = { _stack_size, _constant_count, p_instance ? (int)p_instance->members.size() : 0 };
735
#endif
736
737
bool awaited = false;
738
Variant *variant_addresses[ADDR_TYPE_MAX] = { stack, _constants_ptr, p_instance ? p_instance->members.ptrw() : nullptr };
739
740
#ifdef DEBUG_ENABLED
741
OPCODE_WHILE(ip < _code_size) {
742
int last_opcode = _code_ptr[ip];
743
#else
744
OPCODE_WHILE(true) {
745
#endif
746
747
OPCODE_SWITCH(_code_ptr[ip]) {
748
OPCODE(OPCODE_OPERATOR) {
749
constexpr int _pointer_size = sizeof(Variant::ValidatedOperatorEvaluator) / sizeof(*_code_ptr);
750
CHECK_SPACE(7 + _pointer_size);
751
752
bool valid;
753
Variant::Operator op = (Variant::Operator)_code_ptr[ip + 4];
754
GD_ERR_BREAK(op >= Variant::OP_MAX);
755
756
GET_VARIANT_PTR(a, 0);
757
GET_VARIANT_PTR(b, 1);
758
GET_VARIANT_PTR(dst, 2);
759
// Compute signatures (types of operands) so it can be optimized when matching.
760
uint32_t op_signature = _code_ptr[ip + 5];
761
uint32_t actual_signature = (a->get_type() << 8) | (b->get_type());
762
763
#ifdef DEBUG_ENABLED
764
if (op == Variant::OP_DIVIDE || op == Variant::OP_MODULE) {
765
// Don't optimize division and modulo since there's not check for division by zero with validated calls.
766
op_signature = 0xFFFF;
767
_code_ptr[ip + 5] = op_signature;
768
}
769
#endif
770
771
// Check if this is the first run. If so, store the current signature for the optimized path.
772
if (unlikely(op_signature == 0)) {
773
static Mutex initializer_mutex;
774
initializer_mutex.lock();
775
Variant::Type a_type = (Variant::Type)((actual_signature >> 8) & 0xFF);
776
Variant::Type b_type = (Variant::Type)(actual_signature & 0xFF);
777
778
Variant::ValidatedOperatorEvaluator op_func = Variant::get_validated_operator_evaluator(op, a_type, b_type);
779
780
if (unlikely(!op_func)) {
781
#ifdef DEBUG_ENABLED
782
err_text = "Invalid operands '" + Variant::get_type_name(a->get_type()) + "' and '" + Variant::get_type_name(b->get_type()) + "' in operator '" + Variant::get_operator_name(op) + "'.";
783
#endif
784
initializer_mutex.unlock();
785
OPCODE_BREAK;
786
} else {
787
Variant::Type ret_type = Variant::get_operator_return_type(op, a_type, b_type);
788
VariantInternal::initialize(dst, ret_type);
789
op_func(a, b, dst);
790
791
// Check again in case another thread already set it.
792
if (_code_ptr[ip + 5] == 0) {
793
_code_ptr[ip + 5] = actual_signature;
794
_code_ptr[ip + 6] = static_cast<int>(ret_type);
795
Variant::ValidatedOperatorEvaluator *tmp = reinterpret_cast<Variant::ValidatedOperatorEvaluator *>(&_code_ptr[ip + 7]);
796
*tmp = op_func;
797
}
798
}
799
initializer_mutex.unlock();
800
} else if (likely(op_signature == actual_signature)) {
801
// If the signature matches, we can use the optimized path.
802
Variant::Type ret_type = static_cast<Variant::Type>(_code_ptr[ip + 6]);
803
Variant::ValidatedOperatorEvaluator op_func = *reinterpret_cast<Variant::ValidatedOperatorEvaluator *>(&_code_ptr[ip + 7]);
804
805
// Make sure the return value has the correct type.
806
VariantInternal::initialize(dst, ret_type);
807
op_func(a, b, dst);
808
} else {
809
// If the signature doesn't match, we have to use the slow path.
810
#ifdef DEBUG_ENABLED
811
812
Variant ret;
813
Variant::evaluate(op, *a, *b, ret, valid);
814
#else
815
Variant::evaluate(op, *a, *b, *dst, valid);
816
#endif
817
#ifdef DEBUG_ENABLED
818
if (!valid) {
819
if (ret.get_type() == Variant::STRING) {
820
//return a string when invalid with the error
821
err_text = ret;
822
err_text += " in operator '" + Variant::get_operator_name(op) + "'.";
823
} else {
824
err_text = "Invalid operands '" + Variant::get_type_name(a->get_type()) + "' and '" + Variant::get_type_name(b->get_type()) + "' in operator '" + Variant::get_operator_name(op) + "'.";
825
}
826
OPCODE_BREAK;
827
}
828
*dst = ret;
829
#endif
830
}
831
ip += 7 + _pointer_size;
832
}
833
DISPATCH_OPCODE;
834
835
OPCODE(OPCODE_OPERATOR_VALIDATED) {
836
CHECK_SPACE(5);
837
838
int operator_idx = _code_ptr[ip + 4];
839
GD_ERR_BREAK(operator_idx < 0 || operator_idx >= _operator_funcs_count);
840
Variant::ValidatedOperatorEvaluator operator_func = _operator_funcs_ptr[operator_idx];
841
842
GET_VARIANT_PTR(a, 0);
843
GET_VARIANT_PTR(b, 1);
844
GET_VARIANT_PTR(dst, 2);
845
846
operator_func(a, b, dst);
847
848
ip += 5;
849
}
850
DISPATCH_OPCODE;
851
852
OPCODE(OPCODE_TYPE_TEST_BUILTIN) {
853
CHECK_SPACE(4);
854
855
GET_VARIANT_PTR(dst, 0);
856
GET_VARIANT_PTR(value, 1);
857
858
Variant::Type builtin_type = (Variant::Type)_code_ptr[ip + 3];
859
GD_ERR_BREAK(builtin_type < 0 || builtin_type >= Variant::VARIANT_MAX);
860
861
*dst = value->get_type() == builtin_type;
862
ip += 4;
863
}
864
DISPATCH_OPCODE;
865
866
OPCODE(OPCODE_TYPE_TEST_ARRAY) {
867
CHECK_SPACE(6);
868
869
GET_VARIANT_PTR(dst, 0);
870
GET_VARIANT_PTR(value, 1);
871
872
GET_VARIANT_PTR(script_type, 2);
873
Variant::Type builtin_type = (Variant::Type)_code_ptr[ip + 4];
874
int native_type_idx = _code_ptr[ip + 5];
875
GD_ERR_BREAK(native_type_idx < 0 || native_type_idx >= _global_names_count);
876
const StringName native_type = _global_names_ptr[native_type_idx];
877
878
bool result = false;
879
if (value->get_type() == Variant::ARRAY) {
880
Array *array = VariantInternal::get_array(value);
881
result = array->get_typed_builtin() == ((uint32_t)builtin_type) && array->get_typed_class_name() == native_type && array->get_typed_script() == *script_type;
882
}
883
884
*dst = result;
885
ip += 6;
886
}
887
DISPATCH_OPCODE;
888
889
OPCODE(OPCODE_TYPE_TEST_DICTIONARY) {
890
CHECK_SPACE(9);
891
892
GET_VARIANT_PTR(dst, 0);
893
GET_VARIANT_PTR(value, 1);
894
895
GET_VARIANT_PTR(key_script_type, 2);
896
Variant::Type key_builtin_type = (Variant::Type)_code_ptr[ip + 5];
897
int key_native_type_idx = _code_ptr[ip + 6];
898
GD_ERR_BREAK(key_native_type_idx < 0 || key_native_type_idx >= _global_names_count);
899
const StringName key_native_type = _global_names_ptr[key_native_type_idx];
900
901
GET_VARIANT_PTR(value_script_type, 3);
902
Variant::Type value_builtin_type = (Variant::Type)_code_ptr[ip + 7];
903
int value_native_type_idx = _code_ptr[ip + 8];
904
GD_ERR_BREAK(value_native_type_idx < 0 || value_native_type_idx >= _global_names_count);
905
const StringName value_native_type = _global_names_ptr[value_native_type_idx];
906
907
bool result = false;
908
if (value->get_type() == Variant::DICTIONARY) {
909
Dictionary *dictionary = VariantInternal::get_dictionary(value);
910
result = dictionary->get_typed_key_builtin() == ((uint32_t)key_builtin_type) && dictionary->get_typed_key_class_name() == key_native_type && dictionary->get_typed_key_script() == *key_script_type &&
911
dictionary->get_typed_value_builtin() == ((uint32_t)value_builtin_type) && dictionary->get_typed_value_class_name() == value_native_type && dictionary->get_typed_value_script() == *value_script_type;
912
}
913
914
*dst = result;
915
ip += 9;
916
}
917
DISPATCH_OPCODE;
918
919
OPCODE(OPCODE_TYPE_TEST_NATIVE) {
920
CHECK_SPACE(4);
921
922
GET_VARIANT_PTR(dst, 0);
923
GET_VARIANT_PTR(value, 1);
924
925
int native_type_idx = _code_ptr[ip + 3];
926
GD_ERR_BREAK(native_type_idx < 0 || native_type_idx >= _global_names_count);
927
const StringName native_type = _global_names_ptr[native_type_idx];
928
929
bool was_freed = false;
930
Object *object = value->get_validated_object_with_check(was_freed);
931
if (was_freed) {
932
err_text = "Left operand of 'is' is a previously freed instance.";
933
OPCODE_BREAK;
934
}
935
936
*dst = object && ClassDB::is_parent_class(object->get_class_name(), native_type);
937
ip += 4;
938
}
939
DISPATCH_OPCODE;
940
941
OPCODE(OPCODE_TYPE_TEST_SCRIPT) {
942
CHECK_SPACE(4);
943
944
GET_VARIANT_PTR(dst, 0);
945
GET_VARIANT_PTR(value, 1);
946
947
GET_VARIANT_PTR(type, 2);
948
Script *script_type = Object::cast_to<Script>(type->operator Object *());
949
GD_ERR_BREAK(!script_type);
950
951
bool was_freed = false;
952
Object *object = value->get_validated_object_with_check(was_freed);
953
if (was_freed) {
954
err_text = "Left operand of 'is' is a previously freed instance.";
955
OPCODE_BREAK;
956
}
957
958
bool result = false;
959
if (object && object->get_script_instance()) {
960
Script *script_ptr = object->get_script_instance()->get_script().ptr();
961
while (script_ptr) {
962
if (script_ptr == script_type) {
963
result = true;
964
break;
965
}
966
script_ptr = script_ptr->get_base_script().ptr();
967
}
968
}
969
970
*dst = result;
971
ip += 4;
972
}
973
DISPATCH_OPCODE;
974
975
OPCODE(OPCODE_SET_KEYED) {
976
CHECK_SPACE(3);
977
978
GET_VARIANT_PTR(dst, 0);
979
GET_VARIANT_PTR(index, 1);
980
GET_VARIANT_PTR(value, 2);
981
982
bool valid;
983
#ifdef DEBUG_ENABLED
984
Variant::VariantSetError err_code;
985
dst->set(*index, *value, &valid, &err_code);
986
#else
987
dst->set(*index, *value, &valid);
988
#endif
989
#ifdef DEBUG_ENABLED
990
if (!valid) {
991
if (dst->is_read_only()) {
992
err_text = "Invalid assignment on read-only value (on base: '" + _get_var_type(dst) + "').";
993
} else {
994
Object *obj = dst->get_validated_object();
995
String v = index->operator String();
996
bool read_only_property = false;
997
if (obj) {
998
read_only_property = ClassDB::has_property(obj->get_class_name(), v) && (ClassDB::get_property_setter(obj->get_class_name(), v) == StringName());
999
}
1000
if (read_only_property) {
1001
err_text = vformat(R"(Cannot set value into property "%s" (on base "%s") because it is read-only.)", v, _get_var_type(dst));
1002
} else {
1003
if (!v.is_empty()) {
1004
v = "'" + v + "'";
1005
} else {
1006
v = "of type '" + _get_var_type(index) + "'";
1007
}
1008
err_text = "Invalid assignment of property or key " + v + " with value of type '" + _get_var_type(value) + "' on a base object of type '" + _get_var_type(dst) + "'.";
1009
if (err_code == Variant::VariantSetError::SET_INDEXED_ERR) {
1010
err_text = "Invalid assignment of index " + v + " (on base: '" + _get_var_type(dst) + "') with value of type '" + _get_var_type(value) + "'.";
1011
}
1012
}
1013
}
1014
OPCODE_BREAK;
1015
}
1016
#endif
1017
ip += 4;
1018
}
1019
DISPATCH_OPCODE;
1020
1021
OPCODE(OPCODE_SET_KEYED_VALIDATED) {
1022
CHECK_SPACE(4);
1023
1024
GET_VARIANT_PTR(dst, 0);
1025
GET_VARIANT_PTR(index, 1);
1026
GET_VARIANT_PTR(value, 2);
1027
1028
int index_setter = _code_ptr[ip + 4];
1029
GD_ERR_BREAK(index_setter < 0 || index_setter >= _keyed_setters_count);
1030
const Variant::ValidatedKeyedSetter setter = _keyed_setters_ptr[index_setter];
1031
1032
bool valid;
1033
setter(dst, index, value, &valid);
1034
1035
#ifdef DEBUG_ENABLED
1036
if (!valid) {
1037
if (dst->is_read_only()) {
1038
err_text = "Invalid assignment on read-only value (on base: '" + _get_var_type(dst) + "').";
1039
} else {
1040
String v = index->operator String();
1041
if (!v.is_empty()) {
1042
v = "'" + v + "'";
1043
} else {
1044
v = "of type '" + _get_var_type(index) + "'";
1045
}
1046
err_text = "Invalid assignment of property or key " + v + " with value of type '" + _get_var_type(value) + "' on a base object of type '" + _get_var_type(dst) + "'.";
1047
}
1048
OPCODE_BREAK;
1049
}
1050
#endif
1051
ip += 5;
1052
}
1053
DISPATCH_OPCODE;
1054
1055
OPCODE(OPCODE_SET_INDEXED_VALIDATED) {
1056
CHECK_SPACE(4);
1057
1058
GET_VARIANT_PTR(dst, 0);
1059
GET_VARIANT_PTR(index, 1);
1060
GET_VARIANT_PTR(value, 2);
1061
1062
int index_setter = _code_ptr[ip + 4];
1063
GD_ERR_BREAK(index_setter < 0 || index_setter >= _indexed_setters_count);
1064
const Variant::ValidatedIndexedSetter setter = _indexed_setters_ptr[index_setter];
1065
1066
int64_t int_index = *VariantInternal::get_int(index);
1067
1068
bool oob;
1069
setter(dst, int_index, value, &oob);
1070
1071
#ifdef DEBUG_ENABLED
1072
if (oob) {
1073
if (dst->is_read_only()) {
1074
err_text = "Invalid assignment on read-only value (on base: '" + _get_var_type(dst) + "').";
1075
} else {
1076
String v = index->operator String();
1077
if (!v.is_empty()) {
1078
v = "'" + v + "'";
1079
} else {
1080
v = "of type '" + _get_var_type(index) + "'";
1081
}
1082
err_text = "Out of bounds set index " + v + " (on base: '" + _get_var_type(dst) + "')";
1083
}
1084
OPCODE_BREAK;
1085
}
1086
#endif
1087
ip += 5;
1088
}
1089
DISPATCH_OPCODE;
1090
1091
OPCODE(OPCODE_GET_KEYED) {
1092
CHECK_SPACE(3);
1093
1094
GET_VARIANT_PTR(src, 0);
1095
GET_VARIANT_PTR(index, 1);
1096
GET_VARIANT_PTR(dst, 2);
1097
1098
bool valid;
1099
#ifdef DEBUG_ENABLED
1100
// Allow better error message in cases where src and dst are the same stack position.
1101
Variant::VariantGetError err_code;
1102
Variant ret = src->get(*index, &valid, &err_code);
1103
#else
1104
*dst = src->get(*index, &valid);
1105
1106
#endif
1107
#ifdef DEBUG_ENABLED
1108
if (!valid) {
1109
String v = index->operator String();
1110
if (!v.is_empty()) {
1111
v = "'" + v + "'";
1112
} else {
1113
v = "of type '" + _get_var_type(index) + "'";
1114
}
1115
err_text = "Invalid access to property or key " + v + " on a base object of type '" + _get_var_type(src) + "'.";
1116
if (err_code == Variant::VariantGetError::GET_INDEXED_ERR) {
1117
err_text = "Invalid access of index " + v + " on a base object of type: '" + _get_var_type(src) + "'.";
1118
}
1119
OPCODE_BREAK;
1120
}
1121
*dst = ret;
1122
#endif
1123
ip += 4;
1124
}
1125
DISPATCH_OPCODE;
1126
1127
OPCODE(OPCODE_GET_KEYED_VALIDATED) {
1128
CHECK_SPACE(4);
1129
1130
GET_VARIANT_PTR(src, 0);
1131
GET_VARIANT_PTR(key, 1);
1132
GET_VARIANT_PTR(dst, 2);
1133
1134
int index_getter = _code_ptr[ip + 4];
1135
GD_ERR_BREAK(index_getter < 0 || index_getter >= _keyed_getters_count);
1136
const Variant::ValidatedKeyedGetter getter = _keyed_getters_ptr[index_getter];
1137
1138
bool valid;
1139
#ifdef DEBUG_ENABLED
1140
// Allow better error message in cases where src and dst are the same stack position.
1141
Variant ret;
1142
getter(src, key, &ret, &valid);
1143
#else
1144
getter(src, key, dst, &valid);
1145
#endif
1146
#ifdef DEBUG_ENABLED
1147
if (!valid) {
1148
String v = key->operator String();
1149
if (!v.is_empty()) {
1150
v = "'" + v + "'";
1151
} else {
1152
v = "of type '" + _get_var_type(key) + "'";
1153
}
1154
err_text = "Invalid access to property or key " + v + " on a base object of type '" + _get_var_type(src) + "'.";
1155
OPCODE_BREAK;
1156
}
1157
*dst = ret;
1158
#endif
1159
ip += 5;
1160
}
1161
DISPATCH_OPCODE;
1162
1163
OPCODE(OPCODE_GET_INDEXED_VALIDATED) {
1164
CHECK_SPACE(4);
1165
1166
GET_VARIANT_PTR(src, 0);
1167
GET_VARIANT_PTR(index, 1);
1168
GET_VARIANT_PTR(dst, 2);
1169
1170
int index_getter = _code_ptr[ip + 4];
1171
GD_ERR_BREAK(index_getter < 0 || index_getter >= _indexed_getters_count);
1172
const Variant::ValidatedIndexedGetter getter = _indexed_getters_ptr[index_getter];
1173
1174
int64_t int_index = *VariantInternal::get_int(index);
1175
1176
bool oob;
1177
getter(src, int_index, dst, &oob);
1178
1179
#ifdef DEBUG_ENABLED
1180
if (oob) {
1181
String v = index->operator String();
1182
if (!v.is_empty()) {
1183
v = "'" + v + "'";
1184
} else {
1185
v = "of type '" + _get_var_type(index) + "'";
1186
}
1187
err_text = "Out of bounds get index " + v + " (on base: '" + _get_var_type(src) + "')";
1188
OPCODE_BREAK;
1189
}
1190
#endif
1191
ip += 5;
1192
}
1193
DISPATCH_OPCODE;
1194
1195
OPCODE(OPCODE_SET_NAMED) {
1196
CHECK_SPACE(3);
1197
1198
GET_VARIANT_PTR(dst, 0);
1199
GET_VARIANT_PTR(value, 1);
1200
1201
int indexname = _code_ptr[ip + 3];
1202
1203
GD_ERR_BREAK(indexname < 0 || indexname >= _global_names_count);
1204
const StringName *index = &_global_names_ptr[indexname];
1205
1206
bool valid;
1207
dst->set_named(*index, *value, valid);
1208
1209
#ifdef DEBUG_ENABLED
1210
if (!valid) {
1211
if (dst->is_read_only()) {
1212
err_text = "Invalid assignment on read-only value (on base: '" + _get_var_type(dst) + "').";
1213
} else {
1214
Object *obj = dst->get_validated_object();
1215
bool read_only_property = false;
1216
if (obj) {
1217
read_only_property = ClassDB::has_property(obj->get_class_name(), *index) && (ClassDB::get_property_setter(obj->get_class_name(), *index) == StringName());
1218
}
1219
if (read_only_property) {
1220
err_text = vformat(R"(Cannot set value into property "%s" (on base "%s") because it is read-only.)", String(*index), _get_var_type(dst));
1221
} else {
1222
err_text = "Invalid assignment of property or key '" + String(*index) + "' with value of type '" + _get_var_type(value) + "' on a base object of type '" + _get_var_type(dst) + "'.";
1223
}
1224
}
1225
OPCODE_BREAK;
1226
}
1227
#endif
1228
ip += 4;
1229
}
1230
DISPATCH_OPCODE;
1231
1232
OPCODE(OPCODE_SET_NAMED_VALIDATED) {
1233
CHECK_SPACE(3);
1234
1235
GET_VARIANT_PTR(dst, 0);
1236
GET_VARIANT_PTR(value, 1);
1237
1238
int index_setter = _code_ptr[ip + 3];
1239
GD_ERR_BREAK(index_setter < 0 || index_setter >= _setters_count);
1240
const Variant::ValidatedSetter setter = _setters_ptr[index_setter];
1241
1242
setter(dst, value);
1243
ip += 4;
1244
}
1245
DISPATCH_OPCODE;
1246
1247
OPCODE(OPCODE_GET_NAMED) {
1248
CHECK_SPACE(4);
1249
1250
GET_VARIANT_PTR(src, 0);
1251
GET_VARIANT_PTR(dst, 1);
1252
1253
int indexname = _code_ptr[ip + 3];
1254
1255
GD_ERR_BREAK(indexname < 0 || indexname >= _global_names_count);
1256
const StringName *index = &_global_names_ptr[indexname];
1257
1258
bool valid;
1259
#ifdef DEBUG_ENABLED
1260
//allow better error message in cases where src and dst are the same stack position
1261
Variant ret = src->get_named(*index, valid);
1262
1263
#else
1264
*dst = src->get_named(*index, valid);
1265
#endif
1266
#ifdef DEBUG_ENABLED
1267
if (!valid) {
1268
err_text = "Invalid access to property or key '" + index->operator String() + "' on a base object of type '" + _get_var_type(src) + "'.";
1269
OPCODE_BREAK;
1270
}
1271
*dst = ret;
1272
#endif
1273
ip += 4;
1274
}
1275
DISPATCH_OPCODE;
1276
1277
OPCODE(OPCODE_GET_NAMED_VALIDATED) {
1278
CHECK_SPACE(3);
1279
1280
GET_VARIANT_PTR(src, 0);
1281
GET_VARIANT_PTR(dst, 1);
1282
1283
int index_getter = _code_ptr[ip + 3];
1284
GD_ERR_BREAK(index_getter < 0 || index_getter >= _getters_count);
1285
const Variant::ValidatedGetter getter = _getters_ptr[index_getter];
1286
1287
getter(src, dst);
1288
ip += 4;
1289
}
1290
DISPATCH_OPCODE;
1291
1292
OPCODE(OPCODE_SET_MEMBER) {
1293
CHECK_SPACE(3);
1294
GET_VARIANT_PTR(src, 0);
1295
int indexname = _code_ptr[ip + 2];
1296
GD_ERR_BREAK(indexname < 0 || indexname >= _global_names_count);
1297
const StringName *index = &_global_names_ptr[indexname];
1298
1299
bool valid;
1300
#ifndef DEBUG_ENABLED
1301
ClassDB::set_property(p_instance->owner, *index, *src, &valid);
1302
#else
1303
bool ok = ClassDB::set_property(p_instance->owner, *index, *src, &valid);
1304
if (!ok) {
1305
err_text = "Internal error setting property: " + String(*index);
1306
OPCODE_BREAK;
1307
} else if (!valid) {
1308
err_text = "Error setting property '" + String(*index) + "' with value of type " + Variant::get_type_name(src->get_type()) + ".";
1309
OPCODE_BREAK;
1310
}
1311
#endif
1312
ip += 3;
1313
}
1314
DISPATCH_OPCODE;
1315
1316
OPCODE(OPCODE_GET_MEMBER) {
1317
CHECK_SPACE(3);
1318
GET_VARIANT_PTR(dst, 0);
1319
int indexname = _code_ptr[ip + 2];
1320
GD_ERR_BREAK(indexname < 0 || indexname >= _global_names_count);
1321
const StringName *index = &_global_names_ptr[indexname];
1322
#ifndef DEBUG_ENABLED
1323
ClassDB::get_property(p_instance->owner, *index, *dst);
1324
#else
1325
bool ok = ClassDB::get_property(p_instance->owner, *index, *dst);
1326
if (!ok) {
1327
err_text = "Internal error getting property: " + String(*index);
1328
OPCODE_BREAK;
1329
}
1330
#endif
1331
ip += 3;
1332
}
1333
DISPATCH_OPCODE;
1334
1335
OPCODE(OPCODE_SET_STATIC_VARIABLE) {
1336
CHECK_SPACE(4);
1337
1338
GET_VARIANT_PTR(value, 0);
1339
1340
GET_VARIANT_PTR(_class, 1);
1341
GDScript *gdscript = Object::cast_to<GDScript>(_class->operator Object *());
1342
GD_ERR_BREAK(!gdscript);
1343
1344
int index = _code_ptr[ip + 3];
1345
GD_ERR_BREAK(index < 0 || index >= gdscript->static_variables.size());
1346
1347
gdscript->static_variables.write[index] = *value;
1348
1349
ip += 4;
1350
}
1351
DISPATCH_OPCODE;
1352
1353
OPCODE(OPCODE_GET_STATIC_VARIABLE) {
1354
CHECK_SPACE(4);
1355
1356
GET_VARIANT_PTR(target, 0);
1357
1358
GET_VARIANT_PTR(_class, 1);
1359
GDScript *gdscript = Object::cast_to<GDScript>(_class->operator Object *());
1360
GD_ERR_BREAK(!gdscript);
1361
1362
int index = _code_ptr[ip + 3];
1363
GD_ERR_BREAK(index < 0 || index >= gdscript->static_variables.size());
1364
1365
*target = gdscript->static_variables[index];
1366
1367
ip += 4;
1368
}
1369
DISPATCH_OPCODE;
1370
1371
OPCODE(OPCODE_ASSIGN) {
1372
CHECK_SPACE(3);
1373
GET_VARIANT_PTR(dst, 0);
1374
GET_VARIANT_PTR(src, 1);
1375
1376
*dst = *src;
1377
1378
ip += 3;
1379
}
1380
DISPATCH_OPCODE;
1381
1382
OPCODE(OPCODE_ASSIGN_NULL) {
1383
CHECK_SPACE(2);
1384
GET_VARIANT_PTR(dst, 0);
1385
1386
*dst = Variant();
1387
1388
ip += 2;
1389
}
1390
DISPATCH_OPCODE;
1391
1392
OPCODE(OPCODE_ASSIGN_TRUE) {
1393
CHECK_SPACE(2);
1394
GET_VARIANT_PTR(dst, 0);
1395
1396
*dst = true;
1397
1398
ip += 2;
1399
}
1400
DISPATCH_OPCODE;
1401
1402
OPCODE(OPCODE_ASSIGN_FALSE) {
1403
CHECK_SPACE(2);
1404
GET_VARIANT_PTR(dst, 0);
1405
1406
*dst = false;
1407
1408
ip += 2;
1409
}
1410
DISPATCH_OPCODE;
1411
1412
OPCODE(OPCODE_ASSIGN_TYPED_BUILTIN) {
1413
CHECK_SPACE(4);
1414
GET_VARIANT_PTR(dst, 0);
1415
GET_VARIANT_PTR(src, 1);
1416
1417
Variant::Type var_type = (Variant::Type)_code_ptr[ip + 3];
1418
GD_ERR_BREAK(var_type < 0 || var_type >= Variant::VARIANT_MAX);
1419
1420
if (src->get_type() != var_type) {
1421
#ifdef DEBUG_ENABLED
1422
if (Variant::can_convert_strict(src->get_type(), var_type)) {
1423
#endif // DEBUG_ENABLED
1424
Callable::CallError ce;
1425
Variant::construct(var_type, *dst, const_cast<const Variant **>(&src), 1, ce);
1426
} else {
1427
#ifdef DEBUG_ENABLED
1428
err_text = "Trying to assign value of type '" + Variant::get_type_name(src->get_type()) +
1429
"' to a variable of type '" + Variant::get_type_name(var_type) + "'.";
1430
OPCODE_BREAK;
1431
}
1432
} else {
1433
#endif // DEBUG_ENABLED
1434
*dst = *src;
1435
}
1436
1437
ip += 4;
1438
}
1439
DISPATCH_OPCODE;
1440
1441
OPCODE(OPCODE_ASSIGN_TYPED_ARRAY) {
1442
CHECK_SPACE(6);
1443
GET_VARIANT_PTR(dst, 0);
1444
GET_VARIANT_PTR(src, 1);
1445
1446
GET_VARIANT_PTR(script_type, 2);
1447
Variant::Type builtin_type = (Variant::Type)_code_ptr[ip + 4];
1448
int native_type_idx = _code_ptr[ip + 5];
1449
GD_ERR_BREAK(native_type_idx < 0 || native_type_idx >= _global_names_count);
1450
const StringName native_type = _global_names_ptr[native_type_idx];
1451
1452
if (src->get_type() != Variant::ARRAY) {
1453
#ifdef DEBUG_ENABLED
1454
err_text = vformat(R"(Trying to assign a value of type "%s" to a variable of type "Array[%s]".)",
1455
_get_var_type(src), _get_element_type(builtin_type, native_type, *script_type));
1456
#endif // DEBUG_ENABLED
1457
OPCODE_BREAK;
1458
}
1459
1460
Array *array = VariantInternal::get_array(src);
1461
1462
if (array->get_typed_builtin() != ((uint32_t)builtin_type) || array->get_typed_class_name() != native_type || array->get_typed_script() != *script_type) {
1463
#ifdef DEBUG_ENABLED
1464
err_text = vformat(R"(Trying to assign an array of type "%s" to a variable of type "Array[%s]".)",
1465
_get_var_type(src), _get_element_type(builtin_type, native_type, *script_type));
1466
#endif // DEBUG_ENABLED
1467
OPCODE_BREAK;
1468
}
1469
1470
*dst = *src;
1471
1472
ip += 6;
1473
}
1474
DISPATCH_OPCODE;
1475
1476
OPCODE(OPCODE_ASSIGN_TYPED_DICTIONARY) {
1477
CHECK_SPACE(9);
1478
GET_VARIANT_PTR(dst, 0);
1479
GET_VARIANT_PTR(src, 1);
1480
1481
GET_VARIANT_PTR(key_script_type, 2);
1482
Variant::Type key_builtin_type = (Variant::Type)_code_ptr[ip + 5];
1483
int key_native_type_idx = _code_ptr[ip + 6];
1484
GD_ERR_BREAK(key_native_type_idx < 0 || key_native_type_idx >= _global_names_count);
1485
const StringName key_native_type = _global_names_ptr[key_native_type_idx];
1486
1487
GET_VARIANT_PTR(value_script_type, 3);
1488
Variant::Type value_builtin_type = (Variant::Type)_code_ptr[ip + 7];
1489
int value_native_type_idx = _code_ptr[ip + 8];
1490
GD_ERR_BREAK(value_native_type_idx < 0 || value_native_type_idx >= _global_names_count);
1491
const StringName value_native_type = _global_names_ptr[value_native_type_idx];
1492
1493
if (src->get_type() != Variant::DICTIONARY) {
1494
#ifdef DEBUG_ENABLED
1495
err_text = vformat(R"(Trying to assign a value of type "%s" to a variable of type "Dictionary[%s, %s]".)",
1496
_get_var_type(src), _get_element_type(key_builtin_type, key_native_type, *key_script_type),
1497
_get_element_type(value_builtin_type, value_native_type, *value_script_type));
1498
#endif // DEBUG_ENABLED
1499
OPCODE_BREAK;
1500
}
1501
1502
Dictionary *dictionary = VariantInternal::get_dictionary(src);
1503
1504
if (dictionary->get_typed_key_builtin() != ((uint32_t)key_builtin_type) || dictionary->get_typed_key_class_name() != key_native_type || dictionary->get_typed_key_script() != *key_script_type ||
1505
dictionary->get_typed_value_builtin() != ((uint32_t)value_builtin_type) || dictionary->get_typed_value_class_name() != value_native_type || dictionary->get_typed_value_script() != *value_script_type) {
1506
#ifdef DEBUG_ENABLED
1507
err_text = vformat(R"(Trying to assign a dictionary of type "%s" to a variable of type "Dictionary[%s, %s]".)",
1508
_get_var_type(src), _get_element_type(key_builtin_type, key_native_type, *key_script_type),
1509
_get_element_type(value_builtin_type, value_native_type, *value_script_type));
1510
#endif // DEBUG_ENABLED
1511
OPCODE_BREAK;
1512
}
1513
1514
*dst = *src;
1515
1516
ip += 9;
1517
}
1518
DISPATCH_OPCODE;
1519
1520
OPCODE(OPCODE_ASSIGN_TYPED_NATIVE) {
1521
CHECK_SPACE(4);
1522
GET_VARIANT_PTR(dst, 0);
1523
GET_VARIANT_PTR(src, 1);
1524
1525
#ifdef DEBUG_ENABLED
1526
GET_VARIANT_PTR(type, 2);
1527
GDScriptNativeClass *nc = Object::cast_to<GDScriptNativeClass>(type->operator Object *());
1528
GD_ERR_BREAK(!nc);
1529
if (src->get_type() != Variant::OBJECT && src->get_type() != Variant::NIL) {
1530
err_text = "Trying to assign value of type '" + Variant::get_type_name(src->get_type()) +
1531
"' to a variable of type '" + nc->get_name() + "'.";
1532
OPCODE_BREAK;
1533
}
1534
1535
if (src->get_type() == Variant::OBJECT) {
1536
bool was_freed = false;
1537
Object *src_obj = src->get_validated_object_with_check(was_freed);
1538
if (!src_obj && was_freed) {
1539
err_text = "Trying to assign invalid previously freed instance.";
1540
OPCODE_BREAK;
1541
}
1542
1543
if (src_obj && !ClassDB::is_parent_class(src_obj->get_class_name(), nc->get_name())) {
1544
err_text = "Trying to assign value of type '" + src_obj->get_class_name() +
1545
"' to a variable of type '" + nc->get_name() + "'.";
1546
OPCODE_BREAK;
1547
}
1548
}
1549
#endif // DEBUG_ENABLED
1550
*dst = *src;
1551
1552
ip += 4;
1553
}
1554
DISPATCH_OPCODE;
1555
1556
OPCODE(OPCODE_ASSIGN_TYPED_SCRIPT) {
1557
CHECK_SPACE(4);
1558
GET_VARIANT_PTR(dst, 0);
1559
GET_VARIANT_PTR(src, 1);
1560
1561
#ifdef DEBUG_ENABLED
1562
GET_VARIANT_PTR(type, 2);
1563
Script *base_type = Object::cast_to<Script>(type->operator Object *());
1564
1565
GD_ERR_BREAK(!base_type);
1566
1567
if (src->get_type() != Variant::OBJECT && src->get_type() != Variant::NIL) {
1568
err_text = "Trying to assign a non-object value to a variable of type '" + base_type->get_path().get_file() + "'.";
1569
OPCODE_BREAK;
1570
}
1571
1572
if (src->get_type() == Variant::OBJECT) {
1573
bool was_freed = false;
1574
Object *val_obj = src->get_validated_object_with_check(was_freed);
1575
if (!val_obj && was_freed) {
1576
err_text = "Trying to assign invalid previously freed instance.";
1577
OPCODE_BREAK;
1578
}
1579
1580
if (val_obj) { // src is not null
1581
ScriptInstance *scr_inst = val_obj->get_script_instance();
1582
if (!scr_inst) {
1583
err_text = "Trying to assign value of type '" + val_obj->get_class_name() +
1584
"' to a variable of type '" + base_type->get_path().get_file() + "'.";
1585
OPCODE_BREAK;
1586
}
1587
1588
Script *src_type = scr_inst->get_script().ptr();
1589
bool valid = false;
1590
1591
while (src_type) {
1592
if (src_type == base_type) {
1593
valid = true;
1594
break;
1595
}
1596
src_type = src_type->get_base_script().ptr();
1597
}
1598
1599
if (!valid) {
1600
err_text = "Trying to assign value of type '" + val_obj->get_script_instance()->get_script()->get_path().get_file() +
1601
"' to a variable of type '" + base_type->get_path().get_file() + "'.";
1602
OPCODE_BREAK;
1603
}
1604
}
1605
}
1606
#endif // DEBUG_ENABLED
1607
1608
*dst = *src;
1609
1610
ip += 4;
1611
}
1612
DISPATCH_OPCODE;
1613
1614
OPCODE(OPCODE_CAST_TO_BUILTIN) {
1615
CHECK_SPACE(4);
1616
GET_VARIANT_PTR(src, 0);
1617
GET_VARIANT_PTR(dst, 1);
1618
Variant::Type to_type = (Variant::Type)_code_ptr[ip + 3];
1619
1620
GD_ERR_BREAK(to_type < 0 || to_type >= Variant::VARIANT_MAX);
1621
1622
#ifdef DEBUG_ENABLED
1623
if (src->operator Object *() && !src->get_validated_object()) {
1624
err_text = "Trying to cast a freed object.";
1625
OPCODE_BREAK;
1626
}
1627
#endif
1628
1629
Callable::CallError err;
1630
Variant::construct(to_type, *dst, (const Variant **)&src, 1, err);
1631
1632
#ifdef DEBUG_ENABLED
1633
if (err.error != Callable::CallError::CALL_OK) {
1634
err_text = "Invalid cast: could not convert value to '" + Variant::get_type_name(to_type) + "'.";
1635
OPCODE_BREAK;
1636
}
1637
#endif
1638
1639
ip += 4;
1640
}
1641
DISPATCH_OPCODE;
1642
1643
OPCODE(OPCODE_CAST_TO_NATIVE) {
1644
CHECK_SPACE(4);
1645
GET_VARIANT_PTR(src, 0);
1646
GET_VARIANT_PTR(dst, 1);
1647
GET_VARIANT_PTR(to_type, 2);
1648
1649
GDScriptNativeClass *nc = Object::cast_to<GDScriptNativeClass>(to_type->operator Object *());
1650
GD_ERR_BREAK(!nc);
1651
1652
#ifdef DEBUG_ENABLED
1653
if (src->operator Object *() && !src->get_validated_object()) {
1654
err_text = "Trying to cast a freed object.";
1655
OPCODE_BREAK;
1656
}
1657
if (src->get_type() != Variant::OBJECT && src->get_type() != Variant::NIL) {
1658
err_text = "Invalid cast: can't convert a non-object value to an object type.";
1659
OPCODE_BREAK;
1660
}
1661
#endif
1662
Object *src_obj = src->operator Object *();
1663
1664
if (src_obj && !ClassDB::is_parent_class(src_obj->get_class_name(), nc->get_name())) {
1665
*dst = Variant(); // invalid cast, assign NULL
1666
} else {
1667
*dst = *src;
1668
}
1669
1670
ip += 4;
1671
}
1672
DISPATCH_OPCODE;
1673
1674
OPCODE(OPCODE_CAST_TO_SCRIPT) {
1675
CHECK_SPACE(4);
1676
GET_VARIANT_PTR(src, 0);
1677
GET_VARIANT_PTR(dst, 1);
1678
GET_VARIANT_PTR(to_type, 2);
1679
1680
Script *base_type = Object::cast_to<Script>(to_type->operator Object *());
1681
1682
GD_ERR_BREAK(!base_type);
1683
1684
#ifdef DEBUG_ENABLED
1685
if (src->operator Object *() && !src->get_validated_object()) {
1686
err_text = "Trying to cast a freed object.";
1687
OPCODE_BREAK;
1688
}
1689
if (src->get_type() != Variant::OBJECT && src->get_type() != Variant::NIL) {
1690
err_text = "Trying to assign a non-object value to a variable of type '" + base_type->get_path().get_file() + "'.";
1691
OPCODE_BREAK;
1692
}
1693
#endif
1694
1695
bool valid = false;
1696
1697
if (src->get_type() != Variant::NIL && src->operator Object *() != nullptr) {
1698
ScriptInstance *scr_inst = src->operator Object *()->get_script_instance();
1699
1700
if (scr_inst) {
1701
Script *src_type = src->operator Object *()->get_script_instance()->get_script().ptr();
1702
1703
while (src_type) {
1704
if (src_type == base_type) {
1705
valid = true;
1706
break;
1707
}
1708
src_type = src_type->get_base_script().ptr();
1709
}
1710
}
1711
}
1712
1713
if (valid) {
1714
*dst = *src; // Valid cast, copy the source object
1715
} else {
1716
*dst = Variant(); // invalid cast, assign NULL
1717
}
1718
1719
ip += 4;
1720
}
1721
DISPATCH_OPCODE;
1722
1723
OPCODE(OPCODE_CONSTRUCT) {
1724
LOAD_INSTRUCTION_ARGS
1725
CHECK_SPACE(2 + instr_arg_count);
1726
1727
ip += instr_arg_count;
1728
1729
int argc = _code_ptr[ip + 1];
1730
1731
Variant::Type t = Variant::Type(_code_ptr[ip + 2]);
1732
1733
Variant **argptrs = instruction_args;
1734
1735
GET_INSTRUCTION_ARG(dst, argc);
1736
1737
Callable::CallError err;
1738
Variant::construct(t, *dst, (const Variant **)argptrs, argc, err);
1739
1740
#ifdef DEBUG_ENABLED
1741
if (err.error != Callable::CallError::CALL_OK) {
1742
err_text = _get_call_error("'" + Variant::get_type_name(t) + "' constructor", (const Variant **)argptrs, argc, *dst, err);
1743
OPCODE_BREAK;
1744
}
1745
#endif
1746
1747
ip += 3;
1748
}
1749
DISPATCH_OPCODE;
1750
1751
OPCODE(OPCODE_CONSTRUCT_VALIDATED) {
1752
LOAD_INSTRUCTION_ARGS
1753
CHECK_SPACE(2 + instr_arg_count);
1754
ip += instr_arg_count;
1755
1756
int argc = _code_ptr[ip + 1];
1757
1758
int constructor_idx = _code_ptr[ip + 2];
1759
GD_ERR_BREAK(constructor_idx < 0 || constructor_idx >= _constructors_count);
1760
Variant::ValidatedConstructor constructor = _constructors_ptr[constructor_idx];
1761
1762
Variant **argptrs = instruction_args;
1763
1764
GET_INSTRUCTION_ARG(dst, argc);
1765
1766
constructor(dst, (const Variant **)argptrs);
1767
1768
ip += 3;
1769
}
1770
DISPATCH_OPCODE;
1771
1772
OPCODE(OPCODE_CONSTRUCT_ARRAY) {
1773
LOAD_INSTRUCTION_ARGS
1774
CHECK_SPACE(1 + instr_arg_count);
1775
ip += instr_arg_count;
1776
1777
int argc = _code_ptr[ip + 1];
1778
Array array;
1779
array.resize(argc);
1780
1781
for (int i = 0; i < argc; i++) {
1782
array[i] = *(instruction_args[i]);
1783
}
1784
1785
GET_INSTRUCTION_ARG(dst, argc);
1786
*dst = Variant(); // Clear potential previous typed array.
1787
1788
*dst = array;
1789
1790
ip += 2;
1791
}
1792
DISPATCH_OPCODE;
1793
1794
OPCODE(OPCODE_CONSTRUCT_TYPED_ARRAY) {
1795
LOAD_INSTRUCTION_ARGS
1796
CHECK_SPACE(3 + instr_arg_count);
1797
ip += instr_arg_count;
1798
1799
int argc = _code_ptr[ip + 1];
1800
1801
GET_INSTRUCTION_ARG(script_type, argc + 1);
1802
Variant::Type builtin_type = (Variant::Type)_code_ptr[ip + 2];
1803
int native_type_idx = _code_ptr[ip + 3];
1804
GD_ERR_BREAK(native_type_idx < 0 || native_type_idx >= _global_names_count);
1805
const StringName native_type = _global_names_ptr[native_type_idx];
1806
1807
Array array;
1808
array.resize(argc);
1809
for (int i = 0; i < argc; i++) {
1810
array[i] = *(instruction_args[i]);
1811
}
1812
1813
GET_INSTRUCTION_ARG(dst, argc);
1814
*dst = Variant(); // Clear potential previous typed array.
1815
1816
*dst = Array(array, builtin_type, native_type, *script_type);
1817
1818
ip += 4;
1819
}
1820
DISPATCH_OPCODE;
1821
1822
OPCODE(OPCODE_CONSTRUCT_DICTIONARY) {
1823
LOAD_INSTRUCTION_ARGS
1824
CHECK_SPACE(2 + instr_arg_count);
1825
1826
ip += instr_arg_count;
1827
1828
int argc = _code_ptr[ip + 1];
1829
Dictionary dict;
1830
1831
for (int i = 0; i < argc; i++) {
1832
GET_INSTRUCTION_ARG(k, i * 2 + 0);
1833
GET_INSTRUCTION_ARG(v, i * 2 + 1);
1834
dict[*k] = *v;
1835
}
1836
1837
GET_INSTRUCTION_ARG(dst, argc * 2);
1838
1839
*dst = Variant(); // Clear potential previous typed dictionary.
1840
1841
*dst = dict;
1842
1843
ip += 2;
1844
}
1845
DISPATCH_OPCODE;
1846
1847
OPCODE(OPCODE_CONSTRUCT_TYPED_DICTIONARY) {
1848
LOAD_INSTRUCTION_ARGS
1849
CHECK_SPACE(6 + instr_arg_count);
1850
ip += instr_arg_count;
1851
1852
int argc = _code_ptr[ip + 1];
1853
1854
GET_INSTRUCTION_ARG(key_script_type, argc * 2 + 1);
1855
Variant::Type key_builtin_type = (Variant::Type)_code_ptr[ip + 2];
1856
int key_native_type_idx = _code_ptr[ip + 3];
1857
GD_ERR_BREAK(key_native_type_idx < 0 || key_native_type_idx >= _global_names_count);
1858
const StringName key_native_type = _global_names_ptr[key_native_type_idx];
1859
1860
GET_INSTRUCTION_ARG(value_script_type, argc * 2 + 2);
1861
Variant::Type value_builtin_type = (Variant::Type)_code_ptr[ip + 4];
1862
int value_native_type_idx = _code_ptr[ip + 5];
1863
GD_ERR_BREAK(value_native_type_idx < 0 || value_native_type_idx >= _global_names_count);
1864
const StringName value_native_type = _global_names_ptr[value_native_type_idx];
1865
1866
Dictionary dict;
1867
1868
for (int i = 0; i < argc; i++) {
1869
GET_INSTRUCTION_ARG(k, i * 2 + 0);
1870
GET_INSTRUCTION_ARG(v, i * 2 + 1);
1871
dict[*k] = *v;
1872
}
1873
1874
GET_INSTRUCTION_ARG(dst, argc * 2);
1875
1876
*dst = Variant(); // Clear potential previous typed dictionary.
1877
1878
*dst = Dictionary(dict, key_builtin_type, key_native_type, *key_script_type, value_builtin_type, value_native_type, *value_script_type);
1879
1880
ip += 6;
1881
}
1882
DISPATCH_OPCODE;
1883
1884
OPCODE(OPCODE_CALL_ASYNC)
1885
OPCODE(OPCODE_CALL_RETURN)
1886
OPCODE(OPCODE_CALL) {
1887
bool call_ret = (_code_ptr[ip]) != OPCODE_CALL;
1888
#ifdef DEBUG_ENABLED
1889
bool call_async = (_code_ptr[ip]) == OPCODE_CALL_ASYNC;
1890
#endif
1891
LOAD_INSTRUCTION_ARGS
1892
CHECK_SPACE(3 + instr_arg_count);
1893
1894
ip += instr_arg_count;
1895
1896
int argc = _code_ptr[ip + 1];
1897
GD_ERR_BREAK(argc < 0);
1898
1899
int methodname_idx = _code_ptr[ip + 2];
1900
GD_ERR_BREAK(methodname_idx < 0 || methodname_idx >= _global_names_count);
1901
const StringName *methodname = &_global_names_ptr[methodname_idx];
1902
1903
GET_INSTRUCTION_ARG(base, argc);
1904
Variant **argptrs = instruction_args;
1905
1906
#ifdef DEBUG_ENABLED
1907
uint64_t call_time = 0;
1908
1909
if (GDScriptLanguage::get_singleton()->profiling) {
1910
call_time = OS::get_singleton()->get_ticks_usec();
1911
}
1912
Variant::Type base_type = base->get_type();
1913
Object *base_obj = base->get_validated_object();
1914
StringName base_class = base_obj ? base_obj->get_class_name() : StringName();
1915
#endif
1916
1917
Variant temp_ret;
1918
Callable::CallError err;
1919
if (call_ret) {
1920
GET_INSTRUCTION_ARG(ret, argc + 1);
1921
base->callp(*methodname, (const Variant **)argptrs, argc, temp_ret, err);
1922
*ret = temp_ret;
1923
#ifdef DEBUG_ENABLED
1924
if (ret->get_type() == Variant::NIL) {
1925
if (base_type == Variant::OBJECT) {
1926
if (base_obj) {
1927
MethodBind *method = ClassDB::get_method(base_class, *methodname);
1928
if (*methodname == CoreStringName(free_) || (method && !method->has_return())) {
1929
err_text = R"(Trying to get a return value of a method that returns "void")";
1930
OPCODE_BREAK;
1931
}
1932
}
1933
} else if (Variant::has_builtin_method(base_type, *methodname) && !Variant::has_builtin_method_return_value(base_type, *methodname)) {
1934
err_text = R"(Trying to get a return value of a method that returns "void")";
1935
OPCODE_BREAK;
1936
}
1937
}
1938
1939
if (!call_async && ret->get_type() == Variant::OBJECT) {
1940
// Check if getting a function state without await.
1941
bool was_freed = false;
1942
Object *obj = ret->get_validated_object_with_check(was_freed);
1943
1944
if (obj && obj->is_class_ptr(GDScriptFunctionState::get_class_ptr_static())) {
1945
err_text = R"(Trying to call an async function without "await".)";
1946
OPCODE_BREAK;
1947
}
1948
}
1949
#endif
1950
} else {
1951
base->callp(*methodname, (const Variant **)argptrs, argc, temp_ret, err);
1952
}
1953
#ifdef DEBUG_ENABLED
1954
1955
if (GDScriptLanguage::get_singleton()->profiling) {
1956
uint64_t t_taken = OS::get_singleton()->get_ticks_usec() - call_time;
1957
if (GDScriptLanguage::get_singleton()->profile_native_calls && _profile_count_as_native(base_obj, *methodname)) {
1958
_profile_native_call(t_taken, *methodname, base_class);
1959
}
1960
function_call_time += t_taken;
1961
}
1962
1963
if (err.error != Callable::CallError::CALL_OK) {
1964
String methodstr = *methodname;
1965
String basestr = _get_var_type(base);
1966
bool is_callable = false;
1967
1968
if (methodstr == "call") {
1969
if (argc >= 1 && base->get_type() != Variant::CALLABLE) {
1970
methodstr = String(*argptrs[0]) + " (via call)";
1971
if (err.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) {
1972
err.argument += 1;
1973
}
1974
} else {
1975
methodstr = base->operator String() + " (Callable)";
1976
is_callable = true;
1977
}
1978
} else if (methodstr == "free") {
1979
if (err.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) {
1980
if (base->is_ref_counted()) {
1981
err_text = "Attempted to free a RefCounted object.";
1982
OPCODE_BREAK;
1983
} else if (base->get_type() == Variant::OBJECT) {
1984
err_text = "Attempted to free a locked object (calling or emitting).";
1985
OPCODE_BREAK;
1986
}
1987
}
1988
} else if (methodstr == "call_recursive" && basestr == "TreeItem") {
1989
if (argc >= 1) {
1990
methodstr = String(*argptrs[0]) + " (via TreeItem.call_recursive)";
1991
if (err.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) {
1992
err.argument += 1;
1993
}
1994
}
1995
}
1996
1997
if (is_callable) {
1998
err_text = _get_callable_call_error(vformat("function '%s'", methodstr), *base, (const Variant **)argptrs, argc, temp_ret, err);
1999
} else {
2000
err_text = _get_call_error(vformat("function '%s' in base '%s'", methodstr, basestr), (const Variant **)argptrs, argc, temp_ret, err);
2001
}
2002
OPCODE_BREAK;
2003
}
2004
#endif // DEBUG_ENABLED
2005
2006
ip += 3;
2007
}
2008
DISPATCH_OPCODE;
2009
2010
OPCODE(OPCODE_CALL_METHOD_BIND)
2011
OPCODE(OPCODE_CALL_METHOD_BIND_RET) {
2012
bool call_ret = (_code_ptr[ip]) == OPCODE_CALL_METHOD_BIND_RET;
2013
LOAD_INSTRUCTION_ARGS
2014
CHECK_SPACE(3 + instr_arg_count);
2015
2016
ip += instr_arg_count;
2017
2018
int argc = _code_ptr[ip + 1];
2019
GD_ERR_BREAK(argc < 0);
2020
GD_ERR_BREAK(_code_ptr[ip + 2] < 0 || _code_ptr[ip + 2] >= _methods_count);
2021
MethodBind *method = _methods_ptr[_code_ptr[ip + 2]];
2022
2023
GET_INSTRUCTION_ARG(base, argc);
2024
2025
#ifdef DEBUG_ENABLED
2026
bool freed = false;
2027
Object *base_obj = base->get_validated_object_with_check(freed);
2028
if (freed) {
2029
err_text = METHOD_CALL_ON_FREED_INSTANCE_ERROR(method);
2030
OPCODE_BREAK;
2031
} else if (!base_obj) {
2032
err_text = METHOD_CALL_ON_NULL_VALUE_ERROR(method);
2033
OPCODE_BREAK;
2034
}
2035
#else
2036
Object *base_obj = base->operator Object *();
2037
#endif
2038
Variant **argptrs = instruction_args;
2039
2040
#ifdef DEBUG_ENABLED
2041
uint64_t call_time = 0;
2042
if (GDScriptLanguage::get_singleton()->profiling && GDScriptLanguage::get_singleton()->profile_native_calls) {
2043
call_time = OS::get_singleton()->get_ticks_usec();
2044
}
2045
#endif
2046
2047
Variant temp_ret;
2048
Callable::CallError err;
2049
if (call_ret) {
2050
GET_INSTRUCTION_ARG(ret, argc + 1);
2051
temp_ret = method->call(base_obj, (const Variant **)argptrs, argc, err);
2052
*ret = temp_ret;
2053
} else {
2054
temp_ret = method->call(base_obj, (const Variant **)argptrs, argc, err);
2055
}
2056
2057
#ifdef DEBUG_ENABLED
2058
2059
if (GDScriptLanguage::get_singleton()->profiling && GDScriptLanguage::get_singleton()->profile_native_calls) {
2060
uint64_t t_taken = OS::get_singleton()->get_ticks_usec() - call_time;
2061
_profile_native_call(t_taken, method->get_name(), method->get_instance_class());
2062
function_call_time += t_taken;
2063
}
2064
2065
if (err.error != Callable::CallError::CALL_OK) {
2066
String methodstr = method->get_name();
2067
String basestr = _get_var_type(base);
2068
2069
if (methodstr == "call") {
2070
if (argc >= 1) {
2071
methodstr = String(*argptrs[0]) + " (via call)";
2072
if (err.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) {
2073
err.argument += 1;
2074
}
2075
}
2076
} else if (methodstr == "free") {
2077
if (err.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) {
2078
if (base->is_ref_counted()) {
2079
err_text = "Attempted to free a RefCounted object.";
2080
OPCODE_BREAK;
2081
} else if (base->get_type() == Variant::OBJECT) {
2082
err_text = "Attempted to free a locked object (calling or emitting).";
2083
OPCODE_BREAK;
2084
}
2085
}
2086
}
2087
err_text = _get_call_error("function '" + methodstr + "' in base '" + basestr + "'", (const Variant **)argptrs, argc, temp_ret, err);
2088
OPCODE_BREAK;
2089
}
2090
#endif
2091
ip += 3;
2092
}
2093
DISPATCH_OPCODE;
2094
2095
OPCODE(OPCODE_CALL_BUILTIN_STATIC) {
2096
LOAD_INSTRUCTION_ARGS
2097
CHECK_SPACE(4 + instr_arg_count);
2098
2099
ip += instr_arg_count;
2100
2101
GD_ERR_BREAK(_code_ptr[ip + 1] < 0 || _code_ptr[ip + 1] >= Variant::VARIANT_MAX);
2102
Variant::Type builtin_type = (Variant::Type)_code_ptr[ip + 1];
2103
2104
int methodname_idx = _code_ptr[ip + 2];
2105
GD_ERR_BREAK(methodname_idx < 0 || methodname_idx >= _global_names_count);
2106
const StringName *methodname = &_global_names_ptr[methodname_idx];
2107
2108
int argc = _code_ptr[ip + 3];
2109
GD_ERR_BREAK(argc < 0);
2110
2111
GET_INSTRUCTION_ARG(ret, argc);
2112
2113
const Variant **argptrs = const_cast<const Variant **>(instruction_args);
2114
2115
Callable::CallError err;
2116
Variant::call_static(builtin_type, *methodname, argptrs, argc, *ret, err);
2117
2118
#ifdef DEBUG_ENABLED
2119
if (err.error != Callable::CallError::CALL_OK) {
2120
err_text = _get_call_error("static function '" + methodname->operator String() + "' in type '" + Variant::get_type_name(builtin_type) + "'", argptrs, argc, *ret, err);
2121
OPCODE_BREAK;
2122
}
2123
#endif
2124
2125
ip += 4;
2126
}
2127
DISPATCH_OPCODE;
2128
2129
OPCODE(OPCODE_CALL_NATIVE_STATIC) {
2130
LOAD_INSTRUCTION_ARGS
2131
CHECK_SPACE(3 + instr_arg_count);
2132
2133
ip += instr_arg_count;
2134
2135
GD_ERR_BREAK(_code_ptr[ip + 1] < 0 || _code_ptr[ip + 1] >= _methods_count);
2136
MethodBind *method = _methods_ptr[_code_ptr[ip + 1]];
2137
2138
int argc = _code_ptr[ip + 2];
2139
GD_ERR_BREAK(argc < 0);
2140
2141
GET_INSTRUCTION_ARG(ret, argc);
2142
2143
const Variant **argptrs = const_cast<const Variant **>(instruction_args);
2144
2145
#ifdef DEBUG_ENABLED
2146
uint64_t call_time = 0;
2147
if (GDScriptLanguage::get_singleton()->profiling && GDScriptLanguage::get_singleton()->profile_native_calls) {
2148
call_time = OS::get_singleton()->get_ticks_usec();
2149
}
2150
#endif
2151
2152
Callable::CallError err;
2153
*ret = method->call(nullptr, argptrs, argc, err);
2154
2155
#ifdef DEBUG_ENABLED
2156
if (GDScriptLanguage::get_singleton()->profiling && GDScriptLanguage::get_singleton()->profile_native_calls) {
2157
uint64_t t_taken = OS::get_singleton()->get_ticks_usec() - call_time;
2158
_profile_native_call(t_taken, method->get_name(), method->get_instance_class());
2159
function_call_time += t_taken;
2160
}
2161
#endif
2162
2163
if (err.error != Callable::CallError::CALL_OK) {
2164
err_text = _get_call_error("static function '" + method->get_name().operator String() + "' in type '" + method->get_instance_class().operator String() + "'", argptrs, argc, *ret, err);
2165
OPCODE_BREAK;
2166
}
2167
2168
ip += 3;
2169
}
2170
DISPATCH_OPCODE;
2171
2172
OPCODE(OPCODE_CALL_NATIVE_STATIC_VALIDATED_RETURN) {
2173
LOAD_INSTRUCTION_ARGS
2174
CHECK_SPACE(3 + instr_arg_count);
2175
2176
ip += instr_arg_count;
2177
2178
int argc = _code_ptr[ip + 1];
2179
GD_ERR_BREAK(argc < 0);
2180
2181
GD_ERR_BREAK(_code_ptr[ip + 2] < 0 || _code_ptr[ip + 2] >= _methods_count);
2182
MethodBind *method = _methods_ptr[_code_ptr[ip + 2]];
2183
2184
Variant **argptrs = instruction_args;
2185
2186
#ifdef DEBUG_ENABLED
2187
uint64_t call_time = 0;
2188
if (GDScriptLanguage::get_singleton()->profiling && GDScriptLanguage::get_singleton()->profile_native_calls) {
2189
call_time = OS::get_singleton()->get_ticks_usec();
2190
}
2191
#endif
2192
2193
GET_INSTRUCTION_ARG(ret, argc);
2194
method->validated_call(nullptr, (const Variant **)argptrs, ret);
2195
2196
#ifdef DEBUG_ENABLED
2197
if (GDScriptLanguage::get_singleton()->profiling && GDScriptLanguage::get_singleton()->profile_native_calls) {
2198
uint64_t t_taken = OS::get_singleton()->get_ticks_usec() - call_time;
2199
_profile_native_call(t_taken, method->get_name(), method->get_instance_class());
2200
function_call_time += t_taken;
2201
}
2202
#endif
2203
2204
ip += 3;
2205
}
2206
DISPATCH_OPCODE;
2207
2208
OPCODE(OPCODE_CALL_NATIVE_STATIC_VALIDATED_NO_RETURN) {
2209
LOAD_INSTRUCTION_ARGS
2210
CHECK_SPACE(3 + instr_arg_count);
2211
2212
ip += instr_arg_count;
2213
2214
int argc = _code_ptr[ip + 1];
2215
GD_ERR_BREAK(argc < 0);
2216
2217
GD_ERR_BREAK(_code_ptr[ip + 2] < 0 || _code_ptr[ip + 2] >= _methods_count);
2218
MethodBind *method = _methods_ptr[_code_ptr[ip + 2]];
2219
2220
Variant **argptrs = instruction_args;
2221
#ifdef DEBUG_ENABLED
2222
uint64_t call_time = 0;
2223
if (GDScriptLanguage::get_singleton()->profiling && GDScriptLanguage::get_singleton()->profile_native_calls) {
2224
call_time = OS::get_singleton()->get_ticks_usec();
2225
}
2226
#endif
2227
2228
GET_INSTRUCTION_ARG(ret, argc);
2229
VariantInternal::initialize(ret, Variant::NIL);
2230
method->validated_call(nullptr, (const Variant **)argptrs, nullptr);
2231
2232
#ifdef DEBUG_ENABLED
2233
if (GDScriptLanguage::get_singleton()->profiling && GDScriptLanguage::get_singleton()->profile_native_calls) {
2234
uint64_t t_taken = OS::get_singleton()->get_ticks_usec() - call_time;
2235
_profile_native_call(t_taken, method->get_name(), method->get_instance_class());
2236
function_call_time += t_taken;
2237
}
2238
#endif
2239
2240
ip += 3;
2241
}
2242
DISPATCH_OPCODE;
2243
2244
OPCODE(OPCODE_CALL_METHOD_BIND_VALIDATED_RETURN) {
2245
LOAD_INSTRUCTION_ARGS
2246
CHECK_SPACE(3 + instr_arg_count);
2247
2248
ip += instr_arg_count;
2249
2250
int argc = _code_ptr[ip + 1];
2251
GD_ERR_BREAK(argc < 0);
2252
2253
GD_ERR_BREAK(_code_ptr[ip + 2] < 0 || _code_ptr[ip + 2] >= _methods_count);
2254
MethodBind *method = _methods_ptr[_code_ptr[ip + 2]];
2255
2256
GET_INSTRUCTION_ARG(base, argc);
2257
2258
#ifdef DEBUG_ENABLED
2259
bool freed = false;
2260
Object *base_obj = base->get_validated_object_with_check(freed);
2261
if (freed) {
2262
err_text = METHOD_CALL_ON_FREED_INSTANCE_ERROR(method);
2263
OPCODE_BREAK;
2264
} else if (!base_obj) {
2265
err_text = METHOD_CALL_ON_NULL_VALUE_ERROR(method);
2266
OPCODE_BREAK;
2267
}
2268
#else
2269
Object *base_obj = *VariantInternal::get_object(base);
2270
#endif
2271
2272
Variant **argptrs = instruction_args;
2273
2274
#ifdef DEBUG_ENABLED
2275
uint64_t call_time = 0;
2276
if (GDScriptLanguage::get_singleton()->profiling && GDScriptLanguage::get_singleton()->profile_native_calls) {
2277
call_time = OS::get_singleton()->get_ticks_usec();
2278
}
2279
#endif
2280
2281
GET_INSTRUCTION_ARG(ret, argc + 1);
2282
method->validated_call(base_obj, (const Variant **)argptrs, ret);
2283
2284
#ifdef DEBUG_ENABLED
2285
if (GDScriptLanguage::get_singleton()->profiling && GDScriptLanguage::get_singleton()->profile_native_calls) {
2286
uint64_t t_taken = OS::get_singleton()->get_ticks_usec() - call_time;
2287
_profile_native_call(t_taken, method->get_name(), method->get_instance_class());
2288
function_call_time += t_taken;
2289
}
2290
#endif
2291
2292
ip += 3;
2293
}
2294
DISPATCH_OPCODE;
2295
2296
OPCODE(OPCODE_CALL_METHOD_BIND_VALIDATED_NO_RETURN) {
2297
LOAD_INSTRUCTION_ARGS
2298
CHECK_SPACE(3 + instr_arg_count);
2299
2300
ip += instr_arg_count;
2301
2302
int argc = _code_ptr[ip + 1];
2303
GD_ERR_BREAK(argc < 0);
2304
2305
GD_ERR_BREAK(_code_ptr[ip + 2] < 0 || _code_ptr[ip + 2] >= _methods_count);
2306
MethodBind *method = _methods_ptr[_code_ptr[ip + 2]];
2307
2308
GET_INSTRUCTION_ARG(base, argc);
2309
#ifdef DEBUG_ENABLED
2310
bool freed = false;
2311
Object *base_obj = base->get_validated_object_with_check(freed);
2312
if (freed) {
2313
err_text = METHOD_CALL_ON_FREED_INSTANCE_ERROR(method);
2314
OPCODE_BREAK;
2315
} else if (!base_obj) {
2316
err_text = METHOD_CALL_ON_NULL_VALUE_ERROR(method);
2317
OPCODE_BREAK;
2318
}
2319
#else
2320
Object *base_obj = *VariantInternal::get_object(base);
2321
#endif
2322
Variant **argptrs = instruction_args;
2323
#ifdef DEBUG_ENABLED
2324
uint64_t call_time = 0;
2325
if (GDScriptLanguage::get_singleton()->profiling && GDScriptLanguage::get_singleton()->profile_native_calls) {
2326
call_time = OS::get_singleton()->get_ticks_usec();
2327
}
2328
#endif
2329
2330
GET_INSTRUCTION_ARG(ret, argc + 1);
2331
VariantInternal::initialize(ret, Variant::NIL);
2332
method->validated_call(base_obj, (const Variant **)argptrs, nullptr);
2333
2334
#ifdef DEBUG_ENABLED
2335
if (GDScriptLanguage::get_singleton()->profiling && GDScriptLanguage::get_singleton()->profile_native_calls) {
2336
uint64_t t_taken = OS::get_singleton()->get_ticks_usec() - call_time;
2337
_profile_native_call(t_taken, method->get_name(), method->get_instance_class());
2338
function_call_time += t_taken;
2339
}
2340
#endif
2341
2342
ip += 3;
2343
}
2344
DISPATCH_OPCODE;
2345
2346
OPCODE(OPCODE_CALL_BUILTIN_TYPE_VALIDATED) {
2347
LOAD_INSTRUCTION_ARGS
2348
2349
CHECK_SPACE(3 + instr_arg_count);
2350
2351
ip += instr_arg_count;
2352
2353
int argc = _code_ptr[ip + 1];
2354
GD_ERR_BREAK(argc < 0);
2355
2356
GET_INSTRUCTION_ARG(base, argc);
2357
2358
GD_ERR_BREAK(_code_ptr[ip + 2] < 0 || _code_ptr[ip + 2] >= _builtin_methods_count);
2359
Variant::ValidatedBuiltInMethod method = _builtin_methods_ptr[_code_ptr[ip + 2]];
2360
Variant **argptrs = instruction_args;
2361
2362
GET_INSTRUCTION_ARG(ret, argc + 1);
2363
method(base, (const Variant **)argptrs, argc, ret);
2364
2365
ip += 3;
2366
}
2367
DISPATCH_OPCODE;
2368
2369
OPCODE(OPCODE_CALL_UTILITY) {
2370
LOAD_INSTRUCTION_ARGS
2371
CHECK_SPACE(3 + instr_arg_count);
2372
2373
ip += instr_arg_count;
2374
2375
int argc = _code_ptr[ip + 1];
2376
GD_ERR_BREAK(argc < 0);
2377
2378
GD_ERR_BREAK(_code_ptr[ip + 2] < 0 || _code_ptr[ip + 2] >= _global_names_count);
2379
StringName function = _global_names_ptr[_code_ptr[ip + 2]];
2380
2381
Variant **argptrs = instruction_args;
2382
2383
GET_INSTRUCTION_ARG(dst, argc);
2384
2385
Callable::CallError err;
2386
Variant::call_utility_function(function, dst, (const Variant **)argptrs, argc, err);
2387
2388
#ifdef DEBUG_ENABLED
2389
if (err.error != Callable::CallError::CALL_OK) {
2390
String methodstr = function;
2391
if (dst->get_type() == Variant::STRING && !dst->operator String().is_empty()) {
2392
// Call provided error string.
2393
err_text = vformat(R"*(Error calling utility function "%s()": %s)*", methodstr, *dst);
2394
} else {
2395
err_text = _get_call_error(vformat(R"*(utility function "%s()")*", methodstr), (const Variant **)argptrs, argc, *dst, err);
2396
}
2397
OPCODE_BREAK;
2398
}
2399
#endif
2400
ip += 3;
2401
}
2402
DISPATCH_OPCODE;
2403
2404
OPCODE(OPCODE_CALL_UTILITY_VALIDATED) {
2405
LOAD_INSTRUCTION_ARGS
2406
CHECK_SPACE(3 + instr_arg_count);
2407
2408
ip += instr_arg_count;
2409
2410
int argc = _code_ptr[ip + 1];
2411
GD_ERR_BREAK(argc < 0);
2412
2413
GD_ERR_BREAK(_code_ptr[ip + 2] < 0 || _code_ptr[ip + 2] >= _utilities_count);
2414
Variant::ValidatedUtilityFunction function = _utilities_ptr[_code_ptr[ip + 2]];
2415
2416
Variant **argptrs = instruction_args;
2417
2418
GET_INSTRUCTION_ARG(dst, argc);
2419
2420
function(dst, (const Variant **)argptrs, argc);
2421
2422
ip += 3;
2423
}
2424
DISPATCH_OPCODE;
2425
2426
OPCODE(OPCODE_CALL_GDSCRIPT_UTILITY) {
2427
LOAD_INSTRUCTION_ARGS
2428
CHECK_SPACE(3 + instr_arg_count);
2429
2430
ip += instr_arg_count;
2431
2432
int argc = _code_ptr[ip + 1];
2433
GD_ERR_BREAK(argc < 0);
2434
2435
GD_ERR_BREAK(_code_ptr[ip + 2] < 0 || _code_ptr[ip + 2] >= _gds_utilities_count);
2436
GDScriptUtilityFunctions::FunctionPtr function = _gds_utilities_ptr[_code_ptr[ip + 2]];
2437
2438
Variant **argptrs = instruction_args;
2439
2440
GET_INSTRUCTION_ARG(dst, argc);
2441
2442
Callable::CallError err;
2443
function(dst, (const Variant **)argptrs, argc, err);
2444
2445
#ifdef DEBUG_ENABLED
2446
if (err.error != Callable::CallError::CALL_OK) {
2447
String methodstr = gds_utilities_names[_code_ptr[ip + 2]];
2448
if (dst->get_type() == Variant::STRING && !dst->operator String().is_empty()) {
2449
// Call provided error string.
2450
err_text = vformat(R"*(Error calling GDScript utility function "%s()": %s)*", methodstr, *dst);
2451
} else {
2452
err_text = _get_call_error(vformat(R"*(GDScript utility function "%s()")*", methodstr), (const Variant **)argptrs, argc, *dst, err);
2453
}
2454
OPCODE_BREAK;
2455
}
2456
#endif
2457
ip += 3;
2458
}
2459
DISPATCH_OPCODE;
2460
2461
OPCODE(OPCODE_CALL_SELF_BASE) {
2462
LOAD_INSTRUCTION_ARGS
2463
CHECK_SPACE(3 + instr_arg_count);
2464
2465
ip += instr_arg_count;
2466
2467
int argc = _code_ptr[ip + 1];
2468
GD_ERR_BREAK(argc < 0);
2469
2470
int self_fun = _code_ptr[ip + 2];
2471
#ifdef DEBUG_ENABLED
2472
if (self_fun < 0 || self_fun >= _global_names_count) {
2473
err_text = "compiler bug, function name not found";
2474
OPCODE_BREAK;
2475
}
2476
#endif
2477
const StringName *methodname = &_global_names_ptr[self_fun];
2478
2479
Variant **argptrs = instruction_args;
2480
2481
GET_INSTRUCTION_ARG(dst, argc);
2482
2483
const GDScript *gds = _script;
2484
2485
HashMap<StringName, GDScriptFunction *>::ConstIterator E;
2486
while (gds->base.ptr()) {
2487
gds = gds->base.ptr();
2488
E = gds->member_functions.find(*methodname);
2489
if (E) {
2490
break;
2491
}
2492
}
2493
2494
Callable::CallError err;
2495
2496
if (E) {
2497
*dst = E->value->call(p_instance, (const Variant **)argptrs, argc, err);
2498
} else if (gds->native.ptr()) {
2499
if (*methodname != GDScriptLanguage::get_singleton()->strings._init) {
2500
MethodBind *mb = ClassDB::get_method(gds->native->get_name(), *methodname);
2501
if (!mb) {
2502
err.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
2503
} else {
2504
*dst = mb->call(p_instance->owner, (const Variant **)argptrs, argc, err);
2505
}
2506
} else {
2507
err.error = Callable::CallError::CALL_OK;
2508
}
2509
} else {
2510
if (*methodname != GDScriptLanguage::get_singleton()->strings._init) {
2511
err.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
2512
} else {
2513
err.error = Callable::CallError::CALL_OK;
2514
}
2515
}
2516
2517
if (err.error != Callable::CallError::CALL_OK) {
2518
String methodstr = *methodname;
2519
err_text = _get_call_error("function '" + methodstr + "'", (const Variant **)argptrs, argc, *dst, err);
2520
2521
OPCODE_BREAK;
2522
}
2523
2524
ip += 3;
2525
}
2526
DISPATCH_OPCODE;
2527
2528
OPCODE(OPCODE_AWAIT) {
2529
CHECK_SPACE(2);
2530
2531
// Do the one-shot connect.
2532
GET_VARIANT_PTR(argobj, 0);
2533
2534
Signal sig;
2535
bool is_signal = true;
2536
2537
{
2538
Variant result = *argobj;
2539
2540
if (argobj->get_type() == Variant::OBJECT) {
2541
bool was_freed = false;
2542
Object *obj = argobj->get_validated_object_with_check(was_freed);
2543
2544
if (was_freed) {
2545
err_text = "Trying to await on a freed object.";
2546
OPCODE_BREAK;
2547
}
2548
2549
// Is this even possible to be null at this point?
2550
if (obj) {
2551
if (obj->is_class_ptr(GDScriptFunctionState::get_class_ptr_static())) {
2552
result = Signal(obj, SNAME("completed"));
2553
}
2554
}
2555
}
2556
2557
if (result.get_type() != Variant::SIGNAL) {
2558
// Not async, return immediately using the target from OPCODE_AWAIT_RESUME.
2559
GET_VARIANT_PTR(target, 2);
2560
*target = result;
2561
ip += 4; // Skip OPCODE_AWAIT_RESUME and its data.
2562
is_signal = false;
2563
} else {
2564
sig = result;
2565
}
2566
}
2567
2568
if (is_signal) {
2569
Ref<GDScriptFunctionState> gdfs = memnew(GDScriptFunctionState);
2570
gdfs->function = this;
2571
2572
gdfs->state.stack.resize(alloca_size);
2573
2574
// First `FIXED_ADDRESSES_MAX` stack addresses are special, so we just skip them here.
2575
for (int i = FIXED_ADDRESSES_MAX; i < _stack_size; i++) {
2576
memnew_placement(&gdfs->state.stack.write[sizeof(Variant) * i], Variant(stack[i]));
2577
}
2578
gdfs->state.stack_size = _stack_size;
2579
gdfs->state.ip = ip + 2;
2580
gdfs->state.line = line;
2581
gdfs->state.script = _script;
2582
{
2583
MutexLock lock(GDScriptLanguage::get_singleton()->mutex);
2584
_script->pending_func_states.add(&gdfs->scripts_list);
2585
if (p_instance) {
2586
gdfs->state.instance = p_instance;
2587
p_instance->pending_func_states.add(&gdfs->instances_list);
2588
} else {
2589
gdfs->state.instance = nullptr;
2590
}
2591
}
2592
#ifdef DEBUG_ENABLED
2593
gdfs->state.function_name = name;
2594
gdfs->state.script_path = _script->get_script_path();
2595
#endif
2596
gdfs->state.defarg = defarg;
2597
gdfs->function = this;
2598
2599
if (p_state) {
2600
// Pass down the signal from the first state.
2601
gdfs->state.completed = p_state->completed;
2602
} else {
2603
gdfs->state.completed = Signal(gdfs.ptr(), SNAME("completed"));
2604
}
2605
2606
retvalue = gdfs;
2607
2608
Error err = sig.connect(Callable(gdfs.ptr(), "_signal_callback").bind(retvalue), Object::CONNECT_ONE_SHOT);
2609
if (err != OK) {
2610
err_text = "Error connecting to signal: " + sig.get_name() + " during await.";
2611
OPCODE_BREAK;
2612
}
2613
2614
awaited = true;
2615
2616
#ifdef DEBUG_ENABLED
2617
exit_ok = true;
2618
#endif
2619
OPCODE_BREAK;
2620
}
2621
}
2622
DISPATCH_OPCODE; // Needed for synchronous calls (when result is immediately available).
2623
2624
OPCODE(OPCODE_AWAIT_RESUME) {
2625
CHECK_SPACE(2);
2626
#ifdef DEBUG_ENABLED
2627
if (!p_state) {
2628
err_text = ("Invalid Resume (bug?)");
2629
OPCODE_BREAK;
2630
}
2631
#endif
2632
GET_VARIANT_PTR(result, 0);
2633
*result = p_state->result;
2634
ip += 2;
2635
}
2636
DISPATCH_OPCODE;
2637
2638
OPCODE(OPCODE_CREATE_LAMBDA) {
2639
LOAD_INSTRUCTION_ARGS
2640
CHECK_SPACE(2 + instr_arg_count);
2641
2642
ip += instr_arg_count;
2643
2644
int captures_count = _code_ptr[ip + 1];
2645
GD_ERR_BREAK(captures_count < 0);
2646
2647
int lambda_index = _code_ptr[ip + 2];
2648
GD_ERR_BREAK(lambda_index < 0 || lambda_index >= _lambdas_count);
2649
GDScriptFunction *lambda = _lambdas_ptr[lambda_index];
2650
2651
Vector<Variant> captures;
2652
captures.resize(captures_count);
2653
for (int i = 0; i < captures_count; i++) {
2654
GET_INSTRUCTION_ARG(arg, i);
2655
captures.write[i] = *arg;
2656
}
2657
2658
GDScriptLambdaCallable *callable = memnew(GDScriptLambdaCallable(Ref<GDScript>(script), lambda, captures));
2659
2660
GET_INSTRUCTION_ARG(result, captures_count);
2661
*result = Callable(callable);
2662
2663
ip += 3;
2664
}
2665
DISPATCH_OPCODE;
2666
2667
OPCODE(OPCODE_CREATE_SELF_LAMBDA) {
2668
LOAD_INSTRUCTION_ARGS
2669
CHECK_SPACE(2 + instr_arg_count);
2670
2671
GD_ERR_BREAK(p_instance == nullptr);
2672
2673
ip += instr_arg_count;
2674
2675
int captures_count = _code_ptr[ip + 1];
2676
GD_ERR_BREAK(captures_count < 0);
2677
2678
int lambda_index = _code_ptr[ip + 2];
2679
GD_ERR_BREAK(lambda_index < 0 || lambda_index >= _lambdas_count);
2680
GDScriptFunction *lambda = _lambdas_ptr[lambda_index];
2681
2682
Vector<Variant> captures;
2683
captures.resize(captures_count);
2684
for (int i = 0; i < captures_count; i++) {
2685
GET_INSTRUCTION_ARG(arg, i);
2686
captures.write[i] = *arg;
2687
}
2688
2689
GDScriptLambdaSelfCallable *callable;
2690
if (Object::cast_to<RefCounted>(p_instance->owner)) {
2691
callable = memnew(GDScriptLambdaSelfCallable(Ref<RefCounted>(Object::cast_to<RefCounted>(p_instance->owner)), lambda, captures));
2692
} else {
2693
callable = memnew(GDScriptLambdaSelfCallable(p_instance->owner, lambda, captures));
2694
}
2695
2696
GET_INSTRUCTION_ARG(result, captures_count);
2697
*result = Callable(callable);
2698
2699
ip += 3;
2700
}
2701
DISPATCH_OPCODE;
2702
2703
OPCODE(OPCODE_JUMP) {
2704
CHECK_SPACE(2);
2705
int to = _code_ptr[ip + 1];
2706
2707
GD_ERR_BREAK(to < 0 || to > _code_size);
2708
ip = to;
2709
}
2710
DISPATCH_OPCODE;
2711
2712
OPCODE(OPCODE_JUMP_IF) {
2713
CHECK_SPACE(3);
2714
2715
GET_VARIANT_PTR(test, 0);
2716
2717
bool result = test->booleanize();
2718
2719
if (result) {
2720
int to = _code_ptr[ip + 2];
2721
GD_ERR_BREAK(to < 0 || to > _code_size);
2722
ip = to;
2723
} else {
2724
ip += 3;
2725
}
2726
}
2727
DISPATCH_OPCODE;
2728
2729
OPCODE(OPCODE_JUMP_IF_NOT) {
2730
CHECK_SPACE(3);
2731
2732
GET_VARIANT_PTR(test, 0);
2733
2734
bool result = test->booleanize();
2735
2736
if (!result) {
2737
int to = _code_ptr[ip + 2];
2738
GD_ERR_BREAK(to < 0 || to > _code_size);
2739
ip = to;
2740
} else {
2741
ip += 3;
2742
}
2743
}
2744
DISPATCH_OPCODE;
2745
2746
OPCODE(OPCODE_JUMP_TO_DEF_ARGUMENT) {
2747
CHECK_SPACE(2);
2748
ip = _default_arg_ptr[defarg];
2749
}
2750
DISPATCH_OPCODE;
2751
2752
OPCODE(OPCODE_JUMP_IF_SHARED) {
2753
CHECK_SPACE(3);
2754
2755
GET_VARIANT_PTR(val, 0);
2756
2757
if (val->is_shared()) {
2758
int to = _code_ptr[ip + 2];
2759
GD_ERR_BREAK(to < 0 || to > _code_size);
2760
ip = to;
2761
} else {
2762
ip += 3;
2763
}
2764
}
2765
DISPATCH_OPCODE;
2766
2767
OPCODE(OPCODE_RETURN) {
2768
CHECK_SPACE(2);
2769
GET_VARIANT_PTR(r, 0);
2770
retvalue = *r;
2771
#ifdef DEBUG_ENABLED
2772
exit_ok = true;
2773
#endif
2774
OPCODE_BREAK;
2775
}
2776
2777
OPCODE(OPCODE_RETURN_TYPED_BUILTIN) {
2778
CHECK_SPACE(3);
2779
GET_VARIANT_PTR(r, 0);
2780
2781
Variant::Type ret_type = (Variant::Type)_code_ptr[ip + 2];
2782
GD_ERR_BREAK(ret_type < 0 || ret_type >= Variant::VARIANT_MAX);
2783
2784
if (r->get_type() != ret_type) {
2785
if (Variant::can_convert_strict(r->get_type(), ret_type)) {
2786
Callable::CallError ce;
2787
Variant::construct(ret_type, retvalue, const_cast<const Variant **>(&r), 1, ce);
2788
} else {
2789
#ifdef DEBUG_ENABLED
2790
err_text = vformat(R"(Trying to return value of type "%s" from a function whose return type is "%s".)",
2791
Variant::get_type_name(r->get_type()), Variant::get_type_name(ret_type));
2792
#endif // DEBUG_ENABLED
2793
2794
// Construct a base type anyway so type constraints are met.
2795
Callable::CallError ce;
2796
Variant::construct(ret_type, retvalue, nullptr, 0, ce);
2797
OPCODE_BREAK;
2798
}
2799
} else {
2800
retvalue = *r;
2801
}
2802
#ifdef DEBUG_ENABLED
2803
exit_ok = true;
2804
#endif // DEBUG_ENABLED
2805
OPCODE_BREAK;
2806
}
2807
2808
OPCODE(OPCODE_RETURN_TYPED_ARRAY) {
2809
CHECK_SPACE(5);
2810
GET_VARIANT_PTR(r, 0);
2811
2812
GET_VARIANT_PTR(script_type, 1);
2813
Variant::Type builtin_type = (Variant::Type)_code_ptr[ip + 3];
2814
int native_type_idx = _code_ptr[ip + 4];
2815
GD_ERR_BREAK(native_type_idx < 0 || native_type_idx >= _global_names_count);
2816
const StringName native_type = _global_names_ptr[native_type_idx];
2817
2818
if (r->get_type() != Variant::ARRAY) {
2819
#ifdef DEBUG_ENABLED
2820
err_text = vformat(R"(Trying to return value of type "%s" from a function whose return type is "Array[%s]".)",
2821
Variant::get_type_name(r->get_type()), Variant::get_type_name(builtin_type));
2822
#endif
2823
OPCODE_BREAK;
2824
}
2825
2826
Array *array = VariantInternal::get_array(r);
2827
2828
if (array->get_typed_builtin() != ((uint32_t)builtin_type) || array->get_typed_class_name() != native_type || array->get_typed_script() != *script_type) {
2829
#ifdef DEBUG_ENABLED
2830
err_text = vformat(R"(Trying to return an array of type "%s" where expected return type is "Array[%s]".)",
2831
_get_var_type(r), _get_element_type(builtin_type, native_type, *script_type));
2832
#endif // DEBUG_ENABLED
2833
OPCODE_BREAK;
2834
}
2835
2836
retvalue = *array;
2837
2838
#ifdef DEBUG_ENABLED
2839
exit_ok = true;
2840
#endif // DEBUG_ENABLED
2841
OPCODE_BREAK;
2842
}
2843
2844
OPCODE(OPCODE_RETURN_TYPED_DICTIONARY) {
2845
CHECK_SPACE(8);
2846
GET_VARIANT_PTR(r, 0);
2847
2848
GET_VARIANT_PTR(key_script_type, 1);
2849
Variant::Type key_builtin_type = (Variant::Type)_code_ptr[ip + 4];
2850
int key_native_type_idx = _code_ptr[ip + 5];
2851
GD_ERR_BREAK(key_native_type_idx < 0 || key_native_type_idx >= _global_names_count);
2852
const StringName key_native_type = _global_names_ptr[key_native_type_idx];
2853
2854
GET_VARIANT_PTR(value_script_type, 2);
2855
Variant::Type value_builtin_type = (Variant::Type)_code_ptr[ip + 6];
2856
int value_native_type_idx = _code_ptr[ip + 7];
2857
GD_ERR_BREAK(value_native_type_idx < 0 || value_native_type_idx >= _global_names_count);
2858
const StringName value_native_type = _global_names_ptr[value_native_type_idx];
2859
2860
if (r->get_type() != Variant::DICTIONARY) {
2861
#ifdef DEBUG_ENABLED
2862
err_text = vformat(R"(Trying to return a value of type "%s" where expected return type is "Dictionary[%s, %s]".)",
2863
_get_var_type(r), _get_element_type(key_builtin_type, key_native_type, *key_script_type),
2864
_get_element_type(value_builtin_type, value_native_type, *value_script_type));
2865
#endif // DEBUG_ENABLED
2866
OPCODE_BREAK;
2867
}
2868
2869
Dictionary *dictionary = VariantInternal::get_dictionary(r);
2870
2871
if (dictionary->get_typed_key_builtin() != ((uint32_t)key_builtin_type) || dictionary->get_typed_key_class_name() != key_native_type || dictionary->get_typed_key_script() != *key_script_type ||
2872
dictionary->get_typed_value_builtin() != ((uint32_t)value_builtin_type) || dictionary->get_typed_value_class_name() != value_native_type || dictionary->get_typed_value_script() != *value_script_type) {
2873
#ifdef DEBUG_ENABLED
2874
err_text = vformat(R"(Trying to return a dictionary of type "%s" where expected return type is "Dictionary[%s, %s]".)",
2875
_get_var_type(r), _get_element_type(key_builtin_type, key_native_type, *key_script_type),
2876
_get_element_type(value_builtin_type, value_native_type, *value_script_type));
2877
#endif // DEBUG_ENABLED
2878
OPCODE_BREAK;
2879
}
2880
2881
retvalue = *dictionary;
2882
2883
#ifdef DEBUG_ENABLED
2884
exit_ok = true;
2885
#endif // DEBUG_ENABLED
2886
OPCODE_BREAK;
2887
}
2888
2889
OPCODE(OPCODE_RETURN_TYPED_NATIVE) {
2890
CHECK_SPACE(3);
2891
GET_VARIANT_PTR(r, 0);
2892
2893
GET_VARIANT_PTR(type, 1);
2894
GDScriptNativeClass *nc = Object::cast_to<GDScriptNativeClass>(type->operator Object *());
2895
GD_ERR_BREAK(!nc);
2896
2897
if (r->get_type() != Variant::OBJECT && r->get_type() != Variant::NIL) {
2898
err_text = vformat(R"(Trying to return value of type "%s" from a function whose return type is "%s".)",
2899
Variant::get_type_name(r->get_type()), nc->get_name());
2900
OPCODE_BREAK;
2901
}
2902
2903
#ifdef DEBUG_ENABLED
2904
bool freed = false;
2905
Object *ret_obj = r->get_validated_object_with_check(freed);
2906
2907
if (freed) {
2908
err_text = "Trying to return a previously freed instance.";
2909
OPCODE_BREAK;
2910
}
2911
#else
2912
Object *ret_obj = r->operator Object *();
2913
#endif // DEBUG_ENABLED
2914
if (ret_obj && !ClassDB::is_parent_class(ret_obj->get_class_name(), nc->get_name())) {
2915
#ifdef DEBUG_ENABLED
2916
err_text = vformat(R"(Trying to return value of type "%s" from a function whose return type is "%s".)",
2917
ret_obj->get_class_name(), nc->get_name());
2918
#endif // DEBUG_ENABLED
2919
OPCODE_BREAK;
2920
}
2921
retvalue = *r;
2922
2923
#ifdef DEBUG_ENABLED
2924
exit_ok = true;
2925
#endif // DEBUG_ENABLED
2926
OPCODE_BREAK;
2927
}
2928
2929
OPCODE(OPCODE_RETURN_TYPED_SCRIPT) {
2930
CHECK_SPACE(3);
2931
GET_VARIANT_PTR(r, 0);
2932
2933
GET_VARIANT_PTR(type, 1);
2934
Script *base_type = Object::cast_to<Script>(type->operator Object *());
2935
GD_ERR_BREAK(!base_type);
2936
2937
if (r->get_type() != Variant::OBJECT && r->get_type() != Variant::NIL) {
2938
#ifdef DEBUG_ENABLED
2939
err_text = vformat(R"(Trying to return value of type "%s" from a function whose return type is "%s".)",
2940
Variant::get_type_name(r->get_type()), GDScript::debug_get_script_name(Ref<Script>(base_type)));
2941
#endif // DEBUG_ENABLED
2942
OPCODE_BREAK;
2943
}
2944
2945
#ifdef DEBUG_ENABLED
2946
bool freed = false;
2947
Object *ret_obj = r->get_validated_object_with_check(freed);
2948
2949
if (freed) {
2950
err_text = "Trying to return a previously freed instance.";
2951
OPCODE_BREAK;
2952
}
2953
#else
2954
Object *ret_obj = r->operator Object *();
2955
#endif // DEBUG_ENABLED
2956
2957
if (ret_obj) {
2958
ScriptInstance *ret_inst = ret_obj->get_script_instance();
2959
if (!ret_inst) {
2960
#ifdef DEBUG_ENABLED
2961
err_text = vformat(R"(Trying to return value of type "%s" from a function whose return type is "%s".)",
2962
ret_obj->get_class_name(), GDScript::debug_get_script_name(Ref<GDScript>(base_type)));
2963
#endif // DEBUG_ENABLED
2964
OPCODE_BREAK;
2965
}
2966
2967
Script *ret_type = ret_obj->get_script_instance()->get_script().ptr();
2968
bool valid = false;
2969
2970
while (ret_type) {
2971
if (ret_type == base_type) {
2972
valid = true;
2973
break;
2974
}
2975
ret_type = ret_type->get_base_script().ptr();
2976
}
2977
2978
if (!valid) {
2979
#ifdef DEBUG_ENABLED
2980
err_text = vformat(R"(Trying to return value of type "%s" from a function whose return type is "%s".)",
2981
GDScript::debug_get_script_name(ret_obj->get_script_instance()->get_script()), GDScript::debug_get_script_name(Ref<GDScript>(base_type)));
2982
#endif // DEBUG_ENABLED
2983
OPCODE_BREAK;
2984
}
2985
}
2986
retvalue = *r;
2987
2988
#ifdef DEBUG_ENABLED
2989
exit_ok = true;
2990
#endif // DEBUG_ENABLED
2991
OPCODE_BREAK;
2992
}
2993
2994
OPCODE(OPCODE_ITERATE_BEGIN) {
2995
CHECK_SPACE(8); // Space for this and a regular iterate.
2996
2997
GET_VARIANT_PTR(counter, 0);
2998
GET_VARIANT_PTR(container, 1);
2999
3000
*counter = Variant();
3001
3002
bool valid;
3003
if (!container->iter_init(*counter, valid)) {
3004
#ifdef DEBUG_ENABLED
3005
if (!valid) {
3006
err_text = "Unable to iterate on object of type '" + Variant::get_type_name(container->get_type()) + "'.";
3007
OPCODE_BREAK;
3008
}
3009
#endif
3010
int jumpto = _code_ptr[ip + 4];
3011
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
3012
ip = jumpto;
3013
} else {
3014
GET_VARIANT_PTR(iterator, 2);
3015
3016
*iterator = container->iter_get(*counter, valid);
3017
#ifdef DEBUG_ENABLED
3018
if (!valid) {
3019
err_text = "Unable to obtain iterator object of type '" + Variant::get_type_name(container->get_type()) + "'.";
3020
OPCODE_BREAK;
3021
}
3022
#endif
3023
ip += 5; // Skip regular iterate which is always next.
3024
}
3025
}
3026
DISPATCH_OPCODE;
3027
3028
OPCODE(OPCODE_ITERATE_BEGIN_INT) {
3029
CHECK_SPACE(8); // Check space for iterate instruction too.
3030
3031
GET_VARIANT_PTR(counter, 0);
3032
GET_VARIANT_PTR(container, 1);
3033
3034
int64_t size = *VariantInternal::get_int(container);
3035
3036
VariantInternal::initialize(counter, Variant::INT);
3037
*VariantInternal::get_int(counter) = 0;
3038
3039
if (size > 0) {
3040
GET_VARIANT_PTR(iterator, 2);
3041
VariantInternal::initialize(iterator, Variant::INT);
3042
*VariantInternal::get_int(iterator) = 0;
3043
3044
// Skip regular iterate.
3045
ip += 5;
3046
} else {
3047
// Jump to end of loop.
3048
int jumpto = _code_ptr[ip + 4];
3049
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
3050
ip = jumpto;
3051
}
3052
}
3053
DISPATCH_OPCODE;
3054
3055
OPCODE(OPCODE_ITERATE_BEGIN_FLOAT) {
3056
CHECK_SPACE(8); // Check space for iterate instruction too.
3057
3058
GET_VARIANT_PTR(counter, 0);
3059
GET_VARIANT_PTR(container, 1);
3060
3061
double size = *VariantInternal::get_float(container);
3062
3063
VariantInternal::initialize(counter, Variant::FLOAT);
3064
*VariantInternal::get_float(counter) = 0.0;
3065
3066
if (size > 0) {
3067
GET_VARIANT_PTR(iterator, 2);
3068
VariantInternal::initialize(iterator, Variant::FLOAT);
3069
*VariantInternal::get_float(iterator) = 0;
3070
3071
// Skip regular iterate.
3072
ip += 5;
3073
} else {
3074
// Jump to end of loop.
3075
int jumpto = _code_ptr[ip + 4];
3076
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
3077
ip = jumpto;
3078
}
3079
}
3080
DISPATCH_OPCODE;
3081
3082
OPCODE(OPCODE_ITERATE_BEGIN_VECTOR2) {
3083
CHECK_SPACE(8); // Check space for iterate instruction too.
3084
3085
GET_VARIANT_PTR(counter, 0);
3086
GET_VARIANT_PTR(container, 1);
3087
3088
Vector2 *bounds = VariantInternal::get_vector2(container);
3089
3090
VariantInternal::initialize(counter, Variant::FLOAT);
3091
*VariantInternal::get_float(counter) = bounds->x;
3092
3093
if (bounds->x < bounds->y) {
3094
GET_VARIANT_PTR(iterator, 2);
3095
VariantInternal::initialize(iterator, Variant::FLOAT);
3096
*VariantInternal::get_float(iterator) = bounds->x;
3097
3098
// Skip regular iterate.
3099
ip += 5;
3100
} else {
3101
// Jump to end of loop.
3102
int jumpto = _code_ptr[ip + 4];
3103
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
3104
ip = jumpto;
3105
}
3106
}
3107
DISPATCH_OPCODE;
3108
3109
OPCODE(OPCODE_ITERATE_BEGIN_VECTOR2I) {
3110
CHECK_SPACE(8); // Check space for iterate instruction too.
3111
3112
GET_VARIANT_PTR(counter, 0);
3113
GET_VARIANT_PTR(container, 1);
3114
3115
Vector2i *bounds = VariantInternal::get_vector2i(container);
3116
3117
VariantInternal::initialize(counter, Variant::FLOAT);
3118
*VariantInternal::get_int(counter) = bounds->x;
3119
3120
if (bounds->x < bounds->y) {
3121
GET_VARIANT_PTR(iterator, 2);
3122
VariantInternal::initialize(iterator, Variant::INT);
3123
*VariantInternal::get_int(iterator) = bounds->x;
3124
3125
// Skip regular iterate.
3126
ip += 5;
3127
} else {
3128
// Jump to end of loop.
3129
int jumpto = _code_ptr[ip + 4];
3130
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
3131
ip = jumpto;
3132
}
3133
}
3134
DISPATCH_OPCODE;
3135
3136
OPCODE(OPCODE_ITERATE_BEGIN_VECTOR3) {
3137
CHECK_SPACE(8); // Check space for iterate instruction too.
3138
3139
GET_VARIANT_PTR(counter, 0);
3140
GET_VARIANT_PTR(container, 1);
3141
3142
Vector3 *bounds = VariantInternal::get_vector3(container);
3143
double from = bounds->x;
3144
double to = bounds->y;
3145
double step = bounds->z;
3146
3147
VariantInternal::initialize(counter, Variant::FLOAT);
3148
*VariantInternal::get_float(counter) = from;
3149
3150
bool do_continue = from == to ? false : (from < to ? step > 0 : step < 0);
3151
3152
if (do_continue) {
3153
GET_VARIANT_PTR(iterator, 2);
3154
VariantInternal::initialize(iterator, Variant::FLOAT);
3155
*VariantInternal::get_float(iterator) = from;
3156
3157
// Skip regular iterate.
3158
ip += 5;
3159
} else {
3160
// Jump to end of loop.
3161
int jumpto = _code_ptr[ip + 4];
3162
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
3163
ip = jumpto;
3164
}
3165
}
3166
DISPATCH_OPCODE;
3167
3168
OPCODE(OPCODE_ITERATE_BEGIN_VECTOR3I) {
3169
CHECK_SPACE(8); // Check space for iterate instruction too.
3170
3171
GET_VARIANT_PTR(counter, 0);
3172
GET_VARIANT_PTR(container, 1);
3173
3174
Vector3i *bounds = VariantInternal::get_vector3i(container);
3175
int64_t from = bounds->x;
3176
int64_t to = bounds->y;
3177
int64_t step = bounds->z;
3178
3179
VariantInternal::initialize(counter, Variant::INT);
3180
*VariantInternal::get_int(counter) = from;
3181
3182
bool do_continue = from == to ? false : (from < to ? step > 0 : step < 0);
3183
3184
if (do_continue) {
3185
GET_VARIANT_PTR(iterator, 2);
3186
VariantInternal::initialize(iterator, Variant::INT);
3187
*VariantInternal::get_int(iterator) = from;
3188
3189
// Skip regular iterate.
3190
ip += 5;
3191
} else {
3192
// Jump to end of loop.
3193
int jumpto = _code_ptr[ip + 4];
3194
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
3195
ip = jumpto;
3196
}
3197
}
3198
DISPATCH_OPCODE;
3199
3200
OPCODE(OPCODE_ITERATE_BEGIN_STRING) {
3201
CHECK_SPACE(8); // Check space for iterate instruction too.
3202
3203
GET_VARIANT_PTR(counter, 0);
3204
GET_VARIANT_PTR(container, 1);
3205
3206
String *str = VariantInternal::get_string(container);
3207
3208
VariantInternal::initialize(counter, Variant::INT);
3209
*VariantInternal::get_int(counter) = 0;
3210
3211
if (!str->is_empty()) {
3212
GET_VARIANT_PTR(iterator, 2);
3213
VariantInternal::initialize(iterator, Variant::STRING);
3214
*VariantInternal::get_string(iterator) = str->substr(0, 1);
3215
3216
// Skip regular iterate.
3217
ip += 5;
3218
} else {
3219
// Jump to end of loop.
3220
int jumpto = _code_ptr[ip + 4];
3221
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
3222
ip = jumpto;
3223
}
3224
}
3225
DISPATCH_OPCODE;
3226
3227
OPCODE(OPCODE_ITERATE_BEGIN_DICTIONARY) {
3228
CHECK_SPACE(8); // Check space for iterate instruction too.
3229
3230
GET_VARIANT_PTR(counter, 0);
3231
GET_VARIANT_PTR(container, 1);
3232
3233
Dictionary *dict = VariantInternal::get_dictionary(container);
3234
const Variant *next = dict->next(nullptr);
3235
3236
if (!dict->is_empty()) {
3237
GET_VARIANT_PTR(iterator, 2);
3238
*counter = *next;
3239
*iterator = *next;
3240
3241
// Skip regular iterate.
3242
ip += 5;
3243
} else {
3244
// Jump to end of loop.
3245
int jumpto = _code_ptr[ip + 4];
3246
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
3247
ip = jumpto;
3248
}
3249
}
3250
DISPATCH_OPCODE;
3251
3252
OPCODE(OPCODE_ITERATE_BEGIN_ARRAY) {
3253
CHECK_SPACE(8); // Check space for iterate instruction too.
3254
3255
GET_VARIANT_PTR(counter, 0);
3256
GET_VARIANT_PTR(container, 1);
3257
3258
Array *array = VariantInternal::get_array(container);
3259
3260
VariantInternal::initialize(counter, Variant::INT);
3261
*VariantInternal::get_int(counter) = 0;
3262
3263
if (!array->is_empty()) {
3264
GET_VARIANT_PTR(iterator, 2);
3265
*iterator = array->get(0);
3266
3267
// Skip regular iterate.
3268
ip += 5;
3269
} else {
3270
// Jump to end of loop.
3271
int jumpto = _code_ptr[ip + 4];
3272
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
3273
ip = jumpto;
3274
}
3275
}
3276
DISPATCH_OPCODE;
3277
3278
#define OPCODE_ITERATE_BEGIN_PACKED_ARRAY(m_var_type, m_elem_type, m_get_func, m_var_ret_type, m_ret_type, m_ret_get_func) \
3279
OPCODE(OPCODE_ITERATE_BEGIN_PACKED_##m_var_type##_ARRAY) { \
3280
CHECK_SPACE(8); \
3281
GET_VARIANT_PTR(counter, 0); \
3282
GET_VARIANT_PTR(container, 1); \
3283
Vector<m_elem_type> *array = VariantInternal::m_get_func(container); \
3284
VariantInternal::initialize(counter, Variant::INT); \
3285
*VariantInternal::get_int(counter) = 0; \
3286
if (!array->is_empty()) { \
3287
GET_VARIANT_PTR(iterator, 2); \
3288
VariantInternal::initialize(iterator, Variant::m_var_ret_type); \
3289
m_ret_type *it = VariantInternal::m_ret_get_func(iterator); \
3290
*it = array->get(0); \
3291
ip += 5; \
3292
} else { \
3293
int jumpto = _code_ptr[ip + 4]; \
3294
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size); \
3295
ip = jumpto; \
3296
} \
3297
} \
3298
DISPATCH_OPCODE
3299
3300
OPCODE_ITERATE_BEGIN_PACKED_ARRAY(BYTE, uint8_t, get_byte_array, INT, int64_t, get_int);
3301
OPCODE_ITERATE_BEGIN_PACKED_ARRAY(INT32, int32_t, get_int32_array, INT, int64_t, get_int);
3302
OPCODE_ITERATE_BEGIN_PACKED_ARRAY(INT64, int64_t, get_int64_array, INT, int64_t, get_int);
3303
OPCODE_ITERATE_BEGIN_PACKED_ARRAY(FLOAT32, float, get_float32_array, FLOAT, double, get_float);
3304
OPCODE_ITERATE_BEGIN_PACKED_ARRAY(FLOAT64, double, get_float64_array, FLOAT, double, get_float);
3305
OPCODE_ITERATE_BEGIN_PACKED_ARRAY(STRING, String, get_string_array, STRING, String, get_string);
3306
OPCODE_ITERATE_BEGIN_PACKED_ARRAY(VECTOR2, Vector2, get_vector2_array, VECTOR2, Vector2, get_vector2);
3307
OPCODE_ITERATE_BEGIN_PACKED_ARRAY(VECTOR3, Vector3, get_vector3_array, VECTOR3, Vector3, get_vector3);
3308
OPCODE_ITERATE_BEGIN_PACKED_ARRAY(COLOR, Color, get_color_array, COLOR, Color, get_color);
3309
OPCODE_ITERATE_BEGIN_PACKED_ARRAY(VECTOR4, Vector4, get_vector4_array, VECTOR4, Vector4, get_vector4);
3310
3311
OPCODE(OPCODE_ITERATE_BEGIN_OBJECT) {
3312
CHECK_SPACE(4);
3313
3314
GET_VARIANT_PTR(counter, 0);
3315
GET_VARIANT_PTR(container, 1);
3316
3317
#ifdef DEBUG_ENABLED
3318
bool freed = false;
3319
Object *obj = container->get_validated_object_with_check(freed);
3320
if (freed) {
3321
err_text = "Trying to iterate on a previously freed object.";
3322
OPCODE_BREAK;
3323
} else if (!obj) {
3324
err_text = "Trying to iterate on a null value.";
3325
OPCODE_BREAK;
3326
}
3327
#else
3328
Object *obj = *VariantInternal::get_object(container);
3329
#endif
3330
3331
*counter = Variant();
3332
Array ref = { *counter };
3333
Variant vref;
3334
VariantInternal::initialize(&vref, Variant::ARRAY);
3335
*VariantInternal::get_array(&vref) = ref;
3336
3337
const Variant *args[] = { &vref };
3338
3339
Callable::CallError ce;
3340
Variant has_next = obj->callp(CoreStringName(_iter_init), args, 1, ce);
3341
3342
#ifdef DEBUG_ENABLED
3343
if (ref.size() != 1 || ce.error != Callable::CallError::CALL_OK) {
3344
err_text = vformat(R"(There was an error calling "_iter_next" on iterator object of type %s.)", *container);
3345
OPCODE_BREAK;
3346
}
3347
#endif
3348
if (!has_next.booleanize()) {
3349
int jumpto = _code_ptr[ip + 4];
3350
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
3351
ip = jumpto;
3352
} else {
3353
*counter = ref[0];
3354
3355
GET_VARIANT_PTR(iterator, 2);
3356
*iterator = obj->callp(CoreStringName(_iter_get), (const Variant **)&counter, 1, ce);
3357
#ifdef DEBUG_ENABLED
3358
if (ce.error != Callable::CallError::CALL_OK) {
3359
err_text = vformat(R"(There was an error calling "_iter_get" on iterator object of type %s.)", *container);
3360
OPCODE_BREAK;
3361
}
3362
#endif
3363
3364
ip += 5; // Loop again.
3365
}
3366
}
3367
DISPATCH_OPCODE;
3368
3369
OPCODE(OPCODE_ITERATE_BEGIN_RANGE) {
3370
CHECK_SPACE(6);
3371
3372
GET_VARIANT_PTR(counter, 0);
3373
GET_VARIANT_PTR(from_ptr, 1);
3374
GET_VARIANT_PTR(to_ptr, 2);
3375
GET_VARIANT_PTR(step_ptr, 3);
3376
3377
int64_t from = *VariantInternal::get_int(from_ptr);
3378
int64_t to = *VariantInternal::get_int(to_ptr);
3379
int64_t step = *VariantInternal::get_int(step_ptr);
3380
3381
VariantInternal::initialize(counter, Variant::INT);
3382
*VariantInternal::get_int(counter) = from;
3383
3384
bool do_continue = from == to ? false : (from < to ? step > 0 : step < 0);
3385
3386
if (do_continue) {
3387
GET_VARIANT_PTR(iterator, 4);
3388
VariantInternal::initialize(iterator, Variant::INT);
3389
*VariantInternal::get_int(iterator) = from;
3390
3391
// Skip regular iterate.
3392
ip += 7;
3393
} else {
3394
// Jump to end of loop.
3395
int jumpto = _code_ptr[ip + 6];
3396
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
3397
ip = jumpto;
3398
}
3399
}
3400
DISPATCH_OPCODE;
3401
3402
OPCODE(OPCODE_ITERATE) {
3403
CHECK_SPACE(4);
3404
3405
GET_VARIANT_PTR(counter, 0);
3406
GET_VARIANT_PTR(container, 1);
3407
3408
bool valid;
3409
if (!container->iter_next(*counter, valid)) {
3410
#ifdef DEBUG_ENABLED
3411
if (!valid) {
3412
err_text = "Unable to iterate on object of type '" + Variant::get_type_name(container->get_type()) + "' (type changed since first iteration?).";
3413
OPCODE_BREAK;
3414
}
3415
#endif
3416
int jumpto = _code_ptr[ip + 4];
3417
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
3418
ip = jumpto;
3419
} else {
3420
GET_VARIANT_PTR(iterator, 2);
3421
3422
*iterator = container->iter_get(*counter, valid);
3423
#ifdef DEBUG_ENABLED
3424
if (!valid) {
3425
err_text = "Unable to obtain iterator object of type '" + Variant::get_type_name(container->get_type()) + "' (but was obtained on first iteration?).";
3426
OPCODE_BREAK;
3427
}
3428
#endif
3429
ip += 5; //loop again
3430
}
3431
}
3432
DISPATCH_OPCODE;
3433
3434
OPCODE(OPCODE_ITERATE_INT) {
3435
CHECK_SPACE(4);
3436
3437
GET_VARIANT_PTR(counter, 0);
3438
GET_VARIANT_PTR(container, 1);
3439
3440
int64_t size = *VariantInternal::get_int(container);
3441
int64_t *count = VariantInternal::get_int(counter);
3442
3443
(*count)++;
3444
3445
if (*count >= size) {
3446
int jumpto = _code_ptr[ip + 4];
3447
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
3448
ip = jumpto;
3449
} else {
3450
GET_VARIANT_PTR(iterator, 2);
3451
*VariantInternal::get_int(iterator) = *count;
3452
3453
ip += 5; // Loop again.
3454
}
3455
}
3456
DISPATCH_OPCODE;
3457
3458
OPCODE(OPCODE_ITERATE_FLOAT) {
3459
CHECK_SPACE(4);
3460
3461
GET_VARIANT_PTR(counter, 0);
3462
GET_VARIANT_PTR(container, 1);
3463
3464
double size = *VariantInternal::get_float(container);
3465
double *count = VariantInternal::get_float(counter);
3466
3467
(*count)++;
3468
3469
if (*count >= size) {
3470
int jumpto = _code_ptr[ip + 4];
3471
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
3472
ip = jumpto;
3473
} else {
3474
GET_VARIANT_PTR(iterator, 2);
3475
*VariantInternal::get_float(iterator) = *count;
3476
3477
ip += 5; // Loop again.
3478
}
3479
}
3480
DISPATCH_OPCODE;
3481
3482
OPCODE(OPCODE_ITERATE_VECTOR2) {
3483
CHECK_SPACE(4);
3484
3485
GET_VARIANT_PTR(counter, 0);
3486
GET_VARIANT_PTR(container, 1);
3487
3488
const Vector2 *bounds = VariantInternal::get_vector2((const Variant *)container);
3489
double *count = VariantInternal::get_float(counter);
3490
3491
(*count)++;
3492
3493
if (*count >= bounds->y) {
3494
int jumpto = _code_ptr[ip + 4];
3495
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
3496
ip = jumpto;
3497
} else {
3498
GET_VARIANT_PTR(iterator, 2);
3499
*VariantInternal::get_float(iterator) = *count;
3500
3501
ip += 5; // Loop again.
3502
}
3503
}
3504
DISPATCH_OPCODE;
3505
3506
OPCODE(OPCODE_ITERATE_VECTOR2I) {
3507
CHECK_SPACE(4);
3508
3509
GET_VARIANT_PTR(counter, 0);
3510
GET_VARIANT_PTR(container, 1);
3511
3512
const Vector2i *bounds = VariantInternal::get_vector2i((const Variant *)container);
3513
int64_t *count = VariantInternal::get_int(counter);
3514
3515
(*count)++;
3516
3517
if (*count >= bounds->y) {
3518
int jumpto = _code_ptr[ip + 4];
3519
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
3520
ip = jumpto;
3521
} else {
3522
GET_VARIANT_PTR(iterator, 2);
3523
*VariantInternal::get_int(iterator) = *count;
3524
3525
ip += 5; // Loop again.
3526
}
3527
}
3528
DISPATCH_OPCODE;
3529
3530
OPCODE(OPCODE_ITERATE_VECTOR3) {
3531
CHECK_SPACE(4);
3532
3533
GET_VARIANT_PTR(counter, 0);
3534
GET_VARIANT_PTR(container, 1);
3535
3536
const Vector3 *bounds = VariantInternal::get_vector3((const Variant *)container);
3537
double *count = VariantInternal::get_float(counter);
3538
3539
*count += bounds->z;
3540
3541
if ((bounds->z < 0 && *count <= bounds->y) || (bounds->z > 0 && *count >= bounds->y)) {
3542
int jumpto = _code_ptr[ip + 4];
3543
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
3544
ip = jumpto;
3545
} else {
3546
GET_VARIANT_PTR(iterator, 2);
3547
*VariantInternal::get_float(iterator) = *count;
3548
3549
ip += 5; // Loop again.
3550
}
3551
}
3552
DISPATCH_OPCODE;
3553
3554
OPCODE(OPCODE_ITERATE_VECTOR3I) {
3555
CHECK_SPACE(4);
3556
3557
GET_VARIANT_PTR(counter, 0);
3558
GET_VARIANT_PTR(container, 1);
3559
3560
const Vector3i *bounds = VariantInternal::get_vector3i((const Variant *)container);
3561
int64_t *count = VariantInternal::get_int(counter);
3562
3563
*count += bounds->z;
3564
3565
if ((bounds->z < 0 && *count <= bounds->y) || (bounds->z > 0 && *count >= bounds->y)) {
3566
int jumpto = _code_ptr[ip + 4];
3567
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
3568
ip = jumpto;
3569
} else {
3570
GET_VARIANT_PTR(iterator, 2);
3571
*VariantInternal::get_int(iterator) = *count;
3572
3573
ip += 5; // Loop again.
3574
}
3575
}
3576
DISPATCH_OPCODE;
3577
3578
OPCODE(OPCODE_ITERATE_STRING) {
3579
CHECK_SPACE(4);
3580
3581
GET_VARIANT_PTR(counter, 0);
3582
GET_VARIANT_PTR(container, 1);
3583
3584
const String *str = VariantInternal::get_string((const Variant *)container);
3585
int64_t *idx = VariantInternal::get_int(counter);
3586
(*idx)++;
3587
3588
if (*idx >= str->length()) {
3589
int jumpto = _code_ptr[ip + 4];
3590
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
3591
ip = jumpto;
3592
} else {
3593
GET_VARIANT_PTR(iterator, 2);
3594
*VariantInternal::get_string(iterator) = str->substr(*idx, 1);
3595
3596
ip += 5; // Loop again.
3597
}
3598
}
3599
DISPATCH_OPCODE;
3600
3601
OPCODE(OPCODE_ITERATE_DICTIONARY) {
3602
CHECK_SPACE(4);
3603
3604
GET_VARIANT_PTR(counter, 0);
3605
GET_VARIANT_PTR(container, 1);
3606
3607
const Dictionary *dict = VariantInternal::get_dictionary((const Variant *)container);
3608
const Variant *next = dict->next(counter);
3609
3610
if (!next) {
3611
int jumpto = _code_ptr[ip + 4];
3612
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
3613
ip = jumpto;
3614
} else {
3615
GET_VARIANT_PTR(iterator, 2);
3616
*counter = *next;
3617
*iterator = *next;
3618
3619
ip += 5; // Loop again.
3620
}
3621
}
3622
DISPATCH_OPCODE;
3623
3624
OPCODE(OPCODE_ITERATE_ARRAY) {
3625
CHECK_SPACE(4);
3626
3627
GET_VARIANT_PTR(counter, 0);
3628
GET_VARIANT_PTR(container, 1);
3629
3630
const Array *array = VariantInternal::get_array((const Variant *)container);
3631
int64_t *idx = VariantInternal::get_int(counter);
3632
(*idx)++;
3633
3634
if (*idx >= array->size()) {
3635
int jumpto = _code_ptr[ip + 4];
3636
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
3637
ip = jumpto;
3638
} else {
3639
GET_VARIANT_PTR(iterator, 2);
3640
*iterator = array->get(*idx);
3641
3642
ip += 5; // Loop again.
3643
}
3644
}
3645
DISPATCH_OPCODE;
3646
3647
#define OPCODE_ITERATE_PACKED_ARRAY(m_var_type, m_elem_type, m_get_func, m_ret_get_func) \
3648
OPCODE(OPCODE_ITERATE_PACKED_##m_var_type##_ARRAY) { \
3649
CHECK_SPACE(4); \
3650
GET_VARIANT_PTR(counter, 0); \
3651
GET_VARIANT_PTR(container, 1); \
3652
const Vector<m_elem_type> *array = VariantInternal::m_get_func((const Variant *)container); \
3653
int64_t *idx = VariantInternal::get_int(counter); \
3654
(*idx)++; \
3655
if (*idx >= array->size()) { \
3656
int jumpto = _code_ptr[ip + 4]; \
3657
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size); \
3658
ip = jumpto; \
3659
} else { \
3660
GET_VARIANT_PTR(iterator, 2); \
3661
*VariantInternal::m_ret_get_func(iterator) = array->get(*idx); \
3662
ip += 5; \
3663
} \
3664
} \
3665
DISPATCH_OPCODE
3666
3667
OPCODE_ITERATE_PACKED_ARRAY(BYTE, uint8_t, get_byte_array, get_int);
3668
OPCODE_ITERATE_PACKED_ARRAY(INT32, int32_t, get_int32_array, get_int);
3669
OPCODE_ITERATE_PACKED_ARRAY(INT64, int64_t, get_int64_array, get_int);
3670
OPCODE_ITERATE_PACKED_ARRAY(FLOAT32, float, get_float32_array, get_float);
3671
OPCODE_ITERATE_PACKED_ARRAY(FLOAT64, double, get_float64_array, get_float);
3672
OPCODE_ITERATE_PACKED_ARRAY(STRING, String, get_string_array, get_string);
3673
OPCODE_ITERATE_PACKED_ARRAY(VECTOR2, Vector2, get_vector2_array, get_vector2);
3674
OPCODE_ITERATE_PACKED_ARRAY(VECTOR3, Vector3, get_vector3_array, get_vector3);
3675
OPCODE_ITERATE_PACKED_ARRAY(COLOR, Color, get_color_array, get_color);
3676
OPCODE_ITERATE_PACKED_ARRAY(VECTOR4, Vector4, get_vector4_array, get_vector4);
3677
3678
OPCODE(OPCODE_ITERATE_OBJECT) {
3679
CHECK_SPACE(4);
3680
3681
GET_VARIANT_PTR(counter, 0);
3682
GET_VARIANT_PTR(container, 1);
3683
3684
#ifdef DEBUG_ENABLED
3685
bool freed = false;
3686
Object *obj = container->get_validated_object_with_check(freed);
3687
if (freed) {
3688
err_text = "Trying to iterate on a previously freed object.";
3689
OPCODE_BREAK;
3690
} else if (!obj) {
3691
err_text = "Trying to iterate on a null value.";
3692
OPCODE_BREAK;
3693
}
3694
#else
3695
Object *obj = *VariantInternal::get_object(container);
3696
#endif
3697
3698
Array ref = { *counter };
3699
Variant vref;
3700
VariantInternal::initialize(&vref, Variant::ARRAY);
3701
*VariantInternal::get_array(&vref) = ref;
3702
3703
const Variant *args[] = { &vref };
3704
3705
Callable::CallError ce;
3706
Variant has_next = obj->callp(CoreStringName(_iter_next), args, 1, ce);
3707
3708
#ifdef DEBUG_ENABLED
3709
if (ref.size() != 1 || ce.error != Callable::CallError::CALL_OK) {
3710
err_text = vformat(R"(There was an error calling "_iter_next" on iterator object of type %s.)", *container);
3711
OPCODE_BREAK;
3712
}
3713
#endif
3714
if (!has_next.booleanize()) {
3715
int jumpto = _code_ptr[ip + 4];
3716
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
3717
ip = jumpto;
3718
} else {
3719
*counter = ref[0];
3720
3721
GET_VARIANT_PTR(iterator, 2);
3722
*iterator = obj->callp(CoreStringName(_iter_get), (const Variant **)&counter, 1, ce);
3723
#ifdef DEBUG_ENABLED
3724
if (ce.error != Callable::CallError::CALL_OK) {
3725
err_text = vformat(R"(There was an error calling "_iter_get" on iterator object of type %s.)", *container);
3726
OPCODE_BREAK;
3727
}
3728
#endif
3729
3730
ip += 5; // Loop again.
3731
}
3732
}
3733
DISPATCH_OPCODE;
3734
3735
OPCODE(OPCODE_ITERATE_RANGE) {
3736
CHECK_SPACE(5);
3737
3738
GET_VARIANT_PTR(counter, 0);
3739
GET_VARIANT_PTR(to_ptr, 1);
3740
GET_VARIANT_PTR(step_ptr, 2);
3741
3742
int64_t to = *VariantInternal::get_int(to_ptr);
3743
int64_t step = *VariantInternal::get_int(step_ptr);
3744
3745
int64_t *count = VariantInternal::get_int(counter);
3746
3747
*count += step;
3748
3749
if ((step < 0 && *count <= to) || (step > 0 && *count >= to)) {
3750
int jumpto = _code_ptr[ip + 5];
3751
GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
3752
ip = jumpto;
3753
} else {
3754
GET_VARIANT_PTR(iterator, 3);
3755
*VariantInternal::get_int(iterator) = *count;
3756
3757
ip += 6; // Loop again.
3758
}
3759
}
3760
DISPATCH_OPCODE;
3761
3762
OPCODE(OPCODE_STORE_GLOBAL) {
3763
CHECK_SPACE(3);
3764
int global_idx = _code_ptr[ip + 2];
3765
GD_ERR_BREAK(global_idx < 0 || global_idx >= GDScriptLanguage::get_singleton()->get_global_array_size());
3766
3767
GET_VARIANT_PTR(dst, 0);
3768
*dst = GDScriptLanguage::get_singleton()->get_global_array()[global_idx];
3769
3770
ip += 3;
3771
}
3772
DISPATCH_OPCODE;
3773
3774
OPCODE(OPCODE_STORE_NAMED_GLOBAL) {
3775
CHECK_SPACE(3);
3776
int globalname_idx = _code_ptr[ip + 2];
3777
GD_ERR_BREAK(globalname_idx < 0 || globalname_idx >= _global_names_count);
3778
const StringName *globalname = &_global_names_ptr[globalname_idx];
3779
GD_ERR_BREAK(!GDScriptLanguage::get_singleton()->get_named_globals_map().has(*globalname));
3780
3781
GET_VARIANT_PTR(dst, 0);
3782
*dst = GDScriptLanguage::get_singleton()->get_named_globals_map()[*globalname];
3783
3784
ip += 3;
3785
}
3786
DISPATCH_OPCODE;
3787
3788
#define OPCODE_TYPE_ADJUST(m_v_type, m_c_type) \
3789
OPCODE(OPCODE_TYPE_ADJUST_##m_v_type) { \
3790
CHECK_SPACE(2); \
3791
GET_VARIANT_PTR(arg, 0); \
3792
VariantTypeAdjust<m_c_type>::adjust(arg); \
3793
ip += 2; \
3794
} \
3795
DISPATCH_OPCODE
3796
3797
OPCODE_TYPE_ADJUST(BOOL, bool);
3798
OPCODE_TYPE_ADJUST(INT, int64_t);
3799
OPCODE_TYPE_ADJUST(FLOAT, double);
3800
OPCODE_TYPE_ADJUST(STRING, String);
3801
OPCODE_TYPE_ADJUST(VECTOR2, Vector2);
3802
OPCODE_TYPE_ADJUST(VECTOR2I, Vector2i);
3803
OPCODE_TYPE_ADJUST(RECT2, Rect2);
3804
OPCODE_TYPE_ADJUST(RECT2I, Rect2i);
3805
OPCODE_TYPE_ADJUST(VECTOR3, Vector3);
3806
OPCODE_TYPE_ADJUST(VECTOR3I, Vector3i);
3807
OPCODE_TYPE_ADJUST(TRANSFORM2D, Transform2D);
3808
OPCODE_TYPE_ADJUST(VECTOR4, Vector4);
3809
OPCODE_TYPE_ADJUST(VECTOR4I, Vector4i);
3810
OPCODE_TYPE_ADJUST(PLANE, Plane);
3811
OPCODE_TYPE_ADJUST(QUATERNION, Quaternion);
3812
OPCODE_TYPE_ADJUST(AABB, AABB);
3813
OPCODE_TYPE_ADJUST(BASIS, Basis);
3814
OPCODE_TYPE_ADJUST(TRANSFORM3D, Transform3D);
3815
OPCODE_TYPE_ADJUST(PROJECTION, Projection);
3816
OPCODE_TYPE_ADJUST(COLOR, Color);
3817
OPCODE_TYPE_ADJUST(STRING_NAME, StringName);
3818
OPCODE_TYPE_ADJUST(NODE_PATH, NodePath);
3819
OPCODE_TYPE_ADJUST(RID, RID);
3820
OPCODE_TYPE_ADJUST(OBJECT, Object *);
3821
OPCODE_TYPE_ADJUST(CALLABLE, Callable);
3822
OPCODE_TYPE_ADJUST(SIGNAL, Signal);
3823
OPCODE_TYPE_ADJUST(DICTIONARY, Dictionary);
3824
OPCODE_TYPE_ADJUST(ARRAY, Array);
3825
OPCODE_TYPE_ADJUST(PACKED_BYTE_ARRAY, PackedByteArray);
3826
OPCODE_TYPE_ADJUST(PACKED_INT32_ARRAY, PackedInt32Array);
3827
OPCODE_TYPE_ADJUST(PACKED_INT64_ARRAY, PackedInt64Array);
3828
OPCODE_TYPE_ADJUST(PACKED_FLOAT32_ARRAY, PackedFloat32Array);
3829
OPCODE_TYPE_ADJUST(PACKED_FLOAT64_ARRAY, PackedFloat64Array);
3830
OPCODE_TYPE_ADJUST(PACKED_STRING_ARRAY, PackedStringArray);
3831
OPCODE_TYPE_ADJUST(PACKED_VECTOR2_ARRAY, PackedVector2Array);
3832
OPCODE_TYPE_ADJUST(PACKED_VECTOR3_ARRAY, PackedVector3Array);
3833
OPCODE_TYPE_ADJUST(PACKED_COLOR_ARRAY, PackedColorArray);
3834
OPCODE_TYPE_ADJUST(PACKED_VECTOR4_ARRAY, PackedVector4Array);
3835
3836
OPCODE(OPCODE_ASSERT) {
3837
CHECK_SPACE(3);
3838
3839
#ifdef DEBUG_ENABLED
3840
GET_VARIANT_PTR(test, 0);
3841
bool result = test->booleanize();
3842
3843
if (!result) {
3844
String message_str;
3845
if (_code_ptr[ip + 2] != 0) {
3846
GET_VARIANT_PTR(message, 1);
3847
Variant message_var = *message;
3848
if (message->get_type() != Variant::NIL) {
3849
message_str = message_var;
3850
}
3851
}
3852
if (message_str.is_empty()) {
3853
err_text = "Assertion failed.";
3854
} else {
3855
err_text = "Assertion failed: " + message_str;
3856
}
3857
OPCODE_BREAK;
3858
}
3859
3860
#endif
3861
ip += 3;
3862
}
3863
DISPATCH_OPCODE;
3864
3865
OPCODE(OPCODE_BREAKPOINT) {
3866
#ifdef DEBUG_ENABLED
3867
if (EngineDebugger::is_active()) {
3868
GDScriptLanguage::get_singleton()->debug_break("Breakpoint Statement", true);
3869
}
3870
#endif
3871
ip += 1;
3872
}
3873
DISPATCH_OPCODE;
3874
3875
OPCODE(OPCODE_LINE) {
3876
CHECK_SPACE(2);
3877
3878
line = _code_ptr[ip + 1];
3879
ip += 2;
3880
3881
if (EngineDebugger::is_active()) {
3882
// line
3883
bool do_break = false;
3884
3885
if (unlikely(EngineDebugger::get_script_debugger()->get_lines_left() > 0)) {
3886
if (EngineDebugger::get_script_debugger()->get_depth() <= 0) {
3887
EngineDebugger::get_script_debugger()->set_lines_left(EngineDebugger::get_script_debugger()->get_lines_left() - 1);
3888
}
3889
if (EngineDebugger::get_script_debugger()->get_lines_left() <= 0) {
3890
do_break = true;
3891
}
3892
}
3893
3894
if (EngineDebugger::get_script_debugger()->is_breakpoint(line, source)) {
3895
do_break = true;
3896
}
3897
3898
if (unlikely(do_break)) {
3899
GDScriptLanguage::get_singleton()->debug_break("Breakpoint", true);
3900
}
3901
3902
EngineDebugger::get_singleton()->line_poll();
3903
}
3904
}
3905
DISPATCH_OPCODE;
3906
3907
OPCODE(OPCODE_END) {
3908
#ifdef DEBUG_ENABLED
3909
exit_ok = true;
3910
#endif
3911
OPCODE_BREAK;
3912
}
3913
3914
#if 0 // Enable for debugging.
3915
default: {
3916
err_text = "Illegal opcode " + itos(_code_ptr[ip]) + " at address " + itos(ip);
3917
OPCODE_BREAK;
3918
}
3919
#endif
3920
}
3921
3922
OPCODES_END
3923
#ifdef DEBUG_ENABLED
3924
if (exit_ok) {
3925
OPCODE_OUT;
3926
}
3927
//error
3928
// function, file, line, error, explanation
3929
String err_file;
3930
bool instance_valid_with_script = p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid();
3931
if (instance_valid_with_script && !get_script()->path.is_empty()) {
3932
err_file = get_script()->path;
3933
} else if (script) {
3934
err_file = script->path;
3935
}
3936
if (err_file.is_empty()) {
3937
err_file = "<built-in>";
3938
}
3939
String err_func = name;
3940
if (instance_valid_with_script && p_instance->script->local_name != StringName()) {
3941
err_func = p_instance->script->local_name.operator String() + "." + err_func;
3942
}
3943
int err_line = line;
3944
if (err_text.is_empty()) {
3945
err_text = "Internal script error! Opcode: " + itos(last_opcode) + " (please report).";
3946
}
3947
3948
_err_print_error(err_func.utf8().get_data(), err_file.utf8().get_data(), err_line, err_text.utf8().get_data(), false, ERR_HANDLER_SCRIPT);
3949
GDScriptLanguage::get_singleton()->debug_break(err_text, false);
3950
3951
// Get a default return type in case of failure
3952
retvalue = _get_default_variant_for_data_type(return_type);
3953
#endif
3954
3955
OPCODE_OUT;
3956
}
3957
3958
OPCODES_OUT
3959
#ifdef DEBUG_ENABLED
3960
if (GDScriptLanguage::get_singleton()->profiling) {
3961
uint64_t time_taken = OS::get_singleton()->get_ticks_usec() - function_start_time;
3962
profile.total_time.add(time_taken);
3963
profile.self_time.add(time_taken - function_call_time);
3964
profile.frame_total_time.add(time_taken);
3965
profile.frame_self_time.add(time_taken - function_call_time);
3966
if (Thread::get_caller_id() == Thread::get_main_id()) {
3967
GDScriptLanguage::get_singleton()->script_frame_time += time_taken - function_call_time;
3968
}
3969
}
3970
#endif
3971
3972
// Check if this is not the last time it was interrupted by `await` or if it's the first time executing.
3973
// If that is the case then we exit the function as normal. Otherwise we postpone it until the last `await` is completed.
3974
// This ensures the call stack can be properly shown when using `await`, showing what resumed the function.
3975
if (!p_state || awaited) {
3976
GDScriptLanguage::get_singleton()->exit_function();
3977
3978
// Free stack, except reserved addresses.
3979
for (int i = FIXED_ADDRESSES_MAX; i < _stack_size; i++) {
3980
stack[i].~Variant();
3981
}
3982
}
3983
3984
// Always free reserved addresses, since they are never copied.
3985
for (int i = 0; i < FIXED_ADDRESSES_MAX; i++) {
3986
stack[i].~Variant();
3987
}
3988
3989
call_depth--;
3990
3991
if (p_state && !awaited) {
3992
// This means we have finished executing a resumed function and it was not awaited again.
3993
3994
// Signal the next function-state to resume.
3995
const Variant *args[1] = { &retvalue };
3996
p_state->completed.emit(args, 1);
3997
3998
// Exit function only after executing the remaining function states to preserve async call stack.
3999
GDScriptLanguage::get_singleton()->exit_function();
4000
}
4001
4002
return retvalue;
4003
}
4004
4005