1 /*************************************************************************/
2 /* gdscript_function.cpp */
3 /*************************************************************************/
4 /* This file is part of: */
5 /* GODOT ENGINE */
6 /* https://godotengine.org */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
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_function.h"
32
33 #include "core/os/os.h"
34 #include "gdscript.h"
35 #include "gdscript_functions.h"
36
_get_variant(int p_address,GDScriptInstance * p_instance,GDScript * p_script,Variant & self,Variant * p_stack,String & r_error) const37 Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant *p_stack, String &r_error) const {
38
39 int address = p_address & ADDR_MASK;
40
41 //sequential table (jump table generated by compiler)
42 switch ((p_address & ADDR_TYPE_MASK) >> ADDR_BITS) {
43
44 case ADDR_TYPE_SELF: {
45 #ifdef DEBUG_ENABLED
46 if (unlikely(!p_instance)) {
47 r_error = "Cannot access self without instance.";
48 return NULL;
49 }
50 #endif
51 return &self;
52 } break;
53 case ADDR_TYPE_CLASS: {
54
55 return &p_script->_static_ref;
56 } break;
57 case ADDR_TYPE_MEMBER: {
58 #ifdef DEBUG_ENABLED
59 if (unlikely(!p_instance)) {
60 r_error = "Cannot access member without instance.";
61 return NULL;
62 }
63 #endif
64 //member indexing is O(1)
65 return &p_instance->members.write[address];
66 } break;
67 case ADDR_TYPE_CLASS_CONSTANT: {
68
69 //todo change to index!
70 GDScript *s = p_script;
71 #ifdef DEBUG_ENABLED
72 ERR_FAIL_INDEX_V(address, _global_names_count, NULL);
73 #endif
74 const StringName *sn = &_global_names_ptr[address];
75
76 while (s) {
77 GDScript *o = s;
78 while (o) {
79
80 Map<StringName, Variant>::Element *E = o->constants.find(*sn);
81 if (E) {
82 return &E->get();
83 }
84 o = o->_owner;
85 }
86 s = s->_base;
87 }
88
89 ERR_FAIL_V_MSG(NULL, "GDScriptCompiler bug.");
90 } break;
91 case ADDR_TYPE_LOCAL_CONSTANT: {
92 #ifdef DEBUG_ENABLED
93 ERR_FAIL_INDEX_V(address, _constant_count, NULL);
94 #endif
95 return &_constants_ptr[address];
96 } break;
97 case ADDR_TYPE_STACK:
98 case ADDR_TYPE_STACK_VARIABLE: {
99 #ifdef DEBUG_ENABLED
100 ERR_FAIL_INDEX_V(address, _stack_size, NULL);
101 #endif
102 return &p_stack[address];
103 } break;
104 case ADDR_TYPE_GLOBAL: {
105 #ifdef DEBUG_ENABLED
106 ERR_FAIL_INDEX_V(address, GDScriptLanguage::get_singleton()->get_global_array_size(), NULL);
107 #endif
108 return &GDScriptLanguage::get_singleton()->get_global_array()[address];
109 } break;
110 #ifdef TOOLS_ENABLED
111 case ADDR_TYPE_NAMED_GLOBAL: {
112 #ifdef DEBUG_ENABLED
113 ERR_FAIL_INDEX_V(address, _named_globals_count, NULL);
114 #endif
115 StringName id = _named_globals_ptr[address];
116
117 if (GDScriptLanguage::get_singleton()->get_named_globals_map().has(id)) {
118 return (Variant *)&GDScriptLanguage::get_singleton()->get_named_globals_map()[id];
119 } else {
120 r_error = "Autoload singleton '" + String(id) + "' has been removed.";
121 return NULL;
122 }
123 } break;
124 #endif
125 case ADDR_TYPE_NIL: {
126 return &nil;
127 } break;
128 }
129
130 ERR_FAIL_V_MSG(NULL, "Bad code! (unknown addressing mode).");
131 return NULL;
132 }
133
134 #ifdef DEBUG_ENABLED
_get_var_type(const Variant * p_var)135 static String _get_var_type(const Variant *p_var) {
136
137 String basestr;
138
139 if (p_var->get_type() == Variant::OBJECT) {
140 Object *bobj = *p_var;
141 if (!bobj) {
142 basestr = "null instance";
143 } else {
144 if (ObjectDB::instance_validate(bobj)) {
145 if (bobj->get_script_instance())
146 basestr = bobj->get_class() + " (" + bobj->get_script_instance()->get_script()->get_path().get_file() + ")";
147 else
148 basestr = bobj->get_class();
149 } else {
150 basestr = "previously freed instance";
151 }
152 }
153
154 } else {
155 basestr = Variant::get_type_name(p_var->get_type());
156 }
157
158 return basestr;
159 }
160 #endif // DEBUG_ENABLED
161
_get_call_error(const Variant::CallError & p_err,const String & p_where,const Variant ** argptrs) const162 String GDScriptFunction::_get_call_error(const Variant::CallError &p_err, const String &p_where, const Variant **argptrs) const {
163
164 String err_text;
165
166 if (p_err.error == Variant::CallError::CALL_ERROR_INVALID_ARGUMENT) {
167 int errorarg = p_err.argument;
168 // Handle the Object to Object case separately as we don't have further class details.
169 #ifdef DEBUG_ENABLED
170 if (p_err.expected == Variant::OBJECT && argptrs[errorarg]->get_type() == p_err.expected) {
171 err_text = "Invalid type in " + p_where + ". The Object-derived class of argument " + itos(errorarg + 1) + " (" + _get_var_type(argptrs[errorarg]) + ") is not a subclass of the expected argument class.";
172 } else
173 #endif // DEBUG_ENABLED
174 {
175 err_text = "Invalid type in " + p_where + ". Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(p_err.expected) + ".";
176 }
177 } else if (p_err.error == Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) {
178 err_text = "Invalid call to " + p_where + ". Expected " + itos(p_err.argument) + " arguments.";
179 } else if (p_err.error == Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) {
180 err_text = "Invalid call to " + p_where + ". Expected " + itos(p_err.argument) + " arguments.";
181 } else if (p_err.error == Variant::CallError::CALL_ERROR_INVALID_METHOD) {
182 err_text = "Invalid call. Nonexistent " + p_where + ".";
183 } else if (p_err.error == Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL) {
184 err_text = "Attempt to call " + p_where + " on a null instance.";
185 } else {
186 err_text = "Bug, call error: #" + itos(p_err.error);
187 }
188
189 return err_text;
190 }
191
192 #if defined(__GNUC__)
193 #define OPCODES_TABLE \
194 static const void *switch_table_ops[] = { \
195 &&OPCODE_OPERATOR, \
196 &&OPCODE_EXTENDS_TEST, \
197 &&OPCODE_IS_BUILTIN, \
198 &&OPCODE_SET, \
199 &&OPCODE_GET, \
200 &&OPCODE_SET_NAMED, \
201 &&OPCODE_GET_NAMED, \
202 &&OPCODE_SET_MEMBER, \
203 &&OPCODE_GET_MEMBER, \
204 &&OPCODE_ASSIGN, \
205 &&OPCODE_ASSIGN_TRUE, \
206 &&OPCODE_ASSIGN_FALSE, \
207 &&OPCODE_ASSIGN_TYPED_BUILTIN, \
208 &&OPCODE_ASSIGN_TYPED_NATIVE, \
209 &&OPCODE_ASSIGN_TYPED_SCRIPT, \
210 &&OPCODE_CAST_TO_BUILTIN, \
211 &&OPCODE_CAST_TO_NATIVE, \
212 &&OPCODE_CAST_TO_SCRIPT, \
213 &&OPCODE_CONSTRUCT, \
214 &&OPCODE_CONSTRUCT_ARRAY, \
215 &&OPCODE_CONSTRUCT_DICTIONARY, \
216 &&OPCODE_CALL, \
217 &&OPCODE_CALL_RETURN, \
218 &&OPCODE_CALL_BUILT_IN, \
219 &&OPCODE_CALL_SELF, \
220 &&OPCODE_CALL_SELF_BASE, \
221 &&OPCODE_YIELD, \
222 &&OPCODE_YIELD_SIGNAL, \
223 &&OPCODE_YIELD_RESUME, \
224 &&OPCODE_JUMP, \
225 &&OPCODE_JUMP_IF, \
226 &&OPCODE_JUMP_IF_NOT, \
227 &&OPCODE_JUMP_TO_DEF_ARGUMENT, \
228 &&OPCODE_RETURN, \
229 &&OPCODE_ITERATE_BEGIN, \
230 &&OPCODE_ITERATE, \
231 &&OPCODE_ASSERT, \
232 &&OPCODE_BREAKPOINT, \
233 &&OPCODE_LINE, \
234 &&OPCODE_END \
235 };
236
237 #define OPCODE(m_op) \
238 m_op:
239 #define OPCODE_WHILE(m_test)
240 #define OPCODES_END \
241 OPSEXIT:
242 #define OPCODES_OUT \
243 OPSOUT:
244 #define DISPATCH_OPCODE goto *switch_table_ops[_code_ptr[ip]]
245 #define OPCODE_SWITCH(m_test) DISPATCH_OPCODE;
246 #define OPCODE_BREAK goto OPSEXIT
247 #define OPCODE_OUT goto OPSOUT
248 #else
249 #define OPCODES_TABLE
250 #define OPCODE(m_op) case m_op:
251 #define OPCODE_WHILE(m_test) while (m_test)
252 #define OPCODES_END
253 #define OPCODES_OUT
254 #define DISPATCH_OPCODE continue
255 #define OPCODE_SWITCH(m_test) switch (m_test)
256 #define OPCODE_BREAK break
257 #define OPCODE_OUT break
258 #endif
259
call(GDScriptInstance * p_instance,const Variant ** p_args,int p_argcount,Variant::CallError & r_err,CallState * p_state)260 Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_args, int p_argcount, Variant::CallError &r_err, CallState *p_state) {
261
262 OPCODES_TABLE;
263
264 if (!_code_ptr) {
265
266 return Variant();
267 }
268
269 r_err.error = Variant::CallError::CALL_OK;
270
271 Variant self;
272 Variant retvalue;
273 Variant *stack = NULL;
274 Variant **call_args;
275 int defarg = 0;
276
277 #ifdef DEBUG_ENABLED
278
279 //GDScriptLanguage::get_singleton()->calls++;
280
281 #endif
282
283 uint32_t alloca_size = 0;
284 GDScript *script;
285 int ip = 0;
286 int line = _initial_line;
287
288 if (p_state) {
289 //use existing (supplied) state (yielded)
290 stack = (Variant *)p_state->stack.ptr();
291 call_args = (Variant **)&p_state->stack.ptr()[sizeof(Variant) * p_state->stack_size]; //ptr() to avoid bounds check
292 line = p_state->line;
293 ip = p_state->ip;
294 alloca_size = p_state->stack.size();
295 script = p_state->script;
296 p_instance = p_state->instance;
297 defarg = p_state->defarg;
298 self = p_state->self;
299 //stack[p_state->result_pos]=p_state->result; //assign stack with result
300
301 } else {
302
303 if (p_argcount != _argument_count) {
304
305 if (p_argcount > _argument_count) {
306
307 r_err.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
308 r_err.argument = _argument_count;
309
310 return Variant();
311 } else if (p_argcount < _argument_count - _default_arg_count) {
312
313 r_err.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
314 r_err.argument = _argument_count - _default_arg_count;
315 return Variant();
316 } else {
317
318 defarg = _argument_count - p_argcount;
319 }
320 }
321
322 alloca_size = sizeof(Variant *) * _call_size + sizeof(Variant) * _stack_size;
323
324 if (alloca_size) {
325
326 uint8_t *aptr = (uint8_t *)alloca(alloca_size);
327
328 if (_stack_size) {
329
330 stack = (Variant *)aptr;
331 for (int i = 0; i < p_argcount; i++) {
332 if (!argument_types[i].has_type) {
333 memnew_placement(&stack[i], Variant(*p_args[i]));
334 continue;
335 }
336
337 if (!argument_types[i].is_type(*p_args[i], true)) {
338 if (argument_types[i].is_type(Variant(), true)) {
339 memnew_placement(&stack[i], Variant);
340 continue;
341 } else {
342 r_err.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
343 r_err.argument = i;
344 r_err.expected = argument_types[i].kind == GDScriptDataType::BUILTIN ? argument_types[i].builtin_type : Variant::OBJECT;
345 return Variant();
346 }
347 }
348 if (argument_types[i].kind == GDScriptDataType::BUILTIN) {
349 Variant arg = Variant::construct(argument_types[i].builtin_type, &p_args[i], 1, r_err);
350 memnew_placement(&stack[i], Variant(arg));
351 } else {
352 memnew_placement(&stack[i], Variant(*p_args[i]));
353 }
354 }
355 for (int i = p_argcount; i < _stack_size; i++) {
356 memnew_placement(&stack[i], Variant);
357 }
358 } else {
359 stack = NULL;
360 }
361
362 if (_call_size) {
363
364 call_args = (Variant **)&aptr[sizeof(Variant) * _stack_size];
365 } else {
366
367 call_args = NULL;
368 }
369
370 } else {
371 stack = NULL;
372 call_args = NULL;
373 }
374
375 if (p_instance) {
376 if (p_instance->base_ref && static_cast<Reference *>(p_instance->owner)->is_referenced()) {
377
378 self = REF(static_cast<Reference *>(p_instance->owner));
379 } else {
380 self = p_instance->owner;
381 }
382 script = p_instance->script.ptr();
383 } else {
384 script = _script;
385 }
386 }
387
388 String err_text;
389
390 #ifdef DEBUG_ENABLED
391
392 if (ScriptDebugger::get_singleton())
393 GDScriptLanguage::get_singleton()->enter_function(p_instance, this, stack, &ip, &line);
394
395 #define GD_ERR_BREAK(m_cond) \
396 { \
397 if (unlikely(m_cond)) { \
398 _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true. Breaking..:"); \
399 OPCODE_BREAK; \
400 } \
401 }
402
403 #define CHECK_SPACE(m_space) \
404 GD_ERR_BREAK((ip + m_space) > _code_size)
405
406 #define GET_VARIANT_PTR(m_v, m_code_ofs) \
407 Variant *m_v; \
408 m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, script, self, stack, err_text); \
409 if (unlikely(!m_v)) \
410 OPCODE_BREAK;
411
412 #else
413 #define GD_ERR_BREAK(m_cond)
414 #define CHECK_SPACE(m_space)
415 #define GET_VARIANT_PTR(m_v, m_code_ofs) \
416 Variant *m_v; \
417 m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, script, self, stack, err_text);
418
419 #endif
420
421 #ifdef DEBUG_ENABLED
422
423 uint64_t function_start_time = 0;
424 uint64_t function_call_time = 0;
425
426 if (GDScriptLanguage::get_singleton()->profiling) {
427 function_start_time = OS::get_singleton()->get_ticks_usec();
428 function_call_time = 0;
429 profile.call_count++;
430 profile.frame_call_count++;
431 }
432 bool exit_ok = false;
433 bool yielded = false;
434 #endif
435
436 #ifdef DEBUG_ENABLED
437 OPCODE_WHILE(ip < _code_size) {
438 int last_opcode = _code_ptr[ip];
439 #else
440 OPCODE_WHILE(true) {
441 #endif
442
443 OPCODE_SWITCH(_code_ptr[ip]) {
444
445 OPCODE(OPCODE_OPERATOR) {
446
447 CHECK_SPACE(5);
448
449 bool valid;
450 Variant::Operator op = (Variant::Operator)_code_ptr[ip + 1];
451 GD_ERR_BREAK(op >= Variant::OP_MAX);
452
453 GET_VARIANT_PTR(a, 2);
454 GET_VARIANT_PTR(b, 3);
455 GET_VARIANT_PTR(dst, 4);
456
457 #ifdef DEBUG_ENABLED
458
459 Variant ret;
460 Variant::evaluate(op, *a, *b, ret, valid);
461 #else
462 Variant::evaluate(op, *a, *b, *dst, valid);
463 #endif
464 #ifdef DEBUG_ENABLED
465 if (!valid) {
466
467 if (ret.get_type() == Variant::STRING) {
468 //return a string when invalid with the error
469 err_text = ret;
470 err_text += " in operator '" + Variant::get_operator_name(op) + "'.";
471 } else {
472 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) + "'.";
473 }
474 OPCODE_BREAK;
475 }
476 *dst = ret;
477 #endif
478 ip += 5;
479 }
480 DISPATCH_OPCODE;
481
482 OPCODE(OPCODE_EXTENDS_TEST) {
483
484 CHECK_SPACE(4);
485
486 GET_VARIANT_PTR(a, 1);
487 GET_VARIANT_PTR(b, 2);
488 GET_VARIANT_PTR(dst, 3);
489
490 #ifdef DEBUG_ENABLED
491 if (b->get_type() != Variant::OBJECT || b->operator Object *() == NULL) {
492
493 err_text = "Right operand of 'is' is not a class.";
494 OPCODE_BREAK;
495 }
496 #endif
497
498 bool extends_ok = false;
499 if (a->get_type() == Variant::OBJECT && a->operator Object *() != NULL) {
500 Object *obj_A = *a;
501 Object *obj_B = *b;
502
503 #ifdef DEBUG_ENABLED
504 if (!ObjectDB::instance_validate(obj_A)) {
505 err_text = "Left operand of 'is' was already freed.";
506 OPCODE_BREAK;
507 }
508 #endif // DEBUG_ENABLED
509
510 GDScript *scr_B = Object::cast_to<GDScript>(obj_B);
511
512 if (scr_B) {
513 //if B is a script, the only valid condition is that A has an instance which inherits from the script
514 //in other situation, this shoul return false.
515
516 if (obj_A->get_script_instance() && obj_A->get_script_instance()->get_language() == GDScriptLanguage::get_singleton()) {
517
518 GDScript *cmp = static_cast<GDScript *>(obj_A->get_script_instance()->get_script().ptr());
519 //bool found=false;
520 while (cmp) {
521
522 if (cmp == scr_B) {
523 //inherits from script, all ok
524 extends_ok = true;
525 break;
526 }
527
528 cmp = cmp->_base;
529 }
530 }
531
532 } else {
533
534 GDScriptNativeClass *nc = Object::cast_to<GDScriptNativeClass>(obj_B);
535
536 #ifdef DEBUG_ENABLED
537 if (!nc) {
538
539 err_text = "Right operand of 'is' is not a class (type: '" + obj_B->get_class() + "').";
540 OPCODE_BREAK;
541 }
542 #endif
543 extends_ok = ClassDB::is_parent_class(obj_A->get_class_name(), nc->get_name());
544 }
545 }
546
547 *dst = extends_ok;
548 ip += 4;
549 }
550 DISPATCH_OPCODE;
551
552 OPCODE(OPCODE_IS_BUILTIN) {
553
554 CHECK_SPACE(4);
555
556 GET_VARIANT_PTR(value, 1);
557 Variant::Type var_type = (Variant::Type)_code_ptr[ip + 2];
558 GET_VARIANT_PTR(dst, 3);
559
560 GD_ERR_BREAK(var_type < 0 || var_type >= Variant::VARIANT_MAX);
561
562 *dst = value->get_type() == var_type;
563 ip += 4;
564 }
565 DISPATCH_OPCODE;
566
567 OPCODE(OPCODE_SET) {
568
569 CHECK_SPACE(3);
570
571 GET_VARIANT_PTR(dst, 1);
572 GET_VARIANT_PTR(index, 2);
573 GET_VARIANT_PTR(value, 3);
574
575 bool valid;
576 dst->set(*index, *value, &valid);
577
578 #ifdef DEBUG_ENABLED
579 if (!valid) {
580 String v = index->operator String();
581 if (v != "") {
582 v = "'" + v + "'";
583 } else {
584 v = "of type '" + _get_var_type(index) + "'";
585 }
586 err_text = "Invalid set index " + v + " (on base: '" + _get_var_type(dst) + "') with value of type '" + _get_var_type(value) + "'";
587 OPCODE_BREAK;
588 }
589 #endif
590 ip += 4;
591 }
592 DISPATCH_OPCODE;
593
594 OPCODE(OPCODE_GET) {
595
596 CHECK_SPACE(3);
597
598 GET_VARIANT_PTR(src, 1);
599 GET_VARIANT_PTR(index, 2);
600 GET_VARIANT_PTR(dst, 3);
601
602 bool valid;
603 #ifdef DEBUG_ENABLED
604 //allow better error message in cases where src and dst are the same stack position
605 Variant ret = src->get(*index, &valid);
606 #else
607 *dst = src->get(*index, &valid);
608
609 #endif
610 #ifdef DEBUG_ENABLED
611 if (!valid) {
612 String v = index->operator String();
613 if (v != "") {
614 v = "'" + v + "'";
615 } else {
616 v = "of type '" + _get_var_type(index) + "'";
617 }
618 err_text = "Invalid get index " + v + " (on base: '" + _get_var_type(src) + "').";
619 OPCODE_BREAK;
620 }
621 *dst = ret;
622 #endif
623 ip += 4;
624 }
625 DISPATCH_OPCODE;
626
627 OPCODE(OPCODE_SET_NAMED) {
628
629 CHECK_SPACE(3);
630
631 GET_VARIANT_PTR(dst, 1);
632 GET_VARIANT_PTR(value, 3);
633
634 int indexname = _code_ptr[ip + 2];
635
636 GD_ERR_BREAK(indexname < 0 || indexname >= _global_names_count);
637 const StringName *index = &_global_names_ptr[indexname];
638
639 bool valid;
640 dst->set_named(*index, *value, &valid);
641
642 #ifdef DEBUG_ENABLED
643 if (!valid) {
644 String err_type;
645 err_text = "Invalid set index '" + String(*index) + "' (on base: '" + _get_var_type(dst) + "') with value of type '" + _get_var_type(value) + "'.";
646 OPCODE_BREAK;
647 }
648 #endif
649 ip += 4;
650 }
651 DISPATCH_OPCODE;
652
653 OPCODE(OPCODE_GET_NAMED) {
654
655 CHECK_SPACE(4);
656
657 GET_VARIANT_PTR(src, 1);
658 GET_VARIANT_PTR(dst, 3);
659
660 int indexname = _code_ptr[ip + 2];
661
662 GD_ERR_BREAK(indexname < 0 || indexname >= _global_names_count);
663 const StringName *index = &_global_names_ptr[indexname];
664
665 bool valid;
666 #ifdef DEBUG_ENABLED
667 //allow better error message in cases where src and dst are the same stack position
668 Variant ret = src->get_named(*index, &valid);
669
670 #else
671 *dst = src->get_named(*index, &valid);
672 #endif
673 #ifdef DEBUG_ENABLED
674 if (!valid) {
675 if (src->has_method(*index)) {
676 err_text = "Invalid get index '" + index->operator String() + "' (on base: '" + _get_var_type(src) + "'). Did you mean '." + index->operator String() + "()' or funcref(obj, \"" + index->operator String() + "\") ?";
677 } else {
678 err_text = "Invalid get index '" + index->operator String() + "' (on base: '" + _get_var_type(src) + "').";
679 }
680 OPCODE_BREAK;
681 }
682 *dst = ret;
683 #endif
684 ip += 4;
685 }
686 DISPATCH_OPCODE;
687
688 OPCODE(OPCODE_SET_MEMBER) {
689
690 CHECK_SPACE(3);
691 int indexname = _code_ptr[ip + 1];
692 GD_ERR_BREAK(indexname < 0 || indexname >= _global_names_count);
693 const StringName *index = &_global_names_ptr[indexname];
694 GET_VARIANT_PTR(src, 2);
695
696 bool valid;
697 #ifndef DEBUG_ENABLED
698 ClassDB::set_property(p_instance->owner, *index, *src, &valid);
699 #else
700 bool ok = ClassDB::set_property(p_instance->owner, *index, *src, &valid);
701 if (!ok) {
702 err_text = "Internal error setting property: " + String(*index);
703 OPCODE_BREAK;
704 } else if (!valid) {
705 err_text = "Error setting property '" + String(*index) + "' with value of type " + Variant::get_type_name(src->get_type()) + ".";
706 OPCODE_BREAK;
707 }
708 #endif
709 ip += 3;
710 }
711 DISPATCH_OPCODE;
712
713 OPCODE(OPCODE_GET_MEMBER) {
714
715 CHECK_SPACE(3);
716 int indexname = _code_ptr[ip + 1];
717 GD_ERR_BREAK(indexname < 0 || indexname >= _global_names_count);
718 const StringName *index = &_global_names_ptr[indexname];
719 GET_VARIANT_PTR(dst, 2);
720
721 #ifndef DEBUG_ENABLED
722 ClassDB::get_property(p_instance->owner, *index, *dst);
723 #else
724 bool ok = ClassDB::get_property(p_instance->owner, *index, *dst);
725 if (!ok) {
726 err_text = "Internal error getting property: " + String(*index);
727 OPCODE_BREAK;
728 }
729 #endif
730 ip += 3;
731 }
732 DISPATCH_OPCODE;
733
734 OPCODE(OPCODE_ASSIGN) {
735
736 CHECK_SPACE(3);
737 GET_VARIANT_PTR(dst, 1);
738 GET_VARIANT_PTR(src, 2);
739
740 *dst = *src;
741
742 ip += 3;
743 }
744 DISPATCH_OPCODE;
745
746 OPCODE(OPCODE_ASSIGN_TRUE) {
747
748 CHECK_SPACE(2);
749 GET_VARIANT_PTR(dst, 1);
750
751 *dst = true;
752
753 ip += 2;
754 }
755 DISPATCH_OPCODE;
756
757 OPCODE(OPCODE_ASSIGN_FALSE) {
758
759 CHECK_SPACE(2);
760 GET_VARIANT_PTR(dst, 1);
761
762 *dst = false;
763
764 ip += 2;
765 }
766 DISPATCH_OPCODE;
767
768 OPCODE(OPCODE_ASSIGN_TYPED_BUILTIN) {
769
770 CHECK_SPACE(4);
771 GET_VARIANT_PTR(dst, 2);
772 GET_VARIANT_PTR(src, 3);
773
774 Variant::Type var_type = (Variant::Type)_code_ptr[ip + 1];
775 GD_ERR_BREAK(var_type < 0 || var_type >= Variant::VARIANT_MAX);
776
777 if (src->get_type() != var_type) {
778 #ifdef DEBUG_ENABLED
779 if (Variant::can_convert_strict(src->get_type(), var_type)) {
780 #endif // DEBUG_ENABLED
781 Variant::CallError ce;
782 *dst = Variant::construct(var_type, const_cast<const Variant **>(&src), 1, ce);
783 } else {
784 #ifdef DEBUG_ENABLED
785 err_text = "Trying to assign value of type '" + Variant::get_type_name(src->get_type()) +
786 "' to a variable of type '" + Variant::get_type_name(var_type) + "'.";
787 OPCODE_BREAK;
788 }
789 } else {
790 #endif // DEBUG_ENABLED
791 *dst = *src;
792 }
793
794 ip += 4;
795 }
796 DISPATCH_OPCODE;
797
798 OPCODE(OPCODE_ASSIGN_TYPED_NATIVE) {
799
800 CHECK_SPACE(4);
801 GET_VARIANT_PTR(dst, 2);
802 GET_VARIANT_PTR(src, 3);
803
804 #ifdef DEBUG_ENABLED
805 GET_VARIANT_PTR(type, 1);
806 GDScriptNativeClass *nc = Object::cast_to<GDScriptNativeClass>(type->operator Object *());
807 GD_ERR_BREAK(!nc);
808 if (src->get_type() != Variant::OBJECT && src->get_type() != Variant::NIL) {
809 err_text = "Trying to assign value of type '" + Variant::get_type_name(src->get_type()) +
810 "' to a variable of type '" + nc->get_name() + "'.";
811 OPCODE_BREAK;
812 }
813 Object *src_obj = src->operator Object *();
814
815 if (src_obj && !ClassDB::is_parent_class(src_obj->get_class_name(), nc->get_name())) {
816 err_text = "Trying to assign value of type '" + src_obj->get_class_name() +
817 "' to a variable of type '" + nc->get_name() + "'.";
818 OPCODE_BREAK;
819 }
820 #endif // DEBUG_ENABLED
821 *dst = *src;
822
823 ip += 4;
824 }
825 DISPATCH_OPCODE;
826
827 OPCODE(OPCODE_ASSIGN_TYPED_SCRIPT) {
828
829 CHECK_SPACE(4);
830 GET_VARIANT_PTR(dst, 2);
831 GET_VARIANT_PTR(src, 3);
832
833 #ifdef DEBUG_ENABLED
834 GET_VARIANT_PTR(type, 1);
835 Script *base_type = Object::cast_to<Script>(type->operator Object *());
836
837 GD_ERR_BREAK(!base_type);
838
839 if (src->get_type() != Variant::OBJECT && src->get_type() != Variant::NIL) {
840 err_text = "Trying to assign a non-object value to a variable of type '" + base_type->get_path().get_file() + "'.";
841 OPCODE_BREAK;
842 }
843
844 if (src->get_type() != Variant::NIL && src->operator Object *() != NULL) {
845
846 ScriptInstance *scr_inst = src->operator Object *()->get_script_instance();
847 if (!scr_inst) {
848 err_text = "Trying to assign value of type '" + src->operator Object *()->get_class_name() +
849 "' to a variable of type '" + base_type->get_path().get_file() + "'.";
850 OPCODE_BREAK;
851 }
852
853 Script *src_type = src->operator Object *()->get_script_instance()->get_script().ptr();
854 bool valid = false;
855
856 while (src_type) {
857 if (src_type == base_type) {
858 valid = true;
859 break;
860 }
861 src_type = src_type->get_base_script().ptr();
862 }
863
864 if (!valid) {
865 err_text = "Trying to assign value of type '" + src->operator Object *()->get_script_instance()->get_script()->get_path().get_file() +
866 "' to a variable of type '" + base_type->get_path().get_file() + "'.";
867 OPCODE_BREAK;
868 }
869 }
870 #endif // DEBUG_ENABLED
871
872 *dst = *src;
873
874 ip += 4;
875 }
876 DISPATCH_OPCODE;
877
878 OPCODE(OPCODE_CAST_TO_BUILTIN) {
879
880 CHECK_SPACE(4);
881 Variant::Type to_type = (Variant::Type)_code_ptr[ip + 1];
882 GET_VARIANT_PTR(src, 2);
883 GET_VARIANT_PTR(dst, 3);
884
885 GD_ERR_BREAK(to_type < 0 || to_type >= Variant::VARIANT_MAX);
886
887 Variant::CallError err;
888 *dst = Variant::construct(to_type, (const Variant **)&src, 1, err);
889
890 #ifdef DEBUG_ENABLED
891 if (err.error != Variant::CallError::CALL_OK) {
892 err_text = "Invalid cast: could not convert value to '" + Variant::get_type_name(to_type) + "'.";
893 OPCODE_BREAK;
894 }
895 #endif
896
897 ip += 4;
898 }
899 DISPATCH_OPCODE;
900
901 OPCODE(OPCODE_CAST_TO_NATIVE) {
902
903 CHECK_SPACE(4);
904 GET_VARIANT_PTR(to_type, 1);
905 GET_VARIANT_PTR(src, 2);
906 GET_VARIANT_PTR(dst, 3);
907
908 GDScriptNativeClass *nc = Object::cast_to<GDScriptNativeClass>(to_type->operator Object *());
909 GD_ERR_BREAK(!nc);
910
911 #ifdef DEBUG_ENABLED
912 if (src->get_type() != Variant::OBJECT && src->get_type() != Variant::NIL) {
913 err_text = "Invalid cast: can't convert a non-object value to an object type.";
914 OPCODE_BREAK;
915 }
916 #endif
917 Object *src_obj = src->operator Object *();
918
919 if (src_obj && !ClassDB::is_parent_class(src_obj->get_class_name(), nc->get_name())) {
920 *dst = Variant(); // invalid cast, assign NULL
921 } else {
922 *dst = *src;
923 }
924
925 ip += 4;
926 }
927 DISPATCH_OPCODE;
928
929 OPCODE(OPCODE_CAST_TO_SCRIPT) {
930
931 CHECK_SPACE(4);
932 GET_VARIANT_PTR(to_type, 1);
933 GET_VARIANT_PTR(src, 2);
934 GET_VARIANT_PTR(dst, 3);
935
936 Script *base_type = Object::cast_to<Script>(to_type->operator Object *());
937
938 GD_ERR_BREAK(!base_type);
939
940 #ifdef DEBUG_ENABLED
941 if (src->get_type() != Variant::OBJECT && src->get_type() != Variant::NIL) {
942 err_text = "Trying to assign a non-object value to a variable of type '" + base_type->get_path().get_file() + "'.";
943 OPCODE_BREAK;
944 }
945 #endif
946
947 bool valid = false;
948
949 if (src->get_type() != Variant::NIL && src->operator Object *() != NULL) {
950
951 ScriptInstance *scr_inst = src->operator Object *()->get_script_instance();
952
953 if (scr_inst) {
954
955 Script *src_type = src->operator Object *()->get_script_instance()->get_script().ptr();
956
957 while (src_type) {
958 if (src_type == base_type) {
959 valid = true;
960 break;
961 }
962 src_type = src_type->get_base_script().ptr();
963 }
964 }
965 }
966
967 if (valid) {
968 *dst = *src; // Valid cast, copy the source object
969 } else {
970 *dst = Variant(); // invalid cast, assign NULL
971 }
972
973 ip += 4;
974 }
975 DISPATCH_OPCODE;
976
977 OPCODE(OPCODE_CONSTRUCT) {
978
979 CHECK_SPACE(2);
980 Variant::Type t = Variant::Type(_code_ptr[ip + 1]);
981 int argc = _code_ptr[ip + 2];
982 CHECK_SPACE(argc + 2);
983 Variant **argptrs = call_args;
984 for (int i = 0; i < argc; i++) {
985 GET_VARIANT_PTR(v, 3 + i);
986 argptrs[i] = v;
987 }
988
989 GET_VARIANT_PTR(dst, 3 + argc);
990 Variant::CallError err;
991 *dst = Variant::construct(t, (const Variant **)argptrs, argc, err);
992
993 #ifdef DEBUG_ENABLED
994 if (err.error != Variant::CallError::CALL_OK) {
995
996 err_text = _get_call_error(err, "'" + Variant::get_type_name(t) + "' constructor", (const Variant **)argptrs);
997 OPCODE_BREAK;
998 }
999 #endif
1000
1001 ip += 4 + argc;
1002 //construct a basic type
1003 }
1004 DISPATCH_OPCODE;
1005
1006 OPCODE(OPCODE_CONSTRUCT_ARRAY) {
1007
1008 CHECK_SPACE(1);
1009 int argc = _code_ptr[ip + 1];
1010 Array array; //arrays are always shared
1011 array.resize(argc);
1012 CHECK_SPACE(argc + 2);
1013
1014 for (int i = 0; i < argc; i++) {
1015 GET_VARIANT_PTR(v, 2 + i);
1016 array[i] = *v;
1017 }
1018
1019 GET_VARIANT_PTR(dst, 2 + argc);
1020
1021 *dst = array;
1022
1023 ip += 3 + argc;
1024 }
1025 DISPATCH_OPCODE;
1026
1027 OPCODE(OPCODE_CONSTRUCT_DICTIONARY) {
1028
1029 CHECK_SPACE(1);
1030 int argc = _code_ptr[ip + 1];
1031 Dictionary dict; //arrays are always shared
1032
1033 CHECK_SPACE(argc * 2 + 2);
1034
1035 for (int i = 0; i < argc; i++) {
1036
1037 GET_VARIANT_PTR(k, 2 + i * 2 + 0);
1038 GET_VARIANT_PTR(v, 2 + i * 2 + 1);
1039 dict[*k] = *v;
1040 }
1041
1042 GET_VARIANT_PTR(dst, 2 + argc * 2);
1043
1044 *dst = dict;
1045
1046 ip += 3 + argc * 2;
1047 }
1048 DISPATCH_OPCODE;
1049
1050 OPCODE(OPCODE_CALL_RETURN)
1051 OPCODE(OPCODE_CALL) {
1052
1053 CHECK_SPACE(4);
1054 bool call_ret = _code_ptr[ip] == OPCODE_CALL_RETURN;
1055
1056 int argc = _code_ptr[ip + 1];
1057 GET_VARIANT_PTR(base, 2);
1058 int nameg = _code_ptr[ip + 3];
1059
1060 GD_ERR_BREAK(nameg < 0 || nameg >= _global_names_count);
1061 const StringName *methodname = &_global_names_ptr[nameg];
1062
1063 GD_ERR_BREAK(argc < 0);
1064 ip += 4;
1065 CHECK_SPACE(argc + 1);
1066 Variant **argptrs = call_args;
1067
1068 for (int i = 0; i < argc; i++) {
1069 GET_VARIANT_PTR(v, i);
1070 argptrs[i] = v;
1071 }
1072
1073 #ifdef DEBUG_ENABLED
1074 uint64_t call_time = 0;
1075
1076 if (GDScriptLanguage::get_singleton()->profiling) {
1077 call_time = OS::get_singleton()->get_ticks_usec();
1078 }
1079
1080 #endif
1081 Variant::CallError err;
1082 if (call_ret) {
1083
1084 GET_VARIANT_PTR(ret, argc);
1085 base->call_ptr(*methodname, (const Variant **)argptrs, argc, ret, err);
1086 } else {
1087
1088 base->call_ptr(*methodname, (const Variant **)argptrs, argc, NULL, err);
1089 }
1090 #ifdef DEBUG_ENABLED
1091 if (GDScriptLanguage::get_singleton()->profiling) {
1092 function_call_time += OS::get_singleton()->get_ticks_usec() - call_time;
1093 }
1094
1095 if (err.error != Variant::CallError::CALL_OK) {
1096
1097 String methodstr = *methodname;
1098 String basestr = _get_var_type(base);
1099
1100 if (methodstr == "call") {
1101 if (argc >= 1) {
1102 methodstr = String(*argptrs[0]) + " (via call)";
1103 if (err.error == Variant::CallError::CALL_ERROR_INVALID_ARGUMENT) {
1104 err.argument += 1;
1105 }
1106 }
1107 } else if (methodstr == "free") {
1108
1109 if (err.error == Variant::CallError::CALL_ERROR_INVALID_METHOD) {
1110
1111 if (base->is_ref()) {
1112 err_text = "Attempted to free a reference.";
1113 OPCODE_BREAK;
1114 } else if (base->get_type() == Variant::OBJECT) {
1115
1116 err_text = "Attempted to free a locked object (calling or emitting).";
1117 OPCODE_BREAK;
1118 }
1119 }
1120 }
1121 err_text = _get_call_error(err, "function '" + methodstr + "' in base '" + basestr + "'", (const Variant **)argptrs);
1122 OPCODE_BREAK;
1123 }
1124 #endif
1125
1126 //_call_func(NULL,base,*methodname,ip,argc,p_instance,stack);
1127 ip += argc + 1;
1128 }
1129 DISPATCH_OPCODE;
1130
1131 OPCODE(OPCODE_CALL_BUILT_IN) {
1132
1133 CHECK_SPACE(4);
1134
1135 GDScriptFunctions::Function func = GDScriptFunctions::Function(_code_ptr[ip + 1]);
1136 int argc = _code_ptr[ip + 2];
1137 GD_ERR_BREAK(argc < 0);
1138
1139 ip += 3;
1140 CHECK_SPACE(argc + 1);
1141 Variant **argptrs = call_args;
1142
1143 for (int i = 0; i < argc; i++) {
1144 GET_VARIANT_PTR(v, i);
1145 argptrs[i] = v;
1146 }
1147
1148 GET_VARIANT_PTR(dst, argc);
1149
1150 Variant::CallError err;
1151
1152 GDScriptFunctions::call(func, (const Variant **)argptrs, argc, *dst, err);
1153
1154 #ifdef DEBUG_ENABLED
1155 if (err.error != Variant::CallError::CALL_OK) {
1156
1157 String methodstr = GDScriptFunctions::get_func_name(func);
1158 if (dst->get_type() == Variant::STRING) {
1159 //call provided error string
1160 err_text = "Error calling built-in function '" + methodstr + "': " + String(*dst);
1161 } else {
1162 err_text = _get_call_error(err, "built-in function '" + methodstr + "'", (const Variant **)argptrs);
1163 }
1164 OPCODE_BREAK;
1165 }
1166 #endif
1167 ip += argc + 1;
1168 }
1169 DISPATCH_OPCODE;
1170
1171 OPCODE(OPCODE_CALL_SELF) {
1172
1173 OPCODE_BREAK;
1174 }
1175
1176 OPCODE(OPCODE_CALL_SELF_BASE) {
1177
1178 CHECK_SPACE(2);
1179 int self_fun = _code_ptr[ip + 1];
1180
1181 #ifdef DEBUG_ENABLED
1182 if (self_fun < 0 || self_fun >= _global_names_count) {
1183
1184 err_text = "compiler bug, function name not found";
1185 OPCODE_BREAK;
1186 }
1187 #endif
1188 const StringName *methodname = &_global_names_ptr[self_fun];
1189
1190 int argc = _code_ptr[ip + 2];
1191
1192 CHECK_SPACE(2 + argc + 1);
1193
1194 Variant **argptrs = call_args;
1195
1196 for (int i = 0; i < argc; i++) {
1197 GET_VARIANT_PTR(v, i + 3);
1198 argptrs[i] = v;
1199 }
1200
1201 GET_VARIANT_PTR(dst, argc + 3);
1202
1203 const GDScript *gds = _script;
1204
1205 const Map<StringName, GDScriptFunction *>::Element *E = NULL;
1206 while (gds->base.ptr()) {
1207 gds = gds->base.ptr();
1208 E = gds->member_functions.find(*methodname);
1209 if (E)
1210 break;
1211 }
1212
1213 Variant::CallError err;
1214
1215 if (E) {
1216
1217 *dst = E->get()->call(p_instance, (const Variant **)argptrs, argc, err);
1218 } else if (gds->native.ptr()) {
1219
1220 if (*methodname != GDScriptLanguage::get_singleton()->strings._init) {
1221
1222 MethodBind *mb = ClassDB::get_method(gds->native->get_name(), *methodname);
1223 if (!mb) {
1224 err.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
1225 } else {
1226 *dst = mb->call(p_instance->owner, (const Variant **)argptrs, argc, err);
1227 }
1228 } else {
1229 err.error = Variant::CallError::CALL_OK;
1230 }
1231 } else {
1232
1233 if (*methodname != GDScriptLanguage::get_singleton()->strings._init) {
1234 err.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
1235 } else {
1236 err.error = Variant::CallError::CALL_OK;
1237 }
1238 }
1239
1240 if (err.error != Variant::CallError::CALL_OK) {
1241
1242 String methodstr = *methodname;
1243 err_text = _get_call_error(err, "function '" + methodstr + "'", (const Variant **)argptrs);
1244
1245 OPCODE_BREAK;
1246 }
1247
1248 ip += 4 + argc;
1249 }
1250 DISPATCH_OPCODE;
1251
1252 OPCODE(OPCODE_YIELD)
1253 OPCODE(OPCODE_YIELD_SIGNAL) {
1254
1255 int ipofs = 1;
1256 if (_code_ptr[ip] == OPCODE_YIELD_SIGNAL) {
1257 CHECK_SPACE(4);
1258 ipofs += 2;
1259 } else {
1260 CHECK_SPACE(2);
1261 }
1262
1263 Ref<GDScriptFunctionState> gdfs = memnew(GDScriptFunctionState);
1264 gdfs->function = this;
1265
1266 gdfs->state.stack.resize(alloca_size);
1267 //copy variant stack
1268 for (int i = 0; i < _stack_size; i++) {
1269 memnew_placement(&gdfs->state.stack.write[sizeof(Variant) * i], Variant(stack[i]));
1270 }
1271 gdfs->state.stack_size = _stack_size;
1272 gdfs->state.self = self;
1273 gdfs->state.alloca_size = alloca_size;
1274 gdfs->state.ip = ip + ipofs;
1275 gdfs->state.line = line;
1276 gdfs->state.script = _script;
1277 #ifndef NO_THREADS
1278 GDScriptLanguage::singleton->lock->lock();
1279 #endif
1280
1281 _script->pending_func_states.add(&gdfs->scripts_list);
1282 if (p_instance) {
1283 gdfs->state.instance = p_instance;
1284 p_instance->pending_func_states.add(&gdfs->instances_list);
1285 } else {
1286 gdfs->state.instance = NULL;
1287 }
1288 #ifndef NO_THREADS
1289 GDScriptLanguage::singleton->lock->unlock();
1290 #endif
1291 #ifdef DEBUG_ENABLED
1292 gdfs->state.function_name = name;
1293 gdfs->state.script_path = _script->get_path();
1294 #endif
1295 //gdfs->state.result_pos=ip+ipofs-1;
1296 gdfs->state.defarg = defarg;
1297 gdfs->function = this;
1298
1299 retvalue = gdfs;
1300
1301 if (_code_ptr[ip] == OPCODE_YIELD_SIGNAL) {
1302 //do the oneshot connect
1303 GET_VARIANT_PTR(argobj, 1);
1304 GET_VARIANT_PTR(argname, 2);
1305
1306 #ifdef DEBUG_ENABLED
1307 if (argobj->get_type() != Variant::OBJECT) {
1308 err_text = "First argument of yield() not of type object.";
1309 OPCODE_BREAK;
1310 }
1311 if (argname->get_type() != Variant::STRING) {
1312 err_text = "Second argument of yield() not a string (for signal name).";
1313 OPCODE_BREAK;
1314 }
1315 #endif
1316
1317 Object *obj = argobj->operator Object *();
1318 String signal = argname->operator String();
1319
1320 #ifdef DEBUG_ENABLED
1321 if (!obj) {
1322 err_text = "First argument of yield() is null.";
1323 OPCODE_BREAK;
1324 }
1325 if (ScriptDebugger::get_singleton()) {
1326 if (!ObjectDB::instance_validate(obj)) {
1327 err_text = "First argument of yield() is a previously freed instance.";
1328 OPCODE_BREAK;
1329 }
1330 }
1331 if (signal.length() == 0) {
1332
1333 err_text = "Second argument of yield() is an empty string (for signal name).";
1334 OPCODE_BREAK;
1335 }
1336
1337 Error err = obj->connect(signal, gdfs.ptr(), "_signal_callback", varray(gdfs), Object::CONNECT_ONESHOT);
1338 if (err != OK) {
1339 err_text = "Error connecting to signal: " + signal + " during yield().";
1340 OPCODE_BREAK;
1341 }
1342 #else
1343 obj->connect(signal, gdfs.ptr(), "_signal_callback", varray(gdfs), Object::CONNECT_ONESHOT);
1344 #endif
1345 }
1346
1347 #ifdef DEBUG_ENABLED
1348 exit_ok = true;
1349 yielded = true;
1350 #endif
1351 OPCODE_BREAK;
1352 }
1353
1354 OPCODE(OPCODE_YIELD_RESUME) {
1355
1356 CHECK_SPACE(2);
1357 #ifdef DEBUG_ENABLED
1358 if (!p_state) {
1359 err_text = ("Invalid Resume (bug?)");
1360 OPCODE_BREAK;
1361 }
1362 #endif
1363 GET_VARIANT_PTR(result, 1);
1364 *result = p_state->result;
1365 ip += 2;
1366 }
1367 DISPATCH_OPCODE;
1368
1369 OPCODE(OPCODE_JUMP) {
1370
1371 CHECK_SPACE(2);
1372 int to = _code_ptr[ip + 1];
1373
1374 GD_ERR_BREAK(to < 0 || to > _code_size);
1375 ip = to;
1376 }
1377 DISPATCH_OPCODE;
1378
1379 OPCODE(OPCODE_JUMP_IF) {
1380
1381 CHECK_SPACE(3);
1382
1383 GET_VARIANT_PTR(test, 1);
1384
1385 bool result = test->booleanize();
1386
1387 if (result) {
1388 int to = _code_ptr[ip + 2];
1389 GD_ERR_BREAK(to < 0 || to > _code_size);
1390 ip = to;
1391 } else {
1392 ip += 3;
1393 }
1394 }
1395 DISPATCH_OPCODE;
1396
1397 OPCODE(OPCODE_JUMP_IF_NOT) {
1398
1399 CHECK_SPACE(3);
1400
1401 GET_VARIANT_PTR(test, 1);
1402
1403 bool result = test->booleanize();
1404
1405 if (!result) {
1406 int to = _code_ptr[ip + 2];
1407 GD_ERR_BREAK(to < 0 || to > _code_size);
1408 ip = to;
1409 } else {
1410 ip += 3;
1411 }
1412 }
1413 DISPATCH_OPCODE;
1414
1415 OPCODE(OPCODE_JUMP_TO_DEF_ARGUMENT) {
1416
1417 CHECK_SPACE(2);
1418 ip = _default_arg_ptr[defarg];
1419 }
1420 DISPATCH_OPCODE;
1421
1422 OPCODE(OPCODE_RETURN) {
1423
1424 CHECK_SPACE(2);
1425 GET_VARIANT_PTR(r, 1);
1426 retvalue = *r;
1427 #ifdef DEBUG_ENABLED
1428 exit_ok = true;
1429 #endif
1430 OPCODE_BREAK;
1431 }
1432
1433 OPCODE(OPCODE_ITERATE_BEGIN) {
1434
1435 CHECK_SPACE(8); //space for this a regular iterate
1436
1437 GET_VARIANT_PTR(counter, 1);
1438 GET_VARIANT_PTR(container, 2);
1439
1440 bool valid;
1441 if (!container->iter_init(*counter, valid)) {
1442 #ifdef DEBUG_ENABLED
1443 if (!valid) {
1444 err_text = "Unable to iterate on object of type '" + Variant::get_type_name(container->get_type()) + "'.";
1445 OPCODE_BREAK;
1446 }
1447 #endif
1448 int jumpto = _code_ptr[ip + 3];
1449 GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
1450 ip = jumpto;
1451 } else {
1452 GET_VARIANT_PTR(iterator, 4);
1453
1454 *iterator = container->iter_get(*counter, valid);
1455 #ifdef DEBUG_ENABLED
1456 if (!valid) {
1457 err_text = "Unable to obtain iterator object of type '" + Variant::get_type_name(container->get_type()) + "'.";
1458 OPCODE_BREAK;
1459 }
1460 #endif
1461 ip += 5; //skip regular iterate which is always next
1462 }
1463 }
1464 DISPATCH_OPCODE;
1465
1466 OPCODE(OPCODE_ITERATE) {
1467
1468 CHECK_SPACE(4);
1469
1470 GET_VARIANT_PTR(counter, 1);
1471 GET_VARIANT_PTR(container, 2);
1472
1473 bool valid;
1474 if (!container->iter_next(*counter, valid)) {
1475 #ifdef DEBUG_ENABLED
1476 if (!valid) {
1477 err_text = "Unable to iterate on object of type '" + Variant::get_type_name(container->get_type()) + "' (type changed since first iteration?).";
1478 OPCODE_BREAK;
1479 }
1480 #endif
1481 int jumpto = _code_ptr[ip + 3];
1482 GD_ERR_BREAK(jumpto < 0 || jumpto > _code_size);
1483 ip = jumpto;
1484 } else {
1485 GET_VARIANT_PTR(iterator, 4);
1486
1487 *iterator = container->iter_get(*counter, valid);
1488 #ifdef DEBUG_ENABLED
1489 if (!valid) {
1490 err_text = "Unable to obtain iterator object of type '" + Variant::get_type_name(container->get_type()) + "' (but was obtained on first iteration?).";
1491 OPCODE_BREAK;
1492 }
1493 #endif
1494 ip += 5; //loop again
1495 }
1496 }
1497 DISPATCH_OPCODE;
1498
1499 OPCODE(OPCODE_ASSERT) {
1500 CHECK_SPACE(3);
1501
1502 #ifdef DEBUG_ENABLED
1503 GET_VARIANT_PTR(test, 1);
1504 bool result = test->booleanize();
1505
1506 if (!result) {
1507 String message_str;
1508 if (_code_ptr[ip + 2] != 0) {
1509 GET_VARIANT_PTR(message, 2);
1510 message_str = *message;
1511 }
1512 if (message_str.empty()) {
1513 err_text = "Assertion failed.";
1514 } else {
1515 err_text = "Assertion failed: " + message_str;
1516 }
1517 OPCODE_BREAK;
1518 }
1519
1520 #endif
1521 ip += 3;
1522 }
1523 DISPATCH_OPCODE;
1524
1525 OPCODE(OPCODE_BREAKPOINT) {
1526 #ifdef DEBUG_ENABLED
1527 if (ScriptDebugger::get_singleton()) {
1528 GDScriptLanguage::get_singleton()->debug_break("Breakpoint Statement", true);
1529 }
1530 #endif
1531 ip += 1;
1532 }
1533 DISPATCH_OPCODE;
1534
1535 OPCODE(OPCODE_LINE) {
1536 CHECK_SPACE(2);
1537
1538 line = _code_ptr[ip + 1];
1539 ip += 2;
1540
1541 if (ScriptDebugger::get_singleton()) {
1542 // line
1543 bool do_break = false;
1544
1545 if (ScriptDebugger::get_singleton()->get_lines_left() > 0) {
1546
1547 if (ScriptDebugger::get_singleton()->get_depth() <= 0)
1548 ScriptDebugger::get_singleton()->set_lines_left(ScriptDebugger::get_singleton()->get_lines_left() - 1);
1549 if (ScriptDebugger::get_singleton()->get_lines_left() <= 0)
1550 do_break = true;
1551 }
1552
1553 if (ScriptDebugger::get_singleton()->is_breakpoint(line, source))
1554 do_break = true;
1555
1556 if (do_break) {
1557 GDScriptLanguage::get_singleton()->debug_break("Breakpoint", true);
1558 }
1559
1560 ScriptDebugger::get_singleton()->line_poll();
1561 }
1562 }
1563 DISPATCH_OPCODE;
1564
1565 OPCODE(OPCODE_END) {
1566 #ifdef DEBUG_ENABLED
1567 exit_ok = true;
1568 #endif
1569 OPCODE_BREAK;
1570 }
1571
1572 #if 0 // Enable for debugging.
1573 default: {
1574 err_text = "Illegal opcode " + itos(_code_ptr[ip]) + " at address " + itos(ip);
1575 OPCODE_BREAK;
1576 }
1577 #endif
1578 }
1579
1580 OPCODES_END
1581 #ifdef DEBUG_ENABLED
1582 if (exit_ok)
1583 OPCODE_OUT;
1584 //error
1585 // function, file, line, error, explanation
1586 String err_file;
1587 if (p_instance && ObjectDB::instance_validate(p_instance->owner) && p_instance->script->is_valid() && p_instance->script->path != "")
1588 err_file = p_instance->script->path;
1589 else if (script)
1590 err_file = script->path;
1591 if (err_file == "")
1592 err_file = "<built-in>";
1593 String err_func = name;
1594 if (p_instance && ObjectDB::instance_validate(p_instance->owner) && p_instance->script->is_valid() && p_instance->script->name != "")
1595 err_func = p_instance->script->name + "." + err_func;
1596 int err_line = line;
1597 if (err_text == "") {
1598 err_text = "Internal Script Error! - opcode #" + itos(last_opcode) + " (report please).";
1599 }
1600
1601 if (!GDScriptLanguage::get_singleton()->debug_break(err_text, false)) {
1602 // debugger break did not happen
1603
1604 _err_print_error(err_func.utf8().get_data(), err_file.utf8().get_data(), err_line, err_text.utf8().get_data(), ERR_HANDLER_SCRIPT);
1605 }
1606
1607 #endif
1608 OPCODE_OUT;
1609 }
1610
1611 OPCODES_OUT
1612 #ifdef DEBUG_ENABLED
1613 if (GDScriptLanguage::get_singleton()->profiling) {
1614 uint64_t time_taken = OS::get_singleton()->get_ticks_usec() - function_start_time;
1615 profile.total_time += time_taken;
1616 profile.self_time += time_taken - function_call_time;
1617 profile.frame_total_time += time_taken;
1618 profile.frame_self_time += time_taken - function_call_time;
1619 GDScriptLanguage::get_singleton()->script_frame_time += time_taken - function_call_time;
1620 }
1621
1622 // Check if this is the last time the function is resuming from yield
1623 // Will be true if never yielded as well
1624 // When it's the last resume it will postpone the exit from stack,
1625 // so the debugger knows which function triggered the resume of the next function (if any)
1626 if (!p_state || yielded) {
1627 if (ScriptDebugger::get_singleton())
1628 GDScriptLanguage::get_singleton()->exit_function();
1629 #endif
1630
1631 if (_stack_size) {
1632 //free stack
1633 for (int i = 0; i < _stack_size; i++)
1634 stack[i].~Variant();
1635 }
1636
1637 #ifdef DEBUG_ENABLED
1638 }
1639 #endif
1640
1641 return retvalue;
1642 }
1643
1644 const int *GDScriptFunction::get_code() const {
1645
1646 return _code_ptr;
1647 }
1648 int GDScriptFunction::get_code_size() const {
1649
1650 return _code_size;
1651 }
1652
1653 Variant GDScriptFunction::get_constant(int p_idx) const {
1654
1655 ERR_FAIL_INDEX_V(p_idx, constants.size(), "<errconst>");
1656 return constants[p_idx];
1657 }
1658
1659 StringName GDScriptFunction::get_global_name(int p_idx) const {
1660
1661 ERR_FAIL_INDEX_V(p_idx, global_names.size(), "<errgname>");
1662 return global_names[p_idx];
1663 }
1664
1665 int GDScriptFunction::get_default_argument_count() const {
1666
1667 return _default_arg_count;
1668 }
1669 int GDScriptFunction::get_default_argument_addr(int p_idx) const {
1670
1671 ERR_FAIL_INDEX_V(p_idx, default_arguments.size(), -1);
1672 return default_arguments[p_idx];
1673 }
1674
1675 GDScriptDataType GDScriptFunction::get_return_type() const {
1676 return return_type;
1677 }
1678
1679 GDScriptDataType GDScriptFunction::get_argument_type(int p_idx) const {
1680 ERR_FAIL_INDEX_V(p_idx, argument_types.size(), GDScriptDataType());
1681 return argument_types[p_idx];
1682 }
1683
1684 StringName GDScriptFunction::get_name() const {
1685
1686 return name;
1687 }
1688
1689 int GDScriptFunction::get_max_stack_size() const {
1690
1691 return _stack_size;
1692 }
1693
1694 struct _GDFKC {
1695
1696 int order;
1697 List<int> pos;
1698 };
1699
1700 struct _GDFKCS {
1701
1702 int order;
1703 StringName id;
1704 int pos;
1705
1706 bool operator<(const _GDFKCS &p_r) const {
1707
1708 return order < p_r.order;
1709 }
1710 };
1711
1712 void GDScriptFunction::debug_get_stack_member_state(int p_line, List<Pair<StringName, int> > *r_stackvars) const {
1713
1714 int oc = 0;
1715 Map<StringName, _GDFKC> sdmap;
1716 for (const List<StackDebug>::Element *E = stack_debug.front(); E; E = E->next()) {
1717
1718 const StackDebug &sd = E->get();
1719 if (sd.line > p_line)
1720 break;
1721
1722 if (sd.added) {
1723
1724 if (!sdmap.has(sd.identifier)) {
1725 _GDFKC d;
1726 d.order = oc++;
1727 d.pos.push_back(sd.pos);
1728 sdmap[sd.identifier] = d;
1729
1730 } else {
1731 sdmap[sd.identifier].pos.push_back(sd.pos);
1732 }
1733 } else {
1734
1735 ERR_CONTINUE(!sdmap.has(sd.identifier));
1736
1737 sdmap[sd.identifier].pos.pop_back();
1738 if (sdmap[sd.identifier].pos.empty())
1739 sdmap.erase(sd.identifier);
1740 }
1741 }
1742
1743 List<_GDFKCS> stackpositions;
1744 for (Map<StringName, _GDFKC>::Element *E = sdmap.front(); E; E = E->next()) {
1745
1746 _GDFKCS spp;
1747 spp.id = E->key();
1748 spp.order = E->get().order;
1749 spp.pos = E->get().pos.back()->get();
1750 stackpositions.push_back(spp);
1751 }
1752
1753 stackpositions.sort();
1754
1755 for (List<_GDFKCS>::Element *E = stackpositions.front(); E; E = E->next()) {
1756
1757 Pair<StringName, int> p;
1758 p.first = E->get().id;
1759 p.second = E->get().pos;
1760 r_stackvars->push_back(p);
1761 }
1762 }
1763
1764 GDScriptFunction::GDScriptFunction() :
1765 function_list(this) {
1766
1767 _stack_size = 0;
1768 _call_size = 0;
1769 rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
1770 name = "<anonymous>";
1771 #ifdef DEBUG_ENABLED
1772 _func_cname = NULL;
1773
1774 if (GDScriptLanguage::get_singleton()->lock) {
1775 GDScriptLanguage::get_singleton()->lock->lock();
1776 }
1777 GDScriptLanguage::get_singleton()->function_list.add(&function_list);
1778
1779 if (GDScriptLanguage::get_singleton()->lock) {
1780 GDScriptLanguage::get_singleton()->lock->unlock();
1781 }
1782
1783 profile.call_count = 0;
1784 profile.self_time = 0;
1785 profile.total_time = 0;
1786 profile.frame_call_count = 0;
1787 profile.frame_self_time = 0;
1788 profile.frame_total_time = 0;
1789 profile.last_frame_call_count = 0;
1790 profile.last_frame_self_time = 0;
1791 profile.last_frame_total_time = 0;
1792
1793 #endif
1794 }
1795
1796 GDScriptFunction::~GDScriptFunction() {
1797 #ifdef DEBUG_ENABLED
1798 if (GDScriptLanguage::get_singleton()->lock) {
1799 GDScriptLanguage::get_singleton()->lock->lock();
1800 }
1801 GDScriptLanguage::get_singleton()->function_list.remove(&function_list);
1802
1803 if (GDScriptLanguage::get_singleton()->lock) {
1804 GDScriptLanguage::get_singleton()->lock->unlock();
1805 }
1806 #endif
1807 }
1808
1809 /////////////////////
1810
1811 Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
1812
1813 Variant arg;
1814 r_error.error = Variant::CallError::CALL_OK;
1815
1816 if (p_argcount == 0) {
1817 r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
1818 r_error.argument = 1;
1819 return Variant();
1820 } else if (p_argcount == 1) {
1821 //noooneee
1822 } else if (p_argcount == 2) {
1823 arg = *p_args[0];
1824 } else {
1825 Array extra_args;
1826 for (int i = 0; i < p_argcount - 1; i++) {
1827 extra_args.push_back(*p_args[i]);
1828 }
1829 arg = extra_args;
1830 }
1831
1832 Ref<GDScriptFunctionState> self = *p_args[p_argcount - 1];
1833
1834 if (self.is_null()) {
1835 r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
1836 r_error.argument = p_argcount - 1;
1837 r_error.expected = Variant::OBJECT;
1838 return Variant();
1839 }
1840
1841 return resume(arg);
1842 }
1843
1844 bool GDScriptFunctionState::is_valid(bool p_extended_check) const {
1845
1846 if (function == NULL)
1847 return false;
1848
1849 if (p_extended_check) {
1850 #ifndef NO_THREADS
1851 MutexLock lock(GDScriptLanguage::get_singleton()->lock);
1852 #endif
1853 // Script gone?
1854 if (!scripts_list.in_list()) {
1855 return false;
1856 }
1857 // Class instance gone? (if not static function)
1858 if (state.instance && !instances_list.in_list()) {
1859 return false;
1860 }
1861 }
1862
1863 return true;
1864 }
1865
1866 Variant GDScriptFunctionState::resume(const Variant &p_arg) {
1867
1868 ERR_FAIL_COND_V(!function, Variant());
1869 {
1870 #ifndef NO_THREADS
1871 MutexLock lock(GDScriptLanguage::singleton->lock);
1872 #endif
1873 if (!scripts_list.in_list()) {
1874 #ifdef DEBUG_ENABLED
1875 ERR_FAIL_V_MSG(Variant(), "Resumed function '" + state.function_name + "()' after yield, but script is gone. At script: " + state.script_path + ":" + itos(state.line));
1876 #else
1877 return Variant();
1878 #endif
1879 }
1880 if (state.instance && !instances_list.in_list()) {
1881 #ifdef DEBUG_ENABLED
1882 ERR_FAIL_V_MSG(Variant(), "Resumed function '" + state.function_name + "()' after yield, but class instance is gone. At script: " + state.script_path + ":" + itos(state.line));
1883 #else
1884 return Variant();
1885 #endif
1886 }
1887 // Do these now to avoid locking again after the call
1888 scripts_list.remove_from_list();
1889 instances_list.remove_from_list();
1890 }
1891
1892 state.result = p_arg;
1893 Variant::CallError err;
1894 Variant ret = function->call(NULL, NULL, 0, err, &state);
1895
1896 bool completed = true;
1897
1898 // If the return value is a GDScriptFunctionState reference,
1899 // then the function did yield again after resuming.
1900 if (ret.is_ref()) {
1901 GDScriptFunctionState *gdfs = Object::cast_to<GDScriptFunctionState>(ret);
1902 if (gdfs && gdfs->function == function) {
1903 completed = false;
1904 gdfs->first_state = first_state.is_valid() ? first_state : Ref<GDScriptFunctionState>(this);
1905 }
1906 }
1907
1908 function = NULL; //cleaned up;
1909 state.result = Variant();
1910
1911 if (completed) {
1912 if (first_state.is_valid()) {
1913 first_state->emit_signal("completed", ret);
1914 } else {
1915 emit_signal("completed", ret);
1916 }
1917
1918 #ifdef DEBUG_ENABLED
1919 if (ScriptDebugger::get_singleton())
1920 GDScriptLanguage::get_singleton()->exit_function();
1921 #endif
1922 }
1923
1924 return ret;
1925 }
1926
1927 void GDScriptFunctionState::_clear_stack() {
1928
1929 if (state.stack_size) {
1930 Variant *stack = (Variant *)state.stack.ptr();
1931 for (int i = 0; i < state.stack_size; i++)
1932 stack[i].~Variant();
1933 state.stack_size = 0;
1934 }
1935 }
1936
1937 void GDScriptFunctionState::_bind_methods() {
1938
1939 ClassDB::bind_method(D_METHOD("resume", "arg"), &GDScriptFunctionState::resume, DEFVAL(Variant()));
1940 ClassDB::bind_method(D_METHOD("is_valid", "extended_check"), &GDScriptFunctionState::is_valid, DEFVAL(false));
1941 ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "_signal_callback", &GDScriptFunctionState::_signal_callback, MethodInfo("_signal_callback"));
1942
1943 ADD_SIGNAL(MethodInfo("completed", PropertyInfo(Variant::NIL, "result", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT)));
1944 }
1945
1946 GDScriptFunctionState::GDScriptFunctionState() :
1947 scripts_list(this),
1948 instances_list(this) {
1949
1950 function = NULL;
1951 }
1952
1953 GDScriptFunctionState::~GDScriptFunctionState() {
1954
1955 _clear_stack();
1956 #ifndef NO_THREADS
1957 GDScriptLanguage::singleton->lock->lock();
1958 #endif
1959 scripts_list.remove_from_list();
1960 instances_list.remove_from_list();
1961 #ifndef NO_THREADS
1962 GDScriptLanguage::singleton->lock->unlock();
1963 #endif
1964 }
1965