gdscript_byte_codegen.cpp 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100
  1. /*************************************************************************/
  2. /* gdscript_byte_codegen.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. #include "gdscript_byte_codegen.h"
  31. #include "core/debugger/engine_debugger.h"
  32. #include "gdscript.h"
  33. uint32_t GDScriptByteCodeGenerator::add_parameter(const StringName &p_name, bool p_is_optional, const GDScriptDataType &p_type) {
  34. #ifdef TOOLS_ENABLED
  35. function->arg_names.push_back(p_name);
  36. #endif
  37. function->_argument_count++;
  38. function->argument_types.push_back(p_type);
  39. if (p_is_optional) {
  40. if (function->_default_arg_count == 0) {
  41. append(GDScriptFunction::OPCODE_JUMP_TO_DEF_ARGUMENT);
  42. }
  43. function->default_arguments.push_back(opcodes.size());
  44. function->_default_arg_count++;
  45. }
  46. return add_local(p_name, p_type);
  47. }
  48. uint32_t GDScriptByteCodeGenerator::add_local(const StringName &p_name, const GDScriptDataType &p_type) {
  49. int stack_pos = increase_stack();
  50. add_stack_identifier(p_name, stack_pos);
  51. return stack_pos;
  52. }
  53. uint32_t GDScriptByteCodeGenerator::add_local_constant(const StringName &p_name, const Variant &p_constant) {
  54. int index = add_or_get_constant(p_constant);
  55. local_constants[p_name] = index;
  56. return index;
  57. }
  58. uint32_t GDScriptByteCodeGenerator::add_or_get_constant(const Variant &p_constant) {
  59. if (constant_map.has(p_constant)) {
  60. return constant_map[p_constant];
  61. }
  62. int index = constant_map.size();
  63. constant_map[p_constant] = index;
  64. return index;
  65. }
  66. uint32_t GDScriptByteCodeGenerator::add_or_get_name(const StringName &p_name) {
  67. return get_name_map_pos(p_name);
  68. }
  69. uint32_t GDScriptByteCodeGenerator::add_temporary() {
  70. current_temporaries++;
  71. return increase_stack();
  72. }
  73. void GDScriptByteCodeGenerator::pop_temporary() {
  74. current_stack_size--;
  75. current_temporaries--;
  76. }
  77. void GDScriptByteCodeGenerator::start_parameters() {}
  78. void GDScriptByteCodeGenerator::end_parameters() {
  79. function->default_arguments.invert();
  80. }
  81. void GDScriptByteCodeGenerator::write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, MultiplayerAPI::RPCMode p_rpc_mode, const GDScriptDataType &p_return_type) {
  82. function = memnew(GDScriptFunction);
  83. debug_stack = EngineDebugger::is_active();
  84. function->name = p_function_name;
  85. function->_script = p_script;
  86. function->source = p_script->get_path();
  87. #ifdef DEBUG_ENABLED
  88. function->func_cname = (String(function->source) + " - " + String(p_function_name)).utf8();
  89. function->_func_cname = function->func_cname.get_data();
  90. #endif
  91. function->_static = p_static;
  92. function->return_type = p_return_type;
  93. function->rpc_mode = p_rpc_mode;
  94. function->_argument_count = 0;
  95. }
  96. GDScriptFunction *GDScriptByteCodeGenerator::write_end() {
  97. append(GDScriptFunction::OPCODE_END, 0);
  98. if (constant_map.size()) {
  99. function->_constant_count = constant_map.size();
  100. function->constants.resize(constant_map.size());
  101. function->_constants_ptr = function->constants.ptrw();
  102. const Variant *K = nullptr;
  103. while ((K = constant_map.next(K))) {
  104. int idx = constant_map[*K];
  105. function->constants.write[idx] = *K;
  106. }
  107. } else {
  108. function->_constants_ptr = nullptr;
  109. function->_constant_count = 0;
  110. }
  111. if (name_map.size()) {
  112. function->global_names.resize(name_map.size());
  113. function->_global_names_ptr = &function->global_names[0];
  114. for (Map<StringName, int>::Element *E = name_map.front(); E; E = E->next()) {
  115. function->global_names.write[E->get()] = E->key();
  116. }
  117. function->_global_names_count = function->global_names.size();
  118. } else {
  119. function->_global_names_ptr = nullptr;
  120. function->_global_names_count = 0;
  121. }
  122. if (opcodes.size()) {
  123. function->code = opcodes;
  124. function->_code_ptr = &function->code[0];
  125. function->_code_size = opcodes.size();
  126. } else {
  127. function->_code_ptr = nullptr;
  128. function->_code_size = 0;
  129. }
  130. if (function->default_arguments.size()) {
  131. function->_default_arg_count = function->default_arguments.size();
  132. function->_default_arg_ptr = &function->default_arguments[0];
  133. } else {
  134. function->_default_arg_count = 0;
  135. function->_default_arg_ptr = nullptr;
  136. }
  137. if (operator_func_map.size()) {
  138. function->operator_funcs.resize(operator_func_map.size());
  139. function->_operator_funcs_count = function->operator_funcs.size();
  140. function->_operator_funcs_ptr = function->operator_funcs.ptr();
  141. for (const Map<Variant::ValidatedOperatorEvaluator, int>::Element *E = operator_func_map.front(); E; E = E->next()) {
  142. function->operator_funcs.write[E->get()] = E->key();
  143. }
  144. } else {
  145. function->_operator_funcs_count = 0;
  146. function->_operator_funcs_ptr = nullptr;
  147. }
  148. if (setters_map.size()) {
  149. function->setters.resize(setters_map.size());
  150. function->_setters_count = function->setters.size();
  151. function->_setters_ptr = function->setters.ptr();
  152. for (const Map<Variant::ValidatedSetter, int>::Element *E = setters_map.front(); E; E = E->next()) {
  153. function->setters.write[E->get()] = E->key();
  154. }
  155. } else {
  156. function->_setters_count = 0;
  157. function->_setters_ptr = nullptr;
  158. }
  159. if (getters_map.size()) {
  160. function->getters.resize(getters_map.size());
  161. function->_getters_count = function->getters.size();
  162. function->_getters_ptr = function->getters.ptr();
  163. for (const Map<Variant::ValidatedGetter, int>::Element *E = getters_map.front(); E; E = E->next()) {
  164. function->getters.write[E->get()] = E->key();
  165. }
  166. } else {
  167. function->_getters_count = 0;
  168. function->_getters_ptr = nullptr;
  169. }
  170. if (keyed_setters_map.size()) {
  171. function->keyed_setters.resize(keyed_setters_map.size());
  172. function->_keyed_setters_count = function->keyed_setters.size();
  173. function->_keyed_setters_ptr = function->keyed_setters.ptr();
  174. for (const Map<Variant::ValidatedKeyedSetter, int>::Element *E = keyed_setters_map.front(); E; E = E->next()) {
  175. function->keyed_setters.write[E->get()] = E->key();
  176. }
  177. } else {
  178. function->_keyed_setters_count = 0;
  179. function->_keyed_setters_ptr = nullptr;
  180. }
  181. if (keyed_getters_map.size()) {
  182. function->keyed_getters.resize(keyed_getters_map.size());
  183. function->_keyed_getters_count = function->keyed_getters.size();
  184. function->_keyed_getters_ptr = function->keyed_getters.ptr();
  185. for (const Map<Variant::ValidatedKeyedGetter, int>::Element *E = keyed_getters_map.front(); E; E = E->next()) {
  186. function->keyed_getters.write[E->get()] = E->key();
  187. }
  188. } else {
  189. function->_keyed_getters_count = 0;
  190. function->_keyed_getters_ptr = nullptr;
  191. }
  192. if (indexed_setters_map.size()) {
  193. function->indexed_setters.resize(indexed_setters_map.size());
  194. function->_indexed_setters_count = function->indexed_setters.size();
  195. function->_indexed_setters_ptr = function->indexed_setters.ptr();
  196. for (const Map<Variant::ValidatedIndexedSetter, int>::Element *E = indexed_setters_map.front(); E; E = E->next()) {
  197. function->indexed_setters.write[E->get()] = E->key();
  198. }
  199. } else {
  200. function->_indexed_setters_count = 0;
  201. function->_indexed_setters_ptr = nullptr;
  202. }
  203. if (indexed_getters_map.size()) {
  204. function->indexed_getters.resize(indexed_getters_map.size());
  205. function->_indexed_getters_count = function->indexed_getters.size();
  206. function->_indexed_getters_ptr = function->indexed_getters.ptr();
  207. for (const Map<Variant::ValidatedIndexedGetter, int>::Element *E = indexed_getters_map.front(); E; E = E->next()) {
  208. function->indexed_getters.write[E->get()] = E->key();
  209. }
  210. } else {
  211. function->_indexed_getters_count = 0;
  212. function->_indexed_getters_ptr = nullptr;
  213. }
  214. if (builtin_method_map.size()) {
  215. function->builtin_methods.resize(builtin_method_map.size());
  216. function->_builtin_methods_ptr = function->builtin_methods.ptrw();
  217. function->_builtin_methods_count = builtin_method_map.size();
  218. for (const Map<Variant::ValidatedBuiltInMethod, int>::Element *E = builtin_method_map.front(); E; E = E->next()) {
  219. function->builtin_methods.write[E->get()] = E->key();
  220. }
  221. } else {
  222. function->_builtin_methods_ptr = nullptr;
  223. function->_builtin_methods_count = 0;
  224. }
  225. if (method_bind_map.size()) {
  226. function->methods.resize(method_bind_map.size());
  227. function->_methods_ptr = function->methods.ptrw();
  228. function->_methods_count = method_bind_map.size();
  229. for (const Map<MethodBind *, int>::Element *E = method_bind_map.front(); E; E = E->next()) {
  230. function->methods.write[E->get()] = E->key();
  231. }
  232. } else {
  233. function->_methods_ptr = nullptr;
  234. function->_methods_count = 0;
  235. }
  236. if (debug_stack) {
  237. function->stack_debug = stack_debug;
  238. }
  239. function->_stack_size = stack_max;
  240. function->_instruction_args_size = instr_args_max;
  241. function->_ptrcall_args_size = ptrcall_max;
  242. ended = true;
  243. return function;
  244. }
  245. #ifdef DEBUG_ENABLED
  246. void GDScriptByteCodeGenerator::set_signature(const String &p_signature) {
  247. function->profile.signature = p_signature;
  248. }
  249. #endif
  250. void GDScriptByteCodeGenerator::set_initial_line(int p_line) {
  251. function->_initial_line = p_line;
  252. }
  253. #define HAS_BUILTIN_TYPE(m_var) \
  254. (m_var.type.has_type && m_var.type.kind == GDScriptDataType::BUILTIN)
  255. #define IS_BUILTIN_TYPE(m_var, m_type) \
  256. (m_var.type.has_type && m_var.type.kind == GDScriptDataType::BUILTIN && m_var.type.builtin_type == m_type)
  257. void GDScriptByteCodeGenerator::write_operator(const Address &p_target, Variant::Operator p_operator, const Address &p_left_operand, const Address &p_right_operand) {
  258. if (HAS_BUILTIN_TYPE(p_left_operand) && HAS_BUILTIN_TYPE(p_right_operand)) {
  259. // Gather specific operator.
  260. Variant::ValidatedOperatorEvaluator op_func = Variant::get_validated_operator_evaluator(p_operator, p_left_operand.type.builtin_type, p_right_operand.type.builtin_type);
  261. append(GDScriptFunction::OPCODE_OPERATOR_VALIDATED, 3);
  262. append(p_left_operand);
  263. append(p_right_operand);
  264. append(p_target);
  265. append(op_func);
  266. return;
  267. }
  268. // No specific types, perform variant evaluation.
  269. append(GDScriptFunction::OPCODE_OPERATOR, 3);
  270. append(p_left_operand);
  271. append(p_right_operand);
  272. append(p_target);
  273. append(p_operator);
  274. }
  275. void GDScriptByteCodeGenerator::write_type_test(const Address &p_target, const Address &p_source, const Address &p_type) {
  276. append(GDScriptFunction::OPCODE_EXTENDS_TEST, 3);
  277. append(p_source);
  278. append(p_type);
  279. append(p_target);
  280. }
  281. void GDScriptByteCodeGenerator::write_type_test_builtin(const Address &p_target, const Address &p_source, Variant::Type p_type) {
  282. append(GDScriptFunction::OPCODE_IS_BUILTIN, 3);
  283. append(p_source);
  284. append(p_target);
  285. append(p_type);
  286. }
  287. void GDScriptByteCodeGenerator::write_and_left_operand(const Address &p_left_operand) {
  288. append(GDScriptFunction::OPCODE_JUMP_IF_NOT, 1);
  289. append(p_left_operand);
  290. logic_op_jump_pos1.push_back(opcodes.size());
  291. append(0); // Jump target, will be patched.
  292. }
  293. void GDScriptByteCodeGenerator::write_and_right_operand(const Address &p_right_operand) {
  294. append(GDScriptFunction::OPCODE_JUMP_IF_NOT, 1);
  295. append(p_right_operand);
  296. logic_op_jump_pos2.push_back(opcodes.size());
  297. append(0); // Jump target, will be patched.
  298. }
  299. void GDScriptByteCodeGenerator::write_end_and(const Address &p_target) {
  300. // If here means both operands are true.
  301. append(GDScriptFunction::OPCODE_ASSIGN_TRUE, 1);
  302. append(p_target);
  303. // Jump away from the fail condition.
  304. append(GDScriptFunction::OPCODE_JUMP, 0);
  305. append(opcodes.size() + 3);
  306. // Here it means one of operands is false.
  307. patch_jump(logic_op_jump_pos1.back()->get());
  308. patch_jump(logic_op_jump_pos2.back()->get());
  309. logic_op_jump_pos1.pop_back();
  310. logic_op_jump_pos2.pop_back();
  311. append(GDScriptFunction::OPCODE_ASSIGN_FALSE, 0);
  312. append(p_target);
  313. }
  314. void GDScriptByteCodeGenerator::write_or_left_operand(const Address &p_left_operand) {
  315. append(GDScriptFunction::OPCODE_JUMP_IF, 1);
  316. append(p_left_operand);
  317. logic_op_jump_pos1.push_back(opcodes.size());
  318. append(0); // Jump target, will be patched.
  319. }
  320. void GDScriptByteCodeGenerator::write_or_right_operand(const Address &p_right_operand) {
  321. append(GDScriptFunction::OPCODE_JUMP_IF, 1);
  322. append(p_right_operand);
  323. logic_op_jump_pos2.push_back(opcodes.size());
  324. append(0); // Jump target, will be patched.
  325. }
  326. void GDScriptByteCodeGenerator::write_end_or(const Address &p_target) {
  327. // If here means both operands are false.
  328. append(GDScriptFunction::OPCODE_ASSIGN_FALSE, 1);
  329. append(p_target);
  330. // Jump away from the success condition.
  331. append(GDScriptFunction::OPCODE_JUMP, 0);
  332. append(opcodes.size() + 3);
  333. // Here it means one of operands is false.
  334. patch_jump(logic_op_jump_pos1.back()->get());
  335. patch_jump(logic_op_jump_pos2.back()->get());
  336. logic_op_jump_pos1.pop_back();
  337. logic_op_jump_pos2.pop_back();
  338. append(GDScriptFunction::OPCODE_ASSIGN_TRUE, 1);
  339. append(p_target);
  340. }
  341. void GDScriptByteCodeGenerator::write_start_ternary(const Address &p_target) {
  342. ternary_result.push_back(p_target);
  343. }
  344. void GDScriptByteCodeGenerator::write_ternary_condition(const Address &p_condition) {
  345. append(GDScriptFunction::OPCODE_JUMP_IF_NOT, 1);
  346. append(p_condition);
  347. ternary_jump_fail_pos.push_back(opcodes.size());
  348. append(0); // Jump target, will be patched.
  349. }
  350. void GDScriptByteCodeGenerator::write_ternary_true_expr(const Address &p_expr) {
  351. append(GDScriptFunction::OPCODE_ASSIGN, 2);
  352. append(ternary_result.back()->get());
  353. append(p_expr);
  354. // Jump away from the false path.
  355. append(GDScriptFunction::OPCODE_JUMP, 0);
  356. ternary_jump_skip_pos.push_back(opcodes.size());
  357. append(0);
  358. // Fail must jump here.
  359. patch_jump(ternary_jump_fail_pos.back()->get());
  360. ternary_jump_fail_pos.pop_back();
  361. }
  362. void GDScriptByteCodeGenerator::write_ternary_false_expr(const Address &p_expr) {
  363. append(GDScriptFunction::OPCODE_ASSIGN, 2);
  364. append(ternary_result.back()->get());
  365. append(p_expr);
  366. }
  367. void GDScriptByteCodeGenerator::write_end_ternary() {
  368. patch_jump(ternary_jump_skip_pos.back()->get());
  369. ternary_jump_skip_pos.pop_back();
  370. }
  371. void GDScriptByteCodeGenerator::write_set(const Address &p_target, const Address &p_index, const Address &p_source) {
  372. if (HAS_BUILTIN_TYPE(p_target)) {
  373. if (IS_BUILTIN_TYPE(p_index, Variant::INT) && Variant::get_member_validated_indexed_setter(p_target.type.builtin_type)) {
  374. // Use indexed setter instead.
  375. Variant::ValidatedIndexedSetter setter = Variant::get_member_validated_indexed_setter(p_target.type.builtin_type);
  376. append(GDScriptFunction::OPCODE_SET_INDEXED_VALIDATED, 3);
  377. append(p_target);
  378. append(p_index);
  379. append(p_source);
  380. append(setter);
  381. return;
  382. } else if (Variant::get_member_validated_keyed_setter(p_target.type.builtin_type)) {
  383. Variant::ValidatedKeyedSetter setter = Variant::get_member_validated_keyed_setter(p_target.type.builtin_type);
  384. append(GDScriptFunction::OPCODE_SET_KEYED_VALIDATED, 3);
  385. append(p_target);
  386. append(p_index);
  387. append(p_source);
  388. append(setter);
  389. return;
  390. }
  391. }
  392. append(GDScriptFunction::OPCODE_SET_KEYED, 3);
  393. append(p_target);
  394. append(p_index);
  395. append(p_source);
  396. }
  397. void GDScriptByteCodeGenerator::write_get(const Address &p_target, const Address &p_index, const Address &p_source) {
  398. if (HAS_BUILTIN_TYPE(p_source)) {
  399. if (IS_BUILTIN_TYPE(p_index, Variant::INT) && Variant::get_member_validated_indexed_getter(p_source.type.builtin_type)) {
  400. // Use indexed getter instead.
  401. Variant::ValidatedIndexedGetter getter = Variant::get_member_validated_indexed_getter(p_source.type.builtin_type);
  402. append(GDScriptFunction::OPCODE_GET_INDEXED_VALIDATED, 3);
  403. append(p_source);
  404. append(p_index);
  405. append(p_target);
  406. append(getter);
  407. return;
  408. } else if (Variant::get_member_validated_keyed_getter(p_source.type.builtin_type)) {
  409. Variant::ValidatedKeyedGetter getter = Variant::get_member_validated_keyed_getter(p_source.type.builtin_type);
  410. append(GDScriptFunction::OPCODE_GET_KEYED_VALIDATED, 3);
  411. append(p_source);
  412. append(p_index);
  413. append(p_target);
  414. append(getter);
  415. return;
  416. }
  417. }
  418. append(GDScriptFunction::OPCODE_GET_KEYED, 3);
  419. append(p_source);
  420. append(p_index);
  421. append(p_target);
  422. }
  423. void GDScriptByteCodeGenerator::write_set_named(const Address &p_target, const StringName &p_name, const Address &p_source) {
  424. if (HAS_BUILTIN_TYPE(p_target) && Variant::get_member_validated_setter(p_target.type.builtin_type, p_name)) {
  425. Variant::ValidatedSetter setter = Variant::get_member_validated_setter(p_target.type.builtin_type, p_name);
  426. append(GDScriptFunction::OPCODE_SET_NAMED_VALIDATED, 2);
  427. append(p_target);
  428. append(p_source);
  429. append(setter);
  430. return;
  431. }
  432. append(GDScriptFunction::OPCODE_SET_NAMED, 2);
  433. append(p_target);
  434. append(p_source);
  435. append(p_name);
  436. }
  437. void GDScriptByteCodeGenerator::write_get_named(const Address &p_target, const StringName &p_name, const Address &p_source) {
  438. if (HAS_BUILTIN_TYPE(p_source) && Variant::get_member_validated_getter(p_source.type.builtin_type, p_name)) {
  439. Variant::ValidatedGetter getter = Variant::get_member_validated_getter(p_source.type.builtin_type, p_name);
  440. append(GDScriptFunction::OPCODE_GET_NAMED_VALIDATED, 2);
  441. append(p_source);
  442. append(p_target);
  443. append(getter);
  444. return;
  445. }
  446. append(GDScriptFunction::OPCODE_GET_NAMED, 2);
  447. append(p_source);
  448. append(p_target);
  449. append(p_name);
  450. }
  451. void GDScriptByteCodeGenerator::write_set_member(const Address &p_value, const StringName &p_name) {
  452. append(GDScriptFunction::OPCODE_SET_MEMBER, 1);
  453. append(p_value);
  454. append(p_name);
  455. }
  456. void GDScriptByteCodeGenerator::write_get_member(const Address &p_target, const StringName &p_name) {
  457. append(GDScriptFunction::OPCODE_GET_MEMBER, 1);
  458. append(p_target);
  459. append(p_name);
  460. }
  461. void GDScriptByteCodeGenerator::write_assign(const Address &p_target, const Address &p_source) {
  462. if (p_target.type.has_type && !p_source.type.has_type) {
  463. // Typed assignment.
  464. switch (p_target.type.kind) {
  465. case GDScriptDataType::BUILTIN: {
  466. append(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN, 2);
  467. append(p_target);
  468. append(p_source);
  469. append(p_target.type.builtin_type);
  470. } break;
  471. case GDScriptDataType::NATIVE: {
  472. int class_idx = GDScriptLanguage::get_singleton()->get_global_map()[p_target.type.native_type];
  473. class_idx |= (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS);
  474. append(GDScriptFunction::OPCODE_ASSIGN_TYPED_NATIVE, 3);
  475. append(p_target);
  476. append(p_source);
  477. append(class_idx);
  478. } break;
  479. case GDScriptDataType::SCRIPT:
  480. case GDScriptDataType::GDSCRIPT: {
  481. Variant script = p_target.type.script_type;
  482. int idx = get_constant_pos(script);
  483. idx |= (GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS);
  484. append(GDScriptFunction::OPCODE_ASSIGN_TYPED_SCRIPT, 3);
  485. append(p_target);
  486. append(p_source);
  487. append(idx);
  488. } break;
  489. default: {
  490. ERR_PRINT("Compiler bug: unresolved assign.");
  491. // Shouldn't get here, but fail-safe to a regular assignment
  492. append(GDScriptFunction::OPCODE_ASSIGN, 2);
  493. append(p_target);
  494. append(p_source);
  495. }
  496. }
  497. } else {
  498. if (p_target.type.kind == GDScriptDataType::BUILTIN && p_source.type.kind == GDScriptDataType::BUILTIN && p_target.type.builtin_type != p_source.type.builtin_type) {
  499. // Need conversion..
  500. append(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN, 2);
  501. append(p_target);
  502. append(p_source);
  503. append(p_target.type.builtin_type);
  504. } else {
  505. // Either untyped assignment or already type-checked by the parser
  506. append(GDScriptFunction::OPCODE_ASSIGN, 2);
  507. append(p_target);
  508. append(p_source);
  509. }
  510. }
  511. }
  512. void GDScriptByteCodeGenerator::write_assign_true(const Address &p_target) {
  513. append(GDScriptFunction::OPCODE_ASSIGN_TRUE, 1);
  514. append(p_target);
  515. }
  516. void GDScriptByteCodeGenerator::write_assign_false(const Address &p_target) {
  517. append(GDScriptFunction::OPCODE_ASSIGN_FALSE, 1);
  518. append(p_target);
  519. }
  520. void GDScriptByteCodeGenerator::write_cast(const Address &p_target, const Address &p_source, const GDScriptDataType &p_type) {
  521. int index = 0;
  522. switch (p_type.kind) {
  523. case GDScriptDataType::BUILTIN: {
  524. append(GDScriptFunction::OPCODE_CAST_TO_BUILTIN, 2);
  525. index = p_type.builtin_type;
  526. } break;
  527. case GDScriptDataType::NATIVE: {
  528. int class_idx = GDScriptLanguage::get_singleton()->get_global_map()[p_type.native_type];
  529. class_idx |= (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS);
  530. append(GDScriptFunction::OPCODE_CAST_TO_NATIVE, 3);
  531. index = class_idx;
  532. } break;
  533. case GDScriptDataType::SCRIPT:
  534. case GDScriptDataType::GDSCRIPT: {
  535. Variant script = p_type.script_type;
  536. int idx = get_constant_pos(script);
  537. idx |= (GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS);
  538. append(GDScriptFunction::OPCODE_CAST_TO_SCRIPT, 3);
  539. index = idx;
  540. } break;
  541. default: {
  542. return;
  543. }
  544. }
  545. append(p_source);
  546. append(p_target);
  547. append(index);
  548. }
  549. void GDScriptByteCodeGenerator::write_call(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) {
  550. append(p_target.mode == Address::NIL ? GDScriptFunction::OPCODE_CALL : GDScriptFunction::OPCODE_CALL_RETURN, 2 + p_arguments.size());
  551. for (int i = 0; i < p_arguments.size(); i++) {
  552. append(p_arguments[i]);
  553. }
  554. append(p_base);
  555. append(p_target);
  556. append(p_arguments.size());
  557. append(p_function_name);
  558. }
  559. void GDScriptByteCodeGenerator::write_super_call(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) {
  560. append(GDScriptFunction::OPCODE_CALL_SELF_BASE, 1 + p_arguments.size());
  561. for (int i = 0; i < p_arguments.size(); i++) {
  562. append(p_arguments[i]);
  563. }
  564. append(p_target);
  565. append(p_arguments.size());
  566. append(p_function_name);
  567. }
  568. void GDScriptByteCodeGenerator::write_call_async(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) {
  569. append(GDScriptFunction::OPCODE_CALL_ASYNC, 2 + p_arguments.size());
  570. for (int i = 0; i < p_arguments.size(); i++) {
  571. append(p_arguments[i]);
  572. }
  573. append(p_base);
  574. append(p_target);
  575. append(p_arguments.size());
  576. append(p_function_name);
  577. }
  578. void GDScriptByteCodeGenerator::write_call_builtin(const Address &p_target, GDScriptFunctions::Function p_function, const Vector<Address> &p_arguments) {
  579. append(GDScriptFunction::OPCODE_CALL_BUILT_IN, 1 + p_arguments.size());
  580. for (int i = 0; i < p_arguments.size(); i++) {
  581. append(p_arguments[i]);
  582. }
  583. append(p_target);
  584. append(p_arguments.size());
  585. append(p_function);
  586. }
  587. void GDScriptByteCodeGenerator::write_call_builtin_type(const Address &p_target, const Address &p_base, Variant::Type p_type, const StringName &p_method, const Vector<Address> &p_arguments) {
  588. bool is_validated = false;
  589. // Check if all types are correct.
  590. if (Variant::is_builtin_method_vararg(p_type, p_method)) {
  591. is_validated = true; // Vararg works fine with any argument, since they can be any type.
  592. } else if (p_arguments.size() == Variant::get_builtin_method_argument_count(p_type, p_method)) {
  593. bool all_types_exact = true;
  594. for (int i = 0; i < p_arguments.size(); i++) {
  595. if (!IS_BUILTIN_TYPE(p_arguments[i], Variant::get_builtin_method_argument_type(p_type, p_method, i))) {
  596. all_types_exact = false;
  597. break;
  598. }
  599. }
  600. is_validated = all_types_exact;
  601. }
  602. if (!is_validated) {
  603. // Perform regular call.
  604. write_call(p_target, p_base, p_method, p_arguments);
  605. return;
  606. }
  607. append(GDScriptFunction::OPCODE_CALL_BUILTIN_TYPE_VALIDATED, 2 + p_arguments.size());
  608. for (int i = 0; i < p_arguments.size(); i++) {
  609. append(p_arguments[i]);
  610. }
  611. append(p_base);
  612. append(p_target);
  613. append(p_arguments.size());
  614. append(Variant::get_validated_builtin_method(p_type, p_method));
  615. }
  616. void GDScriptByteCodeGenerator::write_call_method_bind(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) {
  617. append(p_target.mode == Address::NIL ? GDScriptFunction::OPCODE_CALL_METHOD_BIND : GDScriptFunction::OPCODE_CALL_METHOD_BIND_RET, 2 + p_arguments.size());
  618. for (int i = 0; i < p_arguments.size(); i++) {
  619. append(p_arguments[i]);
  620. }
  621. append(p_base);
  622. append(p_target);
  623. append(p_arguments.size());
  624. append(p_method);
  625. }
  626. void GDScriptByteCodeGenerator::write_call_ptrcall(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) {
  627. #define CASE_TYPE(m_type) \
  628. case Variant::m_type: \
  629. append(GDScriptFunction::OPCODE_CALL_PTRCALL_##m_type, 2 + p_arguments.size()); \
  630. break
  631. bool is_ptrcall = true;
  632. if (p_method->has_return()) {
  633. MethodInfo info;
  634. ClassDB::get_method_info(p_method->get_instance_class(), p_method->get_name(), &info);
  635. switch (info.return_val.type) {
  636. CASE_TYPE(BOOL);
  637. CASE_TYPE(INT);
  638. CASE_TYPE(FLOAT);
  639. CASE_TYPE(STRING);
  640. CASE_TYPE(VECTOR2);
  641. CASE_TYPE(VECTOR2I);
  642. CASE_TYPE(RECT2);
  643. CASE_TYPE(RECT2I);
  644. CASE_TYPE(VECTOR3);
  645. CASE_TYPE(VECTOR3I);
  646. CASE_TYPE(TRANSFORM2D);
  647. CASE_TYPE(PLANE);
  648. CASE_TYPE(AABB);
  649. CASE_TYPE(BASIS);
  650. CASE_TYPE(TRANSFORM);
  651. CASE_TYPE(COLOR);
  652. CASE_TYPE(STRING_NAME);
  653. CASE_TYPE(NODE_PATH);
  654. CASE_TYPE(RID);
  655. CASE_TYPE(QUAT);
  656. CASE_TYPE(OBJECT);
  657. CASE_TYPE(CALLABLE);
  658. CASE_TYPE(SIGNAL);
  659. CASE_TYPE(DICTIONARY);
  660. CASE_TYPE(ARRAY);
  661. CASE_TYPE(PACKED_BYTE_ARRAY);
  662. CASE_TYPE(PACKED_INT32_ARRAY);
  663. CASE_TYPE(PACKED_INT64_ARRAY);
  664. CASE_TYPE(PACKED_FLOAT32_ARRAY);
  665. CASE_TYPE(PACKED_FLOAT64_ARRAY);
  666. CASE_TYPE(PACKED_STRING_ARRAY);
  667. CASE_TYPE(PACKED_VECTOR2_ARRAY);
  668. CASE_TYPE(PACKED_VECTOR3_ARRAY);
  669. CASE_TYPE(PACKED_COLOR_ARRAY);
  670. default:
  671. append(p_target.mode == Address::NIL ? GDScriptFunction::OPCODE_CALL_METHOD_BIND : GDScriptFunction::OPCODE_CALL_METHOD_BIND_RET, 2 + p_arguments.size());
  672. is_ptrcall = false;
  673. break;
  674. }
  675. } else {
  676. append(GDScriptFunction::OPCODE_CALL_PTRCALL_NO_RETURN, 2 + p_arguments.size());
  677. }
  678. for (int i = 0; i < p_arguments.size(); i++) {
  679. append(p_arguments[i]);
  680. }
  681. append(p_base);
  682. append(p_target);
  683. append(p_arguments.size());
  684. append(p_method);
  685. if (is_ptrcall) {
  686. alloc_ptrcall(p_arguments.size());
  687. }
  688. #undef CASE_TYPE
  689. }
  690. void GDScriptByteCodeGenerator::write_call_self(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) {
  691. append(p_target.mode == Address::NIL ? GDScriptFunction::OPCODE_CALL : GDScriptFunction::OPCODE_CALL_RETURN, 2 + p_arguments.size());
  692. for (int i = 0; i < p_arguments.size(); i++) {
  693. append(p_arguments[i]);
  694. }
  695. append(GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS);
  696. append(p_target);
  697. append(p_arguments.size());
  698. append(p_function_name);
  699. }
  700. void GDScriptByteCodeGenerator::write_call_script_function(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) {
  701. append(p_target.mode == Address::NIL ? GDScriptFunction::OPCODE_CALL : GDScriptFunction::OPCODE_CALL_RETURN, 2 + p_arguments.size());
  702. for (int i = 0; i < p_arguments.size(); i++) {
  703. append(p_arguments[i]);
  704. }
  705. append(p_base);
  706. append(p_target);
  707. append(p_arguments.size());
  708. append(p_function_name);
  709. }
  710. void GDScriptByteCodeGenerator::write_construct(const Address &p_target, Variant::Type p_type, const Vector<Address> &p_arguments) {
  711. append(GDScriptFunction::OPCODE_CONSTRUCT, 1 + p_arguments.size());
  712. for (int i = 0; i < p_arguments.size(); i++) {
  713. append(p_arguments[i]);
  714. }
  715. append(p_target);
  716. append(p_arguments.size());
  717. append(p_type);
  718. }
  719. void GDScriptByteCodeGenerator::write_construct_array(const Address &p_target, const Vector<Address> &p_arguments) {
  720. append(GDScriptFunction::OPCODE_CONSTRUCT_ARRAY, 1 + p_arguments.size());
  721. for (int i = 0; i < p_arguments.size(); i++) {
  722. append(p_arguments[i]);
  723. }
  724. append(p_target);
  725. append(p_arguments.size());
  726. }
  727. void GDScriptByteCodeGenerator::write_construct_dictionary(const Address &p_target, const Vector<Address> &p_arguments) {
  728. append(GDScriptFunction::OPCODE_CONSTRUCT_DICTIONARY, 1 + p_arguments.size());
  729. for (int i = 0; i < p_arguments.size(); i++) {
  730. append(p_arguments[i]);
  731. }
  732. append(p_target);
  733. append(p_arguments.size() / 2); // This is number of key-value pairs, so only half of actual arguments.
  734. }
  735. void GDScriptByteCodeGenerator::write_await(const Address &p_target, const Address &p_operand) {
  736. append(GDScriptFunction::OPCODE_AWAIT, 1);
  737. append(p_operand);
  738. append(GDScriptFunction::OPCODE_AWAIT_RESUME, 1);
  739. append(p_target);
  740. }
  741. void GDScriptByteCodeGenerator::write_if(const Address &p_condition) {
  742. append(GDScriptFunction::OPCODE_JUMP_IF_NOT, 1);
  743. append(p_condition);
  744. if_jmp_addrs.push_back(opcodes.size());
  745. append(0); // Jump destination, will be patched.
  746. }
  747. void GDScriptByteCodeGenerator::write_else() {
  748. append(GDScriptFunction::OPCODE_JUMP, 0); // Jump from true if block;
  749. int else_jmp_addr = opcodes.size();
  750. append(0); // Jump destination, will be patched.
  751. patch_jump(if_jmp_addrs.back()->get());
  752. if_jmp_addrs.pop_back();
  753. if_jmp_addrs.push_back(else_jmp_addr);
  754. }
  755. void GDScriptByteCodeGenerator::write_endif() {
  756. patch_jump(if_jmp_addrs.back()->get());
  757. if_jmp_addrs.pop_back();
  758. }
  759. void GDScriptByteCodeGenerator::write_for(const Address &p_variable, const Address &p_list) {
  760. int counter_pos = add_temporary() | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
  761. int container_pos = add_temporary() | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
  762. current_breaks_to_patch.push_back(List<int>());
  763. // Assign container.
  764. append(GDScriptFunction::OPCODE_ASSIGN, 2);
  765. append(container_pos);
  766. append(p_list);
  767. GDScriptFunction::Opcode begin_opcode = GDScriptFunction::OPCODE_ITERATE_BEGIN;
  768. GDScriptFunction::Opcode iterate_opcode = GDScriptFunction::OPCODE_ITERATE;
  769. if (p_list.type.has_type) {
  770. if (p_list.type.kind == GDScriptDataType::BUILTIN) {
  771. switch (p_list.type.builtin_type) {
  772. case Variant::INT:
  773. begin_opcode = GDScriptFunction::OPCODE_ITERATE_BEGIN_INT;
  774. iterate_opcode = GDScriptFunction::OPCODE_ITERATE_INT;
  775. break;
  776. case Variant::FLOAT:
  777. begin_opcode = GDScriptFunction::OPCODE_ITERATE_BEGIN_FLOAT;
  778. iterate_opcode = GDScriptFunction::OPCODE_ITERATE_FLOAT;
  779. break;
  780. case Variant::VECTOR2:
  781. begin_opcode = GDScriptFunction::OPCODE_ITERATE_BEGIN_VECTOR2;
  782. iterate_opcode = GDScriptFunction::OPCODE_ITERATE_VECTOR2;
  783. break;
  784. case Variant::VECTOR2I:
  785. begin_opcode = GDScriptFunction::OPCODE_ITERATE_BEGIN_VECTOR2I;
  786. iterate_opcode = GDScriptFunction::OPCODE_ITERATE_VECTOR2I;
  787. break;
  788. case Variant::VECTOR3:
  789. begin_opcode = GDScriptFunction::OPCODE_ITERATE_BEGIN_VECTOR3;
  790. iterate_opcode = GDScriptFunction::OPCODE_ITERATE_VECTOR3;
  791. break;
  792. case Variant::VECTOR3I:
  793. begin_opcode = GDScriptFunction::OPCODE_ITERATE_BEGIN_VECTOR3I;
  794. iterate_opcode = GDScriptFunction::OPCODE_ITERATE_VECTOR3I;
  795. break;
  796. case Variant::STRING:
  797. begin_opcode = GDScriptFunction::OPCODE_ITERATE_BEGIN_STRING;
  798. iterate_opcode = GDScriptFunction::OPCODE_ITERATE_STRING;
  799. break;
  800. case Variant::DICTIONARY:
  801. begin_opcode = GDScriptFunction::OPCODE_ITERATE_BEGIN_DICTIONARY;
  802. iterate_opcode = GDScriptFunction::OPCODE_ITERATE_DICTIONARY;
  803. break;
  804. case Variant::ARRAY:
  805. begin_opcode = GDScriptFunction::OPCODE_ITERATE_BEGIN_ARRAY;
  806. iterate_opcode = GDScriptFunction::OPCODE_ITERATE_ARRAY;
  807. break;
  808. case Variant::PACKED_BYTE_ARRAY:
  809. begin_opcode = GDScriptFunction::OPCODE_ITERATE_BEGIN_PACKED_BYTE_ARRAY;
  810. iterate_opcode = GDScriptFunction::OPCODE_ITERATE_PACKED_BYTE_ARRAY;
  811. break;
  812. case Variant::PACKED_INT32_ARRAY:
  813. begin_opcode = GDScriptFunction::OPCODE_ITERATE_BEGIN_PACKED_INT32_ARRAY;
  814. iterate_opcode = GDScriptFunction::OPCODE_ITERATE_PACKED_INT32_ARRAY;
  815. break;
  816. case Variant::PACKED_INT64_ARRAY:
  817. begin_opcode = GDScriptFunction::OPCODE_ITERATE_BEGIN_PACKED_INT64_ARRAY;
  818. iterate_opcode = GDScriptFunction::OPCODE_ITERATE_PACKED_INT64_ARRAY;
  819. break;
  820. case Variant::PACKED_FLOAT32_ARRAY:
  821. begin_opcode = GDScriptFunction::OPCODE_ITERATE_BEGIN_PACKED_FLOAT32_ARRAY;
  822. iterate_opcode = GDScriptFunction::OPCODE_ITERATE_PACKED_FLOAT32_ARRAY;
  823. break;
  824. case Variant::PACKED_FLOAT64_ARRAY:
  825. begin_opcode = GDScriptFunction::OPCODE_ITERATE_BEGIN_PACKED_FLOAT64_ARRAY;
  826. iterate_opcode = GDScriptFunction::OPCODE_ITERATE_PACKED_FLOAT64_ARRAY;
  827. break;
  828. case Variant::PACKED_STRING_ARRAY:
  829. begin_opcode = GDScriptFunction::OPCODE_ITERATE_BEGIN_PACKED_STRING_ARRAY;
  830. iterate_opcode = GDScriptFunction::OPCODE_ITERATE_PACKED_STRING_ARRAY;
  831. break;
  832. case Variant::PACKED_VECTOR2_ARRAY:
  833. begin_opcode = GDScriptFunction::OPCODE_ITERATE_BEGIN_PACKED_VECTOR2_ARRAY;
  834. iterate_opcode = GDScriptFunction::OPCODE_ITERATE_PACKED_VECTOR2_ARRAY;
  835. break;
  836. case Variant::PACKED_VECTOR3_ARRAY:
  837. begin_opcode = GDScriptFunction::OPCODE_ITERATE_BEGIN_PACKED_VECTOR3_ARRAY;
  838. iterate_opcode = GDScriptFunction::OPCODE_ITERATE_PACKED_VECTOR3_ARRAY;
  839. break;
  840. case Variant::PACKED_COLOR_ARRAY:
  841. begin_opcode = GDScriptFunction::OPCODE_ITERATE_BEGIN_PACKED_COLOR_ARRAY;
  842. iterate_opcode = GDScriptFunction::OPCODE_ITERATE_PACKED_COLOR_ARRAY;
  843. break;
  844. default:
  845. break;
  846. }
  847. } else {
  848. begin_opcode = GDScriptFunction::OPCODE_ITERATE_BEGIN_OBJECT;
  849. iterate_opcode = GDScriptFunction::OPCODE_ITERATE_OBJECT;
  850. }
  851. }
  852. // Begin loop.
  853. append(begin_opcode, 3);
  854. append(counter_pos);
  855. append(container_pos);
  856. append(p_variable);
  857. for_jmp_addrs.push_back(opcodes.size());
  858. append(0); // End of loop address, will be patched.
  859. append(GDScriptFunction::OPCODE_JUMP, 0);
  860. append(opcodes.size() + 6); // Skip over 'continue' code.
  861. // Next iteration.
  862. int continue_addr = opcodes.size();
  863. continue_addrs.push_back(continue_addr);
  864. append(iterate_opcode, 3);
  865. append(counter_pos);
  866. append(container_pos);
  867. append(p_variable);
  868. for_jmp_addrs.push_back(opcodes.size());
  869. append(0); // Jump destination, will be patched.
  870. }
  871. void GDScriptByteCodeGenerator::write_endfor() {
  872. // Jump back to loop check.
  873. append(GDScriptFunction::OPCODE_JUMP, 0);
  874. append(continue_addrs.back()->get());
  875. continue_addrs.pop_back();
  876. // Patch end jumps (two of them).
  877. for (int i = 0; i < 2; i++) {
  878. patch_jump(for_jmp_addrs.back()->get());
  879. for_jmp_addrs.pop_back();
  880. }
  881. // Patch break statements.
  882. for (const List<int>::Element *E = current_breaks_to_patch.back()->get().front(); E; E = E->next()) {
  883. patch_jump(E->get());
  884. }
  885. current_breaks_to_patch.pop_back();
  886. // Remove loop temporaries.
  887. pop_temporary();
  888. pop_temporary();
  889. }
  890. void GDScriptByteCodeGenerator::start_while_condition() {
  891. current_breaks_to_patch.push_back(List<int>());
  892. continue_addrs.push_back(opcodes.size());
  893. }
  894. void GDScriptByteCodeGenerator::write_while(const Address &p_condition) {
  895. // Condition check.
  896. append(GDScriptFunction::OPCODE_JUMP_IF_NOT, 1);
  897. append(p_condition);
  898. while_jmp_addrs.push_back(opcodes.size());
  899. append(0); // End of loop address, will be patched.
  900. }
  901. void GDScriptByteCodeGenerator::write_endwhile() {
  902. // Jump back to loop check.
  903. append(GDScriptFunction::OPCODE_JUMP, 0);
  904. append(continue_addrs.back()->get());
  905. continue_addrs.pop_back();
  906. // Patch end jump.
  907. patch_jump(while_jmp_addrs.back()->get());
  908. while_jmp_addrs.pop_back();
  909. // Patch break statements.
  910. for (const List<int>::Element *E = current_breaks_to_patch.back()->get().front(); E; E = E->next()) {
  911. patch_jump(E->get());
  912. }
  913. current_breaks_to_patch.pop_back();
  914. }
  915. void GDScriptByteCodeGenerator::start_match() {
  916. match_continues_to_patch.push_back(List<int>());
  917. }
  918. void GDScriptByteCodeGenerator::start_match_branch() {
  919. // Patch continue statements.
  920. for (const List<int>::Element *E = match_continues_to_patch.back()->get().front(); E; E = E->next()) {
  921. patch_jump(E->get());
  922. }
  923. match_continues_to_patch.pop_back();
  924. // Start a new list for next branch.
  925. match_continues_to_patch.push_back(List<int>());
  926. }
  927. void GDScriptByteCodeGenerator::end_match() {
  928. // Patch continue statements.
  929. for (const List<int>::Element *E = match_continues_to_patch.back()->get().front(); E; E = E->next()) {
  930. patch_jump(E->get());
  931. }
  932. match_continues_to_patch.pop_back();
  933. }
  934. void GDScriptByteCodeGenerator::write_break() {
  935. append(GDScriptFunction::OPCODE_JUMP, 0);
  936. current_breaks_to_patch.back()->get().push_back(opcodes.size());
  937. append(0);
  938. }
  939. void GDScriptByteCodeGenerator::write_continue() {
  940. append(GDScriptFunction::OPCODE_JUMP, 0);
  941. append(continue_addrs.back()->get());
  942. }
  943. void GDScriptByteCodeGenerator::write_continue_match() {
  944. append(GDScriptFunction::OPCODE_JUMP, 0);
  945. match_continues_to_patch.back()->get().push_back(opcodes.size());
  946. append(0);
  947. }
  948. void GDScriptByteCodeGenerator::write_breakpoint() {
  949. append(GDScriptFunction::OPCODE_BREAKPOINT, 0);
  950. }
  951. void GDScriptByteCodeGenerator::write_newline(int p_line) {
  952. append(GDScriptFunction::OPCODE_LINE, 0);
  953. append(p_line);
  954. current_line = p_line;
  955. }
  956. void GDScriptByteCodeGenerator::write_return(const Address &p_return_value) {
  957. append(GDScriptFunction::OPCODE_RETURN, 1);
  958. append(p_return_value);
  959. }
  960. void GDScriptByteCodeGenerator::write_assert(const Address &p_test, const Address &p_message) {
  961. append(GDScriptFunction::OPCODE_ASSERT, 2);
  962. append(p_test);
  963. append(p_message);
  964. }
  965. void GDScriptByteCodeGenerator::start_block() {
  966. push_stack_identifiers();
  967. }
  968. void GDScriptByteCodeGenerator::end_block() {
  969. pop_stack_identifiers();
  970. }
  971. GDScriptByteCodeGenerator::~GDScriptByteCodeGenerator() {
  972. if (!ended && function != nullptr) {
  973. memdelete(function);
  974. }
  975. }